2015-10-09 5 views
17

Android Marshmallow'un yeni izin modelini inceliyorum, ancak garip bulduğum bir sorunla karşılaşıyorum.checkSelfPermission, targetSdkVersion ile iptal edilmiş izin için PERMISSION_GRANTED döndürüyor <= 22

targetSdkVersion 22 (şimdiye henüz Android Marshmallow Yeni izin modelini kullanarak değil) sahip bir uygulama

manifest'te READ_CONTACTS izni beyan :

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

ve Intent.ACTION_PICK üzerinden bir kişinin telefon numarasını okumak çalışır:

Intent intent = new Intent(Intent.ACTION_PICK); 
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); 
startActivityForResult(intent, PICK_CONTACT_REQUEST); 

I ADB ile uygulamayı yükledikten sonra izni iptal sonra ContextCompat.checkSelfPermission() yöntemi haladöndürür, hatmi MRA58K olan bir cihaz üzerinde çalışırken, ancak kayıtlara sahip bir imleç döndürülür, çünkü daha sonra kişiler erişirken işlem başarısız olur. Anladığım kadarıyla, eski uygulamanın çökmesini önlemek için varsayılan "retro uyumluluk" stratejisi budur.

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == PICK_CONTACT_REQUEST && resultCode == Activity.RESULT_OK) { 
     Log.i("", "Permission granted: " + (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED)); 
     Uri contactUri = data.getData(); 
     Cursor c = null; 
     try { 
      c = getContentResolver().query(contactUri, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null); 
      if (c != null && c.moveToFirst()) { 
       Log.i("", "got phone number: " + c.getString(0)); 
      } else { 
       Log.w("", "No data received"); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (c != null) { 
       c.close(); 
      } 
     } 
    } else { 
     super.onActivityResult(requestCode, resultCode, data); 
    } 
} 

olmadığını nasıl güvenle algılayabilir açıkça işlemi başlamadan önce izin önce kullanıcı?

Ben de aynı sonucu 22'ye targetSdkVersion ayarı https://github.com/googlesamples/android-RuntimePermissions de resmi Google örneği çalıştı: bu izni kullanıcı tarafından iptal bile verilmiş olduğunu kaydeder, karınca sonra işlem başarısız olur.

teşekkürler;)

+1

target "ContextCompat.checkSelfPermission() yöntemi hala PERMISSION_GRANTED döner" - doğru. 'checkSelfPermission()' 'targetMEDION_GRANTED'' için 'targetSdkVersion' değerinin% 100'ünü 22 ve daha düşük bir değer olarak döndürecektir. "İşlemi gerçekleştirmeden önce kullanıcının açıkça izin almadan önce güvenli bir şekilde nasıl tespit edebilirim?" - Genelde yapamazsın. Durumunuzda, var olduğu bilinen bir şey için (örneğin, adı) sorgu() 'yi deneyebilir ve sıfır sonucu geri alırsanız, iletişim bilgilerine erişemeyeceğinizi biliyorsunuzdur. – CommonsWare

+1

Aklınızda tuttuğunuz tüm kişi, kişi seçtiğinde seçili kişi ile çalışıyorsa, yalnızca seçilen kişi için otomatik olarak erişim sağladığınızdan, Android'in herhangi bir sürümü için "READ_CONTACTS" seçeneğine ihtiyacınız yoktur. . Bu izni tamamen kaldırmayı deneyebilirsiniz, aksi takdirde kullanıcı bunu iptal edebilir. Davanız bazı ilginç etkiler getiriyor; Gelecek hafta ilgili bazı deneyler yapmaya çalışacağım. – CommonsWare

+0

Hmm, bu bana korkunç bir API tasarım seçeneği gibi görünüyor. İşlemi gerçekleştirmeden önce iptal edilmiş bir izni tespit etmenin başka yolu yok mu? Belki AppOps kullanıyor? – Venator85

cevap

11
+1

Bir çekicilik gibi çalışır!Teşekkürler – Venator85

+0

Kullanım durumum biraz farklı (kamera), ama bulduğum şey: 'ContextCompat.checkSelfPermission' yerine' PermissionsChecker.checkSelfPermission' yerine gerçekten izin veriliyor mu kontrol etmek yardımcı olur. Sorun şu ki, bu istek üzerine 'requestPermissions' öğesini tetikliyorsanız ve kullanıcı tıklıyorsa * Deny *, 'onRequestPermissionsResult 'hala grantResults dizisinde' PERMISSION_GRANTED' olacaktır. – TWiStErRob

+0

@TWiStErRob bu durumda, teorik olarak, yalnızca 'PermissionChecker' kullanarak istenen izinlerin verildiğini kontrol edebilirsiniz. Ancak, "targetSDK" 22 (veya daha düşük) kullanırsanız, kullanıcının izne izin vermesi durumunda, uygulama işlemini sonlandırır ve geri aranmanız çağrılmaz. Yani, bunun için düzgün bir şekilde başa çıkmanın tek yolu "targetSDK" ye yükseltme yapmaktır. 23 – Muzikant

0
Yeni izin modellerini kullanmak için

(ve uygulama vardır veya 23'e hedef SDK'yı güncellemeniz gerekir izni) Bu tutmak için hiçbir anlam ifade etmez olmadığını kontrol

+3

Aslında bazı durumlarda anlamlıdır. –