【问题标题】:Why BluetoothAdapter.startDiscovery(..) require to get Bluetooth device broadcast?为什么 BluetoothAdapter.startDiscovery(..) 需要获取蓝牙设备广播?
【发布时间】:2014-01-03 13:08:46
【问题描述】:

通常 Android 广播的工作方式是:应用必须创建 BroadcastReceiver 并且必须注册动作 Intent 才能获得接收事件。

但在蓝牙设备发现/扫描的情况下,为什么需要通过 BluetoothAdapter.startDsiccovery() 进行请求调用。

基本上我想通过long live后台运行的服务来发现BLE设备。

这里有人知道吗?

【问题讨论】:

  • 这里有人知道吗?

标签: android service broadcastreceiver android-bluetooth


【解决方案1】:
private void listenPairedDevice() {
Button listenBtn = (Button)findViewById(R.id.button_listen);
listenBtn.setOnClickListener(new OnClickListener() {
  public void onClick(View view) {
    Intent disc = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    startActivityForResult(disc, DISCOVERY_REQUEST);     
 }
 });
}
@Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 if (requestCode == DISCOVERY_REQUEST) {
boolean isDiscoverable = resultCode > 0;
 if (isDiscoverable) {
 String name = "bluetoothserver";
 try {
final BluetoothServerSocket btserver = bluetooth.listenUsingRfcommWithServiceRecord(name, uuid);


      AsyncTask<Integer, Void, BluetoothSocket> acceptThread = new AsyncTask<Integer, Void, BluetoothSocket>() {

        @Override
        protected BluetoothSocket doInBackground(Integer... params) {
          try {

             socket = btserver.accept();
            return socket;
             } catch (IOException e) {
            Log.d("BLUETOOTH", e.getMessage());            
          }
          finally {
            //close statement added later by MR
              try{
              btserver.close();
              } catch (IOException e){

              }
          }
          return null;
        }

        @Override
        protected void onPostExecute(BluetoothSocket result) {
          if (result != null)
            changeLayout();
        }            
      };          
      acceptThread.execute(resultCode);
    } catch (IOException e) {
      Log.d("BLUETOOTH", e.getMessage());            
    }
  }
}

【讨论】:

  • 使用此代码您可以发现蓝牙设备,
  • 发现设备在这里根本不是问题...我要求的是有什么方法可以在 BG 服务中连续运行扫描...通常我们有“startDiscovery()”调用.. .但是每次应用程序都必须请求广播...还有其他想法吗?
【解决方案2】:

startDiscovery() 分两步处理,

  • 通过查询找到设备。

  • 随后是名称发现,即分页和连接到设备。

如果您浏览过文档,上面写着public boolean startDiscovery ()

启动远程设备发现过程。

发现过程通常涉及大约 12 秒的查询扫描,然后对每个新设备进行页面扫描以检索其蓝牙名称。

这是一个异步调用,它会立即返回。注册 ACTION_DISCOVERY_STARTED 和 ACTION_DISCOVERY_FINISHED 意图以确定发现何时开始和完成。注册 ACTION_FOUND,以便在找到远程蓝牙设备时收到通知。

设备发现是一个重量级的过程。在发现过程中,不应尝试与远程蓝牙设备建立新连接,现有连接将遇到带宽有限和高延迟的问题。使用 cancelDiscovery() 取消正在进行的发现。 Discovery 不由 Activity 管理,而是作为系统服务运行,因此应用程序应始终调用 cancelDiscovery(),即使它没有直接请求发现,只是为了确定。

设备发现只会发现当前可发现的远程设备(启用查询扫描)。许多蓝牙设备默认是不可发现的,需要进入特殊模式。

如果蓝牙状态不是 STATE_ON,此 API 将返回 false。开启蓝牙后,等待 ACTION_STATE_CHANGED 和 STATE_ON 获取更新值。

需要 BLUETOOTH_ADMIN。

退货 成功为真,错误为假

编辑

请关注Bluetooth device discovery in Android — startDiscovery()

【讨论】:

  • 感谢并感谢您的回答......这是真正的设备扫描繁重的过程......但在 android doc 中,他们从未提及任何地方要执行“扫描请求”以获取 Broadcast(BC).. BC 的正常行为是...应用程序需要使用所需的操作注册 BC...就是这样...n 系统将适用于您的应用程序...如果您有任何相关帖子,请在此处提及
  • 没有帮助,亲爱的...任何想法在后台运行连续扫描过程...或特定于设备?
【解决方案3】:

我认为您必须开始使用 UUId 和套接字进行蓝牙发现。

在获得任何设备后,您必须建立与此的连接并启动一个线程,该线程将在连接与否时定期检查。

【讨论】:

  • 同样我不想......不想从应用程序执行基于线程/计时器的请求......基本上如果系统广播服务有帮助......所以在应用程序级别不用担心保持电池耗尽。
  • 我不认为它会在没有线程的情况下工作,因为您必须检查它是否已连接,一段时间后连接可能会失败。使用广播只能检查蓝牙设备是否可用。
【解决方案4】:

扫描外围设备不仅是一项繁重的任务,而且对电池也不友好,因此不能一直开着。

也就是说,您仍然可以让某些东西在后台为您工作,例如每 15 秒唤醒一次并扫描 5 秒的东西。在某些设备上,当您尝试连接到不再可用的设备时,您将在BluetoothGattCallback 中收到对onConnectionStateChange 的断开回调,而在其他设备上,相同的连接尝试将等到设备恢复后再连接.

所以基本上,如果找到您的设备,请等待、扫描、连接,如果没有则再次等待。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    相关资源
    最近更新 更多