码:
我使用来自here的以下代码,目标API级别为23(最低API级别为18)。
private final BroadcastReceiver mReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
deviceNameTextView.setText(bluetoothDevice.getName());
}
}
};
在按下按钮的事件中,我称:
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
mBluetoothAdapter.startDiscovery(); // was initialized successsfully
我的AndroidManifest.xml包含:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
设备:
三星Galaxy S III(API级别18)
索尼Xperia Z3(API级别23)
事实:
两种设备都运行完全相同的代码
设备1可以发现设备2(以及任何其他蓝牙设备)
设备2无法发现设备1(或任何其他蓝牙设备)
两种设备都是可发现的
使用标准系统对话框对可发现性进行了测试,以成功将两个设备配对
这两个设备一直都未配对(我不想配对)
没有异常被抛出。
怎么了?
更新1:
由于API级别23,可能必须在运行时请求权限。伊薇特指出了这一点,谢谢!不幸的是它没有解决我的问题。
反对她的理论的是:
mBluetoothAdapter.startDiscovery()
返回true,表示成功(请参见here)。// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity , Manifest.permission.BLUETOOTH_ADMIN);
if(permissionCheck == PackageManager.PERMISSION_GRANTED)
Log.i("info", "Permission granted!");
else
Log.i("info", "Permission not granted!");
使用
BLUETOOTH_ADMIN
和BLUETOOTH
运行此代码将返回两次:许可授予!
最佳答案
在进行一些研究时,我从官方文档中找到了关于Android 6.0(API级别23)更改的following article。
通过访问附近的外部设备的硬件标识符
蓝牙和Wi-Fi扫描,您的应用现在必须具有
ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION权限:
-WifiManager.getScanResults()
-BluetoothDevice.ACTION_FOUND
-BluetoothLeScanner.startScan()
因此,我一直都缺少权限ACCESS_FINE_LOCATION
和ACCESS_COARSE_LOCATION
。但是仅将它们添加到AndroidManifest.xml文件中是不够的。您必须在运行时像Yvette建议的那样请求这些特权。
您可以找到here如何做到这一点,或者只是使用我编写的这段代码来获取蓝牙发现所需的权限。
final int CODE = 5; // app defined constant used for onRequestPermissionsResult
String[] permissionsToRequest =
{
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
};
boolean allPermissionsGranted = true;
for(String permission : permissionsToRequest)
{
allPermissionsGranted = allPermissionsGranted && (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED);
}
if(!allPermissionsGranted)
{
ActivityCompat.requestPermissions(this, permissionsToRequest, CODE);
}
mBluetoothAdapter.startDiscovery();
此代码假定用户授予了权限(为简单起见)。如果希望您的应用在未授予权限时表现不同,请参阅此article中的“处理权限请求响应”。