Configuración de “Aplicaciones protegidas” en teléfonos Huawei, y cómo manejarlo

Tengo un Huawei P8 con Android 5.0 que estoy usando para probar una aplicación. La aplicación debe ejecutarse en segundo plano, ya que rastrea las regiones BLE.

Descubrí que Huawei ha incorporado una “función” llamada Aplicaciones protegidas, a la que se puede acceder desde la configuración del teléfono (Administrador de batería> Aplicaciones protegidas). Esto permite que las aplicaciones elegidas sigan funcionando después de que se apaga la pantalla.

Perceptiblemente para Huawei, pero desafortunadamente para mí, parece que es una opción, es decir, las aplicaciones están desactivadas de manera predeterminada, y tienes que ingresarlas manualmente. Esto no es una excepción, ya que puedo aconsejar a los usuarios en las preguntas frecuentes o impreso documentación sobre la solución, pero recientemente instalé Tinder (¡con fines de investigación!) y noté que se incluía en la lista protegida automáticamente.

¿Alguien sabe cómo puedo hacer esto para mi aplicación? ¿Es un ajuste en el manifiesto? ¿Es algo que Huawei ha habilitado para Tinder porque es una aplicación popular?

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(); } 

No hay una configuración en el manifiesto, y Huawei ha habilitado a Tinder porque es una aplicación popular. No hay forma de saber si las aplicaciones están protegidas.

De todos modos, utilicé “ifHuaweiAlert ()” en “onCreate” para mostrar un 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 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 Aiuspaktyn para la solución java

Solución Xamarin

Uso:

 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(); } } } 

Todavía quiero resolverlo para lo siguiente ( desde aquí ):

 private static List POWERMANAGER_INTENTS = new List() { 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; } } } 

Sería bueno simplemente ejecutar el siguiente comando, y todo está cubierto:

 MyUtils.StartPowerSaverIntent(this); 

EDITAR:

Esto debería hacer:

 public class MyUtils { private static List POWERMANAGER_INTENTS = new List() { 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; } } } } } 

+1 para Pierre por su gran solución que funciona para múltiples fabricantes de dispositivos (Huawei, asus, oppo …).

Quería usar su código en mi aplicación de Android que está en Java. Inspiré mi código de las respuestas de Pierre y 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 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 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")) ); } 

}

Espero que esto ayude a alguien.

He recostackdo alguna intención de varias publicaciones para verificar a todos los productores:

¿Cómo iniciar Power Manager de todos los fabricantes de Android para habilitar la notificación push?

Estoy usando @Aiuspaktyn solución que le falta la parte de cómo detectar cuándo detener la presentación del cuadro de diálogo después de que el usuario configure la aplicación como protegida. Estoy usando un Servicio para verificar si la aplicación fue cancelada o no, verificando si existe.

PowerMaster -> AutoStart -> Encuentra tu aplicación en la sección bloqueada y permite