Android 8.0 蓝牙唤醒 Ble 锁屏 保活 后台 持续扫描 进程拉活 自动唤醒

主要是api的说明,嫌啰嗦的可以直接看demo,demo中有个检测锁屏时间重复开启扫描的代码,主要是如果APP没有获得电量或者后台运行的权限,只能持续后台运行几小时。

这个demo的作用是实现8.0以后的后台监测到特定蓝牙信号自动唤醒APP的功能,首先需要另外一个装了可以发射蓝牙信号软件的手机,我这边是选取的ios平台上的lightblue,然后在这个软件里面新建一个虚拟设备名称是要demo搜索的蓝牙模块名称。然后把app杀掉,过一段时间打开lightblue发射蓝牙信号,然后关掉,再次打开demo,会发现demo中记录的时间就是你发射蓝牙信号的时间,说明被杀后它还是在监测蓝牙信号的

先看gif的效果

Demo的Github地址如下

https://github.com/TracyEminem/BleSingle    

 

在Android 8.0以上的版本中,Google提供了一种可以在后台持续扫描的方式,如果不给后台运行的权限,也是可以在锁屏后持续进行蓝牙扫描,可以持续大概几个小时,还可以利用传的intent来从后台唤醒APP。。。我做了尝试,如果把app从任务栏删掉,再发出蓝牙信号也可以让app自动运行唤醒。。。如果你给与了电量限制,后台运行相关的权限,那么这个扫描是可以持续很久的,使用前台service我做到过5天保持扫描一直在运行。而且这个耗电量很低,基本上忽略不计。。原理有点类似于IOS上的IBEACON唤醒APP,虽然Android也有类似的Eddystone,但是Eddystone不支持后台持续监测,Eddystone可以利用Google nearby的api检测到甚至IBEACON也是可以检测的,但是google nearby的检测方式依赖于你何时按下锁屏按钮的,如果你在beacon附近没有按锁屏按钮,那么是不会再后台检测BEACON信号的。。

唤醒的api如下

很明显,也是利用了ScanFilter来检测指定的设备,来实现这个后台扫描的功能的,实际上单纯只是锁屏后台持续扫描的API还有另外一个,也是利用了ScanFilter。。另外一个api如下

 

下面是如何使用 首先是一堆权限 

   <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

然后是创建一个Penddingintent来执行唤醒操作

   callbackIntent = PendingIntent.getForegroundService(
                this,
                1,
                new Intent("com.hungrytree.receiver.BleService").setPackage(getPackageName()),
                PendingIntent.FLAG_UPDATE_CURRENT );

这个callbackIntent在开启和关闭蓝牙扫描时也要用到,然后开启蓝牙的扫描,这一步可以在Activity中操作,也可以在service中操作。。。

    public void onOpen(){
        //BluetoothManager是向蓝牙设备通讯的入口
        BluetoothManager bluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();

        //指定需要识别到的蓝牙设备
        List<ScanFilter> scanFilterList = new ArrayList<>();

        ScanFilter.Builder builder2 = new ScanFilter.Builder();
        builder2.setDeviceName("test2");//你要扫描的设备的名称,如果使用lightble这个app来模拟蓝牙可以直接设置name,这个只是filter的一种,你可以指定uuid,这个只是指定设备名
        ScanFilter scanFilter2 = builder2.build();

//        scanFilterList.add(scanFilter);
        scanFilterList.add(scanFilter2);

        //指定蓝牙的方式,这里设置的ScanSettings.SCAN_MODE_LOW_POWER是比较节电的扫描方式,而且在效率方面没有很大的影响,而且相当省电
        ScanSettings.Builder settingBuilder = new ScanSettings.Builder();
        settingBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
        settingBuilder.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE);
        settingBuilder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
        settingBuilder.setLegacy(true);
        ScanSettings settings = settingBuilder.build();


        //启动蓝牙扫描
        bluetoothAdapter.getBluetoothLeScanner().startScan(scanFilterList,settings,callbackIntent);
        // bluetoothAdapter.getBluetoothLeScanner().startScan(scanFilterList,settings,mScanCallback);
    }

后面是关闭蓝牙扫描

   public void onClose(){
        BluetoothManager bluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();

        bluetoothAdapter.getBluetoothLeScanner().stopScan(callbackIntent);
        //这个callbackintent必须是之前创建的那个,不然无法关闭扫描

    }

下面是接收蓝牙扫描的结果,在Service中接收结果,并且处理

     <service android:name=".TestService">
            <intent-filter>
                <action android:name="com.hungrytree.receiver.BleService"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </service>

处理是在service的onstartcommand方法中,结果会不断的回调该方法,在该方法中进行处理

  @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent.getAction() == null) {
            return START_STICKY;
        }

        //获取返回的错误码
        int errorCode = intent.getIntExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, -1);//ScanSettings.SCAN_FAILED_*
        //获取到的蓝牙设备的回调类型
        int callbackType = intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, -1);//ScanSettings.CALLBACK_TYPE_*
        if (errorCode == -1) {
            //扫描到蓝牙设备信息
            List<ScanResult> scanResults = (List<ScanResult>) intent.getSerializableExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT);
            if (scanResults != null) {
                for (ScanResult result : scanResults) {
                   Utils.writeFile(getApplicationContext(),"wakeup.log",Integer.toString(numRSSI));
                    Log.i("Wakeup", "onScanResult2: name: " + result.getDevice().getName() +
                            ", address: " + result.getDevice().getAddress() +
                            ", rssi: " + result.getRssi() + ", scanRecord: " + result.getScanRecord());
                }
            }
        } else {
            //此处为扫描失败的错误处理

        }
        return START_STICKY;
    }

如果中途关闭蓝牙,那么扫描会自动恢复。。如果被杀了,你关闭蓝牙,那么无法再执行唤醒的操作。。。如果要利用手机发出特定的蓝牙信号,可以安装LightBlue 这个app,要发出beacon信号的话,请安装玩转Beacon。。这两个app都是ios平台的

 

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
以下是Android Studio中扫描BLE蓝牙设备、连接设备、以及断开连接的代码: 1. 检查蓝牙是否打开 ```java // 检查蓝牙是否打开 private boolean isBluetoothEnabled() { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); return bluetoothAdapter != null && bluetoothAdapter.isEnabled(); } ``` 2. 扫描BLE设备 ```java // 扫描BLE设备 private void scanBLEDevices() { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { Log.e(TAG, "Device doesn't support Bluetooth"); return; } if (!isBluetoothEnabled()) { Log.e(TAG, "Bluetooth is not enabled"); return; } bluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) { // 处理扫描到的设备 runOnUiThread(new Runnable() { @Override public void run() { // 处理扫描到的设备 } }); } }); } ``` 3. 连接设备 ```java // 连接设备 private void connectToDevice(BluetoothDevice device) { BluetoothGatt bluetoothGatt = device.connectGatt(this, false, new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { // 处理连接状态改变 } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { // 处理服务发现 } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { // 处理读取特征值 } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { // 处理特征值改变 } @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { // 处理写入特征值 } }); } ``` 4. 断开连接 ```java // 断开连接 private void disconnectGatt(BluetoothGatt bluetoothGatt) { if (bluetoothGatt != null) { bluetoothGatt.disconnect(); bluetoothGatt.close(); } } ``` 注意:以上代码仅为示例,需要根据具体需求进行修改。同时,BLE蓝牙连接需要遵循一定的协议,需要根据设备提供的文档进行开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值