使用 Log
类跟踪运行时显示 onReceive()
方法没有调用,为什么?
动态注册广播接收器
private void discoverDevices () {
Log.e("MOHAB","BEFORE ON RECEIVE");
mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
Log.e("MOHAB","ON RECEIVE");
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
Bluetooth b = new Bluetooth(device.getName(),device.getAddress());
list.add(b);
}
}
};
Log.e("MOHAB","create intentFilter");
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
}
最佳答案
除了starting with Android 6.0 you have to have the ACCESS_COARSE_LOCATION
permission to receive ACTION_FOUND
(正如@siniux 已经提到的),还有另一个相关的事情:
ACCESS_COARSE_LOCATION
在 dangerous permissions 中您必须在运行时向用户明确请求(6.0 中的另一项安全改进)。
要进行诊断,您可以运行 adb logcat | grep BroadcastQueue
,然后看到类似这样的内容:
W/BroadcastQueue: Permission Denial: receiving Intent {
act=android.bluetooth.device.action.FOUND flg=0x10 (has extras) }
to ProcessRecord{9007:com.examplepackage} (pid=9007, uid=10492)
requires android.permission.ACCESS_COARSE_LOCATION due to sender
com.android.bluetooth (uid 1002)
因此,在 Marshmallow 上发现 BT 设备的正确过程如下:
list 中有
ACCESS_COARSE_LOCATION
权限要求以及通常的蓝牙权限:<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Ensure you have run-time permission对于
ACCESS_COARSE_LOCATION
protected void checkLocationPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_COARSE_LOCATION); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case REQUEST_COARSE_LOCATION: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { proceedDiscovery(); // ---> } else { //TODO re-request } break; } }
为
ACTION_FOUND
注册广播接收器并调用BluetoothAdapter.startDiscovery()
protected void proceedDiscovery() { IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); filter.addAction(BluetoothDevice.ACTION_NAME_CHANGED); registerReceiver(mReceiver, filter); mBluetoothAdapter.startDiscovery(); }
ACTION_NAME_CHANGED
的有趣之处。尽管 6.0 不会在未经粗略位置许可的情况下为您提供 ACTION_FOUND
,但您仍然会收到 ACTION_NAME_CHANGED
事件,这些事件通常与 ACTION_FOUND
发现设备时。 IE。你得到了这两个事件,所以没有许可,你仍然可以处理 ACTION_NAME_CHANGED
几乎相同的行为。 (大师,如果我错了请纠正我)
关于android - 动态注册广播接收器不起作用 - BluetoothDevice.ACTION_FOUND,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32656510/