Android 系统已经更新到13了,各个Rom厂商也控制越来越严格了,还能做保活App。答案肯定是可以的,然而路线是很艰难的。
最近接到一个项目,需要安装一次app后,就需要一直获取定位。随着Android系统的不断完善,厂商rom的不断优化,想要实现后台不断定位的功能,要面临的问题很多。先总结下此次开发中遇到的难点和要点。首先确认的是一点,用白名单保活的方式来实现,如果是可以实现黑名单保活的大牛,此文请忽略。
需要解决的主要问题有以下几项:
1.白名单保活核心:权限-自启动管理 要求用户手动设置打开自启动和后台运行权限。
2.电池优化:关闭电池优化。或者说耗电管理
3.进程复活:即使开启了自启动权限也要有自身拉活机制。
4.维持cpu唤醒状态:此项很重要,某些机器不一定需要,但是某些机器不这么处理,程序百分之百死掉。比如华为的某些pad。
5.比保活还重要的是定位权限:如果是做后台定位的话,熄屏后失去定位权限的解决方案。
解决方案:
如果做白名单保活,那么在做权限获取的时候需要两部分来完成,软件自动调整权限设置页或者引导用户手动开启权限设置。
这套方案目前在大多数手机或pad中可以保证服务不死定位不停,个别设备需要单独进行设置或处理才行,文章末尾会说。
先看代码上能做的处理有哪些:
1.关闭电池优化
我的所有处理都是从MainActivity开始的,
int checkTime = 0; 在onCreate中执行 //忽略电池优化
KeepAliveUtils.Checkbattery(this, 0);
checkTime++;
public static void Checkbattery(Activity activity, int time) {
if (time > 1)
return;
PowerManager manager = (PowerManager) activity.getSystemService(Context.POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
boolean ignoringBatteryOptimizations = manager.isIgnoringBatteryOptimizations(activity.getPackageName());
if (!ignoringBatteryOptimizations) {
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + activity.getPackageName()));
activity.startActivityForResult(intent, 110);
}
}
}
然后在MainActivity中处理
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 110) {
KeepAliveUtils.Checkbattery(this, checkTime);
}
}
这段代码会弹出提示框提示用户是否关闭电池优化功能。
2.提示框提示用户手动打开自启动权限管理
int checkGoTime = 0;
在onCreate中执行
checkGoTime = KvUtils.getInstance().getInt("checkGoTime", 0);
if (checkGoTime == 0) {
KvUtils.getInstance().put("checkGoTime", 1);
//打开自启动
new XPopup.Builder(this)
.isDestroyOnDismiss(true)
.asCustom(new ConfirmCenterPop(this, "为保证App正常运行,请打开应用自启动权限和后台弹窗权限", new ConfirmCenterPop.OnSubmitListenner() {
@Override
public void onClick() {
// CheckPermissionUtils.startToAutoStartSetting(MainActivity.this);
JumpPermissionManagement.GoToSetting(MainActivity.this);
}
}))
.show();
}
这段加了次数管理,避免弹出多次。
3.检查并申请定位权限和通知并开启服务
//请求权限开启定位
XXPermissions.with(this)
// 申请单个权限
.permission(Permission.ACCESS_FINE_LOCATION)
.permission(Permission.ACCESS_COARSE_LOCATION)
.permission(Permission.ACCESS_BACKGROUND_LOCATION)
// 申请多个权限
// 设置权限请求拦截器(局部设置)
//.interceptor(new PermissionInterceptor())
// 设置不触发错误检测机制(局部设置)
//.unchecked()
.request(new OnPermissionCallback() {
@Override
public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
if (!allGranted) {
ToastUtils.showShort("获取部分权限成功,但部分权限未正常授予");
return;
}
startService(new Intent(MainActivity.this, AliveService.class));
startService(new Intent(MainActivity.this, SAliveService.class));
}
@Override
public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
if (doNotAskAgain) {
ToastUtils.showShort("被永久拒绝授权,请手动开启定位权限");
// 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(MainActivity.this, permissions);
} else {
ToastUtils.showShort("获取定位权限失败");
}
}
});
//获取通知权限,后台持续定位
XXPermissions.with(this)
// 申请单个权限
.permission(Permission.POST_NOTIFICATIONS)
// 申请多个权限
// 设置权限请求拦截器(局部设置)
//.interceptor(new PermissionInterceptor())
// 设置不触发错误检测机制(局部设置)
//.unchecked()
.request(new OnPermissionCallback() {
@Override
public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
if (!allGranted) {
ToastUtils.showShort("获取部分权限成功,但部分权限未正常授予");
return;
}
startService(new Intent(MainActivity.this, AliveService.class));
startService(new Intent(MainActivity.this, SAliveService.class));
}
@Override
public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
if (doNotAskAgain) {
ToastUtils.showShort("被永久拒绝授权,请手动开启定位权限");
// 如果是被永久拒绝就跳转到应用权限系统设置页面
XXPermissions.startPermissionActivity(MainActivity.this, permissions);
} else {
ToastUtils.showShort("获取定位权限失败");
}
}
});
之所以把定位权限和通知权限放在一起,是因为做后台定位的时候需要发送通知,将定位变成前台服务才能保证后台持续定位。
接下来就是核心中的核心
AliveService.class和SAliveService
双进程保活互相拉起,维持服务不死和定位权限不失的核心内容都在这两个服务里边处理文章来源:https://www.toymoban.com/news/detail-712486.html
4.AliveService.class和SAliveService文章来源地址https://www.toymoban.com/news/detail-712486.html
public class AliveService extends Service {
private MyBinder myBinder;
/**
* 连接对象
*/
private Connection connection;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
private static final int NOTIFICATION_ID = 1;
private Runnable runnable;
private Handler handler;
PowerManager pm;
@SuppressLint("InvalidWakeLockTag")
PowerManager.WakeLock wakeLock;
@Override
public void onCreate() {
super.onCreate();
//创建NotificationChannel
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(1, LocationUtils.buildNotification());
}
myBinder = new MyBinder();
到了这里,关于2023Android白名单保活(后台定位)分享的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!