获取android 3.1及更高版本中已连接的蓝牙低功耗设备的列表

时间:2018-07-22 22:51:04

标签: java android bluetooth-lowenergy

我正在研究显示某些已连接的蓝牙低功耗设备列表的应用程序,因此用户可以选择要配置的设备之一。

问题是you can't just list all connected devices. As far as I know there are three possible ways

  1. 使用BluetoothProfiles

     bluetoothManager.getConnectedDevices(BluetoothProfile.GATT_SERVER);
    

    此操作失败,因为设备连接时android不会连接到GATT服务器,因此设备既不在GATT_SERVER也不在GATT配置文件下。但是,一旦我调用connectGatt方法,

     bluetoothDevice.connectGatt(getApplicationContext(), false, gattCallback);
    

    设备可以在GATT_SERVER和GATT配置文件下找到。低能耗设备不支持其他配置文件。

  2. 列出已配对的设备,并在每个设备上尝试使用connectGatt

     List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>();
     for(BluetoothDevice device : bluetoothAdapter.getBondedDevices()) {
          BluetoothGatt gatt = device.connectGatt(getApplicationContext(), false, gattCallback);
          if(gatt != null) {
              connectedDevices.add(device);
          }
          gatt.disconnect();
     }
    

    此方法无法使用,因为它无法确定设备是否已连接或仅在范围内但未连接

  3. 在系统引导启动服务上,侦听ACL_CONNECTED and ACL_DISCONNECTED的意图并维护已连接设备的列表

    清单

     <service android:name=".ManagerService" android:enabled="true" />
     <receiver
        android:name=".BootFinishedReceiver"
        android:directBootAware="true"
        android:enabled="true"
        android:exported="false"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
    
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    

    接收器

     public class BootFinishedReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
               Intent serviceIntent = new Intent(context, ManagerService.class);
               context.startService(serviceIntent);
          }
      }
    

    服务

     public class ManagerService extends Service {
          private static List<BluetoothDevice> connectedDevices;
    
          @Override
          public void onCreate() {
              connectedDevices = new ArrayList<BluetoothDevice>();
              super.onCreate();
          }
    
          @Override
          public int onStartCommand(Intent intent, int flags, int startId) {
              IntentFilter filter = new IntentFilter();
              filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
              filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
              registerReceiver(connectionReceiver, filter);
              return super.onStartCommand(intent, flags, startId);
          }
    
          @Override
          public void onDestroy() {
              unregisterReceiver(connectionReceiver);
              super.onDestroy();
          }
    
          @Nullable
          @Override
          public IBinder onBind(Intent intent) {
              return null;
          }
    
          private final BroadcastReceiver connectionReceiver = new BroadcastReceiver() {
              @Override
              public void onReceive(Context context, Intent intent) {
                  String action = intent.getAction();
                  BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                  if(BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
                      connectedDevices.add(device);
                  }else{
                      connectedDevices.remove(device);
                  }
              }
          };
    
          public static List<BluetoothDevice> getConnectedDevices() {
              return connectedDevices;
          }
     }
    

    Since 3.1 apps can no longer receive system intents before activity is started,因此也无法使用。

还有其他方法或现在如何在更高的android版本中实现它?

感谢任何建议

1 个答案:

答案 0 :(得分:0)

好吧,我发现了you can still use ON_BOOT_COMPLETED,但是必须在设备上进行设置。这样我的问题就解决了