תרחישים לדוגמה ושיטות מומלצות בנוגע לאחסון ב-Android

כדי לתת למשתמשים יותר שליטה בקבצים שלהם ולהגביל את העומס על הקבצים, ב-Android 10 נוספה פרדיגמת אחסון חדשה לאפליקציות בשם נפח אחסון בהיקף. שינויים בנפח האחסון בהיקף האופן שבו אפליקציות שומרות קבצים באחסון החיצוני של המכשיר וניגשים אליהם. כדי לעזור לך מעבירים את האפליקציה לתמיכה בנפח אחסון בהיקף, ופועלים בהתאם לשיטות המומלצות בתרחישים לדוגמה של נפח אחסון, שמתוארים במדריך הזה. התרחישים לדוגמה מאורגנים לשתי קטגוריות: טיפול בקובצי מדיה וטיפול שאינם קובצי מדיה.

כדי לקבל מידע נוסף על אחסון קבצים ב-Android ולגשת אליהם, אפשר לעיין באחסון מדריכי הדרכה.

טיפול בקובצי מדיה

בקטע הזה מתוארים כמה מהתרחישים לדוגמה הנפוצים של טיפול בקובצי מדיה (קובצי וידאו, תמונה ואודיו) ומסביר את הגישה הכללית שלפיה שבה האפליקציה יכולה להשתמש. הטבלה הבאה מציגה סיכום של כל אחד מהתרחישים לדוגמה האלה, וכוללת קישורים לכל אחד מהקטעים שמכילים פרטים נוספים.

תרחיש לדוגמה סיכום
הצגת כל קובצי התמונות או הסרטונים צריך להשתמש באותה גישה לכל הגרסאות של Android.
הצגת תמונות או סרטונים של מוצר ספציפי תיקייה צריך להשתמש באותה גישה לכל הגרסאות של Android.
גישה לנתוני מיקום מ- תמונות צריך להשתמש בגישה אחת אם האפליקציה משתמשת בנפח אחסון בהיקף. שימוש במשתנה אחר אם האפליקציה מפסיקה להשתמש בנפח אחסון בהיקף מסוים.
הגדרת מיקום אחסון להורדות חדשות צריך להשתמש בגישה אחת אם האפליקציה משתמשת בנפח אחסון בהיקף. שימוש במשתנה אחר אם האפליקציה מפסיקה להשתמש בנפח אחסון בהיקף מסוים.
ייצוא קובצי מדיה של משתמשים למכשיר צריך להשתמש באותה גישה לכל הגרסאות של Android.
שינוי או מחיקה של קובצי מדיה מרובים ב- פעולה אחת כדאי להשתמש בגישה אחת ל-Android 11. ב-Android 10, צריך לבטל את ההסכמה לשימוש בהיקף אחסון ולהשתמש בגישה ל-Android 9 ומטה.
לייבא תמונה אחת שכבר קיים צריך להשתמש באותה גישה לכל הגרסאות של Android.
צילום תמונה אחת צריך להשתמש באותה גישה לכל הגרסאות של Android.
שיתוף קובצי מדיה עם אפליקציות אחרות צריך להשתמש באותה גישה לכל הגרסאות של Android.
שיתוף קובצי מדיה באמצעות אפליקציה ספציפית צריך להשתמש באותה גישה לכל הגרסאות של Android.
גישה לקבצים מקוד או מספריות שמשתמשים בנתיבים ישירים של קבצים כדאי להשתמש בגישה אחת ל-Android 11. ב-Android 10, צריך לבטל את ההסכמה לשימוש בהיקף אחסון וליישם גישה ל-Android 9 ומטה.

הצגה של קובצי תמונה או וידאו מכמה תיקיות

שאילתות על אוסף מדיה באמצעות query() API. כדי לסנן או למיין את קובצי המדיה, צריך לשנות את המאפיינים projection, selection, selectionArgs ו-sortOrder.

הצגת תמונות או סרטונים מתיקייה מסוימת

כדאי להשתמש בגישה הזו:

  1. בהתאם לשיטות המומלצות שמתוארות במאמר בקשת הרשאות לאפליקציה, לשלוח בקשה אל READ_EXTERNAL_STORAGE הרשאה.
  2. אחזור קובצי מדיה על סמך הערך של MediaColumns.DATA שמכיל את הנתיב המוחלט של מערכת הקבצים לפריט המדיה בכונן.

הערה: כשניגשים לקובץ מדיה קיים, אפשר להשתמש בערך של DATA בלוגיקה. הסיבה לכך היא שלערך הזה יש נתיב קובץ חוקי. עם זאת, אין להניח שהקובץ זמין תמיד. מתכוננים לטיפול קיימות שגיאות קלט/פלט מבוססות-קבצים.

מצד שני, כדי ליצור או לעדכן קובץ מדיה, אל תשתמשו עמודה DATA. במקום זאת, השתמש DISPLAY_NAME RELATIVE_PATH עמודות.

גישה לפרטי מיקום מתמונות

אם האפליקציה משתמשת בנפח אחסון בהיקף, צריך לפעול לפי השלבים שמפורטים בקטע פרטי המיקום. בתמונות בקטע של המדריך לאחסון מדיה.

הגדרת מיקום אחסון להורדות חדשות

אם האפליקציה משתמשת בנפח אחסון בהיקף, חשוב לשים לב למיקום שבו אתם בוחרים להשתמש לאחסן את קובצי המדיה שהורדתם.

אם לאפליקציות אחרות נדרשת גישה לקבצים, כדאי להשתמש במדיה מוגדרת היטב אוספים להורדות או לאוספים של מסמכים.

במכשיר Android מגרסה 11 ואילך, הקבצים שבתוך האפליקציה החיצונית הספציפית לא נגישה לאפליקציות אחרות, גם אם אתם משתמשים ב-DownloadManager כדי לאחזר את הקבצים האלה.

ייצוא קובצי מדיה של משתמשים למכשיר

להגדיר מיקום ברירת מחדל מתאים לאחסון המדיה של המשתמש קבצים:

שינוי או מחיקה של קובצי מדיה מרובים בפעולה אחת

שילוב לוגיקה על סמך גרסאות Android שהאפליקציה פועלת בהן.

מערכת ההפעלה Android 11

כדאי להשתמש בגישה הזו:

  1. יצירת Intent בהמתנה עבור בקשת הכתיבה או המחיקה של האפליקציה באמצעות MediaStore.createWriteRequest() או MediaStore.createTrashRequest() ואז מבקשים מהמשתמש הרשאה לערוך קבוצת קבצים על ידי הפעלה בכוונה טובה.
  2. בודקים את תגובת המשתמש:

    • אם ניתנה ההרשאה, אפשר להמשיך בפעולת השינוי או המחיקה.
    • אם ההרשאה לא ניתנה, הסבר למשתמש מדוע התכונה לאפליקציה שלך נדרשת ההרשאה.

מידע נוסף על ניהול קבוצות של מדיה קבצים באמצעות שזמינות ב-Android 11 ואילך.

מערכת ההפעלה Android 10

אם האפליקציה מטרגטת את Android 10 (רמת API 29), אתם יכולים לבטל את ההסכמה לשימוש בהיקף אחסון ולהמשיך להשתמש בגישה ל-Android 9 ונמוכה יותר כדי לבצע את הפעולה הזו.

מערכת Android מגרסה 9 ומטה

כדאי להשתמש בגישה הזו:

  1. בהתאם לשיטות המומלצות שמתוארות במאמר בקשת הרשאות לאפליקציה, לשלוח בקשה אל WRITE_EXTERNAL_STORAGE הרשאה.
  2. משתמשים ב-API של MediaStore כדי לשנות או למחוק את קובצי המדיה.

ייבוא של תמונה אחת שכבר קיימת

כשרוצים לייבא תמונה יחידה שכבר קיימת (לדוגמה, כדי לייבא כתמונה לפרופיל של משתמש), האפליקציה שלך יכולה להשתמש בממשק משתמש משלה עבור או להשתמש בבורר המערכת.

הצגת ממשק המשתמש שלכם

כדאי להשתמש בגישה הזו:

  1. בהתאם לשיטות המומלצות שמתוארות במאמר בקשת הרשאות לאפליקציה, לשלוח בקשה אל READ_EXTERNAL_STORAGE הרשאה.
  2. שימוש בquery() ממשק ה-API של הרצת שאילתות באוסף מדיה.
  3. התוצאות יוצגו בממשק המשתמש המותאם אישית של האפליקציה שלך.

שימוש בבורר המערכת

שימוש בACTION_GET_CONTENT Intent, שמבקש מהמשתמש לבחור תמונה לייבוא.

אם אתם רוצים לסנן את סוגי התמונות שבורר המערכת מציג של משתמש לבחירה, אפשר להשתמש 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 (רמת API 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 (רמת API 29) ומטה.
  3. להצהיר על WRITE_EXTERNAL_STORAGE הרשאה.
  4. לבצע אחד מסוגי הגישה הבאים:
    • גישה לקובץ באמצעות ה-API של MediaStore.
    • גישה ישירה לנתיב הקובץ באמצעות ממשקי API כמו File או fopen().

פועלות בגרסאות ישנות יותר

שימוש בגישה לאחסון Framework, שמאפשרת למשתמשים בחירת המיקום בנפח אחסון משני שבו האפליקציה יכולה לכתוב חדש.

העברת קבצים קיימים ממיקום אחסון מדור קודם

ספרייה נחשבת למיקום אחסון מדור קודם, אם היא לא ספרייה ספציפית לאפליקציה או ספרייה משותפת ציבורית. אם האפליקציה יוצרת או משתמש בקבצים במיקום אחסון מדור קודם, מומלץ להעביר את של האפליקציה במיקומים שאפשר לגשת אליהם באמצעות שטח אחסון בהיקף מסוים, את השינויים הנדרשים באפליקציה כדי לעבוד עם קבצים באחסון בהיקף.

שמירה על גישה למיקום האחסון הקודם לצורך העברת נתונים

לאפליקציה שלך צריכה להיות גישה למיקום האחסון הקודם כדי להעביר את כל קובצי האפליקציה למיקומים שאפשר לגשת אליהם באמצעות נפח אחסון בהיקף. הגישה שבה כדאי להשתמש תלויה ברמת ה-API המטורגטת של האפליקציה.

אם האפליקציה מטרגטת את Android 11
  1. מגדירים את preserveLegacyExternalStorage סימון ל-true כדי לשמר את האחסון מהדור הקודם כך שהאפליקציה שלך יכולה להעביר נתוני משתמש כשהוא משודרג לגרסה החדשה של לאפליקציה שמטרגטת את Android 11.

  2. להמשיך לבטל את ההסכמה לנפח אחסון בהיקף כדי לאפליקציה שלך תהיה אפשרות להמשיך לגשת לקבצים במיקום האחסון הקודם דרך מכשירי Android 10.

אם האפליקציה מטרגטת את Android 10

לבטל את ההסכמה לנפח אחסון בהיקף כדי שיהיה קל יותר: לשמור על התנהגות האפליקציה בכל הגרסאות של Android.

העברת נתוני האפליקציה

כשהאפליקציה מוכנה להעברה, פועלים לפי השיטה הבאה:

  1. כדאי לטרגט ל-Android מגרסה 10 ומטה.
  2. לבטל את ההסכמה לנפח אחסון בהיקף כדי לאפליקציה שלך יש גישה לקבצים שצריך להעביר.
  3. פריסת קוד שמשתמש ב-API של File כדי להעביר קבצים המיקום הנוכחי מתחת ל-/sdcard/ למיקום שאפשר לגשת אליו עם נפח אחסון בהיקף:

    1. להעביר קובצי אפליקציה פרטיים לספרייה שמוחזרת על ידי getExternalFilesDir() .
    2. העברת קבצים משותפים שאינם מדיה לספריית משנה ייעודית של אפליקציה של הספרייה Downloads/.
  4. מסירים את ספריות האחסון הקודמות של האפליקציה מ ספריית /sdcard/.

אחרי שהמשתמשים מתקינים את הגרסה החדשה של האפליקציה, הם משלימים את הנתונים את תהליך ההעברה במכשירים שלהם. תוכלו לעקוב אחרי תהליך ההעברה את בסיס המשתמשים על ידי יצירת אירוע ב-Analytics.

אחרי שהמשתמשים העבירו את הנתונים שלהם, צריך לפרסם באפליקציה עדכון נוסף. שאתם מטרגטים את Android 11.

שיתוף תוכן עם אפליקציות אחרות

כדי לשתף את קובצי האפליקציה עם אפליקציה אחת אחרת, צריך להשתמש ב FileProvider אפליקציות שכולן צריכות לשתף הקבצים בין שני הקבצים, מומלץ להשתמש בתוכן ספק לכל אפליקציה, וגם ולאחר מכן לסנכרן את הנתונים בזמן שהאפליקציות מתווספות לאוסף.

שמירה במטמון של קבצים שאינם מדיה

הגישה שבה צריך להשתמש תלויה בסוג הקבצים שדרושים לכם במטמון.

  • קבצים קטנים או קבצים שמכילים מידע רגיש: יש להשתמש ב- Context#getCacheDir().
  • קבצים גדולים או קבצים שלא מכילים מידע רגיש: יש להשתמש ב- Context#getExternalCacheDir().

ייצוא קבצים שאינם מדיה למכשיר

להגדיר מיקום ברירת מחדל מתאים לאחסון קבצים שאינם מדיה . המשתמשים יכולים לייצא קבצים מתוך ספריות ספציפיות לאפליקציה למיקום נגיש יותר. שימוש בהורדות או אוספי מסמכים של MediaStore כדי לייצא קבצים שאינם מדיה אל במכשיר.

ביטול זמני של אי-שימוש בנפח אחסון

כדי שהאפליקציה תתאים במלואה לנפח אחסון בהיקף, אפשר לאשר את השימוש באופן זמני גם בבדיקות שלכם וגם בסביבת הייצור אפליקציה.

ביטול ההסכמה בבדיקות

בגרסה Android 10 (רמת API 29) ואילך, הבדיקות של האפליקציה פועלות באחסון כברירת מחדל. ארגז החול הזה מונע מהאפליקציה לגשת לקבצים מחוץ לבית של הספריות הספציפיות לאפליקציה ושל הספריות המשותפות באופן ציבורי.

אם בדיקה מניבה קובצי פלט עבור המארח - כמו צילומי מסך, נתוני ניפוי באגים, נתוני כיסוי או מדדי ביצועים — אפשר לכתוב את הקבצים האלה של ספריות. כדי לעשות את זה, צריך להוסיף את הדגל הבא לרתמה הרלוונטית. מפעיל את am instrument:

-e no-isolated-storage 1

הדגל הזה משפיע על כל ההתנהגות של תרחיש הבדיקה שאליו בוצעה האינסטרומנטציה, והוא משפיע על כל הזנה של קוד הבדיקה. לכן, כשמשתמשים בדגל הזה, אי אפשר לאמת התאימות של האפליקציה לנפח אחסון בהיקף. לפלט הבדיקה עדיף כתיבה לאחסון ברמת האפליקציה שהמעטפת יכולה לקרוא. ואז אפשר למשוך ספרייה ברמת האפליקציה. כדי לבחור מאיזו ספרייה לשלוף, קוראים לפונקציה getExternalMediaDirs()

ביטול ההסכמה לשימוש באפליקציה בסביבת הייצור

אם האפליקציה מטרגטת את Android 10 (רמת API 29) ומטה, אפשר לבטל את ההסכמה באופן זמני מחוץ להיקף האחסון באפליקציה בסביבת הייצור. אם אתם מטרגטים עם זאת, ב-Android 10 צריך להגדיר את הערך של requestLegacyExternalStorage עד true בקובץ המניפסט של האפליקציה:

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

כדי לבדוק איך פועלת אפליקציה שמטרגטת את Android 10 ומטה באמצעות נפח אחסון בהיקף, אפשר להביע הסכמה להתנהגות על ידי הגדרת הערך של requestLegacyExternalStorage עד false. אם אתם בודקים את המכשיר מערכת ההפעלה Android בגרסה 11. אפשר גם להשתמש בתאימות של האפליקציה דגלים כדי לבדוק להתנהגות האפליקציה, עם או בלי נפח אחסון בהיקף.

מקורות מידע נוספים

למידע נוסף על אחסון Android, אפשר לעיין בחומרים הבאים:

פוסטים בבלוגים