Android 6.0 Marshmallow sürümünden beri Android, uygulama yükleme ve otomatik güncelleme işlemlerini kolaylaştıran bir izin modeli kullanır. İzinler, uygulama yüklenmeden önce değil, çalışma zamanında istenir. Ayrıca kullanıcılar belirli izinleri reddetmeyi tercih edebilir. Kullanıcılara bu esnekliği sağlamak için, kullanıcı belirli bir izni etkinleştirdiğinde veya devre dışı bıraktığında uygulamanızın beklendiği gibi çalıştığından emin olmanız gerekir.
Google Play hizmetlerinin kendisinde, kullanıcıların uygulamanız tarafından özel olarak istenen izinlerden ayrı olarak reddetmeyi seçebilecekleri çalışma zamanı izinleri bulunur. Google Play Hizmetleri, API'lerini desteklemek için gereken tüm izinleri otomatik olarak alır. Bununla birlikte, uygulamanız yine de çalışma zamanı izinlerini gerekli şekilde kontrol edip istemeli ve bir kullanıcının, uygulamanızın kullandığı bir API için gereken bir izni Google Play Hizmetleri'ni reddettiği durumlarda hataları uygun şekilde ele almalıdır.
Kullanıcının, çalışma zamanının ihtiyaç duyabileceği izinleri ayarlarken beklentilerini yönetmek iyi bir uygulamadır. Aşağıdaki en iyi uygulamalar, olası sorunlardan kaçınmanıza yardımcı olacaktır.
Ön koşullar
AndroidManifest.xml
dosyanızda izinleri beyan etmeniz gerekiyor.
Örneğin:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Yönergeler
API'leri çağırmadan önce izinleri doğrulayın
AndroidManifest.xml
dosyanızda kullanmak istediğiniz API'leri beyan ettikten sonra, API çağırmadan önce gerekli izne sahip olduğunuzdan emin olun. Bu, checkSelfPermission
ActivityCompat
veya ContextCompat
yöntemi kullanılarak yapılabilir.
Çağrı "false" değerini döndürürse bu, izinlerin verilmediği ve izin istemek için requestPermissions
işlevini kullanmanız gerektiği anlamına gelir. Buna verilen yanıt, bir sonraki adımda göreceğiniz geri çağırmada döndürülür.
Örneğin:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
} else {
// permission has been granted, continue as usual
Task<Location> locationResult = LocationServices
.getFusedLocationProviderClient(this /** Context */)
.getLastLocation();
}
İstek izni geri çağırma işlemini uygulayın
Kullanıcı, uygulamanıza ihtiyaç duyduğu izni vermediyse kullanıcıdan bu izni vermesini istemek için requestPermissions
yöntemi çağrılmalıdır. Kullanıcının yanıtı onRequestPermissionsResult
geri çağırmasında yakalanır. Uygulamanız bunu uygulamalı ve istek reddedilebileceği veya iptal edilebileceği için döndürülen değerleri her zaman kontrol etmelidir. Ayrıca, bir defada birden çok izin isteyip kontrol edebilirsiniz. Aşağıdaki örnek, yalnızca tek bir izni kontrol eder.
public void onRequestPermissionsResult(int requestCode,
String[] permissions,
int[] grantResults) {
if (requestCode == REQUEST_LOCATION) {
if(grantResults.length == 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// We can now safely use the API we requested access to
Task<Location> locationResult = LocationServices
.getFusedLocationProviderClient(this /** Context */)
.getLastLocation();
} else {
// Permission was denied or request was cancelled
}
}
}
İzin gerekçesini göster
Uygulamanızın istediği izinler uygulamanın temel özellikleri için gerekiyorsa ve kullanıcı daha önce izin isteğini reddetmişse uygulamanızın izni tekrar istemeden önce ek bir açıklama göstermesi gerekir. Kullanıcıların, iznin neden gerekli olduğunu ve anında faydasını anladıklarında izin verme olasılıkları artar.
Bu durumda, requestPermissions
numaralı telefondan önce shouldShowRequestPermissionRationale
numarasını aramanız gerekir. Doğru döndürülürse izinle ilgili ek bağlam görüntülemek için bazı kullanıcı arayüzü oluşturmanız gerekir.
Örneğin, kodunuz aşağıdaki gibi görünebilir:
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
private static final int REQUEST_LOCATION = 2;
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Display UI and wait for user interaction
} else {
ActivityCompat.requestPermissions(
this, new String[]{Manifest.permission.LOCATION_FINE},
ACCESS_FINE_LOCATION);
}
} else {
// permission has been granted, continue as usual
Task<Location> locationResult = LocationServices
.getFusedLocationProviderClient(this /** Context */)
.getLastLocation();
}
Bağlantı hatalarını işleme
Uygulamanız kullanımdan kaldırılan GoogleApiClient
sürümünü kullanıyorsa connect()
aracını aradığınızda Google Play Hizmetleri, uygulamanın gerekli tüm izinlere sahip olduğunu doğrular. Google Play Hizmetleri'nin ihtiyaç duyduğu izin grupları eksik olduğunda connect()
başarısız olur.
connect()
çağrısı başarısız olursa uygulamanızın bağlantı hatasını doğru şekilde ele aldığından emin olun. Google Play Hizmetleri'nin kendisinde izinler yoksa startResolutionForResult()
yöntemini çağırarak bu izinleri düzeltecek kullanıcı akışını başlatabilirsiniz.
Örneğin:
@Override
public void onConnectionFailed(ConnectionResult result) {
if (mResolvingError) {
// Already attempting to resolve an error.
return;
} else if (result.hasResolution()) {
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}
Daha yeni GoogleApi
tabanlı API çağrıları, kullanıcının izin çözümleme amacını başlatmak için dokunabileceği bir iletişim kutusu (istemci bir Activity
ile örneklendiyse) veya sistem tepsisi bildirimi (istemci bir Context
ile örneklendiyse) görüntüler. Aramalar sıraya alınır ve izin verildikten sonra yeniden denenir.