公司需要对安卓播放机上的播放软件进行意外退出自动保活,除了添加崩溃自启外,还使用了JobService进行定时检测软件是否正常运行。不正常则自动启动。这里做个记录.。
安卓播放机 的安卓版本为7.1.2。
先是AliveJobService
public class AliveJobService extends JobService {
private final static String TAG = "AliveService";
// 告知编译器,这个变量不能被优化
private volatile static Service mKeepAliveService = null;
public static boolean isJobServiceAlive(){
return mKeepAliveService != null;
}
private static final int MESSAGE_ID_TASK = 0x01;
private Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// 具体任务逻辑 Config.PACKAGE_NAME 为APP包名
if(SystemUtil.isAppAlive(getApplicationContext(), Config.PACKAGE_NAME)){
}else{
Intent intent = new Intent(getApplicationContext(), PageProjectMVPActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
// 通知系统任务执行结束
/* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
jobFinished((JobParameters) msg.obj, true);
} else {
jobFinished((JobParameters) msg.obj, false);
}*/
jobFinished( (JobParameters) msg.obj, false );
return true;
}
});
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
if(Config.isDebug)
Log.d(TAG,"AliveService----->JobService服务被启动...");
mKeepAliveService = this;
// 返回false,系统假设这个方法返回时任务已经执行完毕;
// 返回true,系统假定这个任务正要被执行
Message msg = Message.obtain(mHandler, MESSAGE_ID_TASK, params);
mHandler.sendMessage(msg);
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
mHandler.removeMessages(MESSAGE_ID_TASK);
if(Config.isDebug)
Log.d(TAG,"AliveService----->JobService服务被关闭");
return false;
}
}
JobSchedulerManager
public class JobSchedulerManager {
private static final int JOB_ID = 123;
private static JobSchedulerManager mJobManager;
private JobScheduler mJobScheduler;
private static Context mContext;
private JobSchedulerManager(Context ctxt){
this.mContext = ctxt;
mJobScheduler = (JobScheduler)ctxt.getSystemService(Context.JOB_SCHEDULER_SERVICE);
}
public final static JobSchedulerManager getJobSchedulerInstance(Context ctxt){
if(mJobManager == null){
mJobManager = new JobSchedulerManager(ctxt);
}
return mJobManager;
}
@TargetApi(21)
public void startJobScheduler(){
// 如果JobService已经启动或API<21,返回
if(AliveJobService.isJobServiceAlive() || isBelowLOLLIPOP()){
return;
}
// 构建JobInfo对象,传递给JobSchedulerService
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID,new ComponentName(mContext, AliveJobService.class));
/* if (Build.VERSION.SDK_INT >= 24) {
builder.setMinimumLatency(60000L); //执行的最小延迟时间
builder.setOverrideDeadline(60000L); //执行的最长延时时间
builder.setMinimumLatency(60000L);
builder.setBackoffCriteria(60000L, JobInfo.BACKOFF_POLICY_LINEAR);//线性重试方案
} else {
builder.setPeriodic(60000L);
}*/
builder.setPeriodic(15 * 60 * 1000L);
// 设置设备重启时,执行该任务
builder.setPersisted(false);
// 当插入充电器,执行该任务
builder.setRequiresCharging(false);
// 设置手机是否空闲的条件
builder.setRequiresDeviceIdle(false);
JobInfo info = builder.build();
//开始定时执行该系统任务
mJobScheduler.schedule(info);
}
@TargetApi(21)
public void stopJobScheduler(){
if(isBelowLOLLIPOP())
return;
mJobScheduler.cancelAll();
}
private boolean isBelowLOLLIPOP(){
// API< 21
return Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP;
}
}
/**
* 判断应用是否已经启动
* @param context 一个context
* @param packageName 要判断应用的包名
* @return boolean
*/
public static boolean isAppAlive(Context context, String packageName) {
ActivityManager activityManager =
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> processInfos
= activityManager.getRunningAppProcesses();
for (int i = 0; i < processInfos.size(); i++) {
if (processInfos.get(i).processName.equals(packageName)) {
Log.i("NotificationLaunch",
String.format("the %s is running, isAppAlive return true", packageName));
return true;
}
}
Log.i("NotificationLaunch",
String.format("the %s is not running, isAppAlive return false", packageName));
return false;
}
启动方式为
JobSchedulerManager.getJobSchedulerInstance(this).startJobScheduler();