以编程方式停用 Android 中的设备管理员?
Posted
技术标签:
【中文标题】以编程方式停用 Android 中的设备管理员?【英文标题】:Programmatically deactivate a Device Admininstrator in Android? 【发布时间】:2013-11-23 08:46:00 【问题描述】:是否可以以编程方式停用(第三方)Device Administrator 应用程序?
我能够使用DevicePolicyManager 和getActiveAdmins() 激活设备管理员检索所有应用程序:
final DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
final List<ComponentName> adminList = dpm.getActiveAdmins();
for ( ComponentName app : adminList )
Log.d(TAG, "App: ", app.getPackageName());
但是,为了停用它们,我不能使用removeActiveAdmin(...),因为它不会删除不是我自己的应用程序的组件。
我正在考虑使用 Intent 和 startActivity() 来打开我要停用的特定组件的设备管理员停用页面。有可能吗?
【问题讨论】:
【参考方案1】:实际上,可以直接进入管理屏幕,但我不确定它有多安全,因为 API 本身不可用,并且路径可能会随着不同的 android 版本和 rom 而改变。
这是我测试过的:
这将直接进入您选择的应用的激活/停用屏幕:
final Intent intent=new Intent();
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.DeviceAdminAdd"));
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,componentName);
activity.startActivity(intent);
这将进入管理应用列表:
final Intent intent=new Intent();
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.DeviceAdminSettings"));
activity.startActivity(intent);
如果有人有更官方、更安全的方法,请写下来。
这些风险很大,所以你可以先用这个方法:
Intent intent=new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
final PackageManager packageManager=context.getPackageManager();
final List<ResolveInfo> resolveInfos=packageManager.queryIntentActivities(intent,0);
if(resolveInfos!=null&&!resolveInfos.isEmpty())
try
final ResolveInfo resolveInfo=resolveInfos.get(0);
intent=new Intent();
intent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,resolveInfo.activityInfo.name));
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,componentNameResult);
context.startActivity(intent);
return true;
catch(final Exception e)
你可以为每个方法添加try-catch,如果都失败了,使用:
final Intent intent=new Intent(Settings.ACTION_SECURITY_SETTINGS);
activity.startActivity(intent);
【讨论】:
感谢您的回答。正如您所说,使用固定路径并不是一个好习惯。但是,正如您所建议的,我可以使用 try-catch 块来捕获可能的 ActivityNotFoundException 异常。 哦.. 我刚刚发现,在某些情况下,Settings.ACTION_SECURITY_SETTINGS 活动也可能不存在。 developer.android.com/reference/android/provider/… @PaoloRovelli 我现在添加了一种更安全的方法。 @PaoloRovelli 真的吗?诡异的。所以应该有另一个后备,去设备的设置? 不确定。也许它不仅仅存在于旧设备上。无论如何,您还需要对 Settings.ACTION_SECURITY_SETTINGS 使用 try-catch 块 (ActivityNotFoundException)。【参考方案2】:是否可以通过编程方式停用(第三方)设备管理员应用程序?
没有。也不可能以编程方式激活一个。
我正在考虑使用 Intent 和 startActivity() 来打开我要停用的特定组件的设备管理员停用页面。
设置应用程序中没有直接进入删除设备管理屏幕的入口点,更不用说记录在案的Intent
操作了。您可以通过这种方式添加设备管理员,但不能将其删除。
【讨论】:
android.googlesource.com/platform/frameworks/base/+/master/core/…@Commonsware 你可以查看上面的链接吗?它有一种方法可以删除其他应用程序的管理员。方法处于隐藏模式。虽然我使用反射模式来使用该方法,但它给出了 NoSuchMethodException。 “它有一种方法可以删除其他应用程序的管理员”——这不是我所看到的。 “但它给出了 NoSuchMethodException”——您可能在旧设备上运行,因为您的链接指向master
分支。如果该方法存在,我希望你得到一个SecurityException
。【参考方案3】:
这应该可行:
ComponentName devAdminReceiver = new ComponentName(context, deviceAdminReceiver.class);
DevicePolicyManager dpm = (DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.removeActiveAdmin(devAdminReceiver);
您需要将其添加到您的活动意图过滤器的清单中:
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
【讨论】:
根据 Android 文档,您只能停用来自您的应用程序的组件,而不能停用来自第三方应用程序的组件。 developer.android.com/reference/android/app/admin/… 删除当前管理组件。这只能由拥有管理组件的应用程序调用;如果您尝试删除其他人的组件,则会引发安全异常。以上是关于以编程方式停用 Android 中的设备管理员?的主要内容,如果未能解决你的问题,请参考以下文章
我可以以编程方式配置 PostgreSQL 以不消除全文搜索中的停用词吗?