当前位置: 首页 > 知识库问答 >
问题:

Android运行时权限-如何实现

闾丘卓
2023-03-14

Android开发人员文档给出了运行时请求权限的示例:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
    != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

示例中的“MY_PERMISSIONS_REQUEST_READ_CONTACTS”是什么?它说它是一个应用程序定义的int常量,但这是否意味着我应该做一个常量.java并声明一个公共静态int?值应该是多少?

在其他例子中,我看到人们在这里使用1,或0或0xFFEEDDCC,但我找不到它是什么的解释。谁能给我解释一下这里需要什么,为什么?(在我的情况下,我需要确保应用程序有权限访问精细位置)

ActivityCompat 文档显示“应用程序特定的请求代码,以匹配报告给 onRequestPermissionsResult 的结果”?这对我没有帮助。

共有3个答案

霍襦宗
2023-03-14

我检查了所有的答案,但没有满足我需要的确切答案,所以这里有一个我编写的示例,即使用户单击“不再询问”复选框,它也能很好地工作。

> < li>

创建一个方法,当您想要请求运行时权限时将调用该方法,如< code>readContacts()或者您也可以使用< code>openCamera(),如下所示:

private void readContacts() {
    if (!askContactsPermission()) {
        return;
    } else {
        queryContacts();
    } }

现在我们需要创建<code>askContactPermission(),您也可以将其命名为<code>askCameraPermission()。

    private boolean askContactsPermission() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return true;
    }
    if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
        return true;
    }
    if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
        Snackbar.make(parentLayout, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
                .setAction(android.R.string.ok, new View.OnClickListener() {
                    @Override
                    @TargetApi(Build.VERSION_CODES.M)
                    public void onClick(View v) {
                        requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
                    }
                }).show();
    } else if (contactPermissionNotGiven) {
        openPermissionSettingDialog();
    } else {
        requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
        contactPermissionNotGiven = true;

    }
    return false;
}

在编写此函数之前,请确保您已定义以下实例变量,如图所示:

    private View parentLayout;
    private boolean contactPermissionNotGiven;;


/**
 * Id to identity READ_CONTACTS permission request.
 */
private static final int REQUEST_READ_CONTACTS = 0;

现在是重写 onRequestPermissionsResult 方法的最后一步,如下所示:

/**
 * Callback received when a permissions request has been completed.
 */
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode == REQUEST_READ_CONTACTS) {
        if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            queryContacts();
        }
    }
}

这里我们完成了运行时权限,插件是<code>openPermissionSettingDialog()

    private void openPermissionSettingDialog() {
    String message = getString(R.string.message_permission_disabled);
    AlertDialog alertDialog =
            new AlertDialog.Builder(MainActivity.this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
                    .setMessage(message)
                    .setPositiveButton(getString(android.R.string.ok),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Intent intent = new Intent();
                                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                                    intent.setData(uri);
                                    startActivity(intent);
                                    dialog.cancel();
                                }
                            }).show();
    alertDialog.setCanceledOnTouchOutside(true);
}

我们错过了什么?1.在<code>strings.xml<code>中定义使用的字符串

<string name="permission_rationale">"Contacts permissions are needed to display Contacts."</string>
    <string name="message_permission_disabled">You have disabled the permissions permanently,
        To enable the permissions please go to Settings -> Permissions and enable the required Permissions,
        pressing OK you will be navigated to Settings screen</string>

在< code>onCreate方法中初始化< code>parentLayout变量

parent layout = findViewById(r . id . content);

在< code>AndroidManifest.xml中定义所需的权限

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

< code>queryContacts方法,根据您的需要或运行时权限,您可以调用之前需要< code >权限的方法。在我的例子中,我简单地使用加载器获取联系人,如下所示:

private void queryContacts() {
getLoaderManager().initLoader(0, null, this);}

这非常适用于快乐编码:)

任小云
2023-03-14

在“处理权限请求响应”下的留档中再往下看一点,你就会看到它的用途。

名为onRequest estPermissionsResult的回调方法会被发送回与参数相同的代码,以便您知道正在请求/授予哪个权限:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

由于该常量仅供您使用,因此您可以为其提供任何您喜欢的值作为公共静态最终int。请求的每个权限都需要自己的常量。

暨高洁
2023-03-14

此示例中的“MY_PERMISSIONS_REQUEST_READ_CONTACTS”是什么?

它是一个int,用于将特定的请求Permissions()调用绑定到相应的onRequestPermissionsResult()回调。

在幕后,< code > request permissions()使用< code > startActivityForResult();此< code>int的作用与它在< code > startActivityForResult()中的作用相同。

这是否意味着我应该Constants.java声明一个公共静态int?

我只是让它成为活动中的私有静态最终int。但是,您可以根据需要在任何地方声明它。

价值应该是什么?

我似乎记得它必须低于0x8000000,否则它可以是任何您想要的。活动中的每个<code>requestPermissions(),但实际数字并不重要。

如果您的活动只有一个< code > request permissions()调用,那么< code>int值实际上并不重要。但是许多应用程序在一个活动中会有几个< code > request permissions()调用。在这种情况下,开发人员可能需要在< code > onRequestPermissionsResult()中知道这是什么请求的结果。

 类似资料:
  • 问题内容: Android开发人员文档提供了以下在运行时请求权限的示例: 在此示例中,什么是“ MY_PERMISSIONS_REQUEST_READ_CONTACTS”?它说这是一个应用程序定义的int常量,但这是否意味着我应该制作一个Constants.java并声明一个公共静态int?该值是多少? 在其他示例中,我看到人们在这里使用1,或者0或0xFFEEDDCC,但是我找不到它的解释。有人

  • 我添加了使用权限,包括WRITE_EXTERNAL_STORAGE,android.permission.相机,READ_EXTERNAL_STORAGEAndroidManifest.xml. 当我在Nexus6(API 24)中运行我的应用程序时,它向我抛出了以下错误: java.io.IOException:权限被拒绝 这是我的代码: 如何在权限相机运行时打开之前使用它?

  • 假设我试图将位图图像保存为png 如果我使用Android 6.0及以上版本,我需要请求运行时权限 我有几个问题: 上面的代码成功地请求了权限,但是我不得不重新启动应用程序,我如何恰当地暂停代码直到权限被授予或未被授予? 在 Android 6.0 下方,权限由清单文件在安装时授予。Android 5 或更低版本如何处理运行时权限代码? 谢谢

  • 我是android的新手,不知道我做错了什么,这个类得到了经度和纬度并发送到另一个类,代码抛出了一个错误请告诉我该怎么做怎么做: public void onRequestPermissionsResult出错(int requestCode,String[]permissions,int[]grantResults

  • 首先,我知道这是一个重复的问题,但我已经看过了其他类似问题的答案,没有找到成功的解决方案。 我已经开发了一款应用程序,可以在我的测试设备上完美运行,这是一款运行Android L(5.0.1)的三星S4。不过,我希望这款应用程序也能在较新版本的Android上运行。 我知道Android M的请求权限已更改,因此必须在运行时请求权限,但当我尝试实现此功能时,对话框从未出现,因此从未请求所需的权限。

  • 问题内容: 我正在测试我的应用,即使清单中已经定义了,它也会被强制关闭。我在某处已经读到,如果我在运行时请求权限,则不会强制关闭您的应用程序。我也已经阅读了这个android文档,用于请求运行时权限。 因此,我知道我们可以请求一个如下所示的权限,该权限在android文档中有所提及。 上面的代码具有获取结果的回调方法。 我的问题是要向用户确切请求权限?我们应该在应用启动时使用请求权限还是应该在需要