Подтвердить что ты не робот

Разрешение отказа: открытие провайдера com.android.providers.contacts.ContactsProvider2 из ProcessRecord в Android Studio

Я получаю эту ошибку, когда пытаюсь читать контакты с телефона, и я включил разрешение READ_CONTACTS в файл манифеста. И странно, что он отлично работал в Eclipse, но когда я преобразовал свой проект в Gradle и запустил его в Android Studio, я получаю эту ошибку.

logcat говорит:

Отказ от прав: открытие провайдера com.android.providers.contacts.ContactsProvider2 из ProcessRecord {302f069 29282: com.GP/u0a322} (pid = 29282, uid = 10322) требует андроида.передать .READ_CONTACTS или android.permission.WRITE_CONTACTS

вот код манифеста:

<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" />
4b9b3361

Ответ 1

Из-за обновления Marshmallow, запрашивающего разрешения во время выполнения, разрешение на чтение контактов не работает. Пример кода

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

Примеры скриншотов: введите описание изображения здесь введите описание изображения здесь

Я получил следующий исходный код здесь

Ответ 2

Моя проблема заключалась в том, что я использовал эмулятор Marshmallow и внес некоторые изменения относительно того, как мы запрашиваем разрешения от пользователя. Поэтому он продолжал запрашивать разрешения даже после их добавления. http://developer.android.com/training/permissions/requesting.html

Ответ 3

Новая схема разрешений во время выполнения используется только в том случае, если для приложения targetSdkVersion (указанного в манифесте) установлено значение 23 или выше. Таким образом, один из способов избежать этой проблемы - сделать targetSdkVersion ниже 23. Смотрите описание здесь:

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

Ответ 4

Просто добавьте это в свой AndroidManifest.xml внутри <manifest>:

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

Ответ 5

Google Play ограничивает использование разрешений высокого риска или конфиденциальных, включая группы разрешений SMS или Журнал вызовов. Короче говоря, даже если вы спросите разрешение во время выполнения, есть большая вероятность, что ваше приложение не будет разрешено в Google Play.

Вы можете подать заявку на исключение, хотя. Google Play рассмотрит запрос и предоставит исключения в каждом конкретном случае. Критерии для разрешения исключения упомянуты здесь.