web-dev-qa-db-ja.com

Android 6.0(Marshmallow)READ_CONTACTS許可により、許可が拒否された場合に連絡先の名前を読み取ることができます

アプリの設定でContactsを無効にするため、新しい許可モデルがどのように機能するかを確認したいと思います。次に、アプリに移動してContactsを読み取ろうとします... ...

try {
    Uri result = data.getData();
    int contentIdx;
    cursor = getContentResolver().query(result, null, null, null, null);
    contentIdx = cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
    if(cursor.moveToFirst()) {
        content = cursor.getInt(contentIdx);
    }

    if(content > 0) {
        contentIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
        if(cursor.moveToFirst()) {
            name = cursor.getString(contentIdx);
        }
        contentIdx = cursor.getColumnIndex(BaseColumns._ID);
        if(cursor.moveToFirst()) {
            content = cursor.getLong(contentIdx);
        }
        cursor = managedQuery(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] { Phone.NUMBER }, Data.CONTACT_ID + "=?", new String[] { String.valueOf(content) }, null);
        if(cursor.moveToFirst()) {
            number = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
        }
    }
} catch (Exception e) {
    //SecurityException
}
  • 連絡先の名前を読むことができます
  • 連絡先の番号を読み取ろうとするとSecurityExceptionがスローされます

Java.lang.SecurityException:許可の拒否:pid = 20123、uid = 10593からのcom.Android.providers.contacts.HtcContactsProvider2 uri content://com.Android.contacts/data/phonesの読み取りにはAndroid.permission.READ_CONTACTS、またはgrantUriPermissionが必要です()

何故ですか?

関連するもの: pickアクティビティを介した連絡先データの漏洩

8

Android Marshmallowには新しい権限システムがあります。実行時に許可を要求する必要があります。 http://developer.Android.com/training/permissions/requesting.html

例:

@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.tv_contact:{
            askForContactPermission();
            break;
        }
    }
 }

private void getContact(){
    Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT);
}

 public void askForContactPermission(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                    Manifest.permission.READ_CONTACTS)) {
                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                builder.setTitle("Contacts access needed");
                builder.setPositiveButton(Android.R.string.ok, null);
                builder.setMessage("please confirm Contacts access");//TODO put real question
                builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @TargetApi(Build.VERSION_CODES.M)
                    @Override
                    public void onDismiss(DialogInterface dialog) {
                        requestPermissions(
                                new String[]
                                        {Manifest.permission.READ_CONTACTS}
                                , PERMISSION_REQUEST_CONTACT);
                    }
                });
                builder.show();
                // 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(getActivity(),
                        new String[]{Manifest.permission.READ_CONTACTS},
                        PERMISSION_REQUEST_CONTACT);

                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        }else{
            getContact();
        }
    }
    else{
        getContact();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CONTACT: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getContact();
                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {
                ToastMaster.showMessage(getActivity(),"No permission for contacts");
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}
25
Maor Hadad
@Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button:{
                askForContactPermission();
                break;
            }
        }
    }

    private void getContact(){
        Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
        while (phones.moveToNext())
        {
            String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            Toast.makeText(getApplicationContext(),name+" "+phoneNumber, Toast.LENGTH_LONG).show();

        }
        phones.close();
    }

    public void askForContactPermission(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

                // Should we show an explanation?
                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                        Manifest.permission.READ_CONTACTS)) {
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle("Contacts access needed");
                    builder.setPositiveButton(Android.R.string.ok, null);
                    builder.setMessage("please confirm Contacts access");//TODO put real question
                    builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @TargetApi(Build.VERSION_CODES.M)
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                            requestPermissions(
                                    new String[]
                                            {Manifest.permission.READ_CONTACTS}
                                    , PERMISSION_REQUEST_CONTACT);
                        }
                    });
                    builder.show();
                    // 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(this,
                            new String[]{Manifest.permission.READ_CONTACTS},
                            PERMISSION_REQUEST_CONTACT);

                    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                    // app-defined int constant. The callback method gets the
                    // result of the request.
                }
            }else{
                getContact();
            }
        }
        else{
            getContact();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CONTACT: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    getContact();
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.

                } else {
                    Toast.makeText(this, "No Permissions ", Toast.LENGTH_SHORT).show();
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

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