华为手机在锁屏时会关闭后台应用程序

4

这是我第一次在这个论坛上提问:

我开发了一个安卓应用,必须在后台运行,即当手机处于待机状态时可以恢复用户的位置。我使用了服务和唤醒锁。

该应用程序在SAMSUNG上工作良好,但我注意到HUAWEI会杀死该应用程序,如果它不在受保护的应用程序列表中。

因此我创建了一个对话框,告诉用户在受保护的应用程序列表中激活应用程序,如下所示:Keeping a periodic service active while the phone is locked

由于我的应用程序应在所有安卓手机上运行,我想知道是否有其他手机品牌在手机空闲时杀死应用程序,以便做出相同的处理。

提前感谢您的帮助:)


1
你的服务是否调用了 startForeground() 方法? - from56
3个回答

2

我曾经遇到同样的问题,使用辅助功能尝试获取类名或活动名称以传递给意图并打开设置,但似乎旧的受保护应用程序列表已不再可用,有了新的方法:

在华为设备上从启动中禁用该应用程序

在Oreo Huawei p10上进行了测试:

手动操作可以按以下步骤进行:

设置 -> 电池 -> 启动

找到您的应用并禁用

编程方式:

public class Constant {


    public static List<Intent> POWERMANAGER_INTENTS = Arrays.asList(
            new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
            new Intent().setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")),
            new Intent().setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity")),
            new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
            new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")),
            new Intent().setComponent(new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity")),
            new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")),
            new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")),
            new Intent().setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")),
            new Intent().setComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.entry.FunctionActivity")).setData(android.net.Uri.parse("mobilemanager://function/entry/AutoStart"))
    );
}

将以下代码放入您的Util或Activity类中
 private static boolean isCallable(Context context, Intent intent) {
      List<ResolveInfo>list=context.getPackageManager().queryIntentActivities(intent,
                PackageManager.MATCH_DEFAULT_ONLY);
        return list.size() > 0;
    }

saveUserSessionManager是一个Preference,你可以设置你的Preference类代替SaveUserSessionManager

public static void startPowerSaverIntent(Context context, SaveUserSessionManager saveUserSessionManager) {
    boolean skipMessage = saveUserSessionManager.getDataByKey("skipProtectedAppCheck", false);

    if (!skipMessage) {
        boolean foundCorrectIntent = false;
        for (Intent intent : Constant.POWERMANAGER_INTENTS) {
            if (isCallable(context, intent)) {
                foundCorrectIntent = true;


                new AlertDialog.Builder(context)
                        .setTitle(Build.MANUFACTURER + " Protected Apps")
                        .setMessage(String.format("%s requires to be 'White list' to function properly.\nDisable %s from list.%n", context.getString(R.string.app_name), context.getString(R.string.app_name)))
                        .setPositiveButton("Go to settings", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                context.startActivity(intent);
                                saveUserSessionManager.storeDataByKey("skipProtectedAppCheck", true);
                                dialog.dismiss();
                            }
                        })
                        .show();
                break;
            }
        }
    }
}

如何调用? 在您的MainActivity中的onResume方法中检查其是否启用。

 @Override
protected void onResume() {
    super.onResume();

    //saveUserSessionManager is just a Preference you can set your preference class instead of SessionManager

    if (!saveUserSessionManager.getDataByKey("skipProtectedAppCheck", false)) {

        Utils.startPowerSaverIntent(mContext, saveUserSessionManager);
    }
}

这是所有内容了 :)

看起来是个不错的解决方案... 有没有关于在Ionic应用中实现它的想法? - vr_driver

1
我正在开发的应用程序需要在后台运行,并使用前台服务来实现。从Android 8+开始(可能不仅限于这些版本),许多华为用户报告说,屏幕锁定后6-7分钟内应用程序会被关闭(没有任何通知)(我在这里链接1链接2中没有看到)。

事实上,华为设备默认情况下会关闭正在运行的应用程序以优化电池消耗(很酷,对吧?)。据我所知,没有办法通过编程来绕过这种行为。许多开发人员建议用户如何将应用程序加入白名单(例如,请参见:Endomondo)。 我还在寻找一种编程方式来检测优化行为,以至少警告用户。此处您可以找到可能的解决方案,但我还没有时间尝试。


1
持有唤醒锁可能不是您想要的,因为这并不能保护您的进程免于被杀死。增加应用程序进程优先级的最好方法是确保您的Service在前台运行。
在Android O上,您可以通过startForegroundService(Intent)来实现这一点。
这将在通知栏中放置一个通知,告诉Android操作系统您的进程正在工作。然后,请确保在任务完成后停止服务。
有关Services的更多信息,请查看Service文档。这将向您展示如何添加带有正确文本的通知。
您也可以通过查看Background Process文档来了解Android O中后台进程的工作方式。如果按照正确的方法进行(并在前台启动),则您的进程应该尽可能地具有弹性,适用于所有制造商。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接