1. 连续定位采集点
后台持续定位主要参照高德官网给的示例主要有一下几点:
1.定位LocationService,另起进程同时创建守卫进程Service, LocationHelperService,Service挂掉时守卫进程唤起LocationService。
package com.yxc.barchart.map.location.service;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import androidx.annotation.Nullable;
import com.yxc.barchart.map.location.util.Utils;
public class LocationHelperService extends Service {
private Utils.CloseServiceReceiver mCloseReceiver;
@Override
public void onCreate() {
super.onCreate();
startBind();
mCloseReceiver = new Utils.CloseServiceReceiver(this);
registerReceiver(mCloseReceiver, Utils.getCloseServiceFilter());
}
@Override
public void onDestroy() {
if (mInnerConnection != null) {
unbindService(mInnerConnection);
mInnerConnection = null;
}
if (mCloseReceiver != null) {
unregisterReceiver(mCloseReceiver);
mCloseReceiver = null;
}
super.onDestroy();
}
private ServiceConnection mInnerConnection;
private void startBind() {
final String locationServiceName = "com.yxc.barchart.map.location.service.LocationService";
mInnerConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
Intent intent = new Intent();
intent.setAction(locationServiceName);
startService(Utils.getExplicitIntent(getApplicationContext(), intent));
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
ILocationServiceAIDL l = ILocationServiceAIDL.Stub.asInterface(service);
try {
l.onFinishBind();
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
Intent intent = new Intent();
intent.setAction(locationServiceName);
bindService(Utils.getExplicitIntent(getApplicationContext(), intent), mInnerConnection, Service.BIND_AUTO_CREATE);
}
private HelperBinder mBinder;
private class HelperBinder extends ILocationHelperServiceAIDL.Stub{
@Override
public void onFinishBind(int notiId) throws RemoteException {
startForeground(notiId, Utils.buildNotification(LocationHelperService.this.getApplicationContext()));
stopForeground(true);
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
if (mBinder == null) {
mBinder = new HelperBinder();
}
return mBinder;
}
}
复制代码
这里因为 LocationService、LocationHelperService、主进程分别为不同的进程,所以需要用AIDL通过进程间的交互。
2.LocationService需要触发利用notification增加进程优先级
/**
* 触发利用notification增加进程优先级
*/
protected void applyNotiKeepMech() {
startForeground(NOTI_ID, Utils.buildNotification(getBaseContext()));
startBindHelperService();
}
复制代码
这里看Keep等运动App也都是这样,没有加在 Android8.0系统的手机上,home键到后台,就没在定位了,定位listener总是返回缓存的上次定位的Location经纬度。
3.屏熄断网电量屏幕
在定位服务中检测是否是由息屏造成的网络中断,如果是,则尝试进行点亮屏幕。同时,为了避免频繁点亮,对最小时间间隔进行了设置(可以按需求修改). 如果息屏没有断网,则无需点亮屏幕.
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 {
/**
* 请根据后台数据自行添加。此处只针对小米手机