蓝牙工具类:
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 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 perms) {
inspect();
}
@Override
public void onPermissionsDenied(int requestCode, List perms) {
Toast.makeText(this, getString(R.string.permissions_hint), Toast.LENGTH_SHORT).show();
}
}