如何以编程方式获取 MIUI Security 应用程序自动启动权限?

Posted

技术标签:

【中文标题】如何以编程方式获取 MIUI Security 应用程序自动启动权限?【英文标题】:How to get MIUI Security app auto start permission programmatically? 【发布时间】:2016-12-24 01:01:40 【问题描述】:

我的小米红米 2 Prime 手机没有收到BOOT_COMPLETE 广播。

我的BroadcastReciever 是---

public class OnBootReceiver extends BroadcastReceiver 

@Override
public void onReceive(Context context, Intent intent) 
    // Setting singleAlarm
    SingleAlarmHandler.getInstance().setAlarm(context);

    try 
        // Sending System Setting broadcast
        String offDate = SharedPrefrencesHandler.getInstance(context).readString(SharedPrefrencesConstants.SWITCH_OFF_DATE);
        int type = SystemSettingsType.PHONE_SWITCH_ON_OFF.getNumericType();

        if (offDate == null)
            offDate = "";

        SystemSettingsHandler.getSystemSettingsHandler().makeSystemSettingsCall(context, type, offDate);
        SharedPrefrencesHandler.getInstance(context).removePrefrence(SharedPrefrencesConstants.SWITCH_OFF_DATE);
         catch (Exception e) 
            Log.e(ChaseForceApplication.TAG, e.getMessage());
        
    

和清单:

    <receiver
        android:name=".broadcastlisteners.OnBootReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

经许可:

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

现在我的小米红米 2 Prime 手机没有收到 BOOT COMPLETE 广播,因为没有设置闹钟。但在其他安卓手机上它工作正常。

我搜索了一下,发现是MIUI固件的问题。在此类移动设备中,它们提供了内置的安全应用程序,除非您在该安全应用程序中允许自动启动权限,否则您无法获得广播(任何通知)。

一旦您在该应用中检查了该权限,您就开始获得广播。

现在我的问题是:

如何以编程方式获取 MIUI Security 应用程序自动启动权限(手机如 Redmi)?

【问题讨论】:

你在说什么?显示您的代码。 (清单和你的接收者) @xdevs23,感谢您的评论,现在我已经在广播接收器中添加了我的代码。手机,但它显示在其他手机,如 Moto e、Micromax android1 等...... 嗨@ImranKhanSaifi。这是 MIUI Roms 中添加的安全功能。任何使用小米手机(带有 MIUI)的开发者都会知道这一点。我面临着同样的问题。我搜索了很多,但似乎 MIUI 家伙没有为开发人员提供任何 SDK 来访问权限管理器左右。如果您找到任何解决方案,请回复。 嗨@Mazhar,感谢您的回复...是的,你说得对。 Sequrity 应用程序是一个系统应用程序,因此我们无法对其进行任何控制,用户可以随时删除任何权限和通知(自动启动检查).....在我的应用程序中造成问题的另一件事是没有获取位置当应用程序未运行时..其背后的原因是另一个设置..在电池->管理应用程序电池使用情况->..默认情况下选择标准模式,当您的应用程序停止您的应用程序获取位置和使用网络没有运行..所以你还必须在选择应用选项中检查你的应用。 谁能提供通用的解决方案,让警报在不同制造的设备上正常工作?我要求在不同设备上提供所有解决方案。谢谢。 【参考方案1】:

您需要在 xiaomi 的内置安全应用程序中授予权限。

1. open the security app
2. go to permissions
3. go to auto start
4. enable the applications that you want to keep running in the background!

这对我有用..!

【讨论】:

如何以编程方式完成这些步骤。您提到了手动步骤。 @VineetKasat 你有什么解决办法吗? @VineetKasat 你有什么解决方案吗,如何以编程方式完成这些步骤? @karthik 这些步骤不能以编程方式完成。在我们的生产应用程序中,我们必须浮动 sop 步骤才能手动执行。 如果说的是真的,那么为流行的应用程序提供强大的功能但拒绝给其他应用程序提供强大的功能,这不是反对公开竞争。这意味着一个新的应用程序处于不利地位。因此,这是阻止来自中国以外的新应用程序流行的一种方式。无论大小,规则都应该相同。【参考方案2】:

这个问题已经在两个 Stack Overflow 线程中有答案:

线程#1 https://***.com/a/40932178/1537413

String xiaomi = "Xiaomi";
final String CALC_PACKAGE_NAME = "com.miui.securitycenter";
final String CALC_PACKAGE_ACITIVITY = "com.miui.permcenter.autostart.AutoStartManagementActivity";
if (deviceManufacturer.equalsIgnoreCase(xiaomi)) 
    DisplayUtils.showDialog(activity, "Ask for permission", new DialogInterface.OnClickListener() 
        @Override
        public void onClick(DialogInterface dialogInterface, int i) 
            try 
                Intent intent = new Intent();
                intent.setComponent(new ComponentName(CALC_PACKAGE_NAME, CALC_PACKAGE_ACITIVITY));
                activity.startActivity(intent);
             catch (ActivityNotFoundException e) 
                Logger.e(TAG, "Failed to launch AutoStart Screen ", e);
             catch (Exception e) 
                Logger.e(TAG, "Failed to launch AutoStart Screen ", e);
            
        
    , new DialogInterface.OnClickListener() 
        @Override
        public void onClick(DialogInterface dialogInterface, int i) 

        
    );

线程#2 https://***.com/a/41696993/1537413

String manufacturer = "xiaomi";
        if(manufacturer.equalsIgnoreCase(android.os.Build.MANUFACTURER)) 
            //this will open auto start screen where user can enable permission for your app
            Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));
            startActivity(intent);
        

对于华为设备上的类似问题:

https://***.com/a/35220476/1537413

    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 "";

【讨论】:

嗨@Dika,感谢您的回复..我正在使用您的小米自动启动代码,通过您的代码,我能够达到自动启动设置活动,但我无法知道天气用户给定自动启动许可与否。我能否以某种方式知道用户的操作,天气用户是否已授予许可(最终许可状态)。 据我所知,您无法知道用户是否已授予权限。小米不提供此功能。您可以做的最好的事情是您可以向用户显示一个带有清单的小对话框:“我已经允许此应用程序自动启动”。如果对您有帮助,请将我的评论标记为答案。 @Dika:如果是华硕设备呢?我使用华硕,它也阻止自动启动,我使用自动启动管理器来允许后台服务

以上是关于如何以编程方式获取 MIUI Security 应用程序自动启动权限?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android中以编程方式打开MIUI系统Activity

如何在android中以编程方式检测MIUI ROM?

如何以编程方式检查某个 URL 是不是需要使用 Spring Security 进行身份验证?

如何在小米设备中以编程方式允许通知声音

如何使用 Spring-security 以编程方式登录用户?

以编程方式获取应用程序池标识