码字不易,都是原创,转载请注明远处, 多谢
蓝牙只让搜到耳机,不让搜到手机,同时不让别人搜到自己 O版本
1 蓝牙只让搜到耳机,不让搜到手机和其他蓝牙设备,查看了一下蓝牙的应用层代码,接收搜到蓝牙设备的原理就是接收广播,于是就可以查找广播发出的地方,很容易就发现
RemoteDevices.java下面void deviceFoundCallback(byte[] address)发送的,在这我们就可以判断设备
首先我们需要把 intent中 new BluetoothClass(deviceProp.mBluetoothClass);的代码提出来,作个变量,
BluetoothClass btClass = new BluetoothClass(deviceProp.mBluetoothClass);
这样就可以用btClass.getMajorDeviceClass()来获取设备类型作判断了,因为我们只需要耳机所以只要为BluetoothClass.Device.Major.WEARABLE 和 BluetoothClass.Device.Major.AUDIO_VIDEO 类型我们就发送广播,
其他类型都直接返回,不发送广播,至此,只搜索到蓝牙耳机的修改就完成了,贴上处理代码
void deviceFoundCallback(byte[] address) {
// The device properties are already registered - we can send the intent
// now
BluetoothDevice device = getDevice(address);
debugLog("deviceFoundCallback: Remote Address is:" + device);
DeviceProperties deviceProp = getDeviceProperties(device);
if (deviceProp == null) {
errorLog("Device Properties is null for Device:" + device);
return;
}
BluetoothClass btClass = new BluetoothClass(deviceProp.mBluetoothClass);//songjian add
Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
intent.putExtra(BluetoothDevice.EXTRA_CLASS,
/*new BluetoothClass(deviceProp.mBluetoothClass)*/btClass); //songjian modify
intent.putExtra(BluetoothDevice.EXTRA_RSSI, deviceProp.mRssi);
intent.putExtra(BluetoothDevice.EXTRA_NAME, deviceProp.mName);
if(xxxxxxx)
{
if(btClass != null) {
int mClass = btClass.getMajorDeviceClass();
if(mClass == BluetoothClass.Device.Major.AUDIO_VIDEO
|| mClass == BluetoothClass.Device.Major.WEARABLE
)
{
Log.d(TAG, "ssssjjjj head ignore: " + mClass);
}
else
return;
}
}
mAdapterService.sendBroadcastMultiplePermissions(intent,
new String[] {AdapterService.BLUETOOTH_PERM,
android.Manifest.permission.ACCESS_COARSE_LOCATION});
}
2 不让别的蓝牙设备搜索到自己,这个应该在设置状态的接口里去作下处理就ok了,
根据应用层的代码接口BluetoothAdapter.setScanMode 来设置扫描状态的,于是我们在setScanMode里处理下就ok了
public boolean setScanMode(int mode) {
Log.e(TAG, "ssss setScanMode="+mode );
if (getState() != STATE_ON) return false;
/* getDiscoverableTimeout() to use the latest from NV than use 0 */
if(xxxxx) //在此我们把状态强制改成 SCAN_MODE_CONNECTABLE 可连接状态,蓝牙设备就不会向外发送广播信号了
mode=BluetoothAdapter.SCAN_MODE_CONNECTABLE;
return setScanMode(mode, getDiscoverableTimeout());
}
看上去修改应该完美了,但是事与愿违,一测试发现设置里进入蓝牙就卡死了,卡死怎么办呢,只有查看Log 看看是哪里出了问题,
发现是卡死在了AlwaysDiscoverable.java中的onReceive 函数中,原来是这里会接收蓝牙的状态改变作些处理,我们在上面setScanMode时强制改
成了SCAN_MODE_CONNECTABLE模式,当然广播会发到这来,这里发现不是SCAN_MODE_CONNECTABLE_DISCOVERABLE状态,又会去setScanMode状态,
这样和我们前面的修改就冲突,造成了死循环,既然知道了问题所在,直接修改就行了,因为我们的需求就是不让别人搜到自己,也就是只要SCAN_MODE_CONNECTABLE
模式,所以onReceive 中,直接返回就行了,不要去设置状态,至此修改就ok了
码字不易,都是原创,转载请注明远处, 多谢