Android锁屏黑屏后连续定位问题解决方案
LocationServiceDemo
该示例主要展示App切换到后台熄灭屏幕后如何持续获得设备位置。
前述
- 高德官网申请Key.
- 阅读参考手册.
- 工程基于高德地图Android定位SDK实现
文章图片
问题说明 小米可以在WLAN高级设置中,设置在息屏情况下关闭wifi,(如果设备手机流量关闭)导致在亮屏时可以定位,息屏后不能定位的情况。针对此种情况,我们在定位服务中,如果检测到上述逻辑,则去点亮屏幕。 小米息屏后,WIFI大概在5分钟之后会断开,所以我们建议点亮屏幕的时间间隔为5分钟。
核心难点
- 在定位服务中检测是否是由息屏造成的网络中断,如果是,则尝试进行点亮屏幕。同时,为了避免频繁点亮,对最小时间间隔进行了设置(可以按需求修改).如果息屏没有断网,则无需点亮屏幕.
- 需要保证定位服务的优先级,以免被杀死。
- 定位服务包含了点亮屏幕的功能,需要有拉活机制,保证此服务一直是alive的。部分机型会杀死尝试多次点亮屏幕的Service(经不完全测试,华为允许的尝试次数为2次,小米为1次).
//在activity中启动自定义本地服务LocationService
getApplicationContext().startService(new Intent(this, LocationService.class));
//在LocationService中启动定位
mLocationClient = new AMapLocationClient(this.getApplicationContext());
mLocationOption = new AMapLocationClientOption();
// 使用连续定位
mLocationOption.setOnceLocation(false);
// 每10秒定位一次
mLocationOption.setInterval(10 * 1000);
mLocationClient.setLocationOption(mLocationOption);
mLocationClient.setLocationListener(locationListener);
mLocationClient.startLocation();
复制代码
2.在locationListener中对结果进行判断,如果是息屏造成的断网,则尝试点亮屏幕:
AMapLocationListener locationListener = new AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
//发送结果的通知
sendLocationBroadcast(aMapLocation);
//判断是否需要对息屏断wifi的情况进行处理
if (!mIsWifiCloseable) {
return;
}//将定位结果和设备状态一起交给mWifiAutoCloseDelegate
if (aMapLocation.getErrorCode() == AMapLocation.LOCATION_SUCCESS) {
//...
} else {
//...
}}private void sendLocationBroadcast(AMapLocation aMapLocation) {
//记录信息并发送广播...
}};
/** 处理息屏后wifi断开的逻辑*/
public class WifiAutoCloseDelegate implements IWifiAutoCloseDelegate {/**
* 请根据后台数据自行添加。此处只针对小米手机
* @param context
* @return
*/
@Override
public boolean isUseful(Context context) {
//...
}/** 由于服务可能被杀掉,所以在服务初始化时,初始相关参数*/
@Override
public void initOnServiceStarted(Context context) {
//...
}/** 处理定位成功的信息*/s
@Override
public void onLocateSuccess(Context context, boolean isScreenOn, boolean isMobileable) {
//...
}/** 处理定位失败的信息。如果需要唤醒屏幕,则尝试唤醒*/
@Override
public void onLocateFail(Context context, int errorCode, boolean isScreenOn, boolean isWifiable) {
//...
}
}
复制代码
【Android锁屏黑屏后连续定位问题解决方案】3.点亮屏幕时,会利用最小间隔时间加以限制:
/**
* 唤醒屏幕
*/
public void wakeUpScreen(final Context context) {try {
acquirePowerLock(context, PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK);
} catch (Exception e) {
throw e;
}
}/**
* 根据levelAndFlags,获得PowerManager的WaveLock
* 利用worker thread去获得锁,以免阻塞主线程,并且增加了最小间隔,防止频繁唤醒
* @param context
* @param levelAndFlags
*/
private void acquirePowerLock(final Context context, final int levelAndFlags) {
//...
}
复制代码
4.采用双service绑定Notification,提高进程优先级
/**
* LocationService.java
* 触发利用notification增加进程优先级
*/
protected void applyNotiKeepMech() {
//...
}/* LocationHelperService
* binder中的回调用于绑定和LocatioService一样的NotificationId,并stopForeground使通知隐藏
*/
private class HelperBinder extends ILocationHelperServiceAIDL.Stub{
@Override
public void onFinishBind(int notiId) throws RemoteException {
//...
}
}复制代码
5.采用了LocationHelperService做为守护进程,在检测到LocationService被杀掉后,重启定位服务。
private void startBind() {
mInnerConnection = new ServiceConnection() {
/** 检测到定位服务被kill掉时,重启定位服务*/
@Override
public void onServiceDisconnected(ComponentName name) {
//...
}};
//...
}
复制代码
项目地址 作者:小Fu??????
链接:https://juejin.cn/post/701069...
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)
- Android|Android install 多个设备时指定设备