Scoped Storage — bu nədir, fayl idarəetməsi və yaddaşa giriş

Müəllif: IT Sectr Dərc olunub: 2026-07-10 Oxuma vaxtı: 10 dəq

Scoped Storage — Android 10-da (API 29) təqdim edilmiş, proqramların cihazın ümumi yaddaşına ixtiyari girişini məhdudlaşdıran fayl sisteminə giriş modelidir. Google Android Developer Documentation (2024) məlumatına görə, Scoped Storage READ_EXTERNAL_STORAGE və WRITE_EXTERNAL_STORAGE icazələrinin köhnə modelini əvəz edərək, proqramlara yalnız izolyasiya edilmiş qum qutusundakı öz fayllarına və MediaStore vasitəsilə ümumi kolleksiyalara giriş imkanı verir. Bu model istifadəçi məlumatlarının məxfiliyini artırır və proqramlar tərəfindən icazəsiz məlumat toplanmasının qarşısını alır.

Əsas məqamlar

  • Scoped Storage — Android 10+-da ümumi yaddaşın ixtiyari oxunmasını məhdudlaşdıran fayl giriş modeli.
  • Proqram əlavə icazələr olmadan tam girişi olan öz qum qutusuna malikdir.
  • Ümumi fayllara (şəkil, video, audio) giriş üçün MediaStore API istifadə olunur.
  • İxtiyari qovluq və fayllara giriş üçün Storage Access Framework (SAF) istifadə olunur.
  • READ_EXTERNAL_STORAGE və WRITE_EXTERNAL_STORAGE icazələri əksər ssenarilər üçün qüvvəsini itirib.

Android-də Scoped Storage nədir?

Scoped Storage — Android 10-da (API 29) təqdim edilmiş, proqramların cihazın fayl sisteminə giriş üsulunu əsaslı şəkildə dəyişən memarlıq dəyişikliyidir. Ümumi yaddaşa tam giriş əvəzinə, proqram yalnız öz qum qutusuna və MediaStore vasitəsilə müəyyən media fayl kolleksiyalarına giriş əldə edir.

Scoped Storage-dən əvvəl READ_EXTERNAL_STORAGE icazəsi olan istənilən proqram ümumi yaddaşdakı bütün faylları — şəkilləri, sənədləri, yükləmələri, digər proqramların məlumatlarını oxuya bilirdi. Bu, məxfilik riskləri yaradırdı: vicdansız proqramlar istifadəçinin xəbəri olmadan onun haqqında məlumat toplaya bilərdi.

Google I/O 2019 məlumatına görə, Android istifadəçilərinin 65%-dən çoxu proqram seçərkən məlumat məxfiliyini kritik amil hesab edir. Scoped Storage bu tələbə birbaşa cavabdır: hər bir proqram izolyasiya edilmiş mühitdə işləyir və digər proqramların məlumatlarına yalnız istifadəçinin açıq razılığı ilə giriş əldə edir.

Vacib: Android 10-da Scoped Storage isteğe bağlı idi (proqram onu requestLegacyExternalStorage vasitəsilə söndürə bilərdi). Android 11-dən (API 30) başlayaraq, Scoped Storage target SDK-dan asılı olmayaraq bütün proqramlar üçün məcburi oldu.

Scoped Storage nə üçün lazım oldu

Google Scoped Storage-i köhnə fayl giriş modelinin üç fundamental problemini həll etmək üçün təqdim etdi: məxfilik, icazələrin idarə edilməsi və qalıq faylların təmizlənməsi.

Məxfilik problemi

Köhnə modeldə READ_EXTERNAL_STORAGE icazəsi olan proqram bütün ümumi yaddaşı skan edə və istifadəçinin faylları haqqında metadata toplaya bilərdi — fotoşəkillərin coğrafi koordinatları, sənəd adları, qovluq strukturu. Scoped Storage bu imkanı aradan qaldırır: icazəyə malik olsa belə, proqram yalnız özünün yaratdığı faylları və istifadəçinin SAF vasitəsilə açıq seçdiyi faylları görür.

Proqram silindikdə təmizləmə problemi

Scoped Storage-dən əvvəl proqram silindikdən sonra ümumi yaddaşda fayllar qoya bilərdi. Zaman keçdikcə zibil qovluqlar yığılırdı. Scoped Storage bunu həll edir: proqramın qum qutusundakı bütün fayllar proqramla birlikdə silinir, MediaStore vasitəsilə fayllar isə sahibinə malikdir və sistem tərəfindən təmizlənə bilər.

AspektKöhnə model (Legacy)Scoped Storage
Ümumi yaddaşa girişTam (icazə ilə)Yalnız öz qum qutusu
Media fayllarıBirbaşa fayl yoluMediaStore URI vasitəsilə
Başqalarının fayllarıHəmişə əlçatanYalnız SAF vasitəsilə
Silinmədə təmizləməFayllar qalırQum qutusu silinir
İstifadəçi nəzarətiMinimalHər fayl üçün açıq razılıq

Scoped Storage Google-nin Android-də məxfiliyi gücləndirmək üzrə ümumi strategiyasının bir hissəsidir ki, bura həmçinin „yalnız istifadə zamanı” icazələri, kamera və mikrofona giriş göstəriciləri və Privacy Dashboard daxildir.

Proqramın şəxsi qovluğu

Hər Android proqramı Context.getFilesDir() və context.getCacheDir() vasitəsilə əldə edilə bilən öz şəxsi qovluğunu alır. Xarici (paylaşılan) şəxsi qovluğa giriş üçün Context.getExternalFilesDir() istifadə olunur.

Scoped Storage-də proqram heç bir icazə olmadan öz xarici şəxsi qovluğuna tam girişə malikdir. Bu, digər proqramlar üçün əlçatan olmamalı və ya proqramın öz istifadəsi üçün yaratdığı faylları saxlamaq üçün əsas yerdir.

kotlin
import android.os.Environment
import java.io.File
import java.io.IOException

class FileManager {

    fun saveToAppStorage(context: Context, fileName: String, data: ByteArray) {
        val appDir = context.getExternalFilesDir(null)
            ?: return
        val file = File(appDir, fileName)
        file.writeBytes(data)
    }

    fun readFromAppStorage(context: Context, fileName: String): ByteArray? {
        val appDir = context.getExternalFilesDir(null)
            ?: return null
        val file = File(appDir, fileName)
        return file.takeIf { it.exists() }?.readBytes()
    }
}

Xarici şəxsi qovluğa yol: /storage/emulated/0/Android/data/{packageName}/files/. Android 11-dən başlayaraq birbaşa fayl yolu mövcud deyil — yalnız API vasitəsilə. Bu, Scoped Storage-in təhlükəsizliyinin daha bir gücləndirilməsidir.

MediaStore — media fayllarına giriş

MediaStore — Scoped Storage-də ümumi media fayllarına (şəkillər, video, audio) giriş üçün əsas API-dir. Proqram fayl yolları ilə deyil, MediaStore provider tərəfindən təmin edilən content URIs ilə işləyir.

MediaStore üç əsas kolleksiyaya bölünür: Images, VideoAudio. Hər bir kolleksiya ContentResolver vasitəsilə CRUD əməliyyatlarını dəstəkləyir. Images kolleksiyasına yeni fayl daxil etmək üçün MediaStore.Images.Media, mövcud olanları sorğulamaq üçün müvafiq URI ilə query istifadə olunur.

kotlin
import android.content.ContentValues
import android.provider.MediaStore
import android.os.Environment
import java.io.OutputStream

fun saveImageToGallery(context: Context, bitmap: Bitmap, title: String) {
    val values = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, "$title.jpg")
        put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        put(
            MediaStore.Images.Media.RELATIVE_PATH,
            "${Environment.DIRECTORY_PICTURES}/MyApp"
        )
    }

    val uri = context.contentResolver
        .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
        ?: return

    context.contentResolver.openOutputStream(uri)?.use { output: OutputStream ->
        bitmap.compress(
            Bitmap.CompressFormat.JPEG,
            95,
            output
        )
    }
}

Vacib: MediaStore ixtiyari fayl yollarını dəstəkləmir — yalnız content URIs. MediaStore.Files.getContentUri() vasitəsilə URI-dən fayl yolu almaq cəhdi Android 11+-da fayla birbaşa yol verməyəcək. Bunun əvəzinə məzmunla işləmək üçün ContentResolver.openInputStream() və openOutputStream() istifadə edin.

Storage Access Framework (SAF)

Storage Access Framework (SAF) — proqramın qum qutusundan kənarda ixtiyari fayl və qovluqlara giriş üçün API-dir. SAF istifadəçiyə fayl və ya qovluq seçmək interfeysi təqdim edir, bundan sonra proqram müvəqqəti girişi olan content URI əldə edir.

SAF MediaStore tərəfindən əhatə olunmayan ssenarilər üçün istifadə olunur: ixtiyari sənədlərlə (PDF, ZIP, APK) işləmək, SD kartdakı qovluqlara giriş, digər proqramlardan faylların idxalı və ixracı. İstifadəçi sistematik fayl seçici vasitəsilə faylı açıq şəkildə seçir — bu, onun girişə razılığını təmin edir.

kotlin
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.provider.DocumentsContract

const val REQUEST_CODE_PICK_DIR = 1001

fun pickDirectory(activity: Activity) {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
    activity.startActivityForResult(intent, REQUEST_CODE_PICK_DIR)
}

fun handlePickResult(requestCode: Int, data: Intent?) {
    if (requestCode == REQUEST_CODE_PICK_DIR && data != null) {
        val treeUri: Uri = data.data ?: return

        // Daimi URI icazəsini əldə edin
        val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
                       Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        contentResolver.takePersistableUriPermission(treeUri, flags)
    }
}

SAF proqrama istifadəçi tərəfindən seçilmiş qovluğa cihaz yenidən başladılana qədər giriş imkanı verir (takePersistableUriPermission istifadə etdikdə). Bu, Android 11+-da ümumi yaddaşda ixtiyari fayllara giriş əldə etməyin yeganə yoludur.

Proqramın Scoped Storage-ə köçürülməsi

Mövcud Android proqramını Scoped Storage-ə köçürmək bir neçə əsas sahədə dəyişiklik tələb edir. Google Android 11+-da sınaqdan keçirməklə mərhələli yanaşma tövsiyə edir.

Fayl yollarının content URIs ilə əvəz edilməsi

Ümumi yaddaşdakı bütün birbaşa File əməliyyatlarını ContentResolver.openInputStream / openOutputStream ilə əvəz edin. Proqramın qum qutusundakı fayllar (getExternalFilesDir) üçün fayl yolları işləməyə davam edir.

AndroidManifest-in yenilənməsi

Xüsusi ssenarilər üçün lazım deyilsə (məsələn, fayl idarəetməsi — bunun üçün xüsusi MANAGE_EXTERNAL_STORAGE icazəsi var), READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE-i silin.

SsenariKöhnə yanaşmaScoped Storage yanaşması
Şəklin saxlanmasıFile(path).writeBytes()MediaStore + ContentResolver
PDF-in oxunmasıFile(path).inputStream()SAF ACTION_OPEN_DOCUMENT
Öz fayllarıEnvironment.getExternalStorageDirectory()context.getExternalFilesDir()
KeşFile(cacheDir).writeBytes()context.cacheDir (dəyişiklik yoxdur)

Köçürmədən sonra proqramı build.gradle-də targetSdk = 30 və ya daha yüksək təyin edərək Android 11+ (API 30)-da sınaqdan keçirin. Ümumi yaddaşdakı bütün fayl əməliyyatlarının birbaşa fayl yolları ilə deyil, MediaStore və ya SAF vasitəsilə işlədiyinə əmin olun.

kotlin
import android.os.Build

fun isScopedStorage(): Boolean {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
}

fun compatReadFile(context: Context, uri: Uri): ByteArray? {
    return if (isScopedStorage()) {
        context.contentResolver
            .openInputStream(uri)?.readBytes()
    } else {
        File(uri.path ?: return null)
            .takeIf { it.exists() }
            ?.readBytes()
    }
}

Google Play Console (2024) məlumatına görə, aktiv Android cihazlarının 78%-dən çoxu Scoped Storage ilə Android 10+-da işləyir. Köçürmə Google Play-də yeniləmələrin dərc edilməsi üçün məcburi addımdır: yeni proqramlar API 31+ hədəfləməlidir, yeniləmələr — API 30+.

Tez-tez verilən suallar

Android 11-də Scoped Storage-i söndürmək mümkündürmü?

Xeyr, Android 11-dən (API 30) başlayaraq Scoped Storage bütün proqramlar üçün məcburidir. Android 10-da mövcud olan requestLegacyExternalStorage bayrağı API 30+-da işləmir. Fayl sisteminə geniş giriş əldə etməyin yeganə yolu MANAGE_EXTERNAL_STORAGE icazəsidir, lakin o, yalnız fayl menecerləri və antiviruslar üçün nəzərdə tutulub.

MANAGE_EXTERNAL_STORAGE nədir və onu necə əldə etmək olar?

MANAGE_EXTERNAL_STORAGE — fayl sisteminə tam girişə ehtiyacı olan proqramlar (fayl menecerləri, backup alətləri) üçün xüsusi icazədir. İcazə sorğusu istifadəçi üçün xəbərdarlıqla sistem ekranını açır. Google Play-də dərc edərkən bu icazənin zəruriliyi barədə Declaration formasını doldurmaq tələb olunur.

Scoped Storage-də content URI-dən fayl yolunu necə əldə etmək olar?

Scoped Storage-də Android 11+-da content URI-dən birbaşa fayl yolu əldə etmək mümkün deyil. Bunun əvəzinə oxumaq üçün ContentResolver.openInputStream(), yazmaq üçün openOutputStream() istifadə edin. Üçüncü tərəf kitabxanası ilə uyğunluq üçün fayl yoluna ehtiyacınız varsa — getCacheDir()-də faylın surətini yaradın və surət ilə işləyin.

Scoped Storage FileProvider-a necə təsir edir?

FileProvider dəyişiklik olmadan işləməyə davam edir — o, proqramın qum qutusundan faylları content URIs vasitəsilə digər proqramlara təqdim etmək üçün istifadə olunur. Scoped Storage FileProvider-a təsir etmir, çünki FileProvider birbaşa fayl yolları deyil, content URIs səviyyəsində işləyir.

Cihazın Scoped Storage-i dəstəklədiyini necə yoxlamaq olar?

Build.VERSION.SDK_INT-i yoxlayın: əgər >= Build.VERSION_CODES.Q (29) olarsa, cihaz Scoped Storage-i dəstəkləyir. Lakin Android 10-da Scoped Storage requestLegacyExternalStorage vasitəsilə söndürülə bilər. Android 11+-da manifestdə requestLegacyExternalStorage bayrağının qoyulub-qoyulmadığını yoxlayın — əgər yoxdursa, Scoped Storage aktivdir.

Nəticə

  • Scoped Storage — Android 10+-da ümumi yaddaşın ixtiyari oxunmasını məhdudlaşdıran fayl giriş modeli.
  • Proqram əlavə icazələr olmadan öz şəxsi qum qutusuna tam girişə malikdir.
  • Ümumi media fayllarına giriş üçün content URIs ilə MediaStore API istifadə olunur.
  • İxtiyari fayl və qovluqlara giriş üçün Storage Access Framework (SAF) istifadə olunur.
  • Android 11-dən başlayaraq Scoped Storage bütün proqramlar üçün məcburidir.
  • READ_EXTERNAL_STORAGE və WRITE_EXTERNAL_STORAGE icazələri Android 11+-da əksər ssenarilərdə işləmir.
  • Köçürmə zamanı birbaşa fayl yollarını ContentResolver.openInputStream / openOutputStream ilə əvəz edin.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun