最近在开发智能手表应用,这是第二个手表项目了。项目中socket需要一直保持心跳连接,经过测试,一旦息屏后台服务很快就被断开连接了,无法保活。经过咨询客服,此品牌的手表不支持非官方应用的息屏保活,所以只能做成保持屏幕常亮来实现不被断开连接。
最近学到的两种保持屏幕亮屏的方式:
一:DisplayManager
DisplayManager dm = (DisplayManager) getSystemService(DISPLAY_SERVICE);
dm.registerDisplayListener(new DisplayManager.DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {}
@Override
public void onDisplayRemoved(int displayId) {}
@Override
public void onDisplayChanged(int displayId) {
if (!isScreenOn(dm)) {
// 屏幕已熄灭,则亮屏操作
lightScreen();
}
}
}, null);
// 判断屏幕是否亮屏
private boolean isScreenOn(DisplayManager dm) {
Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);
return display.getState() == Display.STATE_ON;
}
//亮屏
public static void lightScreen() {
PowerManager pm = (PowerManager) App.app.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wakeLock = pm.newWakeLock(
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
App.app.getClass().getSimpleName()
);
wakeLock.acquire();
wakeLock.release();
}
在activity布局中加入 android:keepScreenOn="true",可以保持常态下屏幕长亮,搭配DisplayManager的息屏监听,实现手表在任何情况下都能保持常亮。
二:JobScheduler
代码使用:JobSchedulerUtil.getJobSchedulerInstance(this).startJobScheduler();
1、创建JobScheduler
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class JobSchedulerUtil {
private final Context mContext;
private final JobScheduler mJobScheduler;
private int JOB_ID = 1;
private static JobSchedulerUtil mJobUtil = null;
private JobSchedulerUtil(Context context){
mContext = context;
mJobScheduler = (JobScheduler) App.app.getSystemService(Context.JOB_SCHEDULER_SERVICE);
}
public static JobSchedulerUtil getJobSchedulerInstance(Context context){
if (mJobUtil== null) {
mJobUtil= new JobSchedulerUtil(context);
}
return mJobUtil;
}
@TargetApi(21)
public void startJobScheduler() {
// 如果JobService已经启动,取消之前的job
// if (MyJobService.isJobServiceAlive()) {
// stopJobScheduler();
// }
// 构建JobInfo对象,传递给JobSchedulerService
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(mContext, MyJobService.class));
//android7.0 及以上系统
if (Build.VERSION.SDK_INT >= 24) {
builder.setMinimumLatency(3000); //至少3s才会执行
builder.setOverrideDeadline(3000); // 3s后一定会执行
// builder.setMinimumLatency(3000)
// //默认3s,如果小于3s,也会按照3s来依次增加
builder.setBackoffCriteria(3000, JobInfo.BACKOFF_POLICY_LINEAR);
} else {
builder.setPeriodic(5000);
}
// 当插入充电器,执行该任务
builder.setRequiresCharging(true);
JobInfo info = builder.build();
mJobScheduler.schedule(info);
}
private void stopJobScheduler() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mJobScheduler.cancel(JOB_ID);
}
}
}
2.创建JobService
public class MyJobService extends JobService {
public static boolean jobServiceHave = false;
@Override
public boolean onStartJob(JobParameters params) {
LogUtils.i("onStartJob");
jobServiceHave = true;
//亮屏
lightScreen();
//再次启动调度器
if (Build.VERSION.SDK_INT >= 24) {
JobSchedulerUtil.getJobSchedulerInstance(this).startJobScheduler();
jobFinished(params,true);
}
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
LogUtils.i("onStopJob");
jobServiceHave = false;
return false;
}
public static boolean isJobServiceAlive() {
return jobServiceHave;
}
}
由于手表在手腕快速垂下时,会直接息屏,所以jobscheduler的任务延时执行时间我设置的很短只有3秒,经过测试能保持手表在任何情况下常亮。