最近項(xiàng)目需求要做藍(lán)牙自動(dòng)配對(duì),也就是在首次配對(duì)的時(shí)候跳過用戶輸入PIN碼。網(wǎng)上有很多分享的如何實(shí)現(xiàn)自動(dòng)配對(duì)。
以下做一個(gè)記錄,方便以后查閱。
注意:
藍(lán)牙開啟需要開啟藍(lán)牙的相關(guān)權(quán)限還有 定位 權(quán)限
在AndroidManifest.xml中添加
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
并且開啟運(yùn)行時(shí)權(quán)限;
private void initPermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
//判斷是否需要向用戶解釋為何要此權(quán)限
if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_CONTACTS)) {
showMessageOKCancel("你必須允許這個(gè)權(quán)限,否則無法搜索到BLE設(shè)備", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},100);
}
});
return;
}
//請(qǐng)求權(quán)限
requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS},100);
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 100) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//用戶允許改權(quán)限,0表示允許,-1表示拒絕 PERMISSION_GRANTED = 0,PERMISSION_DENIED = -1
//這里進(jìn)行授權(quán)被允許的處理
//可以彈個(gè)Toast,感謝用戶允許了。
scanLeDevice(true);
Toast.makeText(MainActivity.this, "謝謝!", Toast.LENGTH_SHORT).show();
} else {
//這里進(jìn)行權(quán)限被拒絕的處理,就跳轉(zhuǎn)到本應(yīng)用的程序管理器
Toast.makeText(MainActivity.this, "請(qǐng)開啟位置權(quán)限", Toast.LENGTH_SHORT).show();
Intent i = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
String pkg = "com.android.settings";
String cls = "com.android.settings.applications.InstalledAppDetails";
i.setComponent(new ComponentName(pkg, cls));
i.setData(Uri.parse("package:" + getPackageName()));
startActivity(i);
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
A、獲取藍(lán)牙,有兩種方式:
/**
- 兩種獲取BluetoothAdapter方式
**/
//方式一:通過BluetoothManager獲取
BluetoothManager mBm = (BluetoothManager)this.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = mBm.getAdapter();
//方式二:通過getDefaultAdapter()獲取
//mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter ==null) {
Log.e("沒有藍(lán)牙模塊");
ToastUtils.showShort("沒有藍(lán)牙模塊");
return;
}
B、打開藍(lán)牙,有兩種方式:
/**
- 打開藍(lán)牙的兩種方式
*/
//一:直接打開,不通過用戶
// if (!mBluetoothAdapter.isEnabled()) {
// mBluetoothAdapter.enable();
// Log.e("開啟藍(lán)牙~");
// }
//二:優(yōu)雅的打開
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enabIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabIntent, 100);
LogUtils.e("開啟藍(lán)牙~");
}
第二種打開會(huì)調(diào)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) {
Toast.makeText(this, "藍(lán)牙已啟用", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "藍(lán)牙未啟用", Toast.LENGTH_SHORT).show();
}
}
C、搜索設(shè)備
//15秒搜索時(shí)間
private Handler mHandler = new Handler();
//15秒搜索時(shí)間
private static final long SCAN_PERIOD = 15000;
private void scanLeDevice(final boolean enable) {
mBluetoothAdapter.startLeScan(mLeScanCallback); //開始搜索
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
}
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//在這里可以把搜索到的設(shè)備保存起來
//device.getName();獲取藍(lán)牙設(shè)備名字
//device.getAddress();獲取藍(lán)牙設(shè)備mac地址
//這里的rssi即信號(hào)強(qiáng)度,即手機(jī)與設(shè)備之間的信號(hào)強(qiáng)度。
list.add(device);
mBleAdapter.setNewData(list);
LogUtils.e("name:" + device.getName());
}
});
}
};
搜索到設(shè)備后我是用List裝,然后用RecyclerView和BaseRecyclerViewAdapterHelper配合顯示
D、連接設(shè)備
mBleAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
//ToastUtils.showShort("點(diǎn)擊了:" + position);
//這里只需要createBond就行了
BluetoothDevice device = list.get(position);
try {
//創(chuàng)建createBond
ClsUtils.createBond(device.getClass(), device);
} catch (Exception e) {
e.printStackTrace();
}
//建立藍(lán)牙連接
mBluetoothGatt = device.connectGatt(MainActivity.this, false, mGattCallback);
}
});
因?yàn)樘^用戶輸入需要用到反射,用到了ClsUtils這個(gè)工具類,感謝一下大牛們得無私分享。在連接的時(shí)候,創(chuàng)建createBond。
藍(lán)牙連接是通過廣播判斷狀態(tài),所以需要自定義
public class BluetoothConnectActivityReceiver extends BroadcastReceiver {
String strPsw = "111111";
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
try {
/**
- cancelPairingUserInput()取消用戶輸入密鑰框,
- 個(gè)人覺得一般情況下不要和setPin(setPasskey、setPairingConfirmation、
- setRemoteOutOfBandData)一起用,
- 這幾個(gè)方法都會(huì)remove掉map里面的key:value(<<<<<也就是互斥的>>>>>>)。
*/
ClsUtils.setPin(device.getClass(), device, strPsw); // 手機(jī)和藍(lán)牙采集器配對(duì)
//ClsUtils.setPasskey(device.getClass(), device, strPsw);
ToastUtils.showShort("配對(duì)信息===>>>>成功了~");
abortBroadcast();//如果沒有將廣播終止,則會(huì)出現(xiàn)一個(gè)一閃而過的配對(duì)框。
} catch (Exception e) {
LogUtils.e("反射異常:"+e);
// TODO Auto-generated catch block
ToastUtils.showShort("請(qǐng)求連接錯(cuò)誤");
}
}
}
}
}
以上基本就是這樣了,表述不清楚待提高。最后附上Activity主要代碼。
public class MainActivity extends AppCompatActivity {
@BindView(R.id.list_view)
RecyclerView listView;
BleAdapter mBleAdapter;
@BindView(R.id.swipeRefreshLayout)
SwipeRefreshLayout swipeRefreshLayout;
private BluetoothAdapter mBluetoothAdapter;
List<BluetoothDevice> list;
private BluetoothGatt mBluetoothGatt;
private BluetoothGattCharacteristic mCharacteristic;
private BluetoothGattCharacteristic rssiCharacteristic;
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// View注入
ButterKnife.bind(this);
initPermission();
initView();
init();
// 注冊(cè)Receiver來獲取藍(lán)牙設(shè)備相關(guān)的結(jié)果
IntentFilter intent = new IntentFilter();
intent.addAction(BluetoothDevice.ACTION_FOUND);// 用BroadcastReceiver來取得搜索結(jié)果
intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(searchDevices,intent);
}
private void initView() {
list = new ArrayList<>();
mBleAdapter = new BleAdapter(R.layout.item_ble_view, list);
// 設(shè)置布局管理器
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
listView.setLayoutManager(linearLayoutManager);
listView.setAdapter(mBleAdapter);
mBleAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
//ToastUtils.showShort("點(diǎn)擊了:" + position);
//這里只需要createBond就行了
BluetoothDevice device = list.get(position);
try {
//創(chuàng)建createBond
ClsUtils.createBond(device.getClass(), device);
} catch (Exception e) {
e.printStackTrace();
}
//建立藍(lán)牙連接
mBluetoothGatt = device.connectGatt(MainActivity.this, false, mGattCallback);
}
});
//下拉刷新
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//停止刷新
swipeRefreshLayout.setRefreshing(false);
list.clear();
}
});
}
private void init() {
/**
* 兩種獲取BluetoothAdapter方式
/
//方式一:通過BluetoothManager獲取
BluetoothManager mBm = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = mBm.getAdapter();
//方式二:通過getDefaultAdapter()獲取
//mBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
LogUtils.e("沒有藍(lán)牙模塊");
ToastUtils.showShort("沒有藍(lán)牙模塊");
return;
}
/
* 打開藍(lán)牙的兩種方式
*/
//一:直接打開,不通過用戶
// if (!mBluetoothAdapter.isEnabled()) {
// mBluetoothAdapter.enable();
// LogUtils.e("開啟藍(lán)牙~");
// }
//二:優(yōu)雅的打開
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enabIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabIntent, 100);
LogUtils.e("開啟藍(lán)牙~");
}
}
private boolean mScanning;//是否正在搜索
private Handler mHandler = new Handler();
//15秒搜索時(shí)間
private static final long SCAN_PERIOD = 15000;
private void scanLeDevice(final boolean enable) {
mBluetoothAdapter.startLeScan(mLeScanCallback); //開始搜索
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
}
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
//在這里可以把搜索到的設(shè)備保存起來
//device.getName();獲取藍(lán)牙設(shè)備名字
//device.getAddress();獲取藍(lán)牙設(shè)備mac地址
//這里的rssi即信號(hào)強(qiáng)度,即手機(jī)與設(shè)備之間的信號(hào)強(qiáng)度。
list.add(device);
mBleAdapter.setNewData(list);
LogUtils.e("name:" + device.getName());
}
});
}
};
@Override
protected void onResume() {
list.clear();
scanLeDevice(true);
super.onResume();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 100) {
Toast.makeText(this, "藍(lán)牙已啟用", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "藍(lán)牙未啟用", Toast.LENGTH_SHORT).show();
}
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void initPermission() {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//判斷是否需要向用戶解釋為何要此權(quán)限
if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.READ_CONTACTS)) {
showMessageOKCancel("你必須允許這個(gè)權(quán)限,否則無法搜索到BLE設(shè)備", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
100);
}
});
return;
}
//請(qǐng)求權(quán)限
requestPermissions(new String[]{Manifest.permission.WRITE_CONTACTS},
100);
}
}
/**
*顯示權(quán)限申請(qǐng)框
*/
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 100) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//用戶允許改權(quán)限,0表示允許,-1表示拒絕 PERMISSION_GRANTED = 0, PERMISSION_DENIED = -1
//這里進(jìn)行授權(quán)被允許的處理
//可以彈個(gè)Toast,感謝用戶爸爸允許了。
scanLeDevice(true);
Toast.makeText(MainActivity.this, "謝謝!", Toast.LENGTH_SHORT).show();
} else {
//這里進(jìn)行權(quán)限被拒絕的處理,就跳轉(zhuǎn)到本應(yīng)用的程序管理器
Toast.makeText(MainActivity.this, "請(qǐng)開啟位置權(quán)限", Toast.LENGTH_SHORT).show();
Intent i = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
String pkg = "com.android.settings";
String cls = "com.android.settings.applications.InstalledAppDetails";
i.setComponent(new ComponentName(pkg, cls));
i.setData(Uri.parse("package:" + getPackageName()));
startActivity(i);
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
/**
-
gatt連接結(jié)果的返回
*/
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (status == BluetoothProfile.STATE_DISCONNECTED) { //藍(lán)牙連接
LogUtils.e("onConnectionStateChange" + "連接成功");
ToastUtils.showShort("連接成功");} }
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
}
/**
- Callback triggered as a result of a remote characteristic notification.
- @param gatt
- @param characteristic
*/
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
System.out.println("onCharacteristicChanged");
LogUtils.e("onCharacteristicChanged");
}
/**
- 寫入數(shù)據(jù)時(shí)操作
- @param gatt
- @param characteristic
- @param status
*/
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
LogUtils.e("onCharacteristicWrite");
}
/**
- 讀取返回值時(shí)操作
- @param gatt
- @param characteristic
- @param status
*/
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
LogUtils.e("onCharacteristicRead");
}
/**
Callback indicating the result of a descriptor write operation.
@param gatt
@param descriptor
-
@param status
*/
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
LogUtils.e("onDescriptorWrite");
}
};/**
- 搜索BroadcastReceiver
*/
private final BroadcastReceiver searchDevices = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Bundle b = intent.getExtras();
Object[] lstName = b.keySet().toArray();
// 顯示所有收到的消息及其細(xì)節(jié)
for (int i = 0; i < lstName.length; i++) {
String keyName = lstName.toString();
LogUtils.e(keyName, String.valueOf(b.get(keyName)));
}
BluetoothDevice device = null;
// 搜索設(shè)備時(shí),取得設(shè)備的MAC地址
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
String str = " 未配對(duì)|" + device.getName() + "|"
+ device.getAddress();
LogUtils.e(str);
// if (lstDevices.indexOf(str) == -1)// 防止重復(fù)添加
// lstDevices.add(str); // 獲取設(shè)備名稱和mac地址
// adtDevices.notifyDataSetChanged();
}
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING:
LogUtils.e("BlueToothTestActivity", "正在配對(duì)......");
break;
case BluetoothDevice.BOND_BONDED:
LogUtils.e("BlueToothTestActivity", "完成配對(duì)");
//connect(device);//連接設(shè)備
break;
case BluetoothDevice.BOND_NONE:
LogUtils.e("BlueToothTestActivity", "取消配對(duì)");
default:
break;
}
}
}
};
- 搜索BroadcastReceiver
}
再貼上ClsUtils類代碼,也可以直接搜ClsUtils,可以搜到。
public class ClsUtils {
static BluetoothDevice remoteDevice;
/**
* 與設(shè)備配對(duì) 參考源碼:platform/packages/apps/Settings.git
* /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
/
static public boolean createBond(Class btClass, BluetoothDevice btDevice)
throws Exception {
Method createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
/*
* 與設(shè)備解除配對(duì) 參考源碼:platform/packages/apps/Settings.git
* /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
/
static public boolean removeBond(Class btClass, BluetoothDevice btDevice)
throws Exception {
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
static public boolean setPin(Class btClass, BluetoothDevice btDevice,String str) throws Exception {
try {
Method removeBondMethod = btClass.getDeclaredMethod("setPin",new Class[]{byte[].class});
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,
new Object[]
{str.getBytes()});
Log.e("returnValue", "" + returnValue);
} catch (SecurityException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (IllegalArgumentException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
static public boolean setPasskey (Class btClass, BluetoothDevice btDevice,String str) throws Exception {
try {
Method removeBondMethod = btClass.getDeclaredMethod("setPasskey", new Class[]{byte[].class});
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice, new Object[]{str.getBytes()});
Log.e("returnValue", "" + returnValue);
} catch (SecurityException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (IllegalArgumentException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
// 取消用戶輸入
static public boolean cancelPairingUserInput(Class btClass,BluetoothDevice device)throws Exception {
Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
// cancelBondProcess()
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
// 取消配對(duì)
static public boolean cancelBondProcess(Class btClass, BluetoothDevice device)throws Exception {
Method createBondMethod = btClass.getMethod("cancelBondProcess");
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
//確認(rèn)配對(duì)
static public void setPairingConfirmation(Class<?> btClass, BluetoothDevice device, boolean isConfirm) throws Exception {
Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation", boolean.class);
setPairingConfirmation.invoke(device, isConfirm);
}
/*
* @param clsShow
*/
static public void printAllInform(Class clsShow) {
try {
// 取得所有方法
Method[] hideMethod = clsShow.getMethods();
int i = 0;
for (; i < hideMethod.length; i++) {
Log.e("method name", hideMethod[i].getName() + ";and the i is:"
+ i);
}
// 取得所有常量
Field[] allFields = clsShow.getFields();
for (i = 0; i < allFields.length; i++) {
Log.e("Field name", allFields[i].getName());
}
} catch (SecurityException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (IllegalArgumentException e) {
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 執(zhí)行時(shí)直接使用:
public static boolean pair(String strAddr, String strPsw) {
boolean result = false;
BluetoothAdapter bluetoothAdapter = BluetoothAdapter .getDefaultAdapter();
bluetoothAdapter.cancelDiscovery();
if (!bluetoothAdapter.isEnabled()) {
bluetoothAdapter.enable();
}
if (!BluetoothAdapter.checkBluetoothAddress(strAddr)) { // 檢查藍(lán)牙地址是否有效
Log.d("mylog", "devAdd un effient!");
}
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(strAddr);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
try {
Log.d("mylog", "NOT BOND_BONDED");
ClsUtils.setPin(device.getClass(), device, strPsw); // 手機(jī)和藍(lán)牙采集器配對(duì)
ClsUtils.createBond(device.getClass(), device);
remoteDevice = device; // 配對(duì)完畢就把這個(gè)設(shè)備對(duì)象傳給全局的remoteDevice
result = true;
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("mylog", "setPiN failed!");
e.printStackTrace();
} //
} else {
Log.d("mylog", "HAS BOND_BONDED");
try {
ClsUtils.createBond(device.getClass(), device);
ClsUtils.setPin(device.getClass(), device, strPsw); // 手機(jī)和藍(lán)牙采集器配對(duì)
ClsUtils.createBond(device.getClass(), device);
remoteDevice = device; // 如果綁定成功,就直接把這個(gè)設(shè)備對(duì)象傳給全局的remoteDevice
result = true;
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("mylog", "setPiN failed!");
e.printStackTrace();
}
}
return result;
}
}
以上在紅米not4x 、 華為榮耀8 、 華為榮耀青春版(不知道具體啥型號(hào))、小米5、vivoX20、華為p9、華為榮耀9、華為Mate 10、小米5x、紅米3X、紅米not5A測(cè)試OK。聽說在三星上不行,到時(shí)候找個(gè)測(cè)試下。
如有錯(cuò)誤,請(qǐng)留言提出。謝謝~