Android 10, kullanıcılara dosyaları üzerinde daha fazla kontrol sağlamak ve dosya dağınıklığını sınırlamak amacıyla kapsamlı depolama adlı uygulamalar için yeni bir depolama alanı paradigmasını kullanıma sundu. Kapsamlı depolama, uygulamaların bir cihazın harici depolama alanındaki dosyaları depolama ve dosyalara erişme biçimini değiştirir. Uygulamanızı kapsamlı depolamayı destekleyecek şekilde taşımanıza yardımcı olması için bu kılavuzda açıklanan yaygın depolama alanı kullanım alanlarıyla ilgili en iyi uygulamaları takip edin. Kullanım alanları iki kategoriye ayrılır: medya dosyalarını işleme ve medya olmayan dosyaları işleme.
Android'de dosyaları depolama ve dosyalara erişme hakkında daha fazla bilgi edinmek için depolama alanı eğitimi kılavuzlarına bakın.
Medya dosyalarını işleme
Bu bölümde, medya dosyalarının (video, resim ve ses dosyaları) işlenmesiyle ilgili yaygın kullanım alanlarından bazıları açıklanmakta ve uygulamanızın kullanabileceği üst düzey yaklaşım açıklanmaktadır. Aşağıdaki tabloda bu kullanım alanlarının her biri özetlenmiş ve daha fazla ayrıntı içeren her bir bölüme bağlantı verilmiştir.
Kullanım alanı | Özet |
---|---|
Tüm resim veya video dosyalarını gösterme | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Belirli bir klasördeki resimleri veya videoları gösterme | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Fotoğraflardan konum bilgilerine erişme | Uygulamanız kapsamlı depolama alanı kullanıyorsa bir yaklaşım kullanın. Uygulamanız, kapsamlı depolamayı devre dışı bırakırsa farklı bir yaklaşım kullanın. |
Yeni indirilenler için depolama konumu tanımlama | Uygulamanız kapsamlı depolama alanı kullanıyorsa bir yaklaşım kullanın. Uygulamanız, kapsamlı depolamayı devre dışı bırakırsa farklı bir yaklaşım kullanın. |
Kullanıcı medya dosyalarını bir cihaza aktarma | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Tek bir işlemde birden çok medya dosyasını değiştirme veya silme | Android 11 için tek bir yaklaşım kullanın. Android 10 için kapsamlı depolamayı devre dışı bırakıp bunun yerine Android 9 ve önceki sürümler için olan yaklaşımı kullanın. |
Mevcut tek bir resmi içe aktarma | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Tek bir resim çekin | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Medya dosyalarını diğer uygulamalarla paylaşma | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Belirli bir uygulamayla medya dosyaları paylaşma | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Dosyalara doğrudan dosya yollarını kullanan kod veya kitaplıklardan erişme | Android 11 için tek bir yaklaşım kullanın. Android 10 için kapsamlı depolamayı devre dışı bırakıp bunun yerine Android 9 ve önceki sürümler için olan yaklaşımı kullanın. |
Birden çok klasördeki resim veya video dosyalarını gösterme
query()
API'sini kullanarak bir medya koleksiyonunu sorgulama. Medya dosyalarını filtrelemek veya sıralamak için projection
, selection
,
selectionArgs
ve sortOrder
parametrelerini ayarlayın.
Belirli bir klasördeki resimleri veya videoları gösterme
Şu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde açıklanan en iyi uygulamaları izleyerek
READ_EXTERNAL_STORAGE
iznini isteyin. - Medya dosyalarını
MediaColumns.DATA
değerine göre alın. Bu değer, diskteki medya öğesinin mutlak dosya sistemi yolunu içerir.
Not: Mevcut bir medya dosyasına eriştiğinizde, mantığınızda DATA
sütununun değerini kullanabilirsiniz. Bunun nedeni, bu değerin geçerli bir dosya yoluna sahip olmasıdır.
Ancak dosyanın her zaman kullanılabilir olduğunu varsaymayın. Oluşabilecek dosya tabanlı G/Ç hatalarını ele almaya hazır olun.
Öte yandan, bir medya dosyasını oluşturmak veya güncellemek için DATA
sütununu kullanmayın. Bunun yerine, DISPLAY_NAME
ve RELATIVE_PATH
sütunlarını kullanın.
Fotoğraflardan konum bilgilerine erişme
Uygulamanız kapsamlı depolama alanı kullanıyorsa medya depolama rehberinin Fotoğraflardaki konum bilgileri bölümündeki adımları uygulayın.
kullanılarak erişilen resimlerdeki çıkartılmamış konum bilgilerini okumak içinACCESS_MEDIA_LOCATION
izni olması gerekir.
Yeni indirilenler için depolama konumu tanımla
Uygulamanız kapsamlı depolamayı kullanıyorsa indirdiğiniz medya dosyalarını depolamayı seçtiğiniz konuma dikkat edin.
Başka uygulamaların dosyalara erişmesi gerekiyorsa indirmeler veya doküman koleksiyonları için iyi tanımlanmış medya koleksiyonları kullanmayı düşünebilirsiniz.
Android 11 ve sonraki sürümlerde harici uygulamaya özgü dizininizin içindeki dosyalara, bu dosyaları getirmek için DownloadManager
kullanıyor olsanız bile diğer uygulamalar erişemez.
Kullanıcının medya dosyalarını bir cihaza aktarın
Kullanıcı medya dosyalarını depolamak için uygun bir varsayılan konum tanımlayın:
- Kullanıcıların, uygulamaya özel depolama alanı veya paylaşılan depolama alanı kullanarak medya dosyalarının diğer uygulamalar tarafından okunup okunamayacağını seçmesine izin verin.
- Kullanıcıların uygulamaya özel dizinlerden, daha genel olarak erişilebilir bir konuma dosya aktarmasına izin verin. Medya dosyalarını cihazın galerisine aktarmak için MediaStore'un resim, video ve ses koleksiyonlarını kullanın.
Tek bir işlemde birden çok medya dosyasını değiştirme veya silme
Uygulamanızın üzerinde çalıştığı Android sürümlerini temel alan bir mantık ekleyin.
Android 11'de çalıştırma
Şu yaklaşımı kullanın:
MediaStore.createWriteRequest()
veyaMediaStore.createTrashRequest()
kullanarak uygulamanızın yazma ya da silme isteği için bekleyen bir niyet oluşturun. Ardından bu amacı çağırarak kullanıcıdan dosya grubunu düzenleme izni isteyin.Kullanıcının yanıtını değerlendirin:
- İzin verildiyse değiştirme veya silme işlemiyle devam edin.
- İzin verilmediyse kullanıcıya uygulamanızdaki özelliğin neden bu izne ihtiyaç duyduğunu açıklayın.
Android 11 ve sonraki sürümlerde kullanılabilen bu yöntemleri kullanarak medya dosyası gruplarını nasıl yöneteceğiniz hakkında daha fazla bilgi edinin.
Android 10'da çalışıyor
Uygulamanız Android 10'u (API düzeyi 29) hedefliyorsa kapsamlı depolamayı devre dışı bırakın ve bu işlemi gerçekleştirmek için Android 9 ve önceki sürümler için yaklaşımı kullanmaya devam edin.
Android 9 veya önceki bir sürümde çalışma
Şu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde açıklanan en iyi uygulamaları izleyerek
WRITE_EXTERNAL_STORAGE
iznini isteyin. - Medya dosyalarını değiştirmek veya silmek için
MediaStore
API'yi kullanın.
Zaten var olan tek bir resmi içe aktarın
Halihazırda mevcut olan tek bir resmi içe aktarmak istediğinizde (örneğin, bir kullanıcı profilinin fotoğrafı olarak kullanmak amacıyla) uygulamanız işlem için kendi kullanıcı arayüzünü veya sistem seçiciyi kullanabilir.
Kendi kullanıcı arayüzünüzü sunun
Şu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde açıklanan en iyi uygulamaları izleyerek
READ_EXTERNAL_STORAGE
iznini isteyin. - Bir medya koleksiyonunu sorgulamak için
query()
API'sini kullanın. - Sonuçları, uygulamanızın özel kullanıcı arayüzünde görüntüleyin.
Sistem seçiciyi kullanma
Kullanıcıdan içe aktarılacak bir resim seçmesini isteyen ACTION_GET_CONTENT
amacını kullanın.
Sistem seçicinin, aralarından seçim yapması için kullanıcıya sunduğu resim türlerini filtrelemek istiyorsanız setType()
veya EXTRA_MIME_TYPES
kullanabilirsiniz.
Tek bir resim çekin
Uygulamanızda kullanmak üzere tek bir resim çekmek istediğinizde (örneğin, bir kullanıcı profilinin fotoğrafı olarak kullanmak için) kullanıcıdan cihazın kamerasını kullanarak bir fotoğraf çekmesini istemek için ACTION_IMAGE_CAPTURE
amacından yararlanın. Sistem, çekilen fotoğrafı MediaStore.Images
tablosunda depolar.
Medya dosyalarını diğer uygulamalarla paylaşma
Kayıtları doğrudan MediaStore'a eklemek için insert()
yöntemini kullanın. Daha fazla bilgi için medya depolama rehberinin Öğe ekleme bölümüne bakın.
Belirli bir uygulamayla medya dosyaları paylaşma
Dosya paylaşımını ayarlama kılavuzunda açıklandığı gibi Android FileProvider
bileşenini kullanın.
Dosyalara, doğrudan dosya yollarını kullanan kod veya kitaplıklardan erişme
Uygulamanızın üzerinde çalıştığı Android sürümlerini temel alan bir mantık ekleyin.
Android 11'de çalıştırma
Şu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde açıklanan en iyi uygulamaları izleyerek
READ_EXTERNAL_STORAGE
iznini isteyin. - Dosyalara doğrudan dosya yollarını kullanarak erişin.
Daha fazla bilgi için doğrudan dosya yollarını kullanarak medya dosyalarını açma ile ilgili bölüme bakın.
Android 10'da çalışıyor
Uygulamanız Android 10'u (API düzeyi 29) hedefliyorsa kapsamlı depolamayı devre dışı bırakın ve bu işlemi gerçekleştirmek için Android 9 ve önceki sürümler için yaklaşımı kullanmaya devam edin.
Android 9 veya önceki bir sürümde çalışma
Şu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde açıklanan en iyi uygulamaları izleyerek
WRITE_EXTERNAL_STORAGE
iznini isteyin. - Dosyalara doğrudan dosya yollarını kullanarak erişin.
Medya dışındaki dosyaları işleme
Bu bölümde, medya harici dosyaların işlenmesiyle ilgili yaygın kullanım alanlarından bazıları ve uygulamanızın kullanabileceği üst düzey yaklaşım açıklanmaktadır. Aşağıdaki tabloda bu kullanım alanlarının her biri özetlenmiş ve daha fazla ayrıntı içeren bölümlerin bağlantıları verilmiştir.
Kullanım alanı | Özet |
---|---|
Doküman dosyası açma | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
İkincil depolama birimlerindeki dosyalara yazma | Android 11 için tek bir yaklaşım kullanın. Android'in önceki sürümleri için farklı bir yaklaşım kullanın. |
Eski depolama konumundaki mevcut dosyaları taşıyın | Mümkün olduğunda dosyalarınızı kapsamlı depolama alanına taşıyın. Gerektiğinde Android 10 için kapsamlı depolamayı devre dışı bırakın. |
Diğer uygulamalarla içerik paylaşma | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Medya dışı dosyaları önbelleğe alma | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Medya dışındaki dosyaları bir cihaza aktarma | Uygulamanız kapsamlı depolama alanı kullanıyorsa bir yaklaşım kullanın. Uygulamanız, kapsamlı depolamayı devre dışı bırakırsa farklı bir yaklaşım kullanın. |
Doküman dosyası aç
Kullanıcıdan sistem seçiciyi kullanarak açacak bir dosya seçmesini istemek için ACTION_OPEN_DOCUMENT
amacından yararlanın. Sistem seçicinin, aralarından seçim yapması için kullanıcıya sunacağı dosya türlerini filtrelemek istiyorsanız setType()
veya EXTRA_MIME_TYPES
aracını kullanabilirsiniz.
Örneğin, aşağıdaki kodu kullanarak tüm PDF, ODT ve TXT dosyalarını bulabilirsiniz:
Kotlin
startActivityForResult( Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "*/*" putExtra(Intent.EXTRA_MIME_TYPES, arrayOf( "application/pdf", // .pdf "application/vnd.oasis.opendocument.text", // .odt "text/plain" // .txt )) }, REQUEST_CODE )
Java
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("*/*"); intent.putExtra(Intent.EXTRA_MIME_TYPES, new String[] { "application/pdf", // .pdf "application/vnd.oasis.opendocument.text", // .odt "text/plain" // .txt }); startActivityForResult(intent, REQUEST_CODE);
İkincil depolama birimlerindeki dosyalara yazma
İkincil depolama birimleri SD kartları içerir. Belirli bir depolama hacmiyle ilgili bilgilere StorageVolume
sınıfını kullanarak erişebilirsiniz.
Uygulamanızın üzerinde çalıştığı Android sürümünü temel alan bir mantık ekleyin.
Android 11'de çalıştırma
Şu yaklaşımı kullanın:
- Kapsamlı depolama modelini kullanın.
- Android 10 (API düzeyi 29) veya önceki sürümleri hedefleyin.
WRITE_EXTERNAL_STORAGE
iznini beyan edin.- Aşağıdaki erişim türlerinden birini gerçekleştirin:
MediaStore
API'yi kullanarak dosya erişimi.File
veyafopen()
gibi API'ler kullanarak doğrudan dosya yolu erişimi.
Eski sürümlerde çalışıyor
Kullanıcıların, uygulamanızın dosyayı yazabileceği ikincil bir depolama biriminde konum seçmesine olanak tanıyan Depolama Erişimi Çerçevesi'ni kullanın.
Eski bir depolama konumundaki mevcut dosyaları taşıyın
Bir dizin, uygulamaya özel bir dizin veya herkese açık bir paylaşılan dizin değilse eski depolama konumu olarak kabul edilir. Uygulamanız eski bir depolama konumunda dosya oluşturuyor veya kullanıyorsa uygulamanızın dosyalarını kapsamlı depolama ile erişilebilen konumlara taşımanızı ve kapsamlı depolama alanındaki dosyalarla çalışmak için gerekli uygulama değişikliklerini yapmanızı öneririz.
Veri taşıma için eski depolama konumuna erişimi koruma
Uygulama dosyalarını kapsamlı depolamayla erişilebilen konumlara taşıyabilmesi için uygulamanızın eski depolama konumuna erişimini koruması gerekir. Kullanmanız gereken yaklaşım, uygulamanızın hedef API seviyesine bağlıdır.
Uygulamanız Android 11'i hedefliyorsa
Eski depolama modelini korumak için
preserveLegacyExternalStorage
işaretinitrue
olarak ayarlayın. Böylece uygulamanız, uygulamanızın Android 11'i hedefleyen yeni sürümüne geçtiğinde kullanıcıların verilerini taşıyabilir.Uygulamanızın Android 10 cihazlarda eski depolama alanındaki dosyalarınıza erişmeye devam edebilmesi için kapsamlı depolama alanını devre dışı bırakmaya devam edin.
Uygulamanız Android 10'u hedefliyorsa
Uygulamanızın Android sürümlerindeki davranışını sürdürmeyi kolaylaştırmak için kapsamlı depolamayı devre dışı bırakın.
Uygulama verilerini taşı
Uygulamanız taşınmaya hazır olduğunda aşağıdaki yaklaşımı kullanın:
- Android 10 veya önceki bir sürümü hedefleyin.
- Uygulamanızın, taşımanız gereken dosyalara erişebilmesi için kapsamlı depolamayı devre dışı bırakın.
-
Dosyaları
/sdcard/
altındaki mevcut konumlarından kapsamlı depolama ile erişilebilen bir konuma taşımak içinFile
API'yi kullanan kodu dağıtın:- Tüm gizli uygulama dosyalarını,
getExternalFilesDir()
yöntemi tarafından döndürülen dizine taşıyın. - Medya dışındaki paylaşılan tüm dosyaları
Downloads/
dizininin uygulamaya özel bir alt dizinine taşıyın.
- Tüm gizli uygulama dosyalarını,
- Uygulamanızın eski depolama dizinlerini
/sdcard/
dizininden kaldırın.
Kullanıcılar uygulamanızın yeni sürümünü yükledikten sonra cihazlarında veri taşıma işlemini tamamlar. Bir analiz etkinliği oluşturarak kullanıcı tabanınız genelinde taşıma sürecini izleyebilirsiniz.
Kullanıcılar verilerini taşıdıktan sonra, Android 11'i hedeflediğiniz uygulamanızda başka bir güncelleme yayınlayın.
Diğer uygulamalarla içerik paylaşma
Uygulamanızın dosyalarını tek bir uygulamayla paylaşmak için FileProvider
kullanın. Tüm uygulamalar arasında dosya paylaşması gereken uygulamalar söz konusu olduğunda her uygulama için bir içerik sağlayıcı kullanmanızı ve koleksiyona eklenen uygulamalar eklendikçe verileri senkronize etmenizi öneririz.
Medya olmayan dosyaları önbelleğe al
Kullanmanız gereken yaklaşım, önbelleğe almanız gereken dosyaların türüne bağlıdır.
- Hassas bilgiler içeren küçük dosyalar veya dosyalar:
Context#getCacheDir()
kullanın. - Hassas bilgiler içermeyen büyük dosyalar veya dosyalar:
Context#getExternalCacheDir()
kullanın.
Medya dışındaki dosyaları bir cihaza aktarın
Medya harici dosyaları depolamak için uygun bir varsayılan konum tanımlayın. Kullanıcıların uygulamaya özel dizinlerden, daha genel olarak erişilebilir bir konuma dosya aktarmasına izin verin. Medya dışındaki dosyaları cihaza aktarmak için MediaStore'un indirilenler veya doküman koleksiyonlarını kullanın.
Kapsamlı depolama geçici olarak devre dışı bırakıldı
Uygulamanız, kapsamlı depolamayla tam olarak uyumlu hale gelmeden önce, hem testlerinizde hem de üretim uygulamanızda geçici olarak kapsam dışında kalmayı seçebilirsiniz.
Testlerinizde devre dışı bırakma
Android 10 (API düzeyi 29) ve sonraki sürümlerde uygulamanızın testleri varsayılan olarak bir depolama korumalı alanında çalıştırılır. Bu korumalı alan, uygulamanızın uygulamaya özel dizin dışındaki ve herkese açık olarak paylaşılan dizinler dışındaki dosyalara erişmesini engeller.
Bir test ana makine için dosyalar (ör. ekran görüntüleri, hata ayıklama verileri, kapsam verileri veya performans metrikleri) oluşturursa bu dosyaları global dizinlere yazabilirsiniz. Bunu yapmak için am instrument
yöntemini çağıran ilgili bant genişliğine aşağıdaki işareti ekleyin:
-e no-isolated-storage 1
Bu işaret, donatılmış test durumunun tüm davranışını etkiler ve çağrılan tüm test kodunu etkiler. Bu nedenle, bu işareti kullandığınızda uygulamanızın kapsamlı depolama ile uyumluluğunu doğrulayamazsınız. Test çıkışı için bunun yerine kabuk tarafından okunabilen uygulama kapsamlı depolama alanına yazmak daha iyidir. Daha sonra, bu uygulama kapsamlı
dizini alabilirsiniz. Hangi dizinden veri çekileceğini belirlemek için getExternalMediaDirs()
çağrısı yapın.
Üretim uygulamanızda devre dışı bırakma
Uygulamanız Android 10 (API düzeyi 29) veya önceki sürümleri hedefliyorsa üretim uygulamanızda kapsamlı depolamayı geçici olarak devre dışı bırakabilirsiniz. Ancak Android 10'u hedeflerseniz uygulamanızın manifest dosyasında requestLegacyExternalStorage
değerini true
olarak ayarlamanız gerekir:
<manifest ... > <!-- This attribute is "false" by default on apps targeting Android 10. --> <application android:requestLegacyExternalStorage="true" ... > ... </application> </manifest>
Android 10 veya önceki sürümleri hedefleyen bir uygulamanın kapsamlı depolamayı kullanırken nasıl davranacağını test etmek için requestLegacyExternalStorage
değerini false
olarak ayarlayarak davranışı etkinleştirebilirsiniz. Testinizi Android 11 çalıştıran bir cihazda yapıyorsanız uygulama uyumluluğu işaretlerini kullanarak uygulamanızın davranışını kapsamlı depolama ile veya kapsamlı depolama olmadan test edebilirsiniz.
Ek kaynaklar
Android depolama alanı hakkında daha fazla bilgi için aşağıdaki materyalleri inceleyin: