Android 10, kullanıcılara dosyalarıyla ilgili daha fazla kontrol imkanı sunmak ve dosya karmaşasını sınırlamak için uygulamalara kapsamlı depolama adı verilen yeni bir depolama paradigması getirdi. Kapsamlı depolama alanı, uygulamaların cihazın harici depolama alanındaki dosyaları depolama ve bu dosyalara erişme şeklini değiştirir. Uygulamanızı, kapsamlı depolama alanını destekleyen bir sürüme taşımanıza yardımcı olması için bu kılavuzda açıklanan yaygın depolama alanı kullanım alanlarına yönelik en iyi uygulamaları takip edin. Kullanım alanları medya dosyalarını işleme ve medya dışı dosyaları işleme olmak üzere iki kategoriye ayrılır.
Uygulamanız çoğu durumda, diğer uygulamaların erişmesi gerekmeyen veya erişmemesi gereken dosyalar oluşturur. Sistem, bu tür dosyaları yönetmek için uygulamaya özel depolama yerleri sağlar.
Android'de dosyaların nasıl depolanacağı ve bunlara nasıl erişileceği hakkında daha fazla bilgi edinmek için depolama alanı eğitim kılavuzlarına göz atın.
Medya dosyalarını işleme
Bu bölümde, medya dosyalarını (video, resim ve ses dosyaları) işlemeyle ilgili bazı yaygın kullanım alanları 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ştir ve daha ayrıntılı bilgi içeren bölümlerin bağlantıları 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ğraflardaki konum bilgilerine erişme | Uygulamanız sınırlı depolama alanı kullanıyorsa tek bir yaklaşım kullanın. Uygulamanız sınırlı depolama alanını devre dışı bırakırsa farklı bir yaklaşım kullanın. |
Yeni indirmelerin depolama konumunu tanımlama | Uygulamanız sınırlı depolama alanı kullanıyorsa tek bir yaklaşım kullanın. Uygulamanız sınırlı depolama alanını 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 fazla medya dosyasını değiştirme veya silme | Android 11 için tek bir yaklaşım kullanın. Android 10 için kapsamlı depolama alanını devre dışı bırakın ve bunun yerine Android 9 ve önceki sürümler için 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 resim çekme | 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. |
Medya dosyalarını belirli bir uygulamayla paylaşma | Android'in tüm sürümleri için aynı yaklaşımı kullanın. |
Doğrudan dosya yollarını kullanan kod veya kitaplıklardan dosyalara erişme | Android 11 için tek bir yaklaşım kullanın. Android 10 için kapsamlı depolama alanını devre dışı bırakın ve bunun yerine Android 9 ve önceki sürümler için yaklaşımı kullanın. |
Birden fazla klasördeki resim veya video dosyalarını gösterme
query()
API'sini kullanarak bir medya koleksiyonunu sorgulayabilirsiniz. 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
Bu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamalara uyarak
READ_EXTERNAL_STORAGE
iznine başvurun. - Diskteki medya öğesinin mutlak dosya sistemi yolunu içeren
MediaColumns.DATA
değerine göre medya dosyalarını alın.
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ılabileceğini varsaymayın. Oluşabilecek dosya tabanlı G/Ç hatalarını gidermeye hazır olun.
Öte yandan, medya dosyası 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ğraflardaki konum bilgilerine erişme
Uygulamanız kapsamlı depolama alanı kullanıyorsa medya depolama alanı kılavuzunun Fotoğraflardaki konum bilgileri bölümündeki adımları uygulayın.
Yeni indirmeler için depolama yerini tanımlama
Uygulamanız kapsamlı depolama alanı kullanıyorsa indirdiğiniz medya dosyalarını depolamak için seçtiğiniz konuma dikkat edin.
Diğer uygulamalar dosyalara erişmek istiyorsa indirmeler veya doküman koleksiyonları için iyi tanımlanmış medya koleksiyonları kullanmayı deneyin.
Android 11 ve sonraki sürümlerde, bu dosyaları almak için DownloadManager
'u kullansanız bile harici uygulamaya özel dizininizdeki dosyalara diğer uygulamalar erişemez.
Kullanıcı medya dosyalarını bir cihaza aktarma
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ı diğer uygulamalar tarafından okunabilir hale getirip getirmeyeceklerini seçmelerine izin verin.
- Kullanıcıların uygulamaya özgü dizinlerdeki dosyaları daha genel erişilebilir bir konuma 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 fazla medya dosyasını değiştirme veya silme
Uygulamanızın çalıştığı Android sürümlerine göre mantık ekleyin.
Android 11 çalıştıran cihazlar
Bu yaklaşımı kullanın:
MediaStore.createWriteRequest()
veyaMediaStore.createTrashRequest()
kullanarak uygulamanızın yazma veya silme isteği için bekleyen bir intent oluşturun ve ardından bu intent'i çağırarak kullanıcıdan bir dosya grubunu düzenleme izni isteyin.Kullanıcının yanıtını değerlendirin:
- İzin verildiyse değiştirme veya silme işlemine devam edin.
- İzin verilmediyse kullanıcıya, uygulamanızdaki özelliğin neden izine ihtiyacı olduğunu açıklayın.
Android 11 ve sonraki sürümlerde kullanılabilen bu yöntemleri kullanarak medya dosyası gruplarını yönetme hakkında daha fazla bilgi edinin.
Android 10 çalıştıran cihazlar
Uygulamanız Android 10'u (API düzeyi 29) hedefliyorsa kapsamlı depolama alanını devre dışı bırakın ve bu işlemi gerçekleştirmek için Android 9 ve önceki sürümlere yönelik yaklaşımı kullanmaya devam edin.
Android 9 veya önceki sürümleri çalıştıran cihazlar
Bu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamalara uyarak
WRITE_EXTERNAL_STORAGE
iznine başvurun. - Medya dosyalarını değiştirmek veya silmek için
MediaStore
API'yi kullanın.
Mevcut tek bir resmi içe aktarma
Mevcut tek bir resmi içe aktarmak istediğinizde (örneğin, kullanıcı profilinin fotoğrafı olarak kullanmak için) uygulamanız bu işlem için kendi kullanıcı arayüzünü veya sistem seçiciyi kullanabilir.
Kendi kullanıcı arayüzünüzü sunma
Bu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamalara uyarak
READ_EXTERNAL_STORAGE
iznine başvurun. - Medya koleksiyonunu sorgulamak için
query()
API'yi kullanın. - Sonuçları uygulamanızın özel kullanıcı arayüzünde gösterin.
Sistem seçiciyi kullanma
Kullanıcıdan içe aktarılacak bir resim seçmesini isteyen ACTION_GET_CONTENT
intent'ini kullanın.
Sistem seçicinin kullanıcıya sunacağı resim türlerini filtrelemek istiyorsanız setType()
veya EXTRA_MIME_TYPES
öğesini kullanabilirsiniz.
Tek bir resim çekme
Uygulamanızda kullanmak üzere tek bir resim çekmek istediğinizde (örneğin, kullanıcının profilinin fotoğrafı olarak kullanmak için) kullanıcıdan cihazın kamerasını kullanarak fotoğraf çekmesini istemek için ACTION_IMAGE_CAPTURE
intent'ini kullanı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 alanı kılavuzunun Öğe ekleme bölümüne bakın.
Medya dosyalarını belirli bir uygulamayla paylaşma
Dosya paylaşımını ayarlama kılavuzunda açıklandığı şekilde Android FileProvider
bileşenini kullanın.
Doğrudan dosya yollarını kullanan kod veya kitaplıklardan dosyalara erişme
Uygulamanızın çalıştığı Android sürümlerine göre mantık ekleyin.
Android 11 çalıştıran cihazlar
Bu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamalara uyarak
READ_EXTERNAL_STORAGE
iznine başvurun. - Dosyalara doğrudan dosya yollarını kullanarak erişebilirsiniz.
Daha fazla bilgi için doğrudan dosya yollarını kullanarak medya dosyalarını açma hakkındaki bölüme bakın.
Android 10 çalıştıran cihazlar
Uygulamanız Android 10'u (API düzeyi 29) hedefliyorsa kapsamlı depolama alanını devre dışı bırakın ve bu işlemi gerçekleştirmek için Android 9 ve önceki sürümlere yönelik yaklaşımı kullanmaya devam edin.
Android 9 veya önceki sürümleri çalıştıran cihazlar
Bu yaklaşımı kullanın:
- Uygulama İzinleri İsteme bölümünde belirtilen en iyi uygulamalara uyarak
WRITE_EXTERNAL_STORAGE
iznine başvurun. - Dosyalara doğrudan dosya yollarını kullanarak erişebilirsiniz.
Medya dışı dosyaları işleme
Bu bölümde, medya dışı dosyaları işlemeyle 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ştir. Ayrıca, daha fazla ayrıntı içeren bölümlerin bağlantıları da 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. |
Mevcut dosyaları eski bir depolama alanından taşıma | Mümkün olduğunda dosyalarınızı kapsamlı depolamaya taşıyın. Gerekirse Android 10 için kapsamlı depolama alanını 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ışı dosyaları bir cihaza aktarma | Uygulamanız sınırlı depolama alanı kullanıyorsa tek bir yaklaşım kullanın. Uygulamanız sınırlı depolama alanını devre dışı bırakırsa farklı bir yaklaşım kullanın. |
Doküman dosyasını açma
Kullanıcıdan sistem seçiciyi kullanarak açılacak bir dosya seçmesini istemek için ACTION_OPEN_DOCUMENT
intent'ini kullanın. Sistem seçicinin kullanıcıya sunacağı dosya türlerini filtrelemek istiyorsanız setType()
veya EXTRA_MIME_TYPES
öğesini 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. StorageVolume
sınıfını kullanarak belirli bir depolama alanı hacmi hakkındaki bilgilere erişebilirsiniz.
Uygulamanızın çalıştığı Android sürümüne göre mantık ekleyin.
Android 11 çalıştıran cihazlar
Bu yaklaşımı kullanın:
- Kapsamlı depolama alanı 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şimiFile
veyafopen()
gibi API'ler kullanılarak doğrudan dosya yolu erişimi.
Eski sürümlerde çalıştırma
Kullanıcıların, uygulamanızın dosyayı yazabileceği ikincil depolama birimi konumunu seçmesine olanak tanıyan Depolama Alanı Erişim Çerçevesi'ni kullanın.
Mevcut dosyaları eski bir depolama konumundan taşıma
Uygulamaya özel bir dizin veya herkese açık bir ortak dizin değilse dizin eski depolama alanı olarak kabul edilir. Uygulamanız eski bir depolama alanında 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 alanına erişimi sürdürme
Uygulama dosyalarını, kapsamlı depolama alanıyla erişilebilen konumlara taşımak için uygulamanızın eski depolama konumuna erişmeye devam etmesi gerekir. Kullanmanız gereken yaklaşım, uygulamanızın hedef API düzeyine bağlıdır.
Uygulamanız Android 11'i hedefliyorsa
Uygulamanızın, kullanıcılar uygulamanızın Android 11'i hedefleyen yeni sürümüne yükselttiğinde kullanıcı verilerini taşıyabilmesi için
preserveLegacyExternalStorage
işaretinitrue
olarak ayarlayarak eski depolama modelini koruyun.Uygulamanızın Android 10 cihazlardaki 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 davranışını Android sürümleri arasında tutarlı tutmak için kapsamlı depolama alanını devre dışı bırakın.
Uygulama verilerini taşıma
Uygulamanız taşınmaya hazır olduğunda aşağıdaki yaklaşımı kullanın:
- Android 10 veya önceki sürümleri hedefleyin.
- Uygulamanızın taşımanız gereken dosyalara erişebilmesi için kısıtlı depolamayı devre dışı bırakın.
-
Dosyaları
/sdcard/
altındaki mevcut konumlarından, kapsamlı depolama alanıyla erişilebilen bir konuma taşımak içinFile
API'yi kullanan kod dağıtın:- Gizli uygulama dosyalarını
getExternalFilesDir()
yöntemi tarafından döndürülen dizin içine taşıyın. - Paylaşılan medya dışı dosyaları
Downloads/
dizininin uygulamaya özel bir alt dizinine taşıyın.
- Gizli uygulama dosyalarını
- Uygulamanızın eski depolama alanı 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ızdaki taşıma sürecini izleyebilirsiniz.
Kullanıcılar verilerini taşıdıktan sonra uygulamanızda Android 11'i hedeflediğiniz 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ünün dosyalarını birbirine paylaşması gereken uygulamalar için her uygulamada bir içerik sağlayıcı kullanmanızı ve ardından uygulamalar koleksiyona eklendikçe verileri senkronize etmenizi öneririz.
Medya dışı dosyaları önbelleğe alma
Kullanmanız gereken yaklaşım, önbelleğe almanız gereken dosyaların türüne bağlıdır.
- Küçük dosyalar veya hassas bilgiler içeren dosyalar:
Context#getCacheDir()
simgesini kullanın. - Büyük dosyalar veya hassas bilgiler içermeyen dosyalar:
Context#getExternalCacheDir()
seçeneğini kullanın.
Medya dışı dosyaları cihaza aktarma
Medya dışı dosyaları depolamak için uygun bir varsayılan konum tanımlayın. Kullanıcıların uygulamaya özgü dizinlerdeki dosyaları daha genel erişilebilir bir konuma aktarmasına izin verin. Medya dışı dosyaları cihaza aktarmak için MediaStore'un indirilenler veya doküman koleksiyonlarını kullanın.
Uygulamaya özgü dosyaları işleme
Uygulamanız, diğer uygulamaların erişmesi gerekmeyen veya erişmemesi gereken dosyalar oluşturuyorsa bu dosyaları uygulamaya özel depolama konumlarında saklayabilirsiniz.
Dahili depolama alanı dizinleri
Sistem, diğer uygulamaların bu konumlara erişmesini engeller ve Android 10 (API düzeyi 29) ve sonraki sürümlerde bu konumlar şifrelenir. Bu konumlar, yalnızca uygulamanızın erişebileceği hassas verileri depolamak için iyi bir yerdir.
Harici depolama alanı dizinleri
Dahili depolama alanı, uygulamaya özgü dosyaları depolamak için yeterli alan sağlamıyorsa bunun yerine harici depolama alanı kullanabilirsiniz. Uygun izinlere sahip başka bir uygulamanın bu dizinlere erişmesi mümkün olsa da bu dizinlerde depolanan dosyalar yalnızca uygulamanız tarafından kullanılmak üzere tasarlanmıştır.
Android 4.4 (API düzeyi 19) veya sonraki sürümlerde, uygulamanızın harici depolama alanındaki uygulamaya özel dizinlere erişmek için depolama alanıyla ilgili izin istemesi gerekmez.
Kullanıcı uygulamanızı kaldırdığında uygulamaya özel depolama alanına kaydedilen dosyalar kaldırılır. Bu nedenle, kullanıcının uygulamanızdan bağımsız olarak kalmasını beklediği hiçbir şeyi kaydetmek için bu depolama alanını kullanmamalısınız.
Kapsamlı depolama alanını geçici olarak devre dışı bırakma
Uygulamanız kapsamlı depolama alanıyla tam uyumlu hale gelmeden önce hem testlerinizde hem de üretim uygulamanızda bu özelliği geçici olarak devre dışı bırakabilirsiniz.
Testlerinizde kapsam dışında kalma
Android 10 (API düzeyi 29) ve sonraki sürümlerde, uygulamanızın testleri varsayılan olarak bir depolama korumalı alanında çalışır. Bu korumalı alan, uygulamanızın uygulamaya özel dizin ve herkese açık olarak paylaşılan dizinlerin dışındaki dosyalara erişmesini engeller.
Bir test, ana makine için ekran görüntüleri, hata ayıklama verileri, kapsam verileri veya performans metrikleri gibi dosyalar oluşturuyorsa bu dosyaları genel dizinlere yazabilirsiniz. Bunu yapmak için am instrument
'ü çağıran ilgili donanıma aşağıdaki işareti ekleyin:
-e no-isolated-storage 1
Bu işaret, enstrümante testin tüm davranışını ve çağrılan tüm test kodunu etkiler. Bu nedenle, bu işareti kullandığınızda uygulamanızın kapsamlı depolama alanıyla uyumluluğunu doğrulayamazsınız. Test çıkışı için kabuk tarafından okunabilen uygulama kapsamlı depolama alanına yazmak daha iyidir. Ardından, uygulama kapsamlı bu dizini alabilirsiniz. Hangi dizinden veri alınacağını belirlemek için getExternalMediaDirs()
işlevini çağırın.
Üretim uygulamanızda devre dışı bırakma
Uygulamanız Android 10'u (API düzeyi 29) veya önceki sürümleri hedefliyorsa üretim uygulamanızda kapsamlı depolama alanını geçici olarak devre dışı bırakabilirsiniz. Ancak Android 10'u hedefliyorsanız 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ı depolama alanını kullanırken nasıl davrandığını test etmek için requestLegacyExternalStorage
değerini false
olarak ayarlayarak davranışı etkinleştirebilirsiniz. Android 11 çalıştıran bir cihazda test yapıyorsanız uygulamanızın kapsamlı depolama alanı ile veya kapsamlı depolama alanı olmadan davranışını test etmek için uygulama uyumluluk işaretlerini de kullanabilirsiniz.
Ek kaynaklar
Android depolama alanı hakkında daha fazla bilgi için aşağıdaki materyalleri inceleyin: