حالات استخدام مساحة التخزين على Android وأفضل الممارسات المتعلِّقة بها

لمنح المستخدمين المزيد من التحكّم في ملفاتهم والحد من فوضى الملفات، قدّم Android 10 نموذجًا جديدًا لمساحة التخزين للتطبيقات يسمى مساحة التخزين على مستوى النطاق. يغير التخزين النطاقي الطريقة التي تخزن بها التطبيقات الملفات وتصل إليها على وحدة التخزين الخارجية للجهاز. لمساعدتك في نقل بيانات تطبيقك لإتاحة مساحة التخزين ذات النطاق المحدّد، يُرجى اتّباع أفضل الممارسات المتعلّقة بحالات استخدام مساحة التخزين الشائعة الموضّحة في هذا الدليل. ويتم تنظيم حالات الاستخدام في فئتين: التعامل مع ملفات الوسائط والتعامل مع الملفات غير المتعلقة بالوسائط.

لمزيد من المعلومات حول كيفية تخزين الملفات والوصول إليها على Android، يمكنك الاطّلاع على أدلة التدريب على مساحة التخزين.

التعامل مع ملفات الوسائط

يصف هذا القسم بعض حالات الاستخدام الشائعة للتعامل مع ملفات الوسائط (ملفات الفيديو والصور والملفات الصوتية) ويشرح الأسلوب العالي المستوى الذي يمكن أن يستخدمه تطبيقك. يلخص الجدول التالي كل حالة من حالات الاستخدام هذه، ويربط لكل قسم من الأقسام التي تحتوي على مزيد من التفاصيل.

حالة الاستخدام ملخّص
عرض كل ملفات الصور أو الفيديو يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
عرض الصور أو الفيديوهات من مجلد معيّن يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
الوصول إلى معلومات الموقع الجغرافي من الصور يمكنك استخدام طريقة واحدة إذا كان تطبيقك يستخدم مساحة تخزين محدَّدة. استخدِم طريقة مختلفة إذا أوقف تطبيقك مساحة التخزين على النطاق.
تحديد مكان التخزين لعمليات التنزيل الجديدة يمكنك استخدام طريقة واحدة إذا كان تطبيقك يستخدم مساحة تخزين محدَّدة. استخدِم طريقة مختلفة إذا أوقف تطبيقك مساحة التخزين على النطاق.
تصدير ملفات وسائط المستخدمين إلى جهاز يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
تعديل ملفات وسائط متعددة أو حذفها في عملية واحدة استخدِم أسلوبًا واحدًا في نظام التشغيل Android 11. بالنسبة إلى نظام التشغيل Android 10، يمكنك إيقاف مساحة التخزين ذات النطاق واستخدام النهج المتّبع في Android 9 والإصدارات الأقدم بدلاً من ذلك.
استيراد صورة واحدة حالية يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
التقاط صورة واحدة يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
مشاركة ملفات الوسائط مع تطبيقات أخرى يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
مشاركة ملفات الوسائط مع تطبيق محدّد يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
الوصول إلى الملفات من الرموز البرمجية أو المكتبات التي تستخدم مسارات الملفات المباشرة استخدِم أسلوبًا واحدًا في نظام التشغيل Android 11. بالنسبة إلى نظام التشغيل Android 10، يمكنك إيقاف مساحة التخزين ذات النطاق واستخدام النهج المتّبع في Android 9 والإصدارات الأقدم بدلاً من ذلك.

عرض ملفات صور أو فيديو من مجلدات متعددة

يمكنك إجراء طلب بحث في مجموعة وسائط باستخدام واجهة برمجة التطبيقات query(). لفلترة ملفات الوسائط أو ترتيبها، عدِّل المعلمات projection وselection وselectionArgs وsortOrder.

عرض صور أو فيديوهات من مجلد معيّن

استخدم هذا النهج:

  1. باتّباع أفضل الممارسات الموضّحة في قسم طلب أذونات التطبيق، اطلب الحصول على إذن READ_EXTERNAL_STORAGE.
  2. استرداد ملفات الوسائط استنادًا إلى قيمة MediaColumns.DATA التي تحتوي على المسار المطلق لنظام الملفات إلى عنصر الوسائط على القرص.

ملاحظة: عند الوصول إلى ملف وسائط حالي، يمكنك استخدام قيمة عمود DATA وفقًا لمنطقك. هذا لأن هذه القيمة لها مسار ملف صالح. ومع ذلك، لا تفترض أنّ الملف متاح دائمًا. الاستعداد للتعامل مع أي أخطاء قد تحدث في وحدات الإدخال والإخراج المستندة إلى ملفات

ولإنشاء ملف وسائط أو تعديله، لا تستخدم العمود DATA. بدلاً من ذلك، استخدِم العمودَين DISPLAY_NAME وRELATIVE_PATH.

الوصول إلى معلومات الموقع الجغرافي من الصور

إذا كان تطبيقك يستخدم مساحة تخزين محدّدة النطاق، يُرجى اتّباع الخطوات الواردة في قسم معلومات الموقع الجغرافي في الصور الفوتوغرافية في دليل تخزين الوسائط.

تحديد مكان التخزين لعمليات التنزيل الجديدة

إذا كان تطبيقك يستخدم مساحة تخزين محدّدة النطاق، انتبه إلى الموقع الذي تختار فيه تخزين ملفات الوسائط التي تنزّلها.

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

في نظام التشغيل Android 11 والإصدارات الأحدث، لا يمكن للتطبيقات الأخرى الوصول إلى الملفات داخل الدليل الخاص بالتطبيقات الخارجية، حتى إذا كنت تستخدم DownloadManager لجلب هذه الملفات.

تصدير ملفات وسائط المستخدم إلى جهاز

حدد موقعًا افتراضيًا مناسبًا لتخزين ملفات وسائط المستخدم:

تعديل ملفات وسائط متعددة أو حذفها في عملية واحدة

تضمين المنطق استنادًا إلى إصدارات Android التي يعمل عليها تطبيقك

تعمل بنظام التشغيل Android 11

استخدم هذا النهج:

  1. أنشِئ هدفًا في انتظار المراجعة لطلب كتابة المحتوى أو حذفه في تطبيقك باستخدام MediaStore.createWriteRequest() أو MediaStore.createTrashRequest()، ثم اطلب من المستخدم الحصول على الإذن لتعديل مجموعة من الملفات من خلال استدعاء هذه القصد.
  2. تقييم رد المستخدم:

    • في حال تم منح الإذن، يُرجى مواصلة عملية التعديل أو الحذف.
    • إذا لم يتم منح الإذن، اشرح للمستخدم سبب احتياج الميزة في تطبيقك إلى الإذن.

تعرَّف على مزيد من المعلومات عن كيفية إدارة مجموعات من ملفات الوسائط باستخدام هذه الطرق المتاحة على نظام التشغيل Android 11 والإصدارات الأحدث.

يعمل على نظام التشغيل Android 10

إذا كان تطبيقك يستهدف نظام التشغيل Android 10 (المستوى 29 لواجهة برمجة التطبيقات)، عليك إيقاف مساحة التخزين على نطاق واسع ومواصلة استخدام أسلوب Android 9 والإصدارات الأقدم لتنفيذ هذه العملية.

يعمل على نظام التشغيل Android 9 أو الإصدارات الأقدم

استخدم هذا النهج:

  1. باتّباع أفضل الممارسات الموضّحة في قسم طلب أذونات التطبيق، اطلب الحصول على إذن WRITE_EXTERNAL_STORAGE.
  2. استخدِم واجهة برمجة تطبيقات MediaStore لتعديل ملفات الوسائط أو حذفها.

استيراد صورة واحدة موجودة من قبل

إذا أردت استيراد صورة واحدة متوفّرة من قبل (على سبيل المثال، لاستخدامها كصورة للملف الشخصي لأحد المستخدمين)، يمكن لتطبيقك إما استخدام واجهة المستخدم الخاصة به للعملية أو استخدام أداة اختيار النظام.

تقديم واجهة المستخدم الخاصة بك

استخدم هذا النهج:

  1. باتّباع أفضل الممارسات الموضّحة في قسم طلب أذونات التطبيق، اطلب الحصول على إذن READ_EXTERNAL_STORAGE.
  2. استخدِم واجهة برمجة التطبيقات query() من أجل إجراء طلب بحث في مجموعة وسائط.
  3. اعرض النتائج في واجهة المستخدم المخصّصة لتطبيقك.

استخدام أداة اختيار النظام

استخدِم الهدف ACTION_GET_CONTENT، الذي يطلب من المستخدم اختيار صورة لاستيرادها.

إذا كنت تريد فلترة أنواع الصور التي يعرضها منتقي النظام للمستخدم للاختيار من بينها، يمكنك استخدام setType() أو EXTRA_MIME_TYPES.

التقاط صورة واحدة

عندما تريد التقاط صورة واحدة لاستخدامها في تطبيقك (على سبيل المثال، لاستخدامها كصورة للملف الشخصي للمستخدم)، استخدِم ACTION_IMAGE_CAPTURE للطلب من المستخدم التقاط صورة باستخدام كاميرا الجهاز. يخزِّن النظام الصورة التي تم التقاطها في جدول MediaStore.Images.

مشاركة ملفات الوسائط مع تطبيقات أخرى

استخدِم الإجراء insert() لإضافة السجلات مباشرةً إلى MediaStore. للمزيد من المعلومات، راجِع القسم إضافة عنصر في دليل تخزين الوسائط.

مشاركة ملفات الوسائط مع تطبيق محدّد

استخدِم مكوّن FileProvider لنظام التشغيل Android، كما هو موضّح في دليل إعداد مشاركة الملفات.

الوصول إلى الملفات من التعليمات البرمجية أو المكتبات التي تستخدم مسارات الملفات المباشرة

تضمين المنطق استنادًا إلى إصدارات Android التي يعمل عليها تطبيقك

تعمل بنظام التشغيل Android 11

استخدم هذا النهج:

  1. باتّباع أفضل الممارسات الموضّحة في قسم طلب أذونات التطبيق، اطلب الحصول على إذن READ_EXTERNAL_STORAGE.
  2. الوصول إلى الملفات باستخدام المسارات المباشرة للملفات

للحصول على مزيد من المعلومات، اطّلِع على القسم المتعلّق بطريقة فتح ملفات الوسائط باستخدام مسارات الملفات المباشرة.

يعمل على نظام التشغيل Android 10

إذا كان تطبيقك يستهدف نظام التشغيل Android 10 (المستوى 29 لواجهة برمجة التطبيقات)، عليك إيقاف مساحة التخزين على نطاق واسع ومواصلة استخدام أسلوب Android 9 والإصدارات الأقدم لتنفيذ هذه العملية.

يعمل على نظام التشغيل Android 9 أو الإصدارات الأقدم

استخدم هذا النهج:

  1. باتّباع أفضل الممارسات الموضّحة في قسم طلب أذونات التطبيق، اطلب الحصول على إذن WRITE_EXTERNAL_STORAGE.
  2. الوصول إلى الملفات باستخدام المسارات المباشرة للملفات

التعامل مع الملفات غير التابعة للوسائط

يصف هذا القسم بعض حالات الاستخدام الشائعة للتعامل مع الملفات التي لا تستخدم الوسائط ويشرح الأسلوب عالي المستوى الذي يمكن أن يستخدمه تطبيقك. يلخص الجدول التالي كل حالة من حالات الاستخدام هذه، ويربط بكل قسم من الأقسام التي تحتوي على مزيد من التفاصيل.

حالة الاستخدام ملخّص
فتح ملف مستند يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
الكتابة في الملفات على وحدات تخزين ثانوية استخدِم أسلوبًا واحدًا في نظام التشغيل Android 11. استخدِم أسلوبًا مختلفًا مع الإصدارات السابقة من Android.
نقل الملفات الحالية من موقع تخزين قديم عليك نقل ملفاتك إلى مساحة تخزين النطاق متى أمكن. يمكنك إيقاف مساحة التخزين على النطاق في نظام التشغيل Android 10 عند الضرورة.
مشاركة المحتوى مع تطبيقات أخرى يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
ذاكرة التخزين المؤقت للملفات التي ليست وسائط يُرجى استخدام الطريقة نفسها مع جميع إصدارات Android.
تصدير الملفات التي ليست وسائط إلى جهاز يمكنك استخدام طريقة واحدة إذا كان تطبيقك يستخدم مساحة تخزين محدَّدة. استخدِم طريقة مختلفة إذا أوقف تطبيقك مساحة التخزين على النطاق.

فتح ملف مستند

استخدِم الغرض من ACTION_OPEN_DOCUMENT لتطلب من المستخدم اختيار ملف لفتحه باستخدام أداة اختيار النظام. إذا كنت تريد فلترة أنواع الملفات التي ستعرِضها أداة اختيار النظام للمستخدم للاختيار من بينها، يمكنك استخدام setType() أو EXTRA_MIME_TYPES.

على سبيل المثال، يمكنك العثور على جميع ملفات PDF وODT وTXT باستخدام الرمز التالي:

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

الكتابة في الملفات على وحدات تخزين ثانوية

تشمل وحدات التخزين الثانوية بطاقات SD. يمكنك الاطّلاع على معلومات حول حجم مساحة تخزين معيّن من خلال استخدام الفئة StorageVolume.

يمكنك تضمين منطق استنادًا إلى إصدار Android الذي يعمل عليه تطبيقك.

قيد التشغيل على نظام التشغيل Android 11

استخدم هذا النهج:

  1. استخدِم نموذج مساحة التخزين المحدّدة.
  2. استهدف نظام Android 10 (المستوى 29 لواجهة برمجة التطبيقات) أو أقل.
  3. عليك تقديم بيان عن إذن WRITE_EXTERNAL_STORAGE.
  4. تنفيذ أحد أنواع الوصول التالية:
    • الوصول إلى الملفات باستخدام واجهة برمجة التطبيقات MediaStore API
    • الوصول المباشر إلى مسار الملف باستخدام واجهات برمجة التطبيقات، مثل File أو fopen()

العمل على إصدارات قديمة

استخدِم إطار عمل الوصول إلى مساحة التخزين، الذي يسمح للمستخدمين بتحديد الموقع على وحدة تخزين ثانوية حيث يمكن لتطبيقك كتابة الملف.

نقل الملفات الحالية من موقع تخزين قديم

يُعتبَر الدليل موقع تخزين قديم إذا لم يكن دليلاً خاصًا بتطبيق أو دليلاً مشتركًا عامًا. إذا كان تطبيقك ينشئ ملفات أو يستهلكها في موقع تخزين قديم، ننصحك بنقل ملفات تطبيقك إلى المواقع الجغرافية التي يمكن الوصول إليها من خلال مساحة تخزين مُفصَّلة وإجراء أي تغييرات لازمة على التطبيق للعمل مع الملفات في مساحة تخزين النطاق.

الحفاظ على إمكانية الوصول إلى موقع التخزين القديم لنقل البيانات

يحتاج تطبيقك إلى الحفاظ على إمكانية الوصول إلى موقع مساحة التخزين القديم من أجل نقل أي ملفات تطبيق إلى المواقع الجغرافية التي يمكن الوصول إليها من خلال مساحة تخزين محدّدة النطاق. ويعتمد النهج الذي يجب عليك استخدامه على مستوى واجهة برمجة التطبيقات المستهدَف لتطبيقك.

إذا كان تطبيقك يستهدف نظام التشغيل Android 11
  1. اضبط العلامة preserveLegacyExternalStorage على true للحفاظ على نموذج مساحة التخزين القديم حتى يتمكّن تطبيقك من نقل بيانات المستخدم عند الترقية إلى الإصدار الجديد من تطبيقك الذي يستهدف نظام Android 11.

  2. واصِل إيقاف ميزة "التخزين الفرعي" كي يواصل تطبيقك الوصول إلى ملفاتك في موقع التخزين القديم على أجهزة Android 10.

إذا كان تطبيقك يستهدف نظام التشغيل Android 10

إيقاف ميزة "التخزين في نطاق واسع" لتسهيل الحفاظ على سلوك تطبيقك في جميع إصدارات Android

نقل بيانات التطبيقات

عندما يكون تطبيقك جاهزًا لنقله، اتّبِع النهج التالي:

  1. استهداف Android 10 أو الإصدارات الأقدم
  2. يمكنك إيقاف مساحة التخزين في النطاق لكي يتمكّن تطبيقك من الوصول إلى الملفات التي تحتاج إلى نقلها.
  3. يمكنك تفعيل رمز يستخدم واجهة برمجة التطبيقات File لنقل الملفات من موقعها الحالي ضمن /sdcard/ إلى موقع يمكن الوصول إليه من خلال مساحة تخزين على نطاق واسع:

    1. انقل أي ملفات تطبيق خاصة إلى الدليل الذي يعرضه طريقة getExternalFilesDir().
    2. انقِل أي ملفات غير وسائط إلى دليل فرعي مخصص للتطبيق في دليل Downloads/.
  4. أزِل أدلة مساحة التخزين القديمة لتطبيقك من دليل /sdcard/.

بعد أن يثبّت المستخدمون الإصدار الجديد من تطبيقك، يكملون عملية نقل البيانات على أجهزتهم. يمكنك مراقبة عملية الترحيل عبر قاعدة المستخدمين من خلال إنشاء حدث تحليلات.

بعد نقل المستخدمين لبياناتهم، انشر تحديثًا آخر لتطبيقك على الإصدار 11 من نظام التشغيل Android.

مشاركة المحتوى مع التطبيقات الأخرى

لمشاركة ملفات التطبيق مع تطبيق واحد آخر، استخدِم إحدى FileProvider. بالنسبة إلى التطبيقات التي تحتاج جميعها إلى مشاركة الملفات فيما بينها، نقترح استخدام موفِّر محتوى لكل تطبيق، ثم مزامنة البيانات أثناء إضافة التطبيقات إلى المجموعة.

تخزين الملفات غير الإعلامية في ذاكرة التخزين المؤقت

يعتمد الأسلوب الذي يجب عليك استخدامه على نوع الملفات التي تحتاج إلى تخزينها مؤقتًا.

  • الملفات الصغيرة أو الملفات التي تحتوي على معلومات حسّاسة: استخدِم الرمز Context#getCacheDir().
  • الملفات الكبيرة أو الملفات التي لا تحتوي على معلومات حسّاسة: استخدِم Context#getExternalCacheDir().

تصدير الملفات التي ليست وسائط إلى جهاز

حدد موقعًا افتراضيًا مناسبًا لتخزين الملفات غير الوسائط. اسمح للمستخدمين بتصدير الملفات من الأدلة الخاصة بالتطبيقات إلى موقع يمكن الوصول إليه بشكل عام. استخدِم عمليات التنزيل أو مجموعات المستندات من MediaStore لتصدير ملفات غير الوسائط إلى الجهاز.

إيقاف مساحة التخزين للنطاق مؤقتًا

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

إلغاء الاشتراك في الاختبارات

على نظام التشغيل Android 10 (المستوى 29 من واجهة برمجة التطبيقات) والإصدارات الأحدث، يتم تنفيذ اختبارات تطبيقك في وضع حماية مساحة التخزين تلقائيًا. يمنع وضع الحماية هذا تطبيقك من الوصول إلى الملفات خارج الدليل الخاص بالتطبيق والأدلة المشتركة بشكل علني.

إذا أدى الاختبار إلى عرض ملفات للمضيف، مثل لقطات الشاشة أو بيانات تصحيح الأخطاء أو بيانات التغطية أو مقاييس الأداء، يمكنك كتابة هذه الملفات إلى أدلة عالمية. لإجراء ذلك، أضِف العلامة التالية إلى الشريط ذي الصلة الذي يستدعي am instrument:

-e no-isolated-storage 1

تؤثر هذه العلامة في جميع سلوك حالة اختبار قياس حالة التطبيق، كما تؤثر في كل رموز الاختبار التي تم استدعاؤها. لذلك، عند استخدام هذه العلامة، لا يمكنك التحقّق من توافق تطبيقك مع مساحة التخزين ذات النطاق المحدد. للحصول على نتائج اختبارية، من الأفضل بدلاً من ذلك كتابة في وحدة تخزين على مستوى التطبيق والتي يمكن قراءتها عن طريق واجهة أوامر. يمكنك بعد ذلك سحب هذا الدليل على مستوى التطبيق. لتحديد الدليل الذي تريد السحب منه، استدعِ getExternalMediaDirs().

إيقاف التطبيق في قناة الإصدار العلني

إذا كان تطبيقك يستهدف نظام التشغيل Android 10 (المستوى 29 لواجهة برمجة التطبيقات) أو الإصدارات الأقدم، يمكنك مؤقتًا إيقاف مساحة التخزين المحدّدة النطاق في تطبيق الإنتاج. أمّا إذا كنت تستهدف الإصدار 10 من نظام التشغيل Android، فعليك ضبط قيمة requestLegacyExternalStorage على true في ملف البيان الخاص بالتطبيق:

<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10. -->
  <application android:requestLegacyExternalStorage="true" ... >
    ...
  </application>
</manifest>

لاختبار سلوك تطبيق يستهدف الإصدار 10 من نظام التشغيل Android أو الإصدارات الأقدم عند استخدام مساحة تخزين ذات نطاق مرتفع، يمكنك تفعيل السلوك من خلال ضبط القيمة requestLegacyExternalStorage على false. إذا كنت تختبر على جهاز يعمل بنظام التشغيل Android 11، يمكنك أيضًا استخدام علامات توافق التطبيقات لاختبار سلوك التطبيق مع مساحة التخزين ذات النطاق المحدّد أو بدونها.

مراجع إضافية

لمزيد من المعلومات حول مساحة تخزين Android، يمكنك الاطّلاع على المواد التالية:

مشاركات المدونة