AI手机网,短视频直播 硬改改机 一键新机 群控软件 刷机定制

 找回密码
 立即注册
搜索
查看: 6262|回复: 0

Android应用保活四步曲

[复制链接]
发表于 2020-4-25 18:03:49 | 显示全部楼层 |阅读模式

本文针对国内手机厂商对于后台应用无法保活的限制下,用户还希望你的应用能在后台保持运行。

ps:如果用户不给权限,除非加入系统白名单,否则你的应用会死的一干二净。

第一步:利用Service类onStartCommand()方法返回值

  1. public class YourService extends Service {
  2.     @Override
  3.     public int onStartCommand(Intent intent, int flags, int startId) {
  4.         //这里默认返回就START_STICKY,当然也可以根据需求返回其他的值
  5.         return super.onStartCommand(intent, flags, startId);
  6.         // return START_STICKY 或 START_REDELIVER_INTENT
  7.     }
  8. }
复制代码

这种方式算是中规中矩了,也不违反官方的编程规范。但是如果用户频繁的杀死你的应用,或者在设置中手动强制停止你的Service,那么重新启动的时机就不好说了,有可能一直启动不起来了。

第二步:捕获系统通知

利用接收一些频繁产生通知,让自己应用重新启动。例如 网络变化、屏幕解锁、充电、停止充电、新图片、新视频等。现在大部分第三方推送都会用这种通知的监听。

目前这种方式有两个弊端:

从7.0系统开始,针对全局应用的通知增加了限制,例如非前台应用无法接收到网络变化、新图片、新视频的通知。个人在测试时(8.1系统),如果应用被杀死后,什么通知也唤醒不了应用。
国内系统的手机管理工具内,有自启动限制功能,这也会导致应用无法重启。

第三步:请求自启动权限 + JobService

如果系统限制你的应用自启动,那么乖乖的请求用户去把自启动权限打开吧,否则永远没戏。
经过在oppo的机器上测试,就算是允许了应用自启动,我们应用也不会立即重新启动,这个启动时机无法确定。
为了尽快让自己应用启动起来,可以添加JobService周期任务,在最短周期内唤醒自己的应用。其中,小米推送就是利用了JobService这种机制。当然,只能在5.0以上的系统使用。

  1. //定义一个Service,继承JobService
  2. @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
  3. public class KeepAliveJobService extends JobService {
  4.     @Override
  5.     public boolean onStartJob(JobParameters params) {
  6.         Timber.d("----onStartJob-----");
  7.         return true;
  8.     }

  9.     @Override
  10.     public boolean onStopJob(JobParameters params) {
  11.         Timber.d("----onStopJob-----");
  12.         return true;
  13.     }
  14. }

  15. //不要忘了在清单文件中声明
  16. <service
  17.   android:name=".service.KeepAliveJobService"
  18.   android:enabled="true"
  19.   android:exported="true"
  20.   android:permission="android.permission.BIND_JOB_SERVICE" />

  21. //最后在应用启动时,开启这个Service
  22. private void startKeepAliveJobService(Context context) {
  23.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  24.             JobInfo.Builder builder = new JobInfo.Builder(245, new ComponentName(context, KeepAliveJobService.class));
  25.             builder.setPeriodic(6 * 60 * 1000);
  26.             //Android 7.0+ 增加了一项针对 JobScheduler 的新限制,最小间隔只能是下面设定的数字
  27.             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  28.                 builder.setPeriodic(JobInfo.getMinPeriodMillis(), JobInfo.getMinFlexMillis());
  29.             }
  30.             builder.setPersisted(true);
  31.             JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
  32.             if (scheduler != null) {
  33.                 scheduler.schedule(builder.build());
  34.             }
  35.         }
  36.     }
复制代码
第四步:利用通知监听服务

经过上面三步,基本上能在拥有自启动权限的情况下,能不定时机的唤醒自己的应用了。大家别忘了,国内厂商系统除了自启动权限,还有什么后台限制运行、锁屏清除应用等牛逼限制。能让用户一并把这些限制给我们的App放开肯定是最好的,不过经过实践发现,有些设置入口很深,一般用户根本找不到,我们的App也无法直接跳转这些设置页面。

咳咳,那么有没有一种权限,比较好设置,允许后不管怎么清除应用,都可以马上重新启动呢?

那就是通知监听服务(NotificationListenerService),读者可以在手机开发者模式中,查看正在运行服务中,有一些服务有一个“通知侦听器”的设置,而这些服务是怎么杀都杀不死的,例如某某0手机助手。它就是开启了通知监听服务,并获取到了权限,大家可以自行尝试。下面是使用方法(4.4系统以上适用):

  1. //新建NotificationListenerService子类
  2. @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
  3. public class MyNotificationListenerService extends NotificationListenerService {

  4.     private static final String TAG = "MyNotificationListenerS";

  5.     @Override
  6.     public void onNotificationPosted(StatusBarNotification sbn) {
  7.         super.onNotificationPosted(sbn);
  8.         Log.i(TAG, "onNotificationPosted: " + sbn.toString());
  9.     }

  10.     @Override
  11.     public void onNotificationRemoved(StatusBarNotification sbn) {
  12.         super.onNotificationRemoved(sbn);
  13.         Log.i(TAG, "onNotificationRemoved: " + sbn.toString());
  14.     }

  15.     @Override
  16.     public void onListenerConnected() {
  17.         super.onListenerConnected();
  18.         Log.i(TAG, "onListenerConnected: ");
  19.     }

  20.     @Override
  21.     public void onListenerDisconnected() {
  22.         super.onListenerDisconnected();
  23.         Log.i(TAG, "onListenerDisconnected: ");
  24.     }

  25.     @Override
  26.     public void onDestroy() {
  27.         super.onDestroy();
  28.         Log.i(TAG, "onDestroy: ");
  29.     }
  30. }

  31. //在清单文件中声明
  32. <service android:name=".feature.notification.MyNotificationListenerService"
  33.             android:label="@string/app_name"
  34.             android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
  35.             >

  36.             <intent-filter>
  37.                 <action android:name="android.service.notification.NotificationListenerService" />
  38.             </intent-filter>

  39.         </service>

  40. //开启服务

  41. Intent intent = new Intent(getBaseContext(), MyNotificationListenerService.class);
  42.         startService(intent);

  43. //检查是否有该权限
  44. Set<String> pckNames = NotificationManagerCompat.getEnabledListenerPackages(getApplicationContext());
  45.         if (pckNames != null && pckNames.contains(getPackageName())) {
  46.             Toaster.showLongToast(getApplicationContext(), "有权限");
  47.         } else {
  48.             Toaster.showLongToast(getApplicationContext(), "无权限");
  49.         }   

  50. //跳转设置页
  51. String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";

  52.         startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS));
复制代码

感觉有点流氓,不过是必须在用户允许的情况才能使用,且用且珍惜。

补充:通知监听服务在oppo和vivo设备上能立即被重新启动。在小米设备不是很及时。



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

技术交流售后群

QQ|小黑屋|手机版|站点找错-建议|AI手机网 |Sitemap



GMT+8, 2024-5-20 06:27 , Processed in 0.142586 second(s), 26 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表