Android保活众所周知,完全保活除非加入白名单,否则只能保住一段时间。下面一一介绍Android保活方案。由于时间有限,保活方案文章的编写,采用的是逐步完善的方式。在保证内容可用的条件下逐步晚上文字,不足之处还请见谅。完善所有代码后,会写成uni-app插件。

方案一、前台服务+Notification

代码

a、首先在AndroidManifest.xml添加以下权限

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

b、前台服务代码


public class KeepServices extends Service {private NotificationManager notificationManager;private String notificationId = "serviceid";private String notificationName = "servicename";@Overridepublic void onCreate() {super.onCreate();notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);//创建NotificationChannelif(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){NotificationChannel channel = new NotificationChannel(notificationId, notificationName, NotificationManager.IMPORTANCE_HIGH);notificationManager.createNotificationChannel(channel);}startForeground(1,getNotification());}private Notification getNotification() {Notification.Builder builder = new Notification.Builder(this).setSmallIcon(R.mipmap.amin_pic).setContentTitle("title").setContentText("text");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {builder.setChannelId(notificationId);}Notification notification = builder.build();return notification;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {new Thread(new Runnable() {@Overridepublic void run() {while (true){try {Thread.sleep(2000);Log.d("Services","====保活服务===数据支持====");} catch (InterruptedException e) {e.printStackTrace();}}}}).start();return super.onStartCommand(intent, flags, startId);}@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onDestroy() {super.onDestroy();}}

c、在AndroidManifest.xml中注册服务

<serviceandroid:name="com.xiaoya.keepalive.KeepServices"// 找到自己的服务路径android:enabled="true"android:exported="true" />

d、启动服务

 Intent intent=new Intent(this, KeepServices.class);startService(intent);

方案二、加入白名单

这里借鉴其他博主的国内厂商白名单跳转工具


public class SettingUtils {public static void enterWhiteListSetting(Context context) {try {context.startActivity(getSettingIntent());} catch (Exception e) {context.startActivity(new Intent(Settings.ACTION_SETTINGS));}}private static Intent getSettingIntent() {ComponentName componentName = null;String brand = android.os.Build.BRAND;switch (brand.toLowerCase()) {case "samsung":componentName = new ComponentName("com.samsung.android.sm","com.samsung.android.sm.app.dashboard.SmartManagerDashBoardActivity");break;case "huawei":componentName = new ComponentName("com.huawei.systemmanager","com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");break;case "xiaomi":componentName = new ComponentName("com.miui.securitycenter","com.miui.permcenter.autostart.AutoStartManagementActivity");break;case "vivo":componentName = new ComponentName("com.iqoo.secure","com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity");break;case "oppo":componentName = new ComponentName("com.coloros.oppoguardelf","com.coloros.powermanager.fuelgaue.PowerUsageModelActivity");break;case "360":componentName = newComponentName("com.yulong.android.coolsafe","com.yulong.android.coolsafe.ui.activity.autorun.AutoRunListActivity");break;case "meizu":componentName = new ComponentName("com.meizu.safe","com.meizu.safe.permission.SmartBGActivity");break;case "oneplus":componentName = new ComponentName("com.oneplus.security","com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity");break;default:break;}Intent intent = new Intent();intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if (componentName != null) {intent.setComponent(componentName);} else {intent.setAction(Settings.ACTION_SETTINGS);}return intent;}}

方案三、双进程守护 + JobScheduler 保活

参考(https://blog.csdn.net/shulianghan/article/details/115607584)

1、JobService 代码

public class KeepAliveJobService extends JobService {@Overridepublic boolean onStartJob(JobParameters params) {Log.i("KeepAliveJobService", "JobService onStartJob 开启");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){// 如果当前设备大于 7.0 , 延迟 5 秒 , 再次执行一次startJob(this);}// 判定本地前台进程是否正在运行boolean isLocalServiceRunning =ServiceUtils.isServiceRunning(this, LocalForegroundService.class.getName());if (!isLocalServiceRunning){startService(new Intent(this, LocalForegroundService.class));}// 判定远程前台进程是否正在运行boolean isRemoteServiceRunning =ServiceUtils.isServiceRunning(this, RemoteForegroundService.class.getName());if (!isRemoteServiceRunning){startService(new Intent(this, RemoteForegroundService.class));}return false;}@Overridepublic boolean onStopJob(JobParameters params) {Log.i("KeepAliveJobService", "JobService onStopJob 关闭");return false;}public static void startJob(Context context){// 创建 JobSchedulerJobScheduler jobScheduler =(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);// 第一个参数指定任务 ID// 第二个参数指定任务在哪个组件中执行// setPersisted 方法需要 android.permission.RECEIVE_BOOT_COMPLETED 权限// setPersisted 方法作用是设备重启后 , 依然执行 JobScheduler 定时任务JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(10,new ComponentName(context.getPackageName(), KeepAliveJobService.class.getName())).setPersisted(true);// 7.0 以下的版本, 可以每隔 5000 毫秒执行一次任务if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N){jobInfoBuilder.setPeriodic(5_000);}else{// 7.0 以上的版本 , 设置延迟 5 秒执行// 该时间不能小于 JobInfo.getMinLatencyMillis 方法获取的最小值jobInfoBuilder.setMinimumLatency(5_000);}// 开启定时任务jobScheduler.schedule(jobInfoBuilder.build());}
}

2、判定服务运行工具类


public class ServiceUtils {/*** 判定 Service 是否在运行* @param context* @return*/public static boolean isServiceRunning(Context context, String serviceName){if(TextUtils.isEmpty(serviceName)) return false;ActivityManager activityManager =(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);// 最多获取 200 个正在运行的 ServiceList<ActivityManager.RunningServiceInfo> infos =activityManager.getRunningServices(200);// 遍历当前运行的 Service 信息, 如果找到相同名称的服务 , 说明某进程正在运行for (ActivityManager.RunningServiceInfo info: infos){if (TextUtils.equals(info.service.getClassName(), serviceName)){return true;}}return false;}
}

3、清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="kim.hsl.two_progress_alive"><uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.Two_Progress_Alive"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><!-- 本地提权前台服务 Service --><serviceandroid:name=".LocalForegroundService"android:enabled="true"android:exported="true"></service><!-- 本地服务 , API 18 ~ 25 以上的设备, 关闭通知到专用服务 --><serviceandroid:name=".LocalForegroundService$CancelNotificationService"android:enabled="true"android:exported="true"></service><!-- 远程提权前台服务 Service --><serviceandroid:name=".RemoteForegroundService"android:enabled="true"android:exported="true"android:process=":remote"></service><!-- 远程服务 , API 18 ~ 25 以上的设备, 关闭通知到专用服务 --><serviceandroid:name=".RemoteForegroundService$CancelNotificationService"android:enabled="true"android:exported="true"android:process=":remote"></service><!-- JobScheduler 拉活 --><serviceandroid:name=".KeepAliveJobService"android:enabled="true"android:exported="true"android:permission="android.permission.BIND_JOB_SERVICE"></service></application></manifest>

4、MainActivity 代码

package kim.hsl.two_progress_alive;import android.content.Intent;
import android.os.Build;
import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 通过前台 Service 提升应用权限// 启动普通 Service , 但是在该 Service 的 onCreate 方法中执行了 startForeground// 变成了前台 Service 服务startService(new Intent(this, LocalForegroundService.class));startService(new Intent(this, RemoteForegroundService.class));// JobScheduler 拉活if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {KeepAliveJobService.startJob(this);}}
}

方案四、使用系统服务的return START_STICKY

START_STICKY:

“粘性”。如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

START_NOT_STICKY:

“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。

START_REDELIVER_INTENT:

重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

START_STICKY_COMPATIBILITY:

START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

只要 targetSdkVersion 不小于5,就默认是 START_STICKY。 但是某些ROM 系统不会拉活。并且经过测试,Service 第一次被异常杀死后很快被重启,第二次会比第一次慢,第三次又会比前一次慢,一旦在短时间内 Service 被杀死4-5次,则系统不再拉起。

原文链接:https://blog.csdn.net/zhang_senlin/article/details/119481636

public int onStartCommand(Intent intent, int flags, int startId) {

......

return START_STICKY;

}

优点:利用services自身的api,可靠。

缺点:很多手机厂商已经做限制,导致很多类似华为、小米手机无效。只会重启5次。被系统强制停止也无法重启。

方案五、一像素

参考(https://www.mianshigee.com/project/wangchunfei-KeepAlive)

1、Activity

public class HooliganActivity extends Activity {private static HooliganActivity instance;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);instance = this;Window window = getWindow();window.setGravity(Gravity.LEFT | Gravity.TOP);WindowManager.LayoutParams params = window.getAttributes();params.x = 0;params.y = 0;params.height = 1;params.width = 1;window.setAttributes(params);}/*** 开启保活页面*/public static void startHooligan() {Intent intent = new Intent(DWApplication.getAppContext(), HooliganActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);DWApplication.getAppContext().startActivity(intent);}@Overrideprotected void onDestroy() {super.onDestroy();instance = null;}/*** 关闭保活页面*/public static void killHooligan() {if(instance != null) {instance.finish();}}}

2.注册清单文件:

    <activity android:name=".activity.HooliganActivity"android:configChanges="keyboardHidden|orientation|screenSize|navigation|keyboard"android:excludeFromRecents="true"android:exported="false"android:finishOnTaskLaunch="false"android:launchMode="singleInstance"android:theme="@style/HooliganActivityStyle"/>
   <style name="HooliganActivityStyle"><item name="android:windowBackground">@color/transparent</item><item name="android:windowContentOverlay">@null</item><item name="android:windowIsTranslucent">true</item><item name="android:windowNoDisplay">false</item><item name="android:windowDisablePreview">true</item></style>

3、监听锁屏和解锁通知,不能静态注册广播,只能动态注册:

IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_SCREEN_ON);filter.addAction(Intent.ACTION_SCREEN_OFF);registerReceiver(new BootCompleteReceiver(),filter);

4、分别在解锁和锁屏时唤醒我的HooliganActivity:

 public class BootCompleteReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {HooliganActivity. startHooligan();} else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){HooliganActivity. killHooligan();}}}

5、在最近使用的列表中隐藏应用

Intent intent = new Intent(Intent.ACTION_MAIN);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.addCategory(Intent.CATEGORY_HOME);getAppContext().startActivity(intent);
android:excludeFromRecents="true"

至此,整个的保活就结束了 这样你在后台每次锁屏,实际上都会吊起一个一像素的页面,假装app在前台,拥有最高进程优先级。

方案六、无声音乐

import android.media.MediaPlayer;
import java.io.File;
import java.io.IOException;
import java.io.FileOutputStream;
import android.util.Base64;
import java.io.FileInputStream;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;public class MySer extends Service {MediaPlayer mediaplayer=null;//转base64的音频文件String base64 = "AAAAGGZ0eXBtcDQyAAAAAG1wNDFpc29tAAAAKHV1aWRcpwj7Mo5CBahhZQ7KCpWWAAAADDEwLjAuMTgzNjMuMAAAAG5tZGF0AAAAAAAAABAnDEMgBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBAIBDSX5AAAAAAAAB9Pp9Pp9Pp9Pp9Pp9Pp9Pp9Pp9Pp9Pp9Pp9AAAC/m1vb3YAAABsbXZoZAAAAADeilCc3opQnAAAu4AAAAIRAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAHBdHJhawAAAFx0a2hkAAAAAd6KUJzeilCcAAAAAgAAAAAAAAIRAAAAAAAAAAAAAAAAAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAABXW1kaWEAAAAgbWRoZAAAAADeilCc3opQnAAAu4AAAAIRVcQAAAAAAC1oZGxyAAAAAAAAAABzb3VuAAAAAAAAAAAAAAAAU291bmRIYW5kbGVyAAAAAQhtaW5mAAAAEHNtaGQAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAMxzdGJsAAAAZHN0c2QAAAAAAAAAAQAAAFRtcDRhAAAAAAAAAAEAAAAAAAAAAAACABAAAAAAu4AAAAAAADBlc2RzAAAAAAOAgIAfAAAABICAgBRAFQAGAAACM2gAAjNoBYCAgAIRkAYBAgAAABhzdHRzAAAAAAAAAAEAAAABAAACEQAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAYc3RzegAAAAAAAAAAAAAAAQAAAF4AAAAUc3RjbwAAAAAAAAABAAAAUAAAAMl1ZHRhAAAAkG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXIAAAAAAAAAAAAAAAAAAAAAY2lsc3QAAAAeqW5hbQAAABZkYXRhAAAAAQAAAADlvZXpn7MAAAAcqWRheQAAABRkYXRhAAAAAQAAAAAyMDIyAAAAIWFBUlQAAAAZZGF0YQAAAAEAAAAA5b2V6Z+z5py6AAAAMVh0cmEAAAApAAAAD1dNL0VuY29kaW5nVGltZQAAAAEAAAAOABUA2rD/dVfYAQ==";@Overridepublic void onCreate() {super.onCreate();if(mediaplayer==null){new Thread(new Runnable(){@Overridepublic void run() {mediaplayer=new MediaPlayer();try {byte[] mp3SoundByteArray = Base64.decode(base64, Base64.DEFAULT);// 将字符串转换为byte数组File tempMp3 = File.createTempFile("s", ".mp3");tempMp3.deleteOnExit();FileOutputStream fos = new FileOutputStream(tempMp3);fos.write(mp3SoundByteArray);fos.close();FileInputStream fis = new FileInputStream(tempMp3);mediaplayer.setDataSource(fis.getFD());mediaplayer.setLooping(true);mediaplayer.prepareAsync ();//异步准备播放 这部必须设置不然无法播放mediaplayer.start();//开始播放} catch (IllegalStateException e) {System.out.print("出错了="+e);} catch (SecurityException e) {} catch (IOException e) {System.out.print("出错了="+e);} catch (IllegalArgumentException e) {}}}).start();}}@Overridepublic void onDestroy() {super.onDestroy();//停止mediaplayer.stop();mediaplayer=null;}@Overridepublic IBinder onBind(Intent intent) {return null;}
}

方案七、推送互相唤醒复活

......

方案八、app相互拉活

.......

Android 原生保活相关推荐

  1. 关于 Android 进程保活,你所需要知道的一切

    早前,我在知乎上回答了这样一个问题:怎么让 Android 程序一直后台运行,像 QQ 一样不被杀死?.关于 Android 平台的进程保活这一块,想必是所有 Android 开发者瞩目的内容之一.你 ...

  2. Android 后台保活,这里有你需要的所有姿势。2019,最新版本。

    DaemonLibrary 项目地址:ShihooWang/DaemonLibrary 简介:Android 后台保活,这里有你需要的所有姿势.2019,最新版本. 更多:作者   提 Bug 标签: ...

  3. qt for android程序保活 程序后台一直运行不被清理掉(未完)

    本博主要就是分享如何让qt开发的android程序在手机上运行,切换到后台的时候,程序仍然在一直运行,为什么这么做呢,因为我有需求是app连接蓝牙后,程序切换到后台,仍然能接受到蓝牙发送的数据并保存时 ...

  4. Android App 保活之 ADJ 算法

    Android开发中,令人头疼的保活问题始终缠绕每一个开发者.如何保证自己的进程不被系统回收呢?首当其冲应该是保证自己进程的优先级. Android系统在运行时,如果遭遇到内存过低,为保证系统稳定与流 ...

  5. Android 后台保活设计2019,最新版本

    DaemonLibrary 使用方式 Step 1. Add the JitPack repository to your build file allprojects {repositories { ...

  6. android系统应用保活_2020年了,Android后台保活还有戏吗?看我如何优雅的实现!...

    1.引言 对于移动端IM应用和消息推送应用的开发者来说,Android后台保活这件事是再熟悉不过了. 自从Android P(即Android 8.0)出现以后,Android已经从系统层面将后台保活 ...

  7. 全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)

    全面盘点当前Android后台保活方案的真实运行效果(截止2019年前) 本文原作者"minminaya",作者网站:minminaya.cn,为了提升文章品质,即时通讯网对内容作 ...

  8. 介绍一款比Android原生模拟器还要快的模拟器Genymotion(转)

    源:介绍一款比Android原生模拟器还要快的模拟器Genymotion

  9. Android进程保活方案

    自己曾经也在这个问题上伤过脑经,前几日刚好有一个北京的哥们在QQ说在做IM类的项目,问我进程保活如何处理比较恰当,决定去总结一下,网上搜索一下进程常驻的方案好多好多,但是很多的方案都是不靠谱的或者不是 ...

最新文章

  1. mysql报错无效默认值1067_Mysql 报错:#1067 - Invalid default value for 'update_time
  2. VMware Workstation 网络连接配置
  3. Angular sort interactively test
  4. PX4的workqueue
  5. python数字从大到小排列_Python练习题 005:三个数字由大到小排序输出
  6. 对于“知识”,我们存在哪些误解?
  7. javaserver_什么是JavaServer Faces(JSF)
  8. Report Style
  9. FJUT 2351 T^T的图论(并查集)
  10. Windows UWP开发系列 – 控件默认样式
  11. 系统可行性研究报告模板
  12. cvpr论文阅读之Deep Spatio-Temporal Random Fields for Efficient Video Segmentation(用于视频分割的深度时空随机场)
  13. jquery查找指定id元素下的某个或某些元素
  14. 使用Guava-retrying优雅地解决异常重试场景
  15. RuntimeWarning: divide by zero encountered in log错误解决
  16. python多态_python多态和规范
  17. STA分析(六) cross talk and noise
  18. 软件测试 | 测试开发 | 3年测试经验跳槽成功拿下30W+年薪
  19. 怪异的JavaScript系列(三)
  20. 常见比较好用的winpe系统有哪几款?

热门文章

  1. Overture 5里如何设置踏板标记?
  2. 删除已存在的SVN账户信息
  3. ffmpeg h264解码器提取
  4. 老年手机进水了有什么方法,手机进水了怎么处理比较好?
  5. 七周学会数据分析 泽楷
  6. 广州联通领航“互联网+”智慧生活
  7. next()、nextLine()的区别
  8. worker服务器推送消息,关于Worker如何向指定Client推送消息
  9. 小程序中所有组件学习
  10. PCIe Summary