Настройка "защищенные приложения" на телефонах Huawei и как с ней обращаться


У меня есть Huawei P8 с Android 5.0, который я использую для тестирования приложения. Приложение должно быть запущено в фоновом режиме, так как оно отслеживает регионы BLE.

Я обнаружил, что Huawei встроила "функцию" под названием Protected Apps, доступ к которой можно получить из настроек телефона (Battery Manager > Protected Apps). Это позволяет избранным приложениям продолжать работать после выключения экрана.

разумно для Huawei, но, к сожалению для меня, похоже, что это выбор, т. е. приложения по умолчанию отсутствуют, и вам нужно вручную их вставить. Это не showstopper, так как я могу посоветовать пользователям в FAQ или печатной документации об исправлении, но я недавно установил Tinder (для исследовательских целей!), и заметил, что он был помещен в защищенный список автоматически.

кто-нибудь знает как я могу сделать это для моего приложения? Это установка в манифесте? Это то, что Huawei включил для Tinder, потому что это популярное приложение?

7 94

7 ответов:

if("huawei".equalsIgnoreCase(android.os.Build.MANUFACTURER) && !sp.getBoolean("protected",false)) {
        AlertDialog.Builder builder  = new AlertDialog.Builder(this);
        builder.setTitle(R.string.huawei_headline).setMessage(R.string.huawei_text)
                .setPositiveButton(R.string.go_to_protected, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Intent intent = new Intent();
                        intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity"));
                        startActivity(intent);
                        sp.edit().putBoolean("protected",true).commit();
                    }
                }).create().show();
    }

в манифесте нет настроек, и Huawei включила Tinder, потому что это популярное приложение. Нет способа узнать, защищены ли приложения.

в любом случае я использовал "ifHuaweiAlert()" в "onCreate", чтобы показать AlertDialog:

private void ifHuaweiAlert() {
    final SharedPreferences settings = getSharedPreferences("ProtectedApps", MODE_PRIVATE);
    final String saveIfSkip = "skipProtectedAppsMessage";
    boolean skipMessage = settings.getBoolean(saveIfSkip, false);
    if (!skipMessage) {
        final SharedPreferences.Editor editor = settings.edit();
        Intent intent = new Intent();
        intent.setClassName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity");
        if (isCallable(intent)) {
            final AppCompatCheckBox dontShowAgain = new AppCompatCheckBox(this);
            dontShowAgain.setText("Do not show again");
            dontShowAgain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    editor.putBoolean(saveIfSkip, isChecked);
                    editor.apply();
                }
            });

            new AlertDialog.Builder(this)
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .setTitle("Huawei Protected Apps")
                    .setMessage(String.format("%s requires to be enabled in 'Protected Apps' to function properly.%n", getString(R.string.app_name)))
                    .setView(dontShowAgain)
                    .setPositiveButton("Protected Apps", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            huaweiProtectedApps();
                        }
                    })
                    .setNegativeButton(android.R.string.cancel, null)
                    .show();
        } else {
            editor.putBoolean(saveIfSkip, true);
            editor.apply();
        }
    }
}

private boolean isCallable(Intent intent) {
    List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,
            PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

private void huaweiProtectedApps() {
    try {
        String cmd = "am start -n com.huawei.systemmanager/.optimize.process.ProtectActivity";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            cmd += " --user " + getUserSerial();
        }
        Runtime.getRuntime().exec(cmd);
    } catch (IOException ignored) {
    }
}

private String getUserSerial() {
    //noinspection ResourceType
    Object userManager = getSystemService("user");
    if (null == userManager) return "";

    try {
        Method myUserHandleMethod = android.os.Process.class.getMethod("myUserHandle", (Class<?>[]) null);
        Object myUserHandle = myUserHandleMethod.invoke(android.os.Process.class, (Object[]) null);
        Method getSerialNumberForUser = userManager.getClass().getMethod("getSerialNumberForUser", myUserHandle.getClass());
        Long userSerial = (Long) getSerialNumberForUser.invoke(userManager, myUserHandle);
        if (userSerial != null) {
            return String.valueOf(userSerial);
        } else {
            return "";
        }
    } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException ignored) {
    }
    return "";
}

+1 для Пьер за его отличное решение, которое работает для нескольких производителей устройств (Huawei, asus, oppo ...).

Я хотел использовать его код в моем Android-приложении, которое находится в Java. Я вдохновил мой код от Пьера и Aiuspaktyn ответы.

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.support.v7.widget.AppCompatCheckBox;
import android.widget.CompoundButton;
import java.util.List;

public class Utils {

public static void startPowerSaverIntent(Context context) {
    SharedPreferences settings = context.getSharedPreferences("ProtectedApps", Context.MODE_PRIVATE);
    boolean skipMessage = settings.getBoolean("skipProtectedAppCheck", false);
    if (!skipMessage) {
        final SharedPreferences.Editor editor = settings.edit();
        boolean foundCorrectIntent = false;
        for (Intent intent : Constants.POWERMANAGER_INTENTS) {
            if (isCallable(context, intent)) {
                foundCorrectIntent = true;
                final AppCompatCheckBox dontShowAgain = new AppCompatCheckBox(context);
                dontShowAgain.setText("Do not show again");
                dontShowAgain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        editor.putBoolean("skipProtectedAppCheck", isChecked);
                        editor.apply();
                    }
                });

                new AlertDialog.Builder(context)
                        .setTitle(Build.MANUFACTURER + " Protected Apps")
                        .setMessage(String.format("%s requires to be enabled in 'Protected Apps' to function properly.%n", context.getString(R.string.app_name)))
                        .setView(dontShowAgain)
                        .setPositiveButton("Go to settings", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                context.startActivity(intent);
                            }
                        })
                        .setNegativeButton(android.R.string.cancel, null)
                        .show();
                break;
            }
        }
        if (!foundCorrectIntent) {
            editor.putBoolean("skipProtectedAppCheck", true);
            editor.apply();
        }
    }
}

private static boolean isCallable(Context context, Intent intent) {
    List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(intent,
            PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}
}

}

import android.content.ComponentName;
import android.content.Intent;
import java.util.Arrays;
import java.util.List;

public class Constants {

public static List<Intent> POWERMANAGER_INTENTS = Arrays.asList(
        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.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
        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"))
);
}

}

Я надеюсь, что это помогает кто-то.

+1 Aiuspaktyn на java solution

Решение Xamarin

использование:

MainActivity =>
protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);

    MyUtils.IfHuaweiAlert(this);
}

public static void IfHuaweiAlert(Context context)
{
    ISharedPreferences settings = context.GetSharedPreferences("ProtectedApps", FileCreationMode.Private);
    string saveIfSkip = "skipProtectedAppsMessage";
    bool skipMessage = settings.GetBoolean(saveIfSkip, false);
    if (!skipMessage)
    {
        ISharedPreferencesEditor editor = settings.Edit();
        Intent intent = new Intent();
        intent.SetClassName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity");

        if (context.PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly).Count > 0)
        {
            var dontShowAgain = new Android.Support.V7.Widget.AppCompatCheckBox(context);
            dontShowAgain.Text = "Do not show again";
            dontShowAgain.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) =>
            {
                editor.PutBoolean(saveIfSkip, e.IsChecked);
                editor.Apply();
            };

            new AlertDialog.Builder(context)
            .SetIcon(Android.Resource.Drawable.IcDialogAlert)
            .SetTitle("Huawei Protected Apps")
            .SetMessage(string.Format("{0} requires to be enabled in 'Protected Apps' to function properly.\n", context.GetString(Resource.String.app_name)))
            .SetView(dontShowAgain)
            .SetPositiveButton("Protected Apps", (o, d) =>
            {
                try
                {
                    string cmd = "am start -n com.huawei.systemmanager/.optimize.process.ProtectActivity";
                    if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr1)
                    {
                        try
                        {
                            UserManager um = (UserManager)context.GetSystemService(Context.UserService);
                            cmd += " --user " + um.GetSerialNumberForUser(Process.MyUserHandle());
                        }
                        catch { }
                    }
                    Java.Lang.Runtime.GetRuntime().Exec(cmd);
                }
                catch (Exception ignored)
                {
                }
            })
            .SetNegativeButton(Android.Resource.String.Cancel, (o, d) => { })
            .Show();
        }
        else
        {
            editor.PutBoolean(saveIfSkip, true);
            editor.Apply();
        }
    }
}

Я все еще хочу выяснить следующее (отсюда):

private static List<Intent> POWERMANAGER_INTENTS = new List<Intent>()
{
    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.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
    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"))
};

/*
    Should this method also run the command for the listed devices?
    I do not have devices to test it with.
*/
public static void StartPowerSaverIntent(Context context)
{
    foreach (Intent intent in POWERMANAGER_INTENTS)
    {
        if (context.PackageManager.ResolveActivity(intent, PackageInfoFlags.MatchDefaultOnly) != null)
        {
            context.StartActivity(intent);
            break;
        }
    }
}

было бы неплохо, чтобы просто запустить следующую команду, и все покрыто:

MyUtils.StartPowerSaverIntent(this);

EDIT:

Это:

public class MyUtils
{
    private static List<Intent> POWERMANAGER_INTENTS = new List<Intent>()
    {
        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.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
        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"))
    };

    public static void StartPowerSaverIntent(Context context)
    {
        ISharedPreferences settings = context.GetSharedPreferences("ProtectedApps", FileCreationMode.Private);
        bool skipMessage = settings.GetBoolean("skipAppListMessage", false);
        if (!skipMessage)
        {
            ISharedPreferencesEditor editor = settings.Edit();
            foreach (Intent intent in POWERMANAGER_INTENTS)
            {
                if (context.PackageManager.ResolveActivity(intent, PackageInfoFlags.MatchDefaultOnly) != null)
                {
                    var dontShowAgain = new Android.Support.V7.Widget.AppCompatCheckBox(context);
                    dontShowAgain.Text = "Do not show again";
                    dontShowAgain.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) =>
                    {
                        editor.PutBoolean("skipAppListMessage", e.IsChecked);
                        editor.Apply();
                    };

                    new AlertDialog.Builder(context)
                    .SetIcon(Android.Resource.Drawable.IcDialogAlert)
                    .SetTitle(string.Format("Add {0} to list", context.GetString(Resource.String.app_name)))
                    .SetMessage(string.Format("{0} requires to be enabled/added in the list to function properly.\n", context.GetString(Resource.String.app_name)))
                    .SetView(dontShowAgain)
                    .SetPositiveButton("Go to settings", (o, d) => context.StartActivity(intent))
                    .SetNegativeButton(Android.Resource.String.Cancel, (o, d) => { })
                    .Show();

                    break;
                }
            }
        }
    }
}

Я собрал некоторые намерения из различных сообщений, чтобы проверить всех производителей:

как запустить Power Manager всех производителей android, чтобы включить push-уведомление?

Я использую решение @Aiuspaktyn, в котором отсутствует часть того, как определить, когда остановить отображение диалогового окна после того, как пользователь установил приложение как защищенное. Я использую сервис, чтобы проверить, было ли приложение прекращено или нет, проверяя, существует ли оно.

PowerMaster - > автозапуск - > найдите свое приложение в заблокированном разделе и разрешите