“Protected Apps” setting on Huawei phones, and how to handle it

后端 未结 7 1535
-上瘾入骨i
-上瘾入骨i 2020-11-22 09:48

I have a Huawei P8 with Android 5.0 that I\'m using for testing an app. The app needs to be running in the background, as it tracks BLE regions.

I\'ve discovered t

7条回答
  •  误落风尘
    2020-11-22 10:31

    Solution for all devices (Xamarin.Android)

    Usage:

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

    Add the following permissions in your Android.Manifest

    
    
    

    To help find the activity of the device not listed here, simply use the following method to help find the correct activity to open for the user

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

    Java

    public static void logDeviceBrandActivities(Context context) {
        String brand = Build.BRAND.toLowerCase();
        String manufacturer = Build.MANUFACTURER.toLowerCase();
    
        List 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 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());
                }
            }
        }
    }
    

    Execute on startup and search through the log file, add a logcat filter on TAG of brand.activities

    MainActivity =>
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    
        MyUtils.LogDeviceBrandActivities(this);
    }
    

    Sample Output:

    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: ...
    

    So the component name will be:

    new ComponentName("", "")
    new ComponentName("com.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")
    

    If the activity has a permission next to it, the following entry in the Android.Manifest is required to open the activity:

    
    

    Comment or edit the new component into this answer. All help will me much appreciated.

提交回复
热议问题