1

我编写了一个应用程序,它定期尝试连接到配对设备,如果连接成功,则执行一个操作。我有一个注册的蓝牙广播接收器,它处理 ACTION_ACL_CONNECTED 和 ACTION_ACL_DISCONNECTED。在服务中,在运行循环中,我获取配对设备的列表并尝试连接到每个设备。当连接成功时,我会收到 ACTION_ACL_CONNECTED 通知,当设备断开连接(或超出范围)时,我会收到 ACTION_ACL_DISCONNECTED。一切正常。

对于耳机,BluetoothHeadset 类会引发 ACTION_ACL_CONNECTED 和 ACTION_ACL_DISCONNECTED,因此我不需要连接到主 UUID 为 00001108 的设备。

我有一个蓝牙扬声器,它的单个 UUID 为 0000110B。它可以整天进出范围,每次我连接到它时我都会收到 ACTION_ACL_CONNECTED 和 ACTION_ACL_DISCONNECTED 信号,并且每次断开连接时都会因为它超出范围而发生。

如果我尝试使用 00001105 连接到另一部手机,则第一次连接成功并引发 ACTION_ACL_CONNECTED。如果我把手机带出范围(或者只是关闭它的蓝牙),我会得到 ACTION_ACL_DISCONNECTED。但是,任何进一步的连接尝试都会导致“服务发现失败”,即使手机在范围内并且蓝牙已打开。这种情况一直持续到我手动或代码切换手机上的蓝牙适配器。然后我可以进行一次连接/断开连接,然后服务发现失败再次发生。显然,切换适配器并不是一个令人满意的解决方案。所以,我的问题是,是什么让 00001105 与 00001108 不同,因为我不能使用 00001105 进行多次连接/断开连接?

代码比较复杂,但在这里(请原谅缩进。剪切和粘贴效果不太好):

public class BluetoothListenerService extends Service  {

    // The BroadcastReceiver that listens for Connected and disconnected blue tooth devices (HSP,HFP and SPP)

    public final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {

        @Override

        public void onReceive(Context context, Intent intent) {

        String devices[]=null;

        Intent service_intent;

        String action = intent.getAction();

            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

    if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {

        // Get the BluetoothDevice object from the Intent

        String testUUID=null;

        try { 

            Method method = device.getClass().getMethod("getUuids",  (Class<?>[]) null);

        ParcelUuid[] phoneUuids = (ParcelUuid[]) method.invoke(device, (Object[]) null);

        UUID myUUID=phoneUuids[0].getUuid();

        testUUID=myUUID.toString().toLowerCase();

                Log.i(TAG,"connected to "+device.getName()+ "using "+ testUUID);

        } catch (Exception e) {}

       return;

    } // end ACTION_ACL_CONNECTED


    if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {

        Log.i(TAG, "disconnected from "+device.getName());

        return;

    }   // end ACTION_ACL_DISCONNECTED

}   // end OnReceive

};  // end broadcast receiver definition

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

@Override

public void onStart(final Intent intent, final int startId) {

super.onStart(intent, startId);

if (mBluetoothAdapter == null) {

        Toast.makeText(this," Bluetooth is not available on this device", Toast.LENGTH_LONG).show();

        return;

}   

Thread t = new Thread("MyService(" + startId + ")") {

     @Override

     public void run() {

         _onStart(intent, startId);

         stopSelf();

     }

 };

 t.start();

 return;

  }

  public void _onStart(Intent intent, int startId) {

  String devices[]=null;

Log.i(TAG,"Bluetooth Listener Service started on thread "+ Integer.toString(android.os.Process.myTid()));


// Register the Bluetooth BroadcastReceiver

    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);

    filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);


     try {

          this.unregisterReceiver(mBluetoothReceiver);
    } catch(IllegalArgumentException ignorable) {}

    registerReceiver(mBluetoothReceiver, filter);

// the loop

    bRun=true;

    while(bRun)  {

    Set <BluetoothDevice> mySet=mBluetoothAdapter.getBondedDevices();

    Iterator <BluetoothDevice> iterator=mySet.iterator();

    while(iterator.hasNext()) {

        BluetoothDevice setElement=iterator.next();

        String testUUID=null;

        try { // Get UUID for device

            Method method = setElement.getClass().getMethod("getUuids",  (Class<?>[]) null);

            ParcelUuid[] phoneUuids = (ParcelUuid[]) method.invoke(setElement, (Object[]) null);

            UUID myUUID=phoneUuids[0].getUuid();

            testUUID=myUUID.toString().toUpperCase();

            Log.i(TAG, "device UUID is "+testUUID);

        if (testUUID.compareTo(headsetUUID)!=0 && testUUID.compareTo(a2dpUUID)!=0) {

        try {   // create a socket

           BluetoothSocket tmp=null;

           tmp=setElement.createInsecureRfcommSocketToServiceRecord(UUID.fromString(testUUID));

           mmSocket=tmp;

           Log.i(TAG,"connecting using socket "+mmSocket.toString());

           Log.i(TAG,"connecting to "+setElement.getName());

          try {

            if (mBluetoothAdapter.isDiscovering()==true) mBluetoothAdapter.cancelDiscovery();

            mmSocket.connect();

            Log.i(TAG,"connection to "+setElement.getName()+" was sucessful");

            //  the connection will be handled by the receiver in ACL_CONNECTED

        } catch (Exception e) { // connection failed

            String sTest=e.getMessage();

            Log.e(TAG,"connection to "+setElement.getName()+" returned "+sTest);
            if (sTest!=null) {

                try {   // closing the socket

            Log.i(TAG,"closing socket due to error: "+sTest);

                Log.i(TAG,"closing socket "+mmSocket.toString());

            if (!mmSocket.equals(null)) {

                mmSocket.close();

                mmSocket=null;

                tmp=null;

            }

            else {

            Log.e(TAG, "socket is null");

            }

            } catch (Exception e1) {    // socket close failed

                Log.e(TAG,"closing socket failed");

            break;
            }

        if (sTest.compareTo("Unable to start Service Discovery")==0) {

            mBluetoothAdapter.disable();

            SystemClock.sleep(3000);

            mBluetoothAdapter.enable();

            SystemClock.sleep(1000);

          }
      }

        }  // end catch connection failed

           } catch (Exception e1) {

          Log.e(TAG, "socket create failed.");

       }
        }   // end test if headset or not

           } catch (Exception e1) {

          Log.e(TAG, "find UUID failed.");

            }  // end find UUID

          }  // end while iterator.hasnext() 

       }    // end of run loop

   }

}
4

0 回答 0