Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord in Android Studio

半城伤御伤魂 提交于 2020-01-19 07:09:41

问题


I am getting this error when I am trying to read contacts from phone and I included READ_CONTACTS permission in Manifest file. And the strange thing is that it was working fine in Eclipse but when I converted my project to Gradle and run it in Android Studio I'm getting this error.

logcat says:

Permission Denial: opening provider com.android.providers.contacts.ContactsProvider2 from ProcessRecord{302f069 29282:com.GP/u0a322} (pid=29282, uid=10322) requires android.permission.READ_CONTACTS or android.permission.WRITE_CONTACTS

here is the Manifest code:

<uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

    <!-- Read Contacts from phone -->
    <uses-permission android:name="android.permission.read_contacts" />
    <uses-permission android:name="android.permission.read_phone_state" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />

回答1:


Due to the Marshmallow update Requesting Permissions at Run Time the read contact permission not work. The sample code is

import android.Manifest;
import android.content.ContentResolver;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Build;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    // The ListView
    private ListView lstNames;

    // Request code for READ_CONTACTS. It can be any number > 0.
    private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Find the list view
        this.lstNames = (ListView) findViewById(R.id.lstNames);

        // Read and show the contacts
        showContacts();
    }

    /**
     * Show the contacts in the ListView.
     */
    private void showContacts() {
        // Check the SDK version and whether the permission is already granted or not.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
            //After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
        } else {
            // Android version is lesser than 6.0 or the permission is already granted.
            List<String> contacts = getContactNames();
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contacts);
            lstNames.setAdapter(adapter);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                           int[] grantResults) {
        if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted
                showContacts();
            } else {
                Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_SHORT).show();
            }
        }
    }

    /**
     * Read the name of all the contacts.
     *
     * @return a list of names.
     */
    private List<String> getContactNames() {
        List<String> contacts = new ArrayList<>();
        // Get the ContentResolver
        ContentResolver cr = getContentResolver();
        // Get the Cursor of all the contacts
        Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);

        // Move the cursor to first. Also check whether the cursor is empty or not.
        if (cursor.moveToFirst()) {
            // Iterate through the cursor
            do {
                // Get the contacts name
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                contacts.add(name);
            } while (cursor.moveToNext());
        }
        // Close the curosor
        cursor.close();

        return contacts;
    }
}

The sample screenshots :

I got the following source code from here




回答2:


My issue was that I was using a Marshmallow emulator and that has made some changes as to how we request permissions from user. Hence it kept asking for the permissions even after adding them. http://developer.android.com/training/permissions/requesting.html




回答3:


The new run-time permission scheme is used only if the app's targetSdkVersion (specified in the manifest) is 23 or higher. So, one way to avoid the issue is to make the targetSdkVersion lower than 23. See the description here:

https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous




回答4:


Google Play restricts the use of high risk or sensitive permissions, including the SMS or Call Log permission groups. So in short, even if you ask permission at runtime, there's a high chance that your app will not be allowed in Google Play.

You can apply for an exception though. Google Play will review the request and grant exceptions on a case by case basis. The criteria for allowing an exception are mentioned here.



来源:https://stackoverflow.com/questions/29915919/permission-denial-opening-provider-com-android-providers-contacts-contactsprovi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!