Bluetooth not connecting on 4.4.2

偶尔善良 提交于 2019-11-29 05:25:26

问题


I've got a Bluetooth device that has connected on all versions of Android that I have tried prior to 4.4.2. Now, it's not connecting on the Galaxy Tab 4 or the S3. The Tab 3 connects fine with 4.1.2. The problem seems to occur in the AcceptThread while trying to initialize the BluetoothSocket. The code I'm using is based off of the chat example in the sdk.

My Accept code

private class AcceptThread extends Thread {
    // The local server socket
    private BluetoothServerSocket mmServerSocket;
    public boolean successInit = false;

    public AcceptThread() {
        closeAllConnections();          
        BluetoothServerSocket tmp = null;

        // Create a new listening server socket
        while(!successInit) {
            try {
                tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
                successInit= true;
                Log.i("TAG", "Socket Server Created");
            }
            catch(Exception e) {
                Log.i("TAG", e.getMessage());
                successInit = false;
            }
        }

        mmServerSocket = tmp;
    }
    public void run() {
        BluetoothSocket socket = null;

        // Listen to the server socket if we're not connected
        Log.i("BluetoothComService", String.valueOf(mState));
        while (mState != STATE_CONNECTED) {
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                mAdapter.cancelDiscovery();

                socket = BluetoothAdapter.getDefaultAdapter()                           
                     .getRemoteDevice(getThermMAC())
                     .createRfcommSocketToServiceRecord(UUID
                     .fromString("00001101-0000-1000-8000-00805F9B34FB"));

           //   socket = mmServerSocket.accept();  // here socket might be closed or timeout
                Log.e("BluetoothComService", "No accept Exception");
            }catch (IOException e) {
                Log.e("TAG", e.getMessage());
            }

getThermMAC() above is my method to return the address of the bonded device.

The errors

In run(), if I use

socket=BluetoothAdapter.getDefaultAdapter()                           
                     .getRemoteDevice(getThermMAC())
                     .createRfcommSocketToServiceRecord(UUID
                     .fromString("00001101-0000-1000-8000-00805F9B34FB"));

then I get a NPE at line 501 of BluetoothSocket.java in the Android framework which is this line

int left = b.length;

So it would appear that b is null but it doesn't appear to be after debugging. b is a byte[] which is sent from my BluetoothService class which sends a brand new, initialized byte[] from within the ConnectedThread just as the sdk example does and as I've been doing on older versions.

If I comment that out and try to use

socket = mmServerSocket.accept();

which has been working in the past, then I get

bt socket is not in listen state

So, I don't know how to put it in "listen state" or why it wouldn't be. Has anyone experienced this or know how to workaround it? Or how to keep from getting the NPE if I use the first snippet (if that is even correct).

I found

When I was getting an IOException I found this post which led me here but this hasn't gotten me anywhere.

Notice: The bounty message says 4.4.4 but it is 4.4.2 on the Tab 4

Device Errors

I also notice these Bluetooth errors when I first connect my device to the computer through USB

09-05 15:18:03.217: E/BluetoothServiceJni(15148): SOCK FLAG = 0 ***********************
09-05 15:18:13.177: E/BluetoothServiceJni(15148): SOCK FLAG = 0 ***********************
09-05 15:18:13.217: E/BluetoothServiceJni(15148): SOCK FLAG = 0 ***********************

but I have not been able to find out what that flag means.

I realize there are known bugs in the BT stack 4.x (See one of many bug reports)

minSDK is currently 10. Though, if I find a working solution then I can work around that.


回答1:


Try this code, this is working android 4.4.2 on nexus 7

private boolean refreshDeviceCache(BluetoothGatt gatt){
    try {
        BluetoothGatt localBluetoothGatt = gatt;
        Method localMethod = localBluetoothGatt.getClass().getMethod("refresh", new Class[0]);
        if (localMethod != null) {
           boolean bool = ((Boolean) localMethod.invoke(localBluetoothGatt, new Object[0])).booleanValue();
            return bool;
         }
    } 
    catch (Exception localException) {
        Log.e(TAG, "An exception occured while refreshing device");
    }
    return false;
}


    public boolean connect(final String address) {
           if (mBluetoothAdapter == null || address == null) {
            Log.w(TAG,"BluetoothAdapter not initialized or unspecified address.");
                return false;
        }
            // Previously connected device. Try to reconnect.
            if (mBluetoothGatt != null) {
                Log.d(TAG,"Trying to use an existing mBluetoothGatt for connection.");
              if (mBluetoothGatt.connect()) {
                    return true;
               } else {
                return false;
               }
        }

        final BluetoothDevice device = mBluetoothAdapter
                .getRemoteDevice(address);
        if (device == null) {
            Log.w(TAG, "Device not found.  Unable to connect.");
            return false;
        }

        // We want to directly connect to the device, so we are setting the
        // autoConnect
        // parameter to false.
        mBluetoothGatt = device.connectGatt(MyApp.getContext(), false, mGattCallback));
        refreshDeviceCache(mBluetoothGatt);
        Log.d(TAG, "Trying to create a new connection.");
        return true;

}




回答2:


I have also used connection steps using the same code but that could work only for Smart Android device.

you can get the BluetoothDevice object of the particular device you want to connect. after that you can use BluetoothHeadset's connect and disconnect method via reflection to connect to the perticular BluetoothDevice.

Class<?> BTHeadset = Class.forName("android.bluetooth.BluetoothHeadset");
        Method conn = BTHeadset.getMethod("connect", new Class[] {BluetoothDevice.class});
               conn.invoke(BTHeadset, new Object[] {btDev});

same code you can use for disconneting a device using disconnect method via reflection.



来源:https://stackoverflow.com/questions/25651586/bluetooth-not-connecting-on-4-4-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!