“受保护应用程序”设置在华为手机上,以及如何处理它

我有一个华为的 p8和 Android 5.0,我正在用它来测试一个应用程序。这个应用程序需要在后台运行,因为它要跟踪 BLE 区域。

我发现华为内置了一个叫做受保护应用的“功能”,可以通过手机设置(电池管理器 > 受保护应用)访问。这允许选定的应用程序在屏幕关闭后继续运行。

对华为来说是明智的,但对我来说不幸的是,它看起来像是选择加入的,也就是说,应用程序在默认情况下是退出的,你必须手动将它们加入进来。 这不是一个精彩的终结,因为我可以建议用户在 FAQ 或打印文档的修复,但我最近安装了 Tinder (为了研究目的!),并注意到它被放在保护列表自动。

有人知道我的应用程序怎么做吗?这是清单上的设置吗?是不是华为因为 Tinder 是一个受欢迎的应用程序而启用了这个功能?

77696 次浏览

清单中没有设置,而华为之所以启用 Tinder,是因为它是一款受欢迎的应用程序。没有办法知道应用程序是否受到保护。

无论如何,我在 onCreate()中使用 ifHuaweiAlert()来显示 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 "";
}

我正在使用@Aiuspaktyn 解决方案,它遗漏了用户将应用程序设置为受保护后如何检测何时停止显示对话框的部分。我使用一个服务来检查应用程序是否被终止,检查它是否存在。

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

所有设备的解决方案(Xamarin. Android)

用法:

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


MyUtils.StartPowerSaverIntent(this);
}

public class MyUtils
{
private const string SKIP_INTENT_CHECK = "skipAppListMessage";


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.appcontrol.activity.StartupAppControlActivity")),
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.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")),
new Intent().SetComponent(new ComponentName("com.htc.pitroad", "com.htc.pitroad.landingpage.activity.LandingPageActivity")),
new Intent().SetComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.autostart.AutoStartActivity")),
new Intent().SetComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.entry.FunctionActivity")).SetData(Android.Net.Uri.Parse("mobilemanager://function/entry/AutoStart")),
new Intent().SetComponent(new ComponentName("com.dewav.dwappmanager", "com.dewav.dwappmanager.memory.SmartClearupWhiteList"))
};


public static void StartPowerSaverIntent(Context context)
{
ISharedPreferences settings = context.GetSharedPreferences("ProtectedApps", FileCreationMode.Private);
bool skipMessage = settings.GetBoolean(SKIP_INTENT_CHECK, false);
if (!skipMessage)
{
bool HasIntent = false;
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(SKIP_INTENT_CHECK, 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();


HasIntent = true;


break;
}
}


if (!HasIntent)
{
editor.PutBoolean(SKIP_INTENT_CHECK, true);
editor.Apply();
}
}
}
}

Android.Manifest中添加以下权限

<uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE"/>
<uses-permission android:name="com.huawei.permission.external_app_settings.USE_COMPONENT"/>

要帮助查找此处未列出的设备的活动,只需使用以下方法来帮助查找要为用户打开的正确活动

C #

public static void LogDeviceBrandActivities(Context context)
{
var Brand = Android.OS.Build.Brand?.ToLower()?.Trim() ?? "";
var Manufacturer = Android.OS.Build.Manufacturer?.ToLower()?.Trim() ?? "";


var apps = context.PackageManager.GetInstalledPackages(PackageInfoFlags.Activities);


foreach (PackageInfo pi in apps.OrderBy(n => n.PackageName))
{
if (pi.PackageName.ToLower().Contains(Brand) || pi.PackageName.ToLower().Contains(Manufacturer))
{
var print = false;
var activityInfo = "";


if (pi.Activities != null)
{
foreach (var activity in pi.Activities.OrderBy(n => n.Name))
{
if (activity.Name.ToLower().Contains(Brand) || activity.Name.ToLower().Contains(Manufacturer))
{
activityInfo += "  Activity: " + activity.Name + (string.IsNullOrEmpty(activity.Permission) ? "" : " - Permission: " + activity.Permission) + "\n";
print = true;
}
}
}


if (print)
{
Android.Util.Log.Error("brand.activities", "PackageName: " + pi.PackageName);
Android.Util.Log.Warn("brand.activities", activityInfo);
}
}
}
}

爪哇咖啡

public static void logDeviceBrandActivities(Context context) {
String brand = Build.BRAND.toLowerCase();
String manufacturer = Build.MANUFACTURER.toLowerCase();


List<PackageInfo> apps = context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES);


Collections.sort(apps, (a, b) -> a.packageName.compareTo(b.packageName));
for (PackageInfo pi : apps) {
if (pi.packageName.toLowerCase().contains(brand) || pi.packageName.toLowerCase().contains(manufacturer)) {
boolean print = false;
StringBuilder activityInfo = new StringBuilder();


if (pi.activities != null && pi.activities.length > 0) {
List<ActivityInfo> activities = Arrays.asList(pi.activities);


Collections.sort(activities, (a, b) -> a.name.compareTo(b.name));
for (ActivityInfo ai : activities) {
if (ai.name.toLowerCase().contains(brand) || ai.name.toLowerCase().contains(manufacturer)) {
activityInfo.append("  Activity: ").append(ai.name)
.append(ai.permission == null || ai.permission.length() == 0 ? "" : " - Permission: " + ai.permission)
.append("\n");
print = true;
}
}
}


if (print) {
Log.e("brand.activities", "PackageName: " + pi.packageName);
Log.w("brand.activities", activityInfo.toString());
}
}
}
}

在启动时执行并搜索日志文件,在 brand.activitiesTAG上添加 logcat 过滤器

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


MyUtils.LogDeviceBrandActivities(this);
}

输出样本:

E/brand.activities: PackageName: com.samsung.android.lool
W/brand.activities: ...
W/brand.activities:   Activity: com.samsung.android.sm.ui.battery.AppSleepSettingActivity
W/brand.activities:   Activity: com.samsung.android.sm.ui.battery.BatteryActivity <-- This is the one...
W/brand.activities:   Activity: com.samsung.android.sm.ui.battery.BatteryActivityForCard
W/brand.activities: ...

因此组件名称将是:

new ComponentName("<PackageName>", "<Activity>")
new ComponentName("com.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")

如果该活动在其旁边有权限,则需要 Android.Manifest中的以下条目来打开该活动:

<uses-permission android:name="<permission>" />

评论或编辑新的组成部分到这个答案。所有的帮助将我非常感谢。

PowerMaster-> AutoStart-> 在阻止区域中找到你的应用程序并允许

他的解决方案为多个设备制造商(华为,华硕,oppo...)工作。

我想在我的 Android 应用程序中使用他的代码,这个应用程序是用 Java 编写的。 我从皮埃尔和 爱斯帕克丁答案中获得灵感编写代码。

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) {
try {
if (intent == null || context == null) {
return false;
} else {
List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
} catch (Exception ignored) {
return false;
}
}
}

}

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


public class Constants {
//updated the POWERMANAGER_INTENTS 26/06/2019
static final 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.huawei.systemmanager", Build.VERSION.SDK_INT >= Build.VERSION_CODES.P? "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity": "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
new Intent().setComponent(new ComponentName("com.coloros.oppoguardelf", "com.coloros.powermanager.fuelgaue.PowerUsageModelActivity")),
new Intent().setComponent(new ComponentName("com.coloros.oppoguardelf", "com.coloros.powermanager.fuelgaue.PowerSaverModeActivity")),
new Intent().setComponent(new ComponentName("com.coloros.oppoguardelf", "com.coloros.powermanager.fuelgaue.PowerConsumptionActivity")),
new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")).setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).setData(Uri.parse("package:"+ MyApplication.getContext().getPackageName())) : null,
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")),
new Intent().setComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.autostart.AutoStartActivity")),
new Intent().setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity"))
.setData(android.net.Uri.parse("mobilemanager://function/entry/AutoStart")),
new Intent().setComponent(new ComponentName("com.meizu.safe", "com.meizu.safe.security.SHOW_APPSEC")).addCategory(Intent.CATEGORY_DEFAULT).putExtra("packageName", BuildConfig.APPLICATION_ID)
);
}

Android.Manifest中添加以下权限

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE"/>
<uses-permission android:name="com.huawei.permission.external_app_settings.USE_COMPONENT"/>

  • 我仍然面临一些问题与 OPPO 设备

我希望这能帮到别人。

您可以使用此库将用户导航到受保护的应用程序或自动启动:

自动启动

如果手机支持自动启动功能,您可以向用户显示一个提示,使您的应用程序在这些应用程序

你可以用这个方法检查:

AutoStartPermissionHelper.getInstance().isAutoStartPermissionAvailable(context)

要将用户导航到该页面,只需调用以下命令:

AutoStartPermissionHelper.getInstance().getAutoStartPermission(context)