Android经典蓝牙与低功耗蓝牙扫描

时间:2019-03-19
本文章向大家介绍Android经典蓝牙与低功耗蓝牙扫描,主要包括Android经典蓝牙与低功耗蓝牙扫描使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

我最近做了一个蓝牙扫描Demo需要将经典蓝牙与BLE低功耗蓝牙进行分开扫描并且显示,发现了一些问题在次总结一下,首先是Android 6.0以后扫描蓝牙需要与定位权限,否则扫描不到。自己写的Demo是前30秒扫描经典蓝牙,后30秒扫描BLe蓝牙,按下扫描键是变成停止,停止扫描工作,再次点击为扫描。

申请蓝牙权限,首先需要自己写一个方法,requestPermission()这个方法用来判断自己是否拥有权限以及没有是申请权限。
checkSelfPermission方法的返回值不等于PERMISSION_GRANTED时没有权限,PERMISSION_GRANTED是个静态常量是0,也就是checkSelfPermission返回值是1是没有权限。

 private void requestPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            int checkAccessFinePermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
       //检查是否拥有权限
            if (checkAccessFinePermission != PackageManager.PERMISSION_GRANTED) {
//没有权限,申请权限回调onRequestPermissionsResult方法
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        REQUEST_PERMISSION_ACCESS_LOCATION);
                Log.e(getPackageName(), "没有权限,请求权限");
                return;
            }
            Log.e(getPackageName(), "已有定位权限");
            startDiscovery();
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.e(getPackageName(), "开启权限permission granted!");
                    //做下面该做的事
                   startDiscovery();
                } else {
                    Log.e(getPackageName(), "没有定位权限,请先开启!");
                }
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

[Click and drag to move]

下面是经典蓝牙扫描,通过广播,回调onReceive方法扫描到蓝牙设备

注册广播

private void registerBroadcast() {
        // Register for broadcasts when a device is discovered
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(myReceive, filter);

        // Register for broadcasts when discovery has finished
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(myReceive, filter);
    }

调用startDiscovery方法开始扫描经典蓝牙

 public void startDiscovery() {
        if (blueToothAdapter.isDiscovering())
            blueToothAdapter.cancelDiscovery();
        blueToothAdapter.startDiscovery();
        Log.e("MAinActivity","执行了Discovery  ");
    }

 经典蓝牙扫描广播的回调方法

 private final int addclassic=5;
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("BluetoothRecrive","开始扫描classic");
        if(BluetoothDevice.ACTION_FOUND.equals(intent.getAction()))
        {
            BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if(device.getAddress()!=null)
            {   //通过Handler传值
                blue bb=new blue(device.getName(),device.getAddress());//自定义类放入进行数据的发送
                Message msg = new Message();
                msg.what =addclassic;
                Bundle b = new Bundle();
                b.putSerializable("CLASSIC", bb);
                msg.setData(b);
                Handler handler=MainActivity.handlerOPeration.getHandler();//自己写的方法获取Activity的Handler对象
                handler.sendMessage(msg);

            }

        }else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())) {
            Log.d("BlutoothReceive","开始搜索");
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())) {
            Log.d("BlutoothReceive","完成搜索");
        }

    }

顺便提供一下获取Handler对象的工具类吧,直接Set,Get方法就行了

public class HandlerOPeration extends Application {
    private Handler mHandler;
    @Override
    public void onCreate()
    {
        super.onCreate();
    }

    //该方法用于保存要传递的handler
    public void setHandler( Handler handler) {
        this.mHandler = handler;
    }
    //该方法用于获取要传递的handler
    public Handler getHandler() {
        return mHandler;
    }
}

 下面是BLE低功耗蓝牙的扫描代码,回调ScanCallBack方法扫描蓝牙

  Callback = new ScanCallback() {
            @Override
            public void onScanResult(int callbackType, ScanResult result) {
                super.onScanResult(callbackType, result);
                BluetoothDevice device = result.getDevice();
                Log.d("Blescan", "开始扫描BLE");
                if(device.getAddress()!=null){
               //Handler进行数据传输
                blue bb = new blue(device.getName(), device.getAddress());
                Message msg = new Message();
                msg.what = addble;
                Bundle b = new Bundle();
                b.putSerializable("BLE", bb);
                msg.setData(b);
                Handler handler = MainActivity.handlerOPeration.getHandler();
                handler.sendMessage(msg);
                }
            }

            @Override
            public void onBatchScanResults(List<ScanResult> results) {
                super.onBatchScanResults(results);
            }

            @Override
            public void onScanFailed(int errorCode) {
                super.onScanFailed(errorCode);
                Log.e("Blescan", "搜索失败");
            }
        };

 开启BLE蓝牙扫描以及关闭

 /**
     * 开启蓝牙
     */
    public void startBlue(){
        if(mScanning){
            mScanning = false;
            //开始扫描并设置回调
            scanner.startScan(Callback);
        }
    }

    /**
     * 停止蓝牙扫描
     */
    public void stopBlue(){
        if(!mScanning){
            //结束蓝牙扫描
            mScanning=true;
           scanner.stopScan(Callback);

        }
    }

Handler通信逻辑

public  Handler mhandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            ListOperation listOperation=new ListOperation();
            handlerOPeration.setHandler(mhandler);
            switch (msg.what) {
                case addclassic://listview1的数据接收
                    blue user = (blue) msg.getData().getSerializable("CLASSIC");
                    if(listOperation.RemoveRepeat(list_classic,user)==true){//去除扫描到的重复的蓝牙设备,listOperation.RemoveRepeat这是自己写的方法
                        list_classic.add(user);
                        blueAdapter_classic.notifyDataSetChanged();  //发现新的设备更新UI
                        Log.d("listviewclassic", "姓名" + user.getName() + "地址  " + user.getAddress());
                        break;
                    }
                    break;
                case addble:
                    blue ble = (blue) msg.getData().getSerializable("BLE");
                    if(listOperation.RemoveRepeat(list_ble,ble)==true){
                        list_ble.add(ble);
                        blueAdapter_ble.notifyDataSetChanged();  //发现新的设备更新UI
                        Log.d("listviewBLE", "姓名" + ble.getName() + "地址  " + ble.getAddress());
                        break;
                    }
                    break;
                case scanble:   //扫描BLE
                    blueToothAdapter.cancelDiscovery();
                    if(flag==true) {//只在扫描的状态下执行下面代码
                        //blueAdapter_classic.notifyDataSetChanged();
                        blescan.getInitialization(MainActivity.this);
                        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
                            Log.e("MainActivity", "支持BLE");
                        } else {
                            Log.e("MainActivity", "bu支持BLE");
                        }

                        blescan.startBlue();  //开始扫描BLE
                        Toast.makeText(MainActivity.this, "开始扫描BLE蓝牙", Toast.LENGTH_SHORT).show();
                        break;
                    }else {
                        break;
                    }
                case scanclassic:  //扫描经典蓝牙
                    Toast.makeText(MainActivity.this,"开始扫描经典蓝牙",Toast.LENGTH_SHORT).show();
                    blueToothAdapter.enable();
                    requestPermission();   //请求定位权限
                    break;
                case stop:
                    //blueAdapter_classic.notifyDataSetChanged();
                    //blueAdapter_ble.notifyDataSetChanged();  //发现新的设备更新UI
                    mhandler.removeMessages(scanble);//清空消息队列
                    mhandler.removeMessages(stop);
                    mhandler.removeMessages(scanclassic);
                    blueToothAdapter.cancelDiscovery();  //结束经典蓝牙扫描
                    //blueToothAdapter.disable();
                    blescan.stopBlue();  //结束BLE扫描
                    button.setText(MainActivity.this.getString(R.string.scan));
                    flag = false;
                    Log.d("BlutoothReceive", "停止");
                    break;
                default:
                    break;
            }

            return false;
        }
    });

刚刚开始写博客,写的比较乱,多多谅解,不明白的可以多交流,

把源码也放进来吧

https://download.csdn.net/download/weixin_43080188/11037776