Storage Access Framework — فریمورک اندروید برای دسترسی امن به فایلها و اسناد از طریق دیالوگ سیستمی انتخاب فایل است. به جای درخواست مجوزهای گسترده برای خواندن حافظه، برنامه یک پیوند URI به فایل انتخاب شده توسط کاربر دریافت میکند. به گفته Android Developers (2026)، SAF از حافظه محلی، سرویسهای ابری Google Drive و Dropbox از طریق DocumentProvider پشتیبانی میکند. این فریمورک در Android 4.4 معرفی شد و از Android 10 به استاندارد کار با اسناد تبدیل شد.
نکات اصلی
Storage Access Framework — بخشی از Android SDK است که یک رابط یکپارچه برای انتخاب و ایجاد اسناد از طریق دیالوگ سیستمی فراهم میکند. SAF مکان فیزیکی فایلها را انتزاع میکند: برنامه نمیداند فایل از کجا خوانده میشود — از دیسک محلی، Google Drive یا Dropbox.
معماری SAF شامل سه مؤلفه است: برنامه مشتری که درخواست را آغاز میکند، انتخابگر سیستمی — دیالوگ استاندارد انتخاب فایل، و DocumentProvider — ارائهدهنده محتوا که دسترسی به فایلهای یک حافظه خاص را پیادهسازی میکند. کاربر بدون توجه به منبع داده یک رابط یکپارچه میبیند.
SAF از Android 4.4 (API 19) در دسترس است. در ابتدا این فریمورک فقط از اسناد پشتیبانی میکرد، اما در Android 5.0 پشتیبانی از دایرکتوریها از طریق ACTION_OPEN_DOCUMENT_TREE اضافه شد. از Android 10، SAF به روش توصیه شده برای دسترسی به هر فایل خارج از app-specific storage تبدیل شد.
SAF دیالوگ سیستمی انتخاب فایل را از طریق Intent با اقدام ACTION_OPEN_DOCUMENT راهاندازی میکند. کاربر لیست منابع موجود را میبیند: حافظه داخلی، Google Drive، Dropbox و سایر ارائهدهندگان ثبت شده. پس از انتخاب فایل، سیستم یک content URI با مجوزهای دسترسی موقت بازمیگرداند.
Content URI دارای فرمت content://com.android.externalstorage.documents/document/primary/Download/file.pdf است. بر خلاف URI file://، content URI مسیر واقعی فایل را فاش نمیکند و از طریق DocumentProvider کار میکند. برنامه فایل را از طریق ContentResolver.openInputStream با URI دریافت شده میخواند.
انتخابگر سیستمی به طور خودکار از جستجو، مرتبسازی و فیلتر کردن فایلها بر اساس انواع MIME پشتیبانی میکند. توسعهدهنده انواع مورد نیاز را از طریق Intent.putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("application/pdf", "image/*")) مشخص میکند و انتخابگر فقط فایلهای مرتبط را نشان میدهد.
به طور پیشفرض، URI تا راهاندازی مجدد برنامه یا راهاندازی مجدد دستگاه معتبر است. برای دسترسی بلندمدت، برنامه takePersistableUriPermission را درخواست میکند — این اجازه میدهد فایل در راهاندازیهای بعدی بدون انتخاب مجدد از طریق دیالوگ خوانده شود.
SAF سه اقدام اصلی برای کار با فایلها فراهم میکند: باز کردن، ایجاد و انتخاب درخت پوشه. ACTION_OPEN_DOCUMENT انتخابگر سیستمی را برای انتخاب فایل موجود باز میکند. ACTION_CREATE_DOCUMENT یک فایل جدید ایجاد میکند — کاربر نام را در دیالوگ وارد میکند و برنامه URI را برای نوشتن دریافت میکند.
ACTION_OPEN_DOCUMENT_TREE امکان انتخاب یک دایرکتوری کامل و دسترسی به تمام فایلهای داخل آن را فراهم میکند. این در مدیران فایل، برنامههای پشتیبانگیری و همگامسازی استفاده میشود. برنامه URI دایرکتوری را دریافت میکند و میتواند محتوا را به صورت بازگشتی از طریق DocumentFile فهرست کند.
| اقدام | هدف | پرچم |
|---|---|---|
| ACTION_OPEN_DOCUMENT | انتخاب فایل موجود | READ_FLAG |
| ACTION_CREATE_DOCUMENT | ایجاد فایل جدید | WRITE_FLAG |
| ACTION_OPEN_DOCUMENT_TREE | انتخاب دایرکتوری | READ + WRITE |
برای هر اقدام، انواع MIME از طریق EXTRA_MIME_TYPES مشخص میشود. میتوان چند نوع را مشخص کرد: "application/pdf"، "image/*"، "text/plain". اگر انواع مشخص نشوند، انتخابگر همه فایلها را نشان میدهد.
Persistent URI permissions — مکانیزم SAF است که امکان حفظ دسترسی به فایل را پس از پایان جلسه فعلی فراهم میکند. بدون این پرچم، URI فقط تا راهاندازی مجدد برنامه معتبر است. برنامه پرچم FLAG_GRANT_PERSISTABLE_URI_PERMISSION را همراه با پرچمهای READ و WRITE درخواست میکند.
برای حفظ مجوزها از روش ContentResolver.takePersistableUriPermission استفاده میشود. سیستم URI را در یک ثبت ویژه ذخیره میکند و در راهاندازی بعدی برنامه دسترسی را بازیابی میکند. برای بررسی اینکه آیا برنامه دسترسی پایدار به URI دارد، از ContentResolver.persistedUriPermissions استفاده میشود.
کاربر میتواند مجوزهای ذخیره شده را از طریق تنظیمات ← برنامهها ← مجوزها لغو کند. برنامه باید سناریویی را که دسترسی به فایل به طور غیرمنتظره از بین میرود، مدیریت کند. توصیه میشود قبل از شروع کار، دسترسی را از طریق ContentResolver.openInputStream بررسی کرده و SecurityException را به درستی مدیریت کنید.
SAF از طریق Intent استاندارد راهاندازی میشود. کد حداقل است: Intent با ACTION_OPEN_DOCUMENT ایجاد کنید، انواع MIME را مشخص کنید و از طریق ActivityResultContracts.StartActivityForResult راهاندازی کنید. پس از انتخاب فایل، callback URI را در data.data دریافت میکند که سپس برای خواندن استفاده میشود.
val pickFile = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
result.data?.data?.let { uri ->
val inputStream = contentResolver?.openInputStream(uri)
// read from inputStream
}
}
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
setType("application/pdf")
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
}
pickFile.launch(intent)
برای نوشتن فایل جدید از ACTION_CREATE_DOCUMENT استفاده کنید. Intent نوع MIME و نام فایل را از طریق EXTRA_TITLE دریافت میکند. پس از انتخاب پوشه و تأیید، کاربر URI را بازمیگرداند که برنامه دادهها را از طریق ContentResolver.openOutputStream در آن مینویسد. سیستم به طور خودکار فایل را در مکان انتخاب شده ایجاد میکند.
SAF با رویکرد اساساً متفاوت به امنیت از READ_EXTERNAL_STORAGE سنتی متمایز میشود. به جای درخواست دسترسی به کل حافظه «یکباره»، SAF فقط به فایل خاصی دسترسی درخواست میکند. این سطح حمله را به حداقل میرساند و اعتماد کاربر را افزایش میدهد.
READ_EXTERNAL_STORAGE به همه فایلهای دستگاه از جمله عکسها و اسناد سایر برنامهها دسترسی میدهد. در Android 10+ این رویکرد محدود شده است. SAF در مقابل، فقط به فایل انتخاب شده توسط کاربر دسترسی میدهد و برای هر فایل تأیید صریح نیاز دارد. برای کار دستهای با رسانه از MediaStore و برای اسناد تکی از SAF استفاده کنید.
عیب اصلی SAF نیاز به انتخاب هر فایل به صورت جداگانه است. برای عملیات انبوه (پشتیبانگیری، همگامسازی پوشه) از ACTION_OPEN_DOCUMENT_TREE استفاده میشود که به همه فایلهای دایرکتوری انتخاب شده دسترسی میدهد. راهحل به سناریو بستگی دارد: SAF برای انتخاب کاربر بهینه است، MediaStore — برای دسترسی برنامه به رسانه.
سوالات متداول
Storage Access Framework — فریمورک اندروید برای دسترسی امن به فایلها از طریق دیالوگ سیستمی انتخاب است. برنامه بدون درخواست مجوزهای گسترده برای خواندن حافظه، content URI فایل انتخاب شده را دریافت میکند.
Intent با ACTION_OPEN_DOCUMENT ایجاد کنید، نوع MIME را از طریق setType مشخص کنید و از طریق ActivityResultContracts راهاندازی کنید. در callback URI را از data.data دریافت کرده و از طریق ContentResolver.openInputStream بخوانید.
Persistent URI permissions — مکانیزم حفظ دسترسی به URI پس از راهاندازی مجدد برنامه است. از طریق پرچم FLAG_GRANT_PERSISTABLE_URI_PERMISSION و روش takePersistableUriPermission درخواست میشود.
SAF از هر نوع MIME پشتیبانی میکند: application/pdf، image/*، text/plain، application/zip و غیره. انواع از طریق Intent.putExtra با آرایه EXTRA_MIME_TYPES مشخص میشوند.
SAF برای انتخاب فایلهای تکی توسط کاربر از طریق دیالوگ سیستمی طراحی شده است. MediaStore دسترسی برنامه به تمام فایلهای رسانهای دستگاه را از طریق پایگاه داده رسانه بدون دخالت کاربر فراهم میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید