蓝牙通信测试app之蓝牙配对(一)

蓝牙配对开发流程

流程是:开启蓝牙 —-》 获取蓝牙各种权限 —-》注册广播(广播的作用是用来接收扫描结果) —-》 扫描蓝牙 —-》广播接收 ——》 蓝牙配对 —-》 解除注册

开启蓝牙

  • 获取BluetoothAdapter对象
  • 判断设备是否支持蓝牙
  • 打开蓝牙
// 获取BluetoothAdapter对象
private BluetoothAdapter mBluetoothAdapter;
   
 private void checkBluetoohStatus() {
	mBluetoothAdapter =   BluetoothAdapter.getDefaultAdapter();
	// 判断设备是否支持蓝牙
	if (mBluetoothAdapter == null) {
		Toast.makeText(BluetoothShowActivity.this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
		finish();
		return;
	}
    // 判读是否打开了蓝牙(蓝牙会弹出提示)
    if(!mBluetoothAdapter.isEnabled())
    {
        Intent turnOn=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(turnOn,-1);
    }
//   // 判读是否打开了蓝牙(蓝牙不会弹出提示)
//    if (isSupportBlue()) {
//        mBluetoothAdapter.enable();
//    }

}

申请权限

  • 在 AndroidManifest.xml 里添加权限

    • 处理6.0以下版本的权限: 在AndroidManifest里面添加权限

      <!-- 使用蓝牙的权限 -->
      <uses-permission android:name="android.permission.BLUETOOTH" />
      <!-- 扫描蓝牙设备或者操作蓝牙设置 -->
      <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
      
    • 处理6.0以上版本的权限: 在AndroidManifest里面添加权限

      <!-- 使用蓝牙的权限 -->
      <uses-permission android:name="android.permission.BLUETOOTH" />
      <!-- 扫描蓝牙设备或者操作蓝牙设置 -->
      <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
      <!--模糊定位权限,仅作用于6.0+-->
      <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
      <!--精准定位权限,仅作用于6.0+-->
      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
      
  • 获取权限

// 申请请求许可权限
private void getBluePermission() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.READ_CONTACTS)) {
            Toast.makeText(this, "shouldShowRequestPermissionRationale", Toast.LENGTH_SHORT).show();
        }
    }
}

/**
 * 解决:无法发现蓝牙设备的问题
 *
 * 对于发现新设备这个功能, 还需另外两个权限(Android M 以上版本需要显式获取授权,附授权代码):
 */
private final int ACCESS_LOCATION=1;
@SuppressLint("WrongConstant")
private void getPermission() {
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
        int permissionCheck = 0;
        permissionCheck = this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
        permissionCheck += this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION);

        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            //未获得权限
            this.requestPermissions( // 请求授权
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION}, ACCESS_LOCATION);// 自定义常量,任意整型
        }
    }
}

/**
 * 请求权限的结果回调。每次调用 requestpermissions(string[],int)时都会调用此方法。
 * @param requestCode 传入的请求代码
 * @param permissions 传入permissions的要求
 * @param grantResults 相应权限的授予结果:PERMISSION_GRANTED 或 PERMISSION_DENIED
 */
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case ACCESS_LOCATION:
            if (hasAllPermissionGranted(grantResults)) {
                Log.i(TAG, "onRequestPermissionsResult: 用户允许权限");
            } else {
                Log.i(TAG, "onRequestPermissionsResult: 拒绝搜索设备权限");
            }
            break;
    }
}

private boolean hasAllPermissionGranted(int[] grantResults) {
    for (int grantResult : grantResults) {
        if (grantResult == PackageManager.PERMISSION_DENIED) {
            return false;
        }
    }
    return true;
}

注册广播和接收广播

注册 :蓝牙状态改变的广播 和 蓝牙扫描设备时的广播。

/**
 * 注册蓝牙广播
 */
private void registerBroadcast(){
    //监听蓝牙状态改变的广播
    IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    registerReceiver(receiver, filter);
    //监听蓝牙设备扫描的广播
    mBlueToothReceiver = new BluetoothReceiver();
    IntentFilter mIntentFilter = new IntentFilter();
        // 扫描到设备的广播
    mIntentFilter.addAction(BluetoothDevice.ACTION_FOUND);
    	// 扫描结束的广播
    mIntentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    mIntentFilter.setPriority(Integer.MAX_VALUE);
        // 注册广播
    registerReceiver(mBlueToothReceiver,mIntentFilter);
}

接收:蓝牙状态改变的广播:

// 这个当蓝牙状态改变时,就会进入
private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 1);
        switch (state) {
            case BluetoothAdapter.STATE_OFF:
                // 吐丝弹窗
                Toast.makeText(BluetoothShowActivity.this, "蓝牙已关闭", Toast.LENGTH_SHORT).show();
                break;
            case BluetoothAdapter.STATE_ON:
                Toast.makeText(BluetoothShowActivity.this, "蓝牙已打开", Toast.LENGTH_SHORT).show();
                break;
        }
    }
};

接收:蓝牙扫描设备时的广播:

public class BluetoothReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent ) {
        String action = intent.getAction();
        // 判断是扫描的哪个状态
        if(BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent.getParcelableExtra( BluetoothDevice.EXTRA_DEVICE );
            // 这是listview视图,添加适配器
            listView.setAdapter(mBluetoothDeviceAdapter);
            // 将设备放到添加到适配器中
            mBluetoothDeviceAdapter.addDevice(device);
            // 数据改变并更新列表
            mBluetoothDeviceAdapter.notifyDataSetChanged();
        }else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
            // 关闭进度条
            progressDialog.dismiss();
            Toast.makeText(BluetoothShowActivity.this, "搜索完成", Toast.LENGTH_SHORT).show();
        }
    }
}

扫描蓝牙

/**
 * 搜索蓝牙
 */
private void searchBluetooth() {
    mBluetoothAdapter =   BluetoothAdapter.getDefaultAdapter();
    //清除适配器的内容,以便从新搜索
    mBluetoothDeviceAdapter.clear();
    mBluetoothDeviceAdapter.notifyDataSetChanged();
    // 如果已经在搜索了,那么取消搜索(主要)
    if(mBluetoothAdapter.isDiscovering()){
        mBluetoothAdapter.cancelDiscovery();
    }
    // 寻找所有蓝牙设备(主要)
    mBluetoothAdapter.startDiscovery();
    //开启进度条
    if (progressDialog == null) {
        progressDialog = new ProgressDialog(BluetoothShowActivity.this);
    }
//        progressDialog.setCanceledOnTouchOutside(false); //实现点击外部不消失。
    progressDialog.setMessage("正在搜索中,请稍候...");
    progressDialog.show();
}

蓝牙配对

// listview视图里的单个对象点击事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // 是否在扫描
        if (mBluetoothAdapter.isDiscovering()) {
            // 取消扫描
            mBluetoothAdapter.cancelDiscovery();
        }
        try {
            // 通过点击对象的位置,获取蓝牙设备
            BluetoothDevice device = mBluetoothDeviceAdapter.getDevice(position);
            Method createBondMethod;
            Boolean returnValue = false;
            // 还没有配对的进入该方法
            if(device.getBondState() == BluetoothDevice.BOND_NONE) {
                // 反射方法调用;
                createBondMethod = BluetoothDevice.class .getMethod("createBond");
                // 与设备建立连接
                returnValue = (Boolean) createBondMethod.invoke(device);
                // 更新当前被选中的位置
                Constant.CURREN_POSITION = position;
                // 刷新 ListView
                mBluetoothDeviceAdapter.notifyDataSetChanged();
            }
            // 如果和该蓝牙设备已经配对
            else if(device.getBondState() == BluetoothDevice.BOND_BONDED){
                // 获取蓝牙设备的地址
                String address= device.getAddress();
                Intent intent =new Intent(BluetoothShowActivity.this,MainActivity.class);
                intent.putExtra(EXTRA_DEVICE_ADDRESS,address);
                // 将蓝牙设备地址返回到 MainActivity.class
                setResult(Activity.RESULT_OK, intent);
                finish();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

解除注册广播

@Override
protected void onDestroy() {
    super.onDestroy();//解除注册
    unregisterReceiver(receiver);
    unregisterReceiver(mBlueToothReceiver);
}

posted @ 2021-06-15 22:13  Swift_十万伏特  阅读(653)  评论(0编辑  收藏  举报