Android BLE Gatt连接问题连接超时状态:8

问题描述

我正在开发一个Android应用,该应用可以发现并连接到我的rPi 3B +所宣传的GATT服务。我已经完成开发的iOS应用程序可以正常工作。但是,几乎每次(95%)我的Android应用程序都连接到GATT服务器并尝试发现服务时,GATT连接会超时并显示状态响应代码:8。

这是我的android代码

package com.example.myapplication;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelUuid;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

BluetoothAdapter bluetoothAdapter;
BluetoothLeScanner bluetoothLeScanner;
BluetoothManager bluetoothManager;
BluetoothScanCallback bluetoothScanCallback;
BluetoothGatt gattClient;
BluetoothGattCharacteristic characteristicID;
TextView scanningText;

final UUID SERVICE_UUID = UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
final UUID CHaraCTERISTIC_UUID_ID = UUID.fromString("6E400002-B5A3-F393-E0A9-E50E24DCCA9E");
final UUID DESCRIPTOR_UUID_ID = UUID.fromString("00002902-0000-1000-8000-00805F9B34FB");

ArrayList<String> wifiSSIDs = new ArrayList<>() ;
ListView listViewSSID;
ArrayAdapter<String> SSIDadapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    getSupportActionBar().setDefaultdisplayHomeAsUpEnabled(true);
    listViewSSID = findViewById(R.id.lv_SSID);
    scanningText = findViewById(R.id.scanningText);
    SSIDadapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,wifiSSIDs);
    listViewSSID.setAdapter(SSIDadapter);
    listViewSSID.setonItemClickListener(this);

    bluetoothManager = (BluetoothManager) getSystemService(BLUetoOTH_SERVICE);
    bluetoothAdapter = bluetoothManager.getAdapter();
    startScan();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i("App","App closing...");
    gattClient.disconnect();
    gattClient.close();
}


private void startScan(){

    ScanFilter scanFilter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(SERVICE_UUID)).build();
    ArrayList<ScanFilter> filters = new ArrayList<>();

    filters.add(scanFilter);

    ScanSettings scanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();

    Log.i("Bluetooth Scan","startScan()");
    bluetoothScanCallback = new BluetoothScanCallback();
    bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
    bluetoothLeScanner.startScan(filters,scanSettings,bluetoothScanCallback);
}

private void connectDevice(BluetoothDevice device) {
    if (device == null) Log.i("Bluetooth Connection","Device is null");
    GattClientCallback gattClientCallback = new GattClientCallback();
    gattClient = device.connectGatt(this,false,gattClientCallback,BluetoothDevice.TRANSPORT_LE);
}

private class BluetoothScanCallback extends ScanCallback {
    @Override
    public void onScanResult(int callbackType,final ScanResult result) {
        Log.i("Bluetooth Scan Result","onScanResult");
        bluetoothLeScanner.stopScan(bluetoothScanCallback); // stop scan
        connectDevice(result.getDevice());
    }

    @Override
    public void onBatchScanResults(List<ScanResult> results) {
        Log.i("Bluetooth Scan Result","onBathScanResults");
    }

    @Override
    public void onScanFailed(int errorCode) {
        Log.i("Bluetooth Scan Result","ErrorCode: " + errorCode);
    }
}

private class GattClientCallback extends BluetoothGattCallback {
    @Override
    public void onConnectionStateChange(final BluetoothGatt gatt,int status,int newState) {
        super.onConnectionStateChange(gatt,status,newState);
        Log.i("Bluetooth Connection","onConnectionStateChange");

        if (status == BluetoothGatt.GATT_FAILURE) {
            Log.i("Bluetooth Connection","onConnectionStateChange GATT FAILURE");
            return;
        } else if (status != BluetoothGatt.GATT_SUCCESS) {
            Log.i("Bluetooth Connection","onConnectionStateChange != GATT_SUCCESS");
            Log.i("Bluetooth Connection",String.valueOf(status));

            startScan();
            return;
        }
        else {
            final BluetoothDevice device = gatt.getDevice();
            if (newState == BluetoothProfile.STATE_CONNECTED) {

                Log.i("Bluetooth Connection","onConnectionStateChange CONNECTED");

                new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                    gatt.discoverServices(); }
                },500);

            } else if (newState == BluetoothProfile.STATE_disCONNECTED) {
                Log.i("Bluetooth Connection","onConnectionStateChange disCONNECTED");
            }
        }
    }

    @Override
    public void onServicesdiscovered(final BluetoothGatt gatt,int status) {
        super.onServicesdiscovered(gatt,status);
        Log.i("Bluetooth Services","onServicesdiscovered");

        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                characteristicID = gatt.getService(SERVICE_UUID).getCharacteristic(CHaraCTERISTIC_UUID_ID);
                gatt.setCharacteristicNotification(characteristicID,true); }
        },500);


        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                BluetoothGattDescriptor descriptor = characteristicID.getDescriptor(DESCRIPTOR_UUID_ID);
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                gatt.writeDescriptor(descriptor); }
        },500);

    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {
        super.onCharacteristicRead(gatt,characteristic,status);
        Log.i("BT characteristics","onCharacteristicRead");
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,int status) {
        super.onCharacteristicWrite(gatt,"onCharacteristicWrite");
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicChanged(gatt,characteristic);
        Log.i("BT characteristics","onCharacteristicChanged");
        Log.i("Characteristic Change",new String(characteristic.getValue()));
        final String characteristicValue = new String(characteristic.getValue());
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                wifiSSIDs.add(characteristicValue);
                SSIDadapter.notifyDataSetChanged();

                listViewSSID.setVisibility(View.VISIBLE);
                scanningText.setVisibility(View.INVISIBLE);
            }
        });
    }

    @Override
    public void onDescriptorRead(BluetoothGatt gatt,BluetoothGattDescriptor descriptor,int status) {
        super.onDescriptorRead(gatt,descriptor,"onDescriptorRead");
    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt,int status) {
        super.onDescriptorWrite(gatt,"onDescriptorWrite");

        characteristicID.setValue("RW");
        gatt.writeCharacteristic(characteristicID);

    }
}

@Override
public void onItemClick(AdapterView<?> parent,View view,int position,long id) {
    String ssid = ((TextView) view).getText().toString();
    Log.i("Item Click","SSID: " + ssid);
    characteristicID.setValue("SSID: " + ssid);
    gattClient.writeCharacteristic(characteristicID);

    Intent intent = new Intent(this,PasswordActivity.class);
    startActivity(intent);
}
}

我可以提供在rPi上运行的python脚本代码,但我认为问题出在android代码。日志返回:

2020-10-05 14:05:53.710 19952-19952/com.example.myapplication I/Bluetooth Scan: startScan()
2020-10-05 14:05:53.711 19952-19952/com.example.myapplication I/chatty: uid=10299(com.example.myapplication) identical 1 line
2020-10-05 14:05:53.852 19952-19952/com.example.myapplication I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
2020-10-05 14:05:54.937 19952-19952/com.example.myapplication I/Bluetooth Scan Result: onScanResult
2020-10-05 14:05:56.688 19952-19966/com.example.myapplication I/Bluetooth Connection: onConnectionStateChange
2020-10-05 14:05:56.688 19952-19966/com.example.myapplication I/Bluetooth Connection: onConnectionStateChange CONNECTED
2020-10-05 14:06:02.208 19952-19966/com.example.myapplication I/Bluetooth Connection: onConnectionStateChange
2020-10-05 14:06:02.208 19952-19966/com.example.myapplication I/Bluetooth Connection: onConnectionStateChange != GATT_SUCCESS
2020-10-05 14:06:02.208 19952-19966/com.example.myapplication I/Bluetooth Connection: 8

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)