【问题标题】:How can I programmatically open the permission screen for a specific app on Android 6.0 (Marshmallow)?如何以编程方式打开 Android 6.0 (Marshmallow) 上特定应用的权限屏幕?
【发布时间】:2015-12-25 15:25:23
【问题描述】:

我对新的 Android 6.0 (Marshmallow) 版本有疑问:

是否可以通过 Intent 或类似的方式显示特定应用的权限屏幕

可以使用以下代码显示应用设置-有没有直接打开权限屏幕的模拟解决方案?

startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null)));

我已经对此进行了一些研究,但我无法找到合适的解决方案。

【问题讨论】:

标签: android android-permissions android-6.0-marshmallow


【解决方案1】:

根据官方 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);

【讨论】:

  • 它正在重定向到应用程序屏幕的一般详细信息。如何去专门的应用程序权限屏幕。我也不想要剩下的一键点击,
  • @MilindMevada - 目前你不能这样做。
  • 您能否使用意图“实时”将数据从设置活动发送到您的活动?我面临的问题是在您的活动中处理此数据一旦从设置中发送。
  • 这在调试应用程序时有效,但在签署 APK 后无故崩溃。在 logcat 中也没有什么明显的。
【解决方案2】:

这是不可能的。我也尝试过这样做。我可以弄清楚包名称和将要启动的活动。但是最后你会因为缺少你不能声明的权限而得到一个安全异常。

更新:

关于其他答案,我还建议打开应用程序设置屏幕。我使用以下代码执行此操作:

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

因为我不想在我的历史堆栈中包含它,所以我使用意图标志将其删除。

【讨论】:

  • 我也遇到了同样的情况,并认为可能有一种解决方法/另一种解决方案... :-/
  • @Mulgard Whatsapp 必须使用 targetSdk="23"。这允许应用程序提示用户启用权限。如果您的目标 SDK
  • Intent.FLAG_ACTIVITY_NO_HISTORY 有时可能会导致平板电脑出现问题,当设置屏幕中显示弹出窗口时,它将关闭设置屏幕。只需删除该标志即可解决此问题。
  • @Thomas R. 您所说的必须启动的活动是什么,但由于缺少无法声明的权限而产生了安全异常?我很好奇。
  • 您可以同时显示一个 Toast,指示用户进入“权限”(即使您的应用程序的其余部分不支持用户的语言,也可以本地化此消息)
【解决方案3】:
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
可选。如果设置,则打开设置屏幕(活动)作为新活动。否则会在当前运行的activity中打开。

Uri.fromParts("package", getPackageName(), null)
准备或创建 URI,而 getPackageName() - 返回应用程序包的名称。

intent.setData(uri)
别忘了设置这个。否则,您将获得android.content.ActivityNotFoundException因为您已将您的意图设置为 Settings.ACTION_APPLICATION_DETAILS_SETTINGS 而 android 希望搜索一些名称。

【讨论】:

  • 这就是投票最多的答案。为什么要复制这个而不是扩展原来的答案?!
  • 感谢您的深入解释。
【解决方案4】:

相反,您可以通过一行打开特定应用的常规设置:

 startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID)));

【讨论】:

  • 您可能希望使用 getActivity().getPackageName() 来获取包名称,具体取决于构建的配置方式。
【解决方案5】:

如果您想在Kotlin 中编写更少的代码,您可以这样做:

fun Context.openAppSystemSettings() {
    startActivity(Intent().apply {
        action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        data = Uri.fromParts("package", packageName, null)
    })
}

基于Martin Konecny的回答

【讨论】:

  • 很好地使用 Kotin 扩展
【解决方案6】:

Kotlin 风格。

startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
    data = Uri.fromParts("package", packageName, null)
})

【讨论】:

  • 非常有用...非常感谢!
【解决方案7】:

无法以编程方式打开权限屏幕。相反,我们可以打开应用设置屏幕。

代码

Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + BuildConfig.APPLICATION_ID));
startActivity(i);

样本输出

【讨论】:

  • 他正在请求权限页面
【解决方案8】:

从 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?

【讨论】:

  • 这是题外话的答案,问题与位置背景权限无关!
【解决方案9】:

Xamarin Forms Android:

//---------------------------------------------------------
public void OpenSettings()
//---------------------------------------------------------
{
    var intent = new Intent(Android.Provider.Settings.ActionApplicationDetailsSettings,
        Android.Net.Uri.Parse("package:" + Forms.Context.PackageName));
    Forms.Context.StartActivity(intent);
}

【讨论】:

    【解决方案10】:

    也许这会对你有所帮助

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

    【讨论】:

    • 解释一下。例如,想法/要点是什么?请通过editing (changing) your answer 回复,而不是在 cmets 中(without "Edit:"、"Update:" 或类似的 - 答案应该看起来像是今天写的)。
    【解决方案11】:

    如果我们谈论的是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

    【讨论】:

      【解决方案12】:

      不可能务实地获得许可... 但我建议您将那行代码放入 try{} catch{} 中,这会使您的应用不幸停止...

      在 catch 正文中,创建一个对话框,将用户导航到一个小教程,以启用对其他应用程序权限的绘制... 然后在 Yes 按钮上单击添加此代码...

      Intent callSettingIntent= new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
      startActivity(callSettingIntent);
      

      本意是直接打开拉过其他应用的列表来管理权限,然后从这里一键拉过其他应用的权限。

      我知道这不是您正在寻找的答案...但我正在我的应用程序中这样做...

      【讨论】:

        【解决方案13】:

        打开特定应用的权限屏幕

                    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 {}
        

        【讨论】:

          【解决方案14】:

          根据安卓documentation

          试试这个

          Intent intent = new Intent(Intent.ACTION_MAIN);
          intent.setComponent(new ComponentName(appDetails.packageName,"com.android.packageinstaller.permission.ui.ManagePermissionsActivity"));
          startActivity(intent);
          

          【讨论】:

          • 解释一下。例如,想法/要点是什么?请通过editing (changing) your answer 回复,而不是在 cmets 中(without "Edit:"、"Update:" 或类似的 - 答案应该看起来像是今天写的)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多