技术标签: 蓝牙唤醒 锁屏蓝牙扫描 后台唤醒 蓝牙 蓝牙扫描
主要是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平台的
文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99
文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效
文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是
文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件
文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件
文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码
文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware
文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停
文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待
文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析
文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code
文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象