5

Chcę sprawdzić, jak działa nowy model uprawnień, więc w ustawieniach aplikacji wyłączam Contacts. Potem przejdź do aplikacji i spróbować odczytać Contacts i ... to trochę działa:Android 6.0 (Marshmallow) uprawnienie READ_CONTACTS zezwala na odczytanie nazwy kontaktu, gdy odmówiono zgody.

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 
} 
  • jestem w stanie odczytać nazwę kontaktu
  • gdy próbuję odczytać numer kontaktowy za SecurityException jest wyrzucane

java.lang.SecurityException: Odmowa zgody: odczyt com.android.providers.contacts.HtcContactsProvider2 URI zawartość: //com.android.contacts/data/phones od PID = 20123, UID = 10593 wymaga androida. pozwolenie. READ_CONTACTS lub grantUriPermission()

Dlaczego tak jest?

Powiązane rzeczy: Contact data leakage via pick activities

+1

pamiętać, że nie używasz ContactsContract z Google, jak widać, widzimy, że masz dostęp com.android.providers.contacts.HtcContractsProvider, może HTC ma problem z sprawdzaniem poprawności. Moja sugestia polegałaby na sprawdzeniu urządzenia AOSP i sprawdzeniu, czy to samo jest prawdą. Jeśli nie jest to prawda, oznacza to, że jest to problem z wyciekiem uprawnień wewnątrz HTC. Jeśli są takie same, brzmi to jak problem z AOSP. – JoxTraex

+0

Powtarza się również na Nexusie. –

Odpowiedz

14

Android prawoślazu ma nowy system uprawnień. Musisz żądać uprawnień w czasie wykonywania. http://developer.android.com/training/permissions/requesting.html.

Przykład:

@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 
    } 
} 
+0

Proszę uważniej przeczytać moje pytanie. –

+0

oh przepraszam, myślałem, że chcesz rozwiązania. –

+0

Czy powinien istnieć jakiś kod dodany po komentarzu "// Pokaż ekspansję ..."? –

1
@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 
     } 
    } 
+0

zawsze przechodzę do "Toast.makeText (this," No Permissions ", Toast.LENGTH_SHORT) .show();" i nie pytaj o pozwolenie –