Настройка "защищенные приложения" на телефонах Huawei и как с ней обращаться
У меня есть Huawei P8 с Android 5.0, который я использую для тестирования приложения. Приложение должно быть запущено в фоновом режиме, так как оно отслеживает регионы BLE.
Я обнаружил, что Huawei встроила "функцию" под названием Protected Apps, доступ к которой можно получить из настроек телефона (Battery Manager > Protected Apps). Это позволяет избранным приложениям продолжать работать после выключения экрана.
разумно для Huawei, но, к сожалению для меня, похоже, что это выбор, т. е. приложения по умолчанию отсутствуют, и вам нужно вручную их вставить. Это не showstopper, так как я могу посоветовать пользователям в FAQ или печатной документации об исправлении, но я недавно установил Tinder (для исследовательских целей!), и заметил, что он был помещен в защищенный список автоматически.
кто-нибудь знает как я могу сделать это для моего приложения? Это установка в манифесте? Это то, что Huawei включил для Tinder, потому что это популярное приложение?
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-уведомление?