Storage Access Framework: ما هو، كيفية عمله والوصول إلى الملفات في Android

المؤلف: IT Sectr نُشر: 2026-07-10 وقت القراءة: 6 دق

Storage Access Framework هو إطار عمل Android للوصول الآمن إلى الملفات والمستندات من خلال حوار اختيار النظام. بدلاً من طلب أذونات واسعة لقراءة التخزين، يحصل التطبيق على رابط URI للملف الذي اختاره المستخدم. وفقاً لـ Android Developers (2026)، يدعم SAF التخزين المحلي وخدمات السحابة Google Drive و Dropbox عبر DocumentProvider. تم تقديم الإطار في Android 4.4 وأصبح المعيار للعمل مع المستندات بدءاً من Android 10.

الرئيسية

  • SAF هو إطار عمل Android لاختيار الملفات من خلال حوار النظام دون أذونات واسعة.
  • رابط URI يحل محل مسار الملف المباشر: يعمل التطبيق مع الملف عبر content URI.
  • الأذونات المستمرة تسمح بالاحتفاظ بالوصول إلى الملف بعد إعادة تشغيل التطبيق.
  • DocumentProvider يوسع SAF للوصول إلى التخزين السحابي والمخصص.
  • Android 10 جعل SAF إلزامياً للوصول إلى الملفات خارج الصندوق الرملي للتطبيق.

ما هو Storage Access Framework؟

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 الطريقة الموصى بها للوصول إلى أي ملف خارج التخزين الخاص بالتطبيق.

كيف يعمل SAF: منتقي النظام و URI

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

افتراضياً، URI صالح حتى إعادة تشغيل التطبيق أو إعادة تشغيل الجهاز. للوصول طويل المدى، يطلب التطبيق takePersistableUriPermission — وهذا يسمح بقراءة الملف في عمليات التشغيل اللاحقة دون إعادة التحديد عبر الحوار.

ACTION_OPEN_DOCUMENT و ACTION_CREATE_DOCUMENT

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". إذا لم يتم تحديد أنواع، يعرض المنتقي جميع الملفات.

أذونات URI المستمرة

أذونات URI المستمرة هي آلية SAF تسمح بالاحتفاظ بالوصول إلى ملف بعد انتهاء الجلسة الحالية. بدون هذه العلامة، URI صالح فقط حتى إعادة تشغيل التطبيق. يطلب التطبيق العلامة FLAG_GRANT_PERSISTABLE_URI_PERMISSION مع علامتي READ و WRITE.

لحفظ الأذونات، يُستخدم الأسلوب ContentResolver.takePersistableUriPermission. يحفظ النظام URI في سجل خاص ويستعيد الوصول عند بدء التشغيل التالي للتطبيق. للتحقق مما إذا كان التطبيق لديه وصول مستمر إلى URI، يُستخدم ContentResolver.persistedUriPermissions.

يمكن للمستخدم إلغاء الأذونات المحفوظة عبر الإعدادات → التطبيقات → الأذونات. يجب على التطبيق معالجة السيناريو الذي يُفقد فيه الوصول إلى الملف بشكل غير متوقع. يُوصى بالتحقق من الوصول عبر ContentResolver.openInputStream قبل بدء العمل ومعالجة SecurityException بشكل صحيح.

أمثلة كود: اختيار ملف عبر SAF

SAF يُطلق عبر Intent قياسي. الكود بسيط: إنشاء Intent مع ACTION_OPEN_DOCUMENT، تحديد أنواع MIME، وتشغيله عبر ActivityResultContracts.StartActivityForResult. بعد اختيار ملف، يتلقى callback URI في data.data، والذي يُستخدم بعد ذلك للقراءة.

kotlin
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

لكتابة ملف جديد، استخدم ACTION_CREATE_DOCUMENT. يقبل Intent نوع MIME واسم الملف عبر EXTRA_TITLE. بعد اختيار مجلد والتأكيد، يعيد المستخدم URI يكتب فيه التطبيق البيانات عبر ContentResolver.openOutputStream. يقوم النظام تلقائياً بإنشاء الملف في الموقع المختار.

SAF ضد READ_EXTERNAL_STORAGE

SAF يختلف عن READ_EXTERNAL_STORAGE التقليدي في نهج مختلف جوهرياً تجاه الأمان. بدلاً من طلب الوصول إلى كل التخزين دفعة واحدة، يطلب SAF الوصول فقط إلى ملف معين. هذا يقلل من سطح الهجوم ويزيد من ثقة المستخدم.

READ_EXTERNAL_STORAGE يمنح الوصول إلى جميع الملفات على الجهاز، بما في ذلك الصور والمستندات من التطبيقات الأخرى. على Android 10+، هذا النهج مقيد. SAF، على العكس، يوفر الوصول فقط إلى الملف الذي اختاره المستخدم ويتطلب تأكيداً صريحاً لكل ملف. للعمليات الجماعية على الوسائط، استخدم MediaStore؛ للمستندات الفردية، استخدم SAF.

العيب الرئيسي لـ SAF هو الحاجة إلى اختيار كل ملف على حدة. للعمليات الجماعية (النسخ الاحتياطي، مزامنة المجلدات)، يُستخدم ACTION_OPEN_DOCUMENT_TREE الذي يمنح الوصول إلى جميع الملفات في الدليل المحدد. يعتمد الحل على السيناريو: SAF مثالي لاختيار المستخدم، MediaStore للوصول البرمجي إلى الوسائط.

الأسئلة الشائعة

ما هو Storage Access Framework في Android؟

Storage Access Framework هو إطار عمل Android للوصول الآمن إلى الملفات من خلال حوار اختيار النظام. يحصل التطبيق على content URI للملف المحدد دون طلب أذونات واسعة لقراءة التخزين.

كيف تفتح ملفاً عبر SAF؟

أنشئ Intent مع ACTION_OPEN_DOCUMENT، حدد نوع MIME عبر setType، وشغله عبر ActivityResultContracts. في callback، احصل على URI من data.data واقرأ عبر ContentResolver.openInputStream.

ما هي أذونات URI المستمرة؟

أذونات URI المستمرة هي آلية للاحتفاظ بالوصول إلى URI بعد إعادة تشغيل التطبيق. تُطلب عبر العلامة FLAG_GRANT_PERSISTABLE_URI_PERMISSION وطريقة takePersistableUriPermission.

ما أنواع MIME التي يدعمها SAF؟

SAF يدعم أي أنواع MIME: application/pdf، image/*، text/plain، application/zip وغيرها. تُحدد الأنواع عبر Intent.putExtra مع مصفوفة EXTRA_MIME_TYPES.

كيف يختلف SAF عن MediaStore؟

SAF مصمم لاختيار ملفات فردية من قبل المستخدم عبر حوار النظام. MediaStore يوفر وصولاً برمجياً إلى جميع ملفات الوسائط على الجهاز عبر قاعدة بيانات الوسائط دون تدخل المستخدم.

الخلاصة

  • Storage Access Framework هو إطار عمل Android للوصول الآمن إلى الملفات عبر منتقي النظام دون أذونات واسعة.
  • Content URI يحل محل مسارات الملفات: يعمل التطبيق مع الملفات عبر DocumentProvider، وليس عبر روابط file:// مباشرة.
  • ACTION_OPEN_DOCUMENT يفتح ملفاً موجوداً، ACTION_CREATE_DOCUMENT ينشئ ملفاً جديداً، ACTION_OPEN_DOCUMENT_TREE يختار مجلداً.
  • الأذونات المستمرة تحتفظ بالوصول إلى URI بعد إعادة تشغيل التطبيق عبر takePersistableUriPermission.
  • Android 10 جعل SAF إلزامياً للوصول إلى الملفات خارج التخزين الخاص بالتطبيق، مقيداً READ_EXTERNAL_STORAGE.
  • DocumentProvider يوسع SAF للتكامل مع التخزين السحابي والمخصص.
  • الاختيار بين SAF و MediaStore يعتمد على السيناريو: SAF لاختيار المستخدم، MediaStore للوصول البرمجي إلى الوسائط.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا