2020Android进程保活的实现(附项目以及代码)

一.原因:
比如一些聊天应用如果退出被杀死就收不到消息,或者金融类应用收到转账消息,应用被杀了就收不到通知
二.现状:
随着谷歌的不断升级改造我们知道,Android 系统会存在杀后台进程的情况,并且随着系统版本的更新,杀进程的力度还有越来越大的趋势。系统这种做法本身出发点是好的,因为可以节省内存,降低功耗,也避免了一些流氓行为。为此作为开发者的我们被老板们逼着炒碎啦心,各种办法尝试,今天为各位大佬带来一篇优雅的保活模式,那就是后台运行白名单。 下次被产品说「莫某某软件都可以保活,为什么我们不行!」的时候,你就知道怎么怼回去了。大厂通过和手机厂商的合作,将自己的应用默认加入到白名单中。如果你在一个能谈成这种合作的大厂,也就不用往下看了。
三.实现:
为了做到保活,出现了不少骚操作,比如 1 个像素的 Activity,播放无声音频,双进程互相守护等。这些做法可以说是很流氓了,甚至破坏了Android 的生态,好在随着 Android 系统版本的更新,这些非常规的保活手段很多都已失效了。对于那些确实需要在后台运行的应用,我们如何做到优雅的保活呢?
运行白名单:
1.在 AndroidManifest.xml 文件中加入一下权限:

2.将以下代码复制在你的代码中:

public class FcfrtAppBhUtils {
    /**
     * 判断我们的应用是否在白名单中
     * @param context
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static boolean isIgnoringBatteryOptimizations(Context context) {
        boolean isIgnoring = false;
        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (powerManager != null) {
            isIgnoring = powerManager.isIgnoringBatteryOptimizations(getPackageName());
        }
        return isIgnoring;
    }

    /**
     * 申请加入白名单
     * @param context
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void requestIgnoreBatteryOptimizations(Context context) {
        try {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 跳转到指定应用的首页
     */
    private static void showActivity(Context context,@NonNull String packageName) {
        Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
        context.startActivity(intent);
    }

    /**
     * 跳转到指定应用的指定页面
     */
    private static void showActivity(Context context,@NonNull String packageName, @NonNull String activityDir) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName(packageName, activityDir));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    /**
     * 华为厂商判断
     * @return
     */
    public boolean isHuawei() {
        if (Build.BRAND == null) {
            return false;
        } else {
            return Build.BRAND.toLowerCase().equals("huawei") || Build.BRAND.toLowerCase().equals("honor");
        }
    }

    /**
     * 小米厂商判断
     * @return
     */
    public static boolean isXiaomi() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("xiaomi");
    }
    /**
     * OPPO厂商判断
     * @return
     */
    public static boolean isOPPO() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("oppo");
    }
    /**
     * VIVO厂商判断
     * @return
     */
    public static boolean isVIVO() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("vivo");
    }

    public static boolean isMeizu() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("meizu");
    }
    public static boolean isSamsung() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("samsung");
    }
    public static boolean isLeTV() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("letv");
    }
    public static boolean isSmartisan() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("smartisan");
    }

    /**
     * 跳转华为手机管家的启动管理页
     * 操作步骤:应用启动管理 -> 关闭应用开关 -> 打开允许自启动
     * @param context
     */
    public static void goHuaweiSetting(Context context) {
        try {
            showActivity(context,"com.huawei.systemmanager",
                    "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");
        } catch (Exception e) {
            showActivity(context,"com.huawei.systemmanager",
                    "com.huawei.systemmanager.optimize.bootstart.BootStartActivity");
        }
    }

    /**
     * 跳转小米安全中心的自启动管理页面
     * 操作步骤:授权管理 -> 自启动管理 -> 允许应用自启动
     * @param context
     */
    public static void goXiaomiSetting(Context context) {
        showActivity(context,"com.miui.securitycenter",
                "com.miui.permcenter.autostart.AutoStartManagementActivity");
    }

    /**
     * 跳转 OPPO 手机管家
     * 操作步骤:权限隐私 -> 自启动管理 -> 允许应用自启动
     * @param context
     */
    public static void goOPPOSetting(Context context) {
        try {
            showActivity(context,"com.coloros.phonemanager");
        } catch (Exception e1) {
            try {
                showActivity(context,"com.oppo.safe");
            } catch (Exception e2) {
                try {
                    showActivity(context,"com.coloros.oppoguardelf");
                } catch (Exception e3) {
                    showActivity(context,"com.coloros.safecenter");
                }
            }
        }
    }

    /**
     * 跳转 VIVO 手机管家
     * 操作步骤:权限管理 -> 自启动 -> 允许应用自启动
     * @param context
     */
    public static void goVIVOSetting(Context context) {
        showActivity(context,"com.iqoo.secure");
    }

    /**
     * 跳转魅族手机管家
     * 操作步骤:权限管理 -> 后台管理 -> 点击应用 -> 允许后台运行
     * @param context
     */
    public static void goMeizuSetting(Context context) {
        showActivity(context,"com.meizu.safe");
    }

    /**
     * 跳转三星智能管理器
     * 操作步骤:自动运行应用程序 -> 打开应用开关 -> 电池管理 -> 未监视的应用程序 -> 添加应用
     * @param context
     */
    public static void goSamsungSetting(Context context) {
        try {
            showActivity(context,"com.samsung.android.sm_cn");
        } catch (Exception e) {
            showActivity(context,"com.samsung.android.sm");
        }
    }

    /**
     *跳转乐视手机管家
     * 操作步骤:自启动管理 -> 允许应用自启动
     * @param context
     */
    public static void goLetvSetting(Context context) {
        showActivity(context,"com.letv.android.letvsafe",
                "com.letv.android.letvsafe.AutobootManageActivity");
    }

    public static void goSmartisanSetting(Context context) {
        showActivity(context,"com.smartisanos.security");
    }

}

使用方式:

if (!FcfrtAppBhUtils.isIgnoringBatteryOptimizations(this)){
            FcfrtAppBhUtils.requestIgnoreBatteryOptimizations(this)
        }

使用后会出现:
2020Android进程保活的实现(附项目以及代码)_第1张图片

今天写了一个kotlin版本的包含白名单申请加入以及相应rxjava3处理的demo,并且在回调回Activity界面的时候若还是没有加入白名单则继续一直申请,我先附上代码,项目在最后自行下载:
MainActivity:


class MainActivity : RxAppCompatActivity() {

    val REQUEST_CODE :Int = 2;

    val isApplyDialogShowing:Boolean = false

    @MyCat
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        btn_apply_white.setOnClickListener{
            applyKeepLive()
        }
        btn_shot.setOnClickListener(View.OnClickListener {
            shotData()
        })

    }

    fun shotData(){
        openJobIntentService()
    }

    open fun applyKeepLive(){
        if (!FcfrtAppBhUtils.isIgnoringBatteryOptimizations(this)) {
            requestIgnoreBatteryOptimizations(this)
        }else{
            Toast.makeText(this@MainActivity,"已经加入白名单",Toast.LENGTH_SHORT).show()
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    fun requestIgnoreBatteryOptimizations(context: Context) {
        try {
            val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
            intent.data = Uri.parse("package:" + context.packageName)
            startActivityForResult(intent,REQUEST_CODE)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        //拒绝电池后走到这里
        Log.d("lwp","onActivityResult")
        if (requestCode == REQUEST_CODE){
            Observable.create(ObservableOnSubscribe {
                if (resultCode == RESULT_OK){
                    Toast.makeText(this@MainActivity,"白名单申请成功",Toast.LENGTH_SHORT).show()
                    it.onNext(0)
                    return@ObservableOnSubscribe
                }else{
                    Toast.makeText(this@MainActivity,"白名单申请失败",Toast.LENGTH_SHORT).show()
                    it.onNext(1)
                }
                it.onComplete()
            }).subscribeOn(AndroidSchedulers.mainThread()).compose(bindToLifecycle())
                .subscribe(Consumer {
                    if (it == 0){
                        return@Consumer
                    }else{
                        if (FcfrtAppBhUtils.isXiaomi()){

                        }else if (FcfrtAppBhUtils.isLeTV()){

                        }else if (FcfrtAppBhUtils.isMeizu()){

                        }else if (FcfrtAppBhUtils.isSmartisan()){

                        }else if (FcfrtAppBhUtils.isHuawei()){
                            FcfrtAppBhUtils.goHuaweiSetting(MainActivity@this)
                        }
                    }
                })

        }

    }

    //轮询服务
    fun openJobIntentService(){
       Observable.timer(2,TimeUnit.SECONDS).subscribe(Consumer {
           Log.d("lwp","timer "+Thread.currentThread().name);
            Observable.interval(2,TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(
                Consumer {
                    Log.d("lwp","Lunxun "+Thread.currentThread().name);
                    if (AppUtil.isForeground(this@MainActivity)){
                        applyKeepLive()
                    }
                })
       })
    }


}

工具类AppUtil:


object AppUtil {
    /**
     * 判断某个activity是否在前台显示
     */
    fun isForeground(activity: RxAppCompatActivity): Boolean {
        return isForeground(activity, activity.javaClass.name)
    }

    /**
     * 判断某个界面是否在前台,返回true,为显示,否则不是
     */
    fun isForeground(context: RxAppCompatActivity?, className: String): Boolean {
        if (context == null || TextUtils.isEmpty(className)) return false
        val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val list = am.getRunningTasks(1)
        if (list != null && list.size > 0) {
            val cpn = list[0].topActivity
            if (className == cpn!!.className) return true
        }
        return false
    }
}

工具类2:判断白名单是否存在以及打开相应设置:


public class FcfrtAppBhUtils {
    /**
     * 判断我们的应用是否在白名单中
     * @param context
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static boolean isIgnoringBatteryOptimizations(Context context) {
        boolean isIgnoring = false;
        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        if (powerManager != null) {
            isIgnoring = powerManager.isIgnoringBatteryOptimizations(context.getPackageName());
        }
        return isIgnoring;
    }

    /**
     * 申请加入白名单
     * @param context
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void requestIgnoreBatteryOptimizations(Context context) {
        try {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            context.startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 跳转到指定应用的首页
     */
    private static void showActivity(Context context,@NonNull String packageName) {
        Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
        context.startActivity(intent);
    }

    /**
     * 跳转到指定应用的指定页面
     */
    private static void showActivity(Context context, @NonNull String packageName, @NonNull String activityDir) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName(packageName, activityDir));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    /**
     * 华为厂商判断
     * @return
     */
    public static boolean isHuawei() {
        if (Build.BRAND == null) {
            return false;
        } else {
            return Build.BRAND.toLowerCase().equals("huawei") || Build.BRAND.toLowerCase().equals("honor");
        }
    }

    /**
     * 小米厂商判断
     * @return
     */
    public static boolean isXiaomi() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("xiaomi");
    }
    /**
     * OPPO厂商判断
     * @return
     */
    public static boolean isOPPO() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("oppo");
    }
    /**
     * VIVO厂商判断
     * @return
     */
    public static boolean isVIVO() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("vivo");
    }

    public static boolean isMeizu() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("meizu");
    }
    public static boolean isSamsung() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("samsung");
    }
    public static boolean isLeTV() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("letv");
    }
    public static boolean isSmartisan() {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("smartisan");
    }

    /**
     * 跳转华为手机管家的启动管理页
     * 操作步骤:应用启动管理 -> 关闭应用开关 -> 打开允许自启动
     * @param context
     */
    public static void goHuaweiSetting(Context context) {
        try {
            showActivity(context,"com.huawei.systemmanager",
                    "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");
        } catch (Exception e) {
            showActivity(context,"com.huawei.systemmanager",
                    "com.huawei.systemmanager.optimize.bootstart.BootStartActivity");
        }
    }

    /**
     * 跳转小米安全中心的自启动管理页面
     * 操作步骤:授权管理 -> 自启动管理 -> 允许应用自启动
     * @param context
     */
    public static void goXiaomiSetting(Context context) {
        showActivity(context,"com.miui.securitycenter",
                "com.miui.permcenter.autostart.AutoStartManagementActivity");
    }

    /**
     * 跳转 OPPO 手机管家
     * 操作步骤:权限隐私 -> 自启动管理 -> 允许应用自启动
     * @param context
     */
    public static void goOPPOSetting(Context context) {
        try {
            showActivity(context,"com.coloros.phonemanager");
        } catch (Exception e1) {
            try {
                showActivity(context,"com.oppo.safe");
            } catch (Exception e2) {
                try {
                    showActivity(context,"com.coloros.oppoguardelf");
                } catch (Exception e3) {
                    showActivity(context,"com.coloros.safecenter");
                }
            }
        }
    }

    /**
     * 跳转 VIVO 手机管家
     * 操作步骤:权限管理 -> 自启动 -> 允许应用自启动
     * @param context
     */
    public static void goVIVOSetting(Context context) {
        showActivity(context,"com.iqoo.secure");
    }

    /**
     * 跳转魅族手机管家
     * 操作步骤:权限管理 -> 后台管理 -> 点击应用 -> 允许后台运行
     * @param context
     */
    public static void goMeizuSetting(Context context) {
        showActivity(context,"com.meizu.safe");
    }

    /**
     * 跳转三星智能管理器
     * 操作步骤:自动运行应用程序 -> 打开应用开关 -> 电池管理 -> 未监视的应用程序 -> 添加应用
     * @param context
     */
    public static void goSamsungSetting(Context context) {
        try {
            showActivity(context,"com.samsung.android.sm_cn");
        } catch (Exception e) {
            showActivity(context,"com.samsung.android.sm");
        }
    }

    /**
     *跳转乐视手机管家
     * 操作步骤:自启动管理 -> 允许应用自启动
     * @param context
     */
    public static void goLetvSetting(Context context) {
        showActivity(context,"com.letv.android.letvsafe",
                "com.letv.android.letvsafe.AutobootManageActivity");
    }

    public static void goSmartisanSetting(Context context) {
        showActivity(context,"com.smartisanos.security");
    }

}

项目地址:https://download.csdn.net/download/kururunga/12880056

你可能感兴趣的:(Android,rxjava3,kotlin)