我需要以编程方式检查MIUI手机中我的应用的自动启动权限是打开还是关闭。 Facebook和whatsapp默认已启用此权限,我该怎么办?
答案 0 :(得分:29)
现在不可能。
因为它完全取决于他们的操作系统API和自定义。甚至开发者也已经在XIOMI的官方论坛上提出要求,但是没有回复。
直到现在我甚至找到了这个问题的答案,但没有任何帮助。
暂时只能使用有根电话。即通过成为超级用户在其固件中进行自定义。 但这根本不可取,因为它可能会损坏用户的手机。
编辑1
您可以使用以下代码
将用户重定向到自动启动权限的设置页面以启用您的应用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 intent1 = new Intent();
intent1.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));
startActivity(intent1);
}
编辑2
我最近使用了来自XIOMI的Mi A1,它有现货android(不是miui)所以这款手机没有来自miui的autostart permission
设置。因此,在将用户导航到此类设备中的设置时要小心,因为它在此处不起作用。
答案 1 :(得分:16)
100%为oppo,vivo,xiomi,letv huawei和荣誉工作
只需调用此函数
private void addAutoStartup() {
try {
Intent intent = new Intent();
String manufacturer = android.os.Build.MANUFACTURER;
if ("xiaomi".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity"));
} else if ("oppo".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity"));
} else if ("vivo".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));
} else if ("Letv".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity"));
} else if ("Honor".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity"));
}
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0) {
startActivity(intent);
}
} catch (Exception e) {
Log.e("exc" , String.valueOf(e));
}
}
答案 2 :(得分:4)
这不是一个完美的解决方案,它需要一些测试,但我已经能够用它来检测我的小米设备的自动启动权限。
自动启动权限允许通过接收隐式广播意图来启动应用。此方法包括使用AlarmManager调度隐式广播,终止应用并检查广播是否导致重新生成。还计划了第二个显式意图,以确保最终启动应用程序。
public class AutostartDetector extends BroadcastReceiver {
// I've omitted all the constant declaration to keep this snippet concise
// they should match the values used in the Manifest
public static void testAutoStart(Context context) {
long now = System.currentTimeMillis();
// this ID is for matching the implicit and explicit intents
// it might be unnecessary
String testId = Long.toHexString(now);
Intent implicitIntent = new Intent(ACTION_IMPLICIT_BROADCAST);
// the category is set just to make sure that no other receivers handle the broadcast
implicitIntent.addCategory(CATEGORY_AUTOSTART);
implicitIntent.putExtra(EXTRA_TEST_ID, testId);
PendingIntent implicitPendingIntent =
PendingIntent.getBroadcast(context, REQUEST_CODE_IMPLICIT_BROADCAST, implicitIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent explicitIntent = new Intent(ACTION_EXPLICIT_BROADCAST);
explicitIntent.addCategory(CATEGORY_AUTOSTART);
explicitIntent.setComponent(new ComponentName(context, AutostartDetector.class));
explicitIntent.putExtra(EXTRA_TEST_ID, testId);
PendingIntent explicitPendingIntent =
PendingIntent.getBroadcast(context, REQUEST_CODE_EXPLICIT_BROADCAST, explicitIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// calling commit() makes sure that the data is written before we kill the app
// again, this might be unnecessary
getSharedPreferences(context).edit().putInt(testId, TestStatus.STARTED).commit();
// the explicit intent is set with an additional delay to let the implicit one be received first; might require some fine tuning
alarmManager.set(AlarmManager.RTC_WAKEUP, now + BASE_DELAY, implicitPendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP, now + BASE_DELAY + EXPLICIT_INTENT_DELAY, explicitPendingIntent);
// kill the app - actually kind of tricky, see below
SelfKiller.killSelf(context);
}
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences = getSharedPreferences(context);
String testId = intent.getStringExtra(EXTRA_TEST_ID);
if (testId == null) {
Log.w(TAG, "Null test ID");
return;
}
if (!sharedPreferences.contains(testId)) {
Log.w(TAG, "Unknown test ID: " + testId);
return;
}
String action = intent.getAction();
if (ACTION_IMPLICIT_BROADCAST.equals(action)) {
// we could assume right here that the autostart permission has been granted,
// but we should receive the explicit intent anyway, so let's use it
// as a test sanity check
Log.v(TAG, "Received implicit broadcast");
sharedPreferences.edit().putInt(testId, TestStatus.IMPLICIT_INTENT_RECEIVED).apply();
} else if (ACTION_EXPLICIT_BROADCAST.equals(action)) {
Log.v(TAG, "Received explicit broadcast");
int testStatus = sharedPreferences.getInt(testId, -1);
switch (testStatus) {
case TestStatus.STARTED:
// the implicit broadcast has NOT been received - autostart permission denied
Log.d(TAG, "Autostart disabled");
sharedPreferences.edit().putBoolean(PREF_AUTOSTART_ENABLED, false).apply();
notifyListener(false);
break;
case TestStatus.IMPLICIT_INTENT_RECEIVED:
// the implicit broadcast has been received - autostart permission granted
Log.d(TAG, "Autostart enabled");
sharedPreferences.edit().putBoolean(PREF_AUTOSTART_ENABLED, true).apply();
notifyListener(true);
break;
default:
Log.w(TAG, "Invalid test status: " + testId + ' ' + testStatus);
break;
}
}
}
private interface TestStatus {
int STARTED = 1;
int IMPLICIT_INTENT_RECEIVED = 2;
}
清单中的接收者声明:
<receiver android:name=".autostart.AutostartDetector">
<intent-filter>
<category android:name="com.example.autostart.CATEGORY_AUTOSTART"/>
<action android:name="com.example.autostart.ACTION_IMPLICIT_BROADCAST"/>
<action android:name="com.example.autostart.ACTION_EXPLICIT_BROADCAST"/>
</intent-filter>
</receiver>
可靠地杀死应用程序是另一个问题。我一直在使用这个辅助方法:
public static void killSelf(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.killBackgroundProcesses(context.getPackageName());
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// this is all we can do before ICS. luckily Xiaomi phones have newer system versions :)
System.exit(1);
return;
}
// set up a callback so System.exit() is called as soon as all
// the activities are finished
context.registerComponentCallbacks(new ComponentCallbacks2() {
@Override
public void onTrimMemory(int i) {
if (i == TRIM_MEMORY_UI_HIDDEN) {
Log.v(TAG, "UI Hidden");
System.exit(1);
}
}
/* ... */
});
// see below
ActivityTracker.getInstance().finishAllActivities();
}
ActivityTracker是另一个跟踪活动生命周期的实用程序。确保在Application子类中注册它。
@RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public final class ActivityTracker implements Application.ActivityLifecycleCallbacks {
private final ArraySet<Activity> mCreatedActivities = new ArraySet<>();
public static ActivityTracker getInstance() {
return Holder.INSTANCE;
}
public static void init(Application application) {
application.registerActivityLifecycleCallbacks(getInstance());
}
public static void release(Application application) {
ActivityTracker activityTracker = getInstance();
application.unregisterActivityLifecycleCallbacks(activityTracker);
activityTracker.mCreatedActivities.clear();
}
public void finishAllActivities() {
// iterate over active activities and finish them all
for (Activity activity : mCreatedActivities) {
Log.v(TAG, "Finishing " + activity);
activity.finish();
}
}
public Set<Activity> getCreatedActivities() {
return Collections.unmodifiableSet(mCreatedActivities);
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
mCreatedActivities.add(activity);
}
@Override
public void onActivityDestroyed(Activity activity) {
mCreatedActivities.remove(activity);
}
private static final class Holder {
private static final ActivityTracker INSTANCE = new ActivityTracker();
}
/* ... */
}
您可能还想要停止所有服务以确保。
答案 3 :(得分:1)
首先,Facebook,Whatsapp等一些应用程序在默认情况下从Xiomi列入白名单,这意味着这些应用程序将自动启动自动启动权限。
如果已启用或未启用自动启动权限,我也找不到任何方法来检查自动启动权限并以编程方式启用它。虽然上面的答案表明我们可以将用户重定向到自动启动权限活动,但是当我们必须重定向用户时,我们仍然不知道,这也不适用于所有的Xiomi设备。
所以我使用了我的同步适配器的替代方案。我存储了一个名为&#34; isSyncAdapterRunning&#34;的布尔变量。在共享首选项中,并在每次运行同步适配器时设置它的值。通过这种方式,我可以知道我的同步适配器是否正常工作。
//in my sync adapter
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.e("TAG", "SyncStarted");
performSync(true);
}
public static void performSync(boolean fromSyncAdapterClass){
//write your code for sync operation
if(fromSyncAdapterClass){
setValueOfIsSyncAdapterRunningVariable();
}
}
如果同步适配器不工作,我还提供了其他后台服务来执行相同的任务。
//In my other background service
public class BackgroundSyncService extends IntentService {
public BackgroundSyncService() {
super("BackgroundSyncService");
}
@Override
protected void onHandleIntent(Intent intent) {
SyncAdapter.performSync(false);
}
}
现在启动同步适配器:
// start your sync adapter here
//And after that just start that service with a condition
if(!getValueOfIsSyncAdapterRunningVariable()){
startService(new Intent(context, BackgroundSyncService.class));
}
所以基本上我运行另一个服务来在后台执行相同的任务,如果我的同步适配器不工作,最好的事情是它们中只有一个会一次运行。 如果用户打开自动启动权限并再次关闭,则上面的代码将失败,因为已经设置了布尔变量的值。为此,您可以在24小时内将布尔变量的值设置为默认值。
希望这有帮助。
答案 4 :(得分:1)
暂时不可能。 因为它完全取决于他们的操作系统 API 和自定义。但是我使用 SharedPreference 实现了修复。它没有解决问题,但它会阻止应用程序在每次打开应用程序时打开设置屏幕。示例:
if (AppPref.getAutoStart(context).isEmpty() && AppPref.getAutoStart(context).equals("")) {
enableAutoStart();
}
private void enableAutoStart() {
if (Build.BRAND.equalsIgnoreCase("xiaomi")) {
new AlertDialog.Builder(context)
.setTitle("Enable AutoStart")
.setMessage("Please allow this app to always run in the background,else our services can't be accessed.")
.setNegativeButton("Deny", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
AppPref.setAutoStart(context, "");
dialog.dismiss();
}
})
.setPositiveButton("ALLOW", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
AppPref.setAutoStart(context, "1");
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.miui.securitycenter",
"com.miui.permcenter.autostart.AutoStartManagementActivity"));
startActivity(intent);
} catch (Exception e) {
Toast.makeText(context, "Can't perform action", Toast.LENGTH_SHORT).show();
}
dialog.dismiss();
}
})
.create()
.show();
}
}
答案 5 :(得分:0)
您无法检查是否启用了自动运行权限,因为自动运行功能是由自定义操作系统提供的,而不是由 mi、vivo、oppo、letv 等 android 操作系统提供的
这是在 MI、Honor 和 vivo 手机上测试的变通方法。
检查os是否像miui一样自定义,荣耀ui复制粘贴这个方法到activity、fragment或者util类中
public static void getAutoStartPermission(final Activity context) {
final String build_info = Build.BRAND.toLowerCase();
switch (build_info) {
case "xiaomi":
Utilities.Companion.showAutorunDialog(context);
break;
case "letv":
Utilities.Companion.showAutorunDialog(context);
break;
case "oppo":
Utilities.Companion.showAutorunDialog(context);
break;
case "vivo":
Utilities.Companion.showAutorunDialog(context);
break;
case "Honor":
Utilities.Companion.showAutorunDialog(context);
break;
default:
break;
}
}
哪里
fun showAutorunDialog(context: Context) {
val builder = AlertDialog.Builder(context)
//set title for alert dialog
builder.setTitle("Alert")
//set message for alert dialog
builder.setMessage("Enable Autostart permission for this app if its disabled in app settings in order to run application in background.")
builder.setCancelable(true)
//performing positive action
builder.setPositiveButton("Enable") { _, _ ->
addAutoStartup(context)
}
// Create the AlertDialog
var vpnDialog = builder.create()
// Set other dialog properties
vpnDialog!!.setCancelable(false)
vpnDialog!!.show()
}
private fun addAutoStartup(context:Context) {
try {
val intent = Intent()
val manufacturer = Build.MANUFACTURER
if ("xiaomi".equals(manufacturer, ignoreCase = true)) {
intent.component = ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")
} else if ("oppo".equals(manufacturer, ignoreCase = true)) {
intent.component = ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")
} else if ("vivo".equals(manufacturer, ignoreCase = true)) {
intent.component = ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")
} else if ("Letv".equals(manufacturer, ignoreCase = true)) {
intent.component = ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity")
} else if ("Honor".equals(manufacturer, ignoreCase = true)) {
intent.component = ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")
}
val list: List<ResolveInfo> = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
if (list.size > 0) {
context.startActivity(intent)
}
} catch (e: java.lang.Exception) {
Log.e("exc", e.toString())
}
}
答案 6 :(得分:0)
要检查是否启用了权限,我只是启动了一个前台服务并检查是否正在运行。
服务:
class ExtraPermissionStateService: Service() {
companion object {
private var instance: ExtraPermissionStateService? = null
fun isAppCanRunOnBackground(context: Context): Boolean {
val serviceIntent = Intent(context, ExtraPermissionStateService::class.java)
context.startService(serviceIntent)
return instance != null
}
}
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
instance = this
}
override fun onDestroy() {
super.onDestroy()
instance = null
}
}
称之为:
ExtraPermissionStateService.isAppCanRunOnBackground(context)
不要忘记在清单上:
<service android:name=".helpers.utils.ExtraPermissionStateService"/>
答案 7 :(得分:-4)
您必须允许和拒绝系统权限。
下面是代码:
private boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
if (result == PackageManager.PERMISSION_GRANTED){
return true;
} else {
return false;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar.make(view,"Permission Granted, Now you can access location data.",Snackbar.LENGTH_LONG).show();
} else {
Snackbar.make(view,"Permission Denied, You cannot access location data.",Snackbar.LENGTH_LONG).show();
}
break;
}
}