权限拒绝:打开提供程序com.android.providers.contacts.ContactsProvider2

6

我是一个新手,使用Android Studio和LoginActivity模板从头开始创建了一个应用程序。我的目标SDK版本是23,最低版本为15。Android Studio生成了以下清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.uprope.uprope" >

    <!-- To auto-complete the email text field in the login form with the user's emails -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".LoginActivity"
            android:label="@string/app_name"
            android:windowSoftInputMode="adjustResize|stateVisible" >
        </activity>
    </application>

</manifest>

当我尝试运行空模板时,出现了以下堆栈跟踪:
E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    Process: com.uprope.uprope, PID: 24790
    java.lang.RuntimeException: An error occurred while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:309)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)
     Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{85980a6 24790:com.uprope.uprope/u0a58} (pid=24790, uid=10058) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS
            at android.os.Parcel.readException(Parcel.java:1599)
            at android.os.Parcel.readException(Parcel.java:1552)
            at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:3550)
            at android.app.ActivityThread.acquireProvider(ActivityThread.java:4778)
            at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2018)
            at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1468)
            at android.content.ContentResolver.query(ContentResolver.java:475)
            at android.content.CursorLoader.loadInBackground(CursorLoader.java:64)
            at android.content.CursorLoader.loadInBackground(CursorLoader.java:56)
            at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:312)
            at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:69)
            at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:66)
            at android.os.AsyncTask$2.call(AsyncTask.java:295)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
            at java.lang.Thread.run(Thread.java:818)

什么导致了这个异常?

你正在测试你的代码在哪个版本的安卓系统上? - CommonsWare
2
如果您正在测试运行M的设备,则应采用新的请求权限方式。如果是这样,请参阅此相关答案,只需更改权限即可。https://dev59.com/o1wY5IYBdhLWcg3w2Kwv#32151901 - Nikola Despotoski
我正在使用Nexus 5虚拟设备。它显示正在使用API 23。 - travis1097
你在新安装的Android Studio上运行了先前API 23之前的代码,但只有API 23:Android 6.0(Marshmallow)可用于编译。你需要下载另一个SDK版本来编译你的代码,或者处理API 23权限模型。 - DritanX
我解决了链接描述中的问题。 - Samir
我提供了我的解决方案[[1]:https://dev59.com/BXE95IYBdhLWcg3wV8a_#38826895][1]。 - Samir
2个回答

7

如果您在 Android M 上进行测试,必须在运行时请求用户的联系人读取权限,如下所示:

private void accessContacts(){
    if (!mayRequestContacts()) {
        return;
    }
    // This Build is < 6 , you can Access contacts here.
}

您可以这样请求权限:

您需要像这样请求权限:

private boolean mayRequestContacts() {
    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(mEmailView, 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);
                    }
                });
    } else {
        requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
    }
    return false;
}

然后重写onRequestPermissionsResult方法

@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) {
            // Permission granted , Access contacts here or do whatever you need.
        }
    }
}

将以下内容添加到您的导入中:

      import static android.Manifest.permission.READ_CONTACTS;

定义一个整数作为标识,用于识别READ_CONTACTS权限请求。

      private static final int REQUEST_READ_CONTACTS = 0;

希望这有所帮助。

3
mEmailViewR.string.permission_rationale 是什么? - Al Lelopath

-11

Api 23有一些安全改进(这意味着一些开发中的错误)。我相信你已经定义了targetSdkVersion="23"。如果你将它改为22,它会正常工作,请检查一下。


1
这不是一个解决方案! - electronix384128
你需要处理Marshmallow权限模型 https://www.google.com/design/spec/patterns/permissions.html - DritanX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接