AndroidManifest.xmle
WRITE_EXTERNAL_STORAGE,
MOUNT_UNMOUNT_FILESYSTEMS,
READ_EXTERNAL_STORAGEdahil olmak üzere
uses-permission` ekledim.
Uygulamamı Nexus5'te (Android 6.0) çalıştırmaya çalıştığımda, aşağıdaki gibi bir istisna attı:
java.io.IOException: open başarısız oldu: EACCES (İzin reddedildi)`
Ve başka bir Android telefon denedim (Android 5.1), her şey yolundaydı. İşte kod:
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
currentPhotoPath = image.getAbsolutePath();
return image;
}
Android 6.0'ın izin konusunda farkı var mı?
Android, Android 6.0 (Marshmallow) için yeni izin modeli ekledi.
Bu yüzden Çalışma Zamanı İzni
ni kontrol etmeniz gerekir:
**Çalışma Zamanı İzinleri Nedir?
Android 6.0 Marshmallow ile Google, kullanıcıların bir uygulamanın neden belirli izinleri talep ediyor olabileceğini daha iyi anlamalarını sağlayan yeni bir izin modeli sundu. Kullanıcının yükleme sırasında tüm izinleri körü körüne kabul etmesi yerine, artık kullanıcıdan uygulama kullanımı sırasında gerekli hale geldikçe izinleri kabul etmesi isteniyor.
**Yeni Model Ne Zaman Uygulanmalı?
siz uygulamanızda 23. sürümü hedeflemeyi seçene kadar tam destek gerektirmez. Sürüm 22 veya altını hedefliyorsanız, uygulamanız Marshmallow'un altında bir işletim sistemi çalıştıran herhangi bir cihazda olduğu gibi yükleme sırasında tüm izinleri talep edecektir.
Bu bilgi buradan alınmıştır:
Lütfen bu bağlantıdan nasıl uygulanacağını kontrol edin:
Android 6'da (Marshmallow)**, kullanıcı yükleme sırasında tüm izinlerinizi kabul etmiş olsa bile, daha sonra bu izinlerden bazılarını sizden almaya karar verebilir.
Hızlı çözüm ama tavsiye edilmez: belki gradledaki
targetSdkVersionı
22` olarak değiştirirseniz, sorun çözülecektir.
Nasıl Uygulanır? (En İyi Uygulamalar)
Öncelikle kullanıcının cihazının Marshmallow cihazı olup olmadığını belirleyin:
private boolean shouldAskPermission(){
return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1);
}
Eğer shouldAskPermission()
return true
ise, ihtiyacınız olan izni isteyin:
String[] perms = {"android.permission.WRITE_EXTERNAL_STORAGE"};
int permsRequestCode = 200;
requestPermissions(perms, permsRequestCode);
RequestPermissions(String[] permissions, int requestCode);` yöntemi, Android Activity sınıfının içinde bulunan genel bir yöntemdir.
Talebinizin sonuçlarını aşağıda gösterildiği gibi onRequestPermissionResult yönteminde alacaksınız:
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
Vaka 200:
boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
Mola;
}
}
Sonuçları aldıktan sonra, bunları uygun şekilde ele almanız gerekecektir.
Önerilen İzin Akışı:
Daha Fazla Bilgi:
Marshmallow cihazı olan bir kullanıcı artık uygulama ayarları aracılığıyla tehlikeli izinleri iptal edebilecek
Android bazı izinleri "tehlikeli" ve bazı izinleri "normal" olarak tanımlar. Her ikisi de uygulamanızın manifestosunda gereklidir, ancak yalnızca tehlikeli izinler bir çalışma zamanı isteği gerektirir.
Yeni izin modelini (çalışma zamanı isteği) uygulamamayı seçtiyseniz, izinlerin iptali istenmeyen kullanıcı deneyimlerine ve bazı durumlarda uygulama çökmelerine neden olabilir.
Aşağıdaki tabloda tüm mevcut tehlikeli izinler ve ilgili grupları listelenmektedir:
Kullanıcı bir grup/kategorideki bir izni kabul ederse, tüm grubu kabul etmiş olur!
Kaynak:http://www.captechconsulting.com
Dexter Kütüphanesini Kullanmak:
Dexter]4 kullanabilirsiniz. Çalışma zamanında izin isteme işlemini basitleştiren Android kütüphanesi.
Geriye dönük uyumluluk için ActivityCompat.requestPermissions adresini de kullanabilirsiniz.
Örnek:
private static final int REQUEST_CODE = 0x11;
String[] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE"};
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE); // without sdk version check
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// save file
} else {
Toast.makeText(getApplicationContext(), "PERMISSION_DENIED", Toast.LENGTH_SHORT).show();
}
}
}