我对新的 Android 6.0 (Marshmallow) 版本有疑问:
是否可以通过 Intent 或类似的方式显示特定应用程序的权限屏幕?
https://i.stack.imgur.com/H4GxJ.png
可以使用以下代码显示应用程序设置 - 是否有直接打开权限屏幕的模拟解决方案?
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null)));
我已经对此进行了一些研究,但我无法找到合适的解决方案。
根据官方 Marshmallow 权限视频(在 4m 43s mark),您必须改为打开应用程序设置页面(从那里可以一键访问权限页面)。
要打开设置页面,你会做
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
这是不可能的。我也尝试过这样做。我可以弄清楚包名称和将要启动的活动。但最后你会因为缺少你不能声明的权限而得到一个安全异常。
更新:
关于其他答案,我还建议打开应用程序设置屏幕。我使用以下代码执行此操作:
public static void startInstalledAppDetailsActivity(final Activity context) {
if (context == null) {
return;
}
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + context.getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivity(i);
}
因为我不想在我的历史堆栈中包含它,所以我使用意图标志将其删除。
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
说明
Settings.ACTION_APPLICATION_DETAILS_SETTINGS
打开应用程序的详细信息设置页面。从这里用户必须手动分配所需的权限。
Intent.FLAG_ACTIVITY_NEW_TASK
可选。如果设置,则打开设置屏幕(活动)作为新活动。否则,它将在当前运行的活动中打开。
Uri.fromParts("package", getPackageName(), null)
准备或创建 URI,而 getPackageName() - 返回应用程序包的名称。
intent.setData(uri)
别忘了设置这个。否则,您将获得 android.content.ActivityNotFoundException
。 因为您已将您的意图设置为 Settings.ACTION_APPLICATION_DETAILS_SETTINGS
并且 android 需要一些名称来搜索。
相反,您可以使用一行打开特定应用程序的常规设置:
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));
如果您想在 Kotlin
中编写更少的代码,您可以这样做:
fun Context.openAppSystemSettings() {
startActivity(Intent().apply {
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
data = Uri.fromParts("package", packageName, null)
})
}
基于 Martin Konecny 答案
科特林风格。
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", packageName, null)
})
无法以编程方式打开权限屏幕。相反,我们可以打开应用设置屏幕。
代码
Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID));
startActivity(i);
样本输出
https://i.stack.imgur.com/dxtGm.jpg
从 Android 11 开始,您可以使用以下代码直接调出 仅限位置权限的应用特定设置页面:requestPermissions(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), PERMISSION_REQUEST_BACKGROUND_LOCATION)
但是,上述方法只会工作一次。如果用户拒绝该权限,甚至不小心关闭了屏幕,应用程序将永远不会触发它再次出现。
除了上述之外,答案与 Android 11 之前的答案相同——您能做的最好的事情就是调出特定于应用程序的设置页面,并要求用户手动向下钻取两个级别以启用适当的权限。
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri: Uri = Uri.fromParts("package", packageName, null)
intent.data = uri
// This will take the user to a page where they have to click twice to drill down to grant the permission
startActivity(intent)
在此处查看我的相关问题:Android 11 users can’t grant background location permission?
Xamarin 窗体 Android:
//---------------------------------------------------------
public void OpenSettings()
//---------------------------------------------------------
{
var intent = new Intent(Android.Provider.Settings.ActionApplicationDetailsSettings,
Android.Net.Uri.Parse("package:" + Forms.Context.PackageName));
Forms.Context.StartActivity(intent);
}
可能这会帮助你
private void openSettings() {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 101);
}
如果我们谈论的是Flyme(魅族)仅限,它有自己的具有权限的安全应用程序。
要打开它,请使用以下意图:
public static void openFlymeSecurityApp(Activity context) {
Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("packageName", BuildConfig.APPLICATION_ID);
try {
context.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
当然,BuildConfig 是您应用的 BuildConfig。
务实地获得许可是不可能的......但我建议你把那行代码放在 try{} catch{} 中,这会让你的应用不幸停止......
在 catch 正文中,创建一个对话框,将用户导航到一个小教程以启用对其他应用程序权限的绘制...然后在“是”按钮上单击添加此代码...
Intent callSettingIntent= new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(callSettingIntent);
这个意图是直接打开在其他应用程序上绘制的列表以管理权限,然后从这里单击即可对其他应用程序的权限进行绘制。
我知道这不是您要寻找的答案...但我正在我的应用程序中执行此操作...
打开特定应用的权限屏幕
if (ContextCompat.checkSelfPermission(
context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
) {
//Permission is not granted yet. Ask for permission.
val alertDialog = AlertDialog.Builder(context)
alertDialog.setMessage(context.getString(R.string.file_permission))
alertDialog.setPositiveButton("सेटिंग") { _, _ ->
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
alertDialog.setNegativeButton("हाँ") { _, _ ->
ActivityCompat.requestPermissions(
context as Activity, arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE
), 1
)
}
alertDialog.show()
} else {}
根据 Android documentation
尝试这个
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName(appDetails.packageName,"com.android.packageinstaller.permission.ui.ManagePermissionsActivity"));
startActivity(intent);