Err*_*ror 13 android android-broadcastreceiver
用Logclass跟踪运行时显示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
}
Run Code Online (Sandbox Code Playgroud)
Iva*_*sov 40
除了从Android 6.0开始你必须ACCESS_COARSE_LOCATION有权接收ACTION_FOUND(如@siniux已经提到的),还有另一个相关的事情:
ACCESS_COARSE_LOCATION是您必须在运行时向用户明确请求的危险权限之一(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)
Run Code Online (Sandbox Code Playgroud)
因此,在棉花糖上发现BT设备的正确程序如下:
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" />
Run Code Online (Sandbox Code Playgroud)确保已运行时允许的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;
}
}
Run Code Online (Sandbox Code Playgroud)
}
注册广播接收器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();
}
Run Code Online (Sandbox Code Playgroud)有趣的事情ACTION_NAME_CHANGED.虽然6.0在ACTION_FOUND没有粗略位置许可的情况下无法为您提供服务,但您仍然可以获得ACTION_NAME_CHANGED事件,这些事件通常会ACTION_FOUND在发现设备时与其联系.也就是说你得到了这两个事件,所以如果没有这个许可,你仍然可以处理ACTION_NAME_CHANGED几乎相同的行为.(大师,如果我错了,请纠正我)
小智 13
我的广播接收器遇到了类似的问题.然后我发现了这个:https: //developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id
基本上,在6.0上,您必须使用位置权限来扫描蓝牙设备.
您错过的是您需要启动设备恢复
首先,获取蓝牙适配器
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Run Code Online (Sandbox Code Playgroud)
之后,您通过调用开始发现
mBtAdapter.startDiscovery();
Run Code Online (Sandbox Code Playgroud)
你也应该在这里阅读详细信息,例如cancelDiscovery()
http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery%28%29
PS此外,context.getSystemService(Context.BLUETOOTH_SERVICE)根据官方文档,建议用于在API 18+上获取BluetoothAdapter.
要获得代表本地蓝牙适配器的BluetoothAdapter,在JELLY_BEAN_MR1及更低版本上运行时,请调用静态getDefaultAdapter()方法; 在JELLY_BEAN_MR2及更高版本上运行时,使用BLUETOOTH_SERVICE通过getSystemService(Class)检索它.
编辑:
提醒您需要BLUETOOTH_ADMIN权限startDiscovery()
小智 6
根据专家的回答,Android 6 及以上版本的 ACTION_FOUND 操作请检查以下几点: 1. 除了设置 BLUETOOTH 和 BLUETOOTH_ADMIN 的权限外,尝试
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Run Code Online (Sandbox Code Playgroud)
有时可能不需要这两个,但它对我有用。您还必须使用代码动态寻求用户权限
int MY_PERMISSIONS_REQUEST = 200;
int permissions=ContextCompat.checkSelfPermission (this,Manifest.permission.ACCESS_FINE_LOCATION);
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST);
Run Code Online (Sandbox Code Playgroud)
现在编写用于执行所需操作的代码。在此之后,我添加了一个 startDiscovery() 方法。当然,这对你有用......快乐编码......
| 归档时间: |
|
| 查看次数: |
14926 次 |
| 最近记录: |