zoukankan      html  css  js  c++  java
  • 蓝牙通信测试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);
    }
    

    十万签名内容......
  • 相关阅读:
    复习:C#3.0面向对象测试开发包
    SQL Server 2000实现一则按类似VB VAL函数功能排序的案例
    SQL Server TEXT类型字段字符串替换示例处理脚本
    获取SQL Server服务器的连接信息用脚本(在原邹建写的基础上作一点改进)与一段查询SQL Server服务器阻塞和死锁信息用的脚本
    字符串前部去除自定义函数(TSQL)
    从数据库系统管理的角度上回答数据库是什么
    话说物联网
    赖床狂想记录
    M1非接触式射频存储卡卡唯一号(十六进制值表示),去除其前部为0的自定义函数
    SQLHelper类
  • 原文地址:https://www.cnblogs.com/myswift/p/14887403.html
Copyright © 2011-2022 走看看