Android 藍芽自動配對連線
阿新 • • 發佈:2019-02-13
藍芽工具類:
public class BTReceiverUtils {
/**
* 與裝置配對
*/
static public boolean createBond(Class btClass, BluetoothDevice btDevice) throws Exception {
Method createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
/**
* 與裝置解除配對
*/
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<? extends BluetoothDevice> 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)
{
e.printStackTrace();
}
return true;
}
/**
* 取消使用者輸入
*/
static public boolean cancelPairingUserInput(Class<?> btClass, BluetoothDevice device) throws Exception
{
Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
/**
* 取消配對
*/
static public boolean cancelBondProcess(Class<?> btClass, BluetoothDevice device) throws Exception {
Method createBondMethod = btClass.getMethod("cancelBondProcess");
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
/**
* 確認配對
*/
static public void setPairingConfirmation(Class<?> btClass,BluetoothDevice device,boolean isConfirm)throws Exception {
Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation",boolean.class);
setPairingConfirmation.invoke(device,isConfirm);
}
}
藍芽搜尋連線:
(預設以 0000 pin連線,不需要使用者輸入)
private BTReceiverAdapter btReceiverAdapter;
private LinearLayoutManager linearLayoutManager;
private BluetoothAdapter mBluetoothAdapter;
private IntentFilter mFilter;
private BluetoothDevice mBluetoothDevice;//搜尋出來的
/**
* 需要連線的藍芽裝置
*/
private BluetoothDevice bluetoothDevice; //選擇的裝置
private SharedPreferences sharedPreferences;
private int clickSelect;//選擇的藍芽裝置在列表中的位置
private List<BluetoothDevice> bluetoothDeviceList = new ArrayList<>();//搜尋出的裝置集合
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.leftmenu_btreceiver);
ButterKnife.bind(this);
sharedPreferences = getApplicationContext().getSharedPreferences(UserInfoConstant.USERINFO_SHREDPREFERENCE, Context.MODE_PRIVATE);
initPairingInfo();
}
/**
* 填充已配對藍芽裝置資訊
*/
private void initPairingInfo() {
leftmenuBtreceiverName.setText(SharedPreferencesUtil.getSharedPreferences(this, UserInfoConstant.USERINFO_SHREDPREFERENCE, UserInfoConstant.USERINFO_BLUETOOTHNAME));
leftmenuBtreceiverId.setText(SharedPreferencesUtil.getSharedPreferences(this, UserInfoConstant.USERINFO_SHREDPREFERENCE, UserInfoConstant.USERINFO_BLUETOOTHID));
}
@OnClick({R.id.leftmenu_btreceiver_back, R.id.leftmenu_btreceiver_scan})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.leftmenu_btreceiver_back:
finish();
break;
case R.id.leftmenu_btreceiver_scan:
methodRequiresTwoPermission();
break;
}
}
/**
* 檢測是否有藍芽許可權和模糊定位許可權
*/
private void methodRequiresTwoPermission() {
String[] perms = {Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.ACCESS_COARSE_LOCATION};
if (EasyPermissions.hasPermissions(this, perms)) {
inspect();
} else {
EasyPermissions.requestPermissions(this, getString(R.string.permissions_hint), 0, perms);
}
}
/**
* 藍芽是否開啟,未開啟則提示使用者,開啟則彈出選擇框
*/
private void inspect() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter.isEnabled()) {
/**註冊搜尋藍芽receiver*/
mFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
mFilter.addAction(BluetoothDevice.ACTION_FOUND);
mFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
mFilter.addAction("android.bluetooth.device.action.PAIRING_REQUEST");
bluetoothDeviceList.clear();
registerReceiver(mReceiver, mFilter);
mBluetoothAdapter.startDiscovery();
scanDialog();
} else {
Toast.makeText(this, R.string.BTReceiverActivity_open_hint, Toast.LENGTH_SHORT).show();
}
}
/**
* 點選掃描彈出框
*/
private void scanDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LinearLayout scanDialog = (LinearLayout) getLayoutInflater().inflate(R.layout.leftmenu_btreceiver_popup, null);
builder.setView(scanDialog);
builder.setCancelable(false);
final AlertDialog dialog = builder.create();
dialog.show();
Button cancel = scanDialog.findViewById(R.id.leftmenu_btreceiver_popup_cancel);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mBluetoothAdapter.cancelDiscovery();
dialog.cancel();
}
});
RecyclerView deviceRecycler = scanDialog.findViewById(R.id.leftmenu_btreceiver_popup_device);
linearLayoutManager = new LinearLayoutManager(this);
deviceRecycler.setLayoutManager(linearLayoutManager);
deviceRecycler.setHasFixedSize(true);
btReceiverAdapter = new BTReceiverAdapter(bluetoothDeviceList);
deviceRecycler.setAdapter(btReceiverAdapter);
btReceiverAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
Log.d(TAG, "onItemClick: " + position);
clickSelect = position;
mBluetoothAdapter.cancelDiscovery();
dialog.cancel();
pairing();
}
});
}
/**
* 進行檢測配對操作
*/
private void pairing() {
//判斷是否已經配對
if (bluetoothDeviceList.get(clickSelect).getBondState() == BluetoothDevice.BOND_BONDED) {
// 儲存
Log.d(TAG, "已配對: " + bluetoothDeviceList.get(clickSelect).getName());
Toast.makeText(BTReceiverActivity.this, R.string.BTReceiverActivity_pairing_succeed, Toast.LENGTH_SHORT).show();
SharedPreferences.Editor edt = sharedPreferences.edit();
edt.putString(UserInfoConstant.USERINFO_BLUETOOTHNAME, bluetoothDeviceList.get(clickSelect).getName());
edt.putString(UserInfoConstant.USERINFO_BLUETOOTHID, bluetoothDeviceList.get(clickSelect).getAddress());
edt.apply();
initPairingInfo();
} else {
// 進行配對
try {
BTReceiverUtils.createBond(bluetoothDeviceList.get(clickSelect).getClass(), bluetoothDeviceList.get(clickSelect));
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 處理廣播
*/
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
/** 搜尋到的藍芽裝置*/
if (action.equals(BluetoothDevice.ACTION_FOUND)) {
mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
bluetoothDeviceList.add(mBluetoothDevice);
Log.d("mReceiver", "search......" + mBluetoothDevice.getName());
btReceiverAdapter.notifyDataSetChanged();
} else if (action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
/** 配對 */
Log.d(TAG, "getDeviceName; " + bluetoothDeviceList.get(clickSelect).getName());
bluetoothDevice = bluetoothDeviceList.get(clickSelect);
Log.d(TAG, "bluetoothDevice.getName : " + bluetoothDevice.getName());
try {
//終止有序廣播
mReceiver.abortBroadcast();//如果沒有將廣播終止,則會出現一個一閃而過的配對框。
//呼叫setPin方法進行配對...
boolean ret = BTReceiverUtils.setPin(bluetoothDevice.getClass(), bluetoothDevice, ModelConstants.BLUETOOTH_PIN);
//確認配對
BTReceiverUtils.setPairingConfirmation(bluetoothDevice.getClass(), bluetoothDevice, true);
//取消使用者輸入
BTReceiverUtils.cancelPairingUserInput(bluetoothDevice.getClass(), bluetoothDevice);
Log.d("pairing", "ret: " + ret + " name" + bluetoothDevice.getName() + " address " + bluetoothDevice.getAddress());
if (ret) {
saveBluetoothDevice();
} else {
Toast.makeText(BTReceiverActivity.this, R.string.BTReceiverActivity_pairing_failure, Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
switch (mBluetoothDevice.getBondState()) {
case BluetoothDevice.BOND_BONDING://正在配對
Log.d(TAG, "正在配對......");
break;
case BluetoothDevice.BOND_BONDED://配對結束
Log.d(TAG, "完成配對");
saveBluetoothDevice();
break;
case BluetoothDevice.BOND_NONE://取消配對/未配對
if (bluetoothDevice.getName().contains("Bluetooth Rec")){
saveBluetoothDevice();
}
default:
break;
}
}
}
};
/**
* 儲存配對
*/
private void saveBluetoothDevice(){
Toast.makeText(BTReceiverActivity.this, R.string.BTReceiverActivity_pairing_succeed, Toast.LENGTH_SHORT).show();
SharedPreferences.Editor edt = sharedPreferences.edit();
edt.putString(UserInfoConstant.USERINFO_BLUETOOTHNAME, bluetoothDevice.getName());
edt.putString(UserInfoConstant.USERINFO_BLUETOOTHID, bluetoothDevice.getAddress());
edt.apply();
initPairingInfo();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//把申請許可權的回撥交由EasyPermissions處理
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
inspect();
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
Toast.makeText(this, getString(R.string.permissions_hint), Toast.LENGTH_SHORT).show();
}
}