1、开启一个像素的Activity
据说这个是手Q的进程保活方案,基本思想,系统一般是不会杀死前台进程的。所以要使得进程常驻,我们只需要在锁屏的时候在本进程开启一个Activity,为了欺骗用户,让这个Activity的大小是1像素,并且透明无切换动画,在开屏幕的时候,把这个Activity关闭掉,所以这个就需要监听系统锁屏广播,我试过了,的确好使,如下。
①OnePixelActivity
public class OnePixelActivity extends Activity { private static final String TAG = "MyLog"; public static OnePixelActivity instance = null; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_one_pixel); Window window = getWindow(); // 放在左上角 window.setGravity(Gravity.START | Gravity.TOP); WindowManager.LayoutParams layoutParams = window.getAttributes(); // 宽高为1px layoutParams.width = 1; layoutParams.height = 1; // 起始坐标 layoutParams.x = 0; layoutParams.y = 0; window.setAttributes(layoutParams); instance = this; Log.d(TAG, "activity onCreate"); } @Override protected void onDestroy() { instance = null; Log.d(TAG, "activity onDestroy"); super.onDestroy(); } }
②编写广播接收器监听锁屏和解锁action:
public class ScreenBroadcastReceiver extends BroadcastReceiver { private static final String TAG = "MyLog"; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); switch (action) { case Intent.ACTION_SCREEN_ON: { // Log.d(TAG, "screen_on"); // 关闭一像素Activity if (OnePixelActivity.instance != null) { OnePixelActivity.instance.finish(); } break; } case Intent.ACTION_SCREEN_OFF: { Log.d(TAG, "screen_off"); // 开启一像素Activity Intent activityIntent = new Intent(context, OnePixelActivity.class); activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(activityIntent); break; } default: break; } } }

public class WorkService extends Service { private static final String TAG = "MyLog"; private ScreenBroadcastReceiver receiver; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "service onCreate"); receiver = new ScreenBroadcastReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); registerReceiver(receiver, intentFilter); } @Override public void onDestroy() { Log.d(TAG, "service onDestroy"); unregisterReceiver(receiver); super.onDestroy(); } }
④主Activity启动服务后关闭自身,模拟没有Activity的情况:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, WorkService.class); startService(intent); finish(); } }


2.利用Notification提升权限
原理:Android 的前台service机制。但该机制的缺陷是通知栏保留了图标。
对于 API level < 18 :调用startForeground(ID, new Notification()),发送空的Notification ,图标则不会显示。
对于 API level >= 18:在需要提优先级的service A启动一个InnerService,两个服务同时startForeground,且绑定同样的 ID。Stop 掉InnerService ,这样通知栏图标即被移除。
这方案实际利用了Android前台service的漏洞。微信在评估了国内不少app已经使用后,才进行了部署。其实目标是让大家站同一起跑线上,哪天google 把漏洞堵了,效果也是一样的。
public class KeepLiveService extends Service { public static final int NOTIFICATION_ID=0x11; public KeepLiveService() { } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); //API 18以下,直接发送Notification并将其置为前台 if (Build.VERSION.SDK_INT <Build.VERSION_CODES.JELLY_BEAN_MR2) { startForeground(NOTIFICATION_ID, new Notification()); } else { //API 18以上,发送Notification并将其置为前台后,启动InnerService Notification.Builder builder = new Notification.Builder(this); builder.setSmallIcon(R.mipmap.ic_launcher); startForeground(NOTIFICATION_ID, builder.build()); startService(new Intent(this, InnerService.class)); } } public static class InnerService extends Service{ @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); //发送与KeepLiveService中ID相同的Notification,然后将其取消并取消自己的前台显示 Notification.Builder builder = new Notification.Builder(this); builder.setSmallIcon(R.mipmap.ic_launcher); startForeground(NOTIFICATION_ID, builder.build()); new Handler().postDelayed(new Runnable() { @Override public void run() { stopForeground(true); NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); manager.cancel(NOTIFICATION_ID); stopSelf(); } },100); } } }
3.利用JobScheduler机制拉活

public class MyJobService extends JobService { private static final String TAG = "MyLog"; @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate"); JobInfo.Builder builder = new JobInfo.Builder(1, new ComponentName(this, MyJobService.class)); // 设置执行延迟 builder.setOverrideDeadline(0); // 设置持续运行 builder.setPersisted(true); JobScheduler jobScheduler = (JobScheduler) this.getSystemService(Context.JOB_SCHEDULER_SERVICE); jobScheduler.schedule(builder.build()); } @Override public boolean onStartJob(JobParameters params) { Log.d(TAG, "onStartJob"); return false; } @Override public boolean onStopJob(JobParameters params) { return false; } }


