Scoped Storage — bu nima, fayl boshqaruvi va xotiraga kirish

Muallif: IT Sectr Nashr etilgan: 2026-07-10 O'qish vaqti: 10 daq

Scoped Storage — Android 10 (API 29) da joriy qilingan, ilovalarning qurilma umumiy xotirasiga o‘zboshimchalik bilan kirishini cheklovchi fayl tizimiga kirish modelidir. Google Android Developer Documentation (2024) ma’lumotlariga ko‘ra, Scoped Storage READ_EXTERNAL_STORAGE va WRITE_EXTERNAL_STORAGE ruxsatlarining eski modelini almashtiradi va ilovalarga faqat izolyatsiya qilingan qum qutisidagi o‘z fayllariga va MediaStore orqali umumiy to‘plamlarga kirish imkonini beradi. Ushbu model foydalanuvchi ma’lumotlarining maxfiyligini oshiradi va ilovalar tomonidan ruxsatsiz ma’lumot to‘planishining oldini oladi.

Asosiy ma’lumotlar

  • Scoped Storage — Android 10+ da umumiy xotirani o‘zboshimchalik bilan o‘qishni cheklovchi faylga kirish modeli.
  • Ilova qo‘shimcha ruxsatlarsiz to‘liq kirish huquqiga ega bo‘lgan o‘z qum qutisiga ega.
  • Umumiy fayllarga (foto, video, audio) kirish uchun MediaStore API ishlatiladi.
  • O‘zboshimchalik bilan katalog va fayllarga kirish uchun Storage Access Framework (SAF) ishlatiladi.
  • READ_EXTERNAL_STORAGE va WRITE_EXTERNAL_STORAGE ruxsatlari ko‘p hollarda o‘z kuchini yo‘qotgan.

Android da Scoped Storage nima?

Scoped Storage — Android 10 (API 29) da ilovalarning qurilma fayl tizimiga kirish usulini tubdan o‘zgartiruvchi arxitekturaviy o‘zgarishdir. Umumiy xotiraga to‘liq kirish o‘rniga, ilova faqat o‘z qum qutisiga va MediaStore orqali ma’lum media fayl to‘plamlariga kirish imkoniyatiga ega bo‘ladi.

Scoped Storage dan oldin READ_EXTERNAL_STORAGE ruxsatiga ega har qanday ilova umumiy xotiradagi barcha fayllarni — fotosuratlar, hujjatlar, yuklab olinganlar, boshqa ilovalarning ma’lumotlarini o‘qiy olardi. Bu maxfiylik xavfini tug‘dirardi: insofsiz ilovalar foydalanuvchining xabarisiz u haqida ma’lumot to‘plashi mumkin edi.

Google I/O 2019 ma’lumotlariga ko‘ra, Android foydalanuvchilarining 65% dan ortig‘i ilova tanlashda ma’lumotlar maxfiyligini muhim omil deb biladi. Scoped Storage bu talabga to‘g‘ridan-to‘g‘ri javobdir: har bir ilova izolyatsiya qilingan muhitda ishlaydi va boshqa ilovalarning ma’lumotlariga faqat foydalanuvchining aniq roziligi bilan kirishadi.

Muhim: Android 10 da Scoped Storage ixtiyoriy edi (ilova uni requestLegacyExternalStorage orqali o‘chirib qo‘yishi mumkin edi). Android 11 (API 30) dan boshlab, Scoped Storage target SDK dan qat’iy nazar barcha ilovalar uchun majburiy bo‘ldi.

Scoped Storage nima uchun kerak bo‘ldi

Google Scoped Storage ni eski faylga kirish modelining uchta asosiy muammosini hal qilish uchun joriy qildi: maxfiylik, ruxsatlarni boshqarish va qoldiq fayllarni tozalash.

Maxfiylik muammosi

Eski modelda READ_EXTERNAL_STORAGE ruxsatiga ega ilova butun umumiy xotirani skanerlashi va foydalanuvchining fayllari haqida metama’lumot to‘plashi mumkin edi — fotosuratlarning geografik koordinatalari, hujjat nomlari, katalog tuzilmasi. Scoped Storage bu imkoniyatni bartaraf etadi: ruxsatga ega bo‘lsa ham, ilova faqat o‘zi yaratgan fayllarni va foydalanuvchi SAF orqali aniq tanlagan fayllarni ko‘radi.

Ilova o‘chirilganda tozalash muammosi

Scoped Storage dan oldin ilova o‘chirilgandan so‘ng umumiy xotiraga fayllarni qoldirishi mumkin edi. Vaqt o‘tishi bilan axlat kataloglari to‘planardi. Scoped Storage buni hal qiladi: ilovaning qum qutisidagi barcha fayllar ilova bilan birga o‘chiriladi, MediaStore orqali fayllar esa egasiga ega va tizim tomonidan tozalanishi mumkin.

AspektEski model (Legacy)Scoped Storage
Umumiy xotiraga kirishTo‘liq (ruxsat bilan)Faqat o‘z qum qutisi
Media fayllarTo‘g‘ridan-to‘g‘ri fayl yo‘liMediaStore URI orqali
Boshqalarning fayllariHar doim mavjudFaqat SAF orqali
O‘chirishda tozalashFayllar qoladiQum qutisi o‘chiriladi
Foydalanuvchi nazoratiMinimalHar bir fayl uchun aniq rozilik

Scoped Storage Google ning Android da maxfiylikni kuchaytirish bo‘yicha umumiy strategiyasining bir qismidir, bunga shuningdek “faqat foydalanish vaqtida” ruxsatlari, kamera va mikrofonga kirish ko‘rsatkichlari va Privacy Dashboard kiradi.

Ilovaning shaxsiy katalogi

Har bir Android ilovasi Context.getFilesDir() va context.getCacheDir() orqali mavjud bo‘lgan o‘z shaxsiy katalogini oladi. Tashqi (umumiy) shaxsiy katalogga kirish uchun Context.getExternalFilesDir() ishlatiladi.

Scoped Storage da ilova hech qanday ruxsatsiz o‘zining tashqi shaxsiy katalogiga to‘liq kirish huquqiga ega. Bu boshqa ilovalar uchun mavjud bo‘lmasligi kerak bo‘lgan yoki ilova o‘z foydalanishi uchun yaratadigan fayllarni saqlash uchun asosiy joydir.

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()
    }
}

Tashqi shaxsiy katalog yo‘li: /storage/emulated/0/Android/data/{packageName}/files/. Android 11 dan boshlab to‘g‘ridan-to‘g‘ri fayl yo‘li mavjud emas — faqat API orqali. Bu Scoped Storage xavfsizligining yana bir kuchaytirilishidir.

MediaStore — media fayllarga kirish

MediaStore — Scoped Storage da umumiy media fayllarga (tasvirlar, video, audio) kirish uchun asosiy API. Ilova fayl yo‘llari bilan emas, balki MediaStore provider tomonidan taqdim etilgan content URIs bilan ishlaydi.

MediaStore uchta asosiy to‘plamga bo‘linadi: Images, Video va Audio. Har bir to‘plam ContentResolver orqali CRUD operatsiyalarini qo‘llab-quvvatlaydi. Images to‘plamiga yangi fayl kiritish uchun MediaStore.Images.Media, mavjudlarini so‘rash uchun tegishli URI bilan query ishlatiladi.

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
        )
    }
}

Muhim: MediaStore o‘zboshimchalik bilan fayl yo‘llarini qo‘llab-quvvatlamaydi — faqat content URIs. MediaStore.Files.getContentUri() orqali URI dan fayl yo‘lini olish urinishi Android 11+ da faylga to‘g‘ridan-to‘g‘ri yo‘l bermaydi. Buning o‘rniga tarkib bilan ishlash uchun ContentResolver.openInputStream() va openOutputStream() dan foydalaning.

Storage Access Framework (SAF)

Storage Access Framework (SAF) — ilovaning qum qutisidan tashqaridagi o‘zboshimchalik bilan fayl va kataloglarga kirish uchun API. SAF foydalanuvchiga fayl yoki katalogni tanlash interfeysini taqdim etadi, shundan so‘ng ilova vaqtinchalik kirish huquqiga ega content URI oladi.

SAF MediaStore qamrab olmagan stsenariylar uchun ishlatiladi: o‘zboshimchalik hujjatlar (PDF, ZIP, APK) bilan ishlash, SD karta kataloglariga kirish, boshqa ilovalardan fayllarni import va eksport qilish. Foydalanuvchi tizim fayl tanlovchi orqali faylni aniq tanlaydi — bu uning kirishga roziligini kafolatlaydi.

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

        // Doimiy URI ruxsatini oling
        val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
                       Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        contentResolver.takePersistableUriPermission(treeUri, flags)
    }
}

SAF ilovaga foydalanuvchi tomonidan tanlangan katalogga qurilma qayta ishga tushirilgunga qadar kirish imkonini beradi (takePersistableUriPermission dan foydalanganda). Bu Android 11+ da umumiy xotirada o‘zboshimchalik bilan fayllarga kirishning yagona yo‘lidir.

Ilovani Scoped Storage ga ko‘chirish

Mavjud Android ilovasini Scoped Storage ga ko‘chirish bir necha asosiy sohalarda o‘zgartirishlarni talab qiladi. Google Android 11+ da sinovdan o‘tkazish bilan bosqichma-bosqich yondashuvni tavsiya qiladi.

Fayl yo‘llarini content URIs bilan almashtirish

Umumiy xotiradagi barcha to‘g‘ridan-to‘g‘ri File operatsiyalarini ContentResolver.openInputStream / openOutputStream bilan almashtiring. Ilovaning qum qutisidagi fayllar (getExternalFilesDir) uchun fayl yo‘llari ishlashda davom etadi.

AndroidManifest ni yangilash

Agar maxsus stsenariylar uchun kerak bo‘lmasa (masalan, fayl boshqaruvi — buning uchun maxsus MANAGE_EXTERNAL_STORAGE ruxsati mavjud), READ_EXTERNAL_STORAGE va WRITE_EXTERNAL_STORAGE ni olib tashlang.

StsenariyEski yondashuvScoped Storage yondashuvi
Fotosuratni saqlashFile(path).writeBytes()MediaStore + ContentResolver
PDF ni o‘qishFile(path).inputStream()SAF ACTION_OPEN_DOCUMENT
O‘z fayllariEnvironment.getExternalStorageDirectory()context.getExternalFilesDir()
KeshFile(cacheDir).writeBytes()context.cacheDir (o‘zgarishsiz)

Ko‘chirishdan so‘ng ilovani build.gradle da targetSdk = 30 yoki undan yuqori o‘rnatib, Android 11+ (API 30) da sinab ko‘ring. Umumiy xotiradagi barcha fayl operatsiyalari to‘g‘ridan-to‘g‘ri fayl yo‘llari orqali emas, balki MediaStore yoki SAF orqali ishlashiga ishonch hosil qiling.

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) ma’lumotlariga ko‘ra, faol Android qurilmalarining 78% dan ortig‘i Scoped Storage bilan Android 10+ da ishlaydi. Ko‘chirish Google Play da yangilanishlarni nashr qilish uchun majburiy qadamdir: yangi ilovalar API 31+, yangilanishlar API 30+ ni nishonga olishi kerak.

Tez-tez beriladigan savollar

Android 11 da Scoped Storage ni o‘chirish mumkinmi?

Yo‘q, Android 11 (API 30) dan boshlab Scoped Storage barcha ilovalar uchun majburiydir. Android 10 da mavjud bo‘lgan requestLegacyExternalStorage flag‘i API 30+ da ishlamaydi. Fayl tizimiga keng kirishning yagona yo‘li MANAGE_EXTERNAL_STORAGE ruxsatidir, lekin u faqat fayl menejerlari va antiviruslar uchun mo‘ljallangan.

MANAGE_EXTERNAL_STORAGE nima va uni qanday olish mumkin?

MANAGE_EXTERNAL_STORAGE — fayl tizimiga to‘liq kirishga muhtoj ilovalar (fayl menejerlari, backup vositalari) uchun maxsus ruxsatdir. Ruxsat so‘rovi foydalanuvchi uchun ogohlantirish bilan tizim ekranini ochadi. Google Play da nashr qilishda ushbu ruxsat zarurligi haqida Declaration formasini to‘ldirish talab qilinadi.

Scoped Storage da content URI dan fayl yo‘lini qanday olish mumkin?

Scoped Storage da Android 11+ da content URI dan to‘g‘ridan-to‘g‘ri fayl yo‘lini olish mumkin emas. Buning o‘rniga o‘qish uchun ContentResolver.openInputStream(), yozish uchun openOutputStream() dan foydalaning. Agar uchinchi tomon kutubxonasi bilan moslik uchun fayl yo‘li kerak bo‘lsa — getCacheDir() da fayl nusxasini yarating va nusxa bilan ishlang.

Scoped Storage FileProvider ga qanday ta’sir qiladi?

FileProvider o‘zgarishsiz ishlashda davom etadi — u ilovaning qum qutisidagi fayllarga content URIs orqali boshqa ilovalarga kirishni ta’minlash uchun ishlatiladi. Scoped Storage FileProvider ga ta’sir qilmaydi, chunki FileProvider to‘g‘ridan-to‘g‘ri fayl yo‘llari emas, balki content URIs darajasida ishlaydi.

Qurilma Scoped Storage ni qo‘llab-quvvatlashini qanday tekshirish mumkin?

Build.VERSION.SDK_INT ni tekshiring: agar >= Build.VERSION_CODES.Q (29) bo‘lsa, qurilma Scoped Storage ni qo‘llab-quvvatlaydi. Biroq, Android 10 da Scoped Storage requestLegacyExternalStorage orqali o‘chirilgan bo‘lishi mumkin. Android 11+ da manifestda requestLegacyExternalStorage flag‘i o‘rnatilganligini tekshiring — agar yo‘q bo‘lsa, Scoped Storage faoldir.

Xulosa

  • Scoped Storage — Android 10+ da umumiy xotirani o‘zboshimchalik bilan o‘qishni cheklovchi faylga kirish modeli.
  • Ilova qo‘shimcha ruxsatlarsiz o‘z shaxsiy qum qutisiga to‘liq kirish huquqiga ega.
  • Umumiy media fayllarga kirish uchun content URIs bilan MediaStore API ishlatiladi.
  • O‘zboshimchalik bilan fayl va kataloglarga kirish uchun Storage Access Framework (SAF) ishlatiladi.
  • Android 11 dan boshlab Scoped Storage barcha ilovalar uchun majburiydir.
  • READ_EXTERNAL_STORAGE va WRITE_EXTERNAL_STORAGE ruxsatlari Android 11+ da ko‘p stsenariylarda ishlamaydi.
  • Ko‘chirishda to‘g‘ridan-to‘g‘ri fayl yo‘llarini ContentResolver.openInputStream / openOutputStream bilan almashtiring.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing