כדי לתת למשתמשים יותר שליטה בקבצים שלהם ולהגביל את העומס על הקבצים, ב-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
.
הצגת תמונות או סרטונים מתיקייה מסוימת
כדאי להשתמש בגישה הזו:
- בהתאם לשיטות המומלצות שמפורטות במאמר בקשה להרשאות לאפליקציה, מבקשים את ההרשאה
READ_EXTERNAL_STORAGE
. - אחזור קובצי מדיה על סמך הערך של
MediaColumns.DATA
, שמכיל את הנתיב המוחלט של מערכת הקבצים לפריט המדיה בכונן.
הערה: כשניגשים לקובץ מדיה קיים, אפשר להשתמש בערך
של DATA
בלוגיקה. הסיבה לכך היא שלערך הזה יש נתיב קובץ תקין.
עם זאת, אין להניח שהקובץ זמין תמיד. חשוב להיות מוכנים לטפל בכל שגיאת קלט/פלט (I/O) מבוססת-קובץ שעלולה להתרחש.
מצד שני, כדי ליצור או לעדכן קובץ מדיה, אל תשתמשו
עמודה DATA
. במקום זאת, השתמש DISPLAY_NAME
RELATIVE_PATH
עמודות.
גישה לפרטי המיקום מהתמונות
אם האפליקציה משתמשת בנפח אחסון בהיקף, צריך לפעול לפי השלבים שמפורטים בקטע פרטי המיקום. בתמונות בקטע של המדריך לאחסון מדיה.
הגדרת מיקום האחסון להורדות חדשות
אם האפליקציה שלכם משתמשת באחסון מוגבל, חשוב לשים לב למיקום שבו בחרתם לאחסן את קובצי המדיה שאתם מורידים.
אם לאפליקציות אחרות נדרשת גישה לקבצים, כדאי להשתמש במדיה מוגדרת היטב אוספים להורדות או לאוספים של מסמכים.
ב-Android 11 ואילך, לאפליקציות אחרות אין גישה לקבצים שבספרייה החיצונית הספציפית לאפליקציה, גם אם משתמשים ב-DownloadManager
כדי לאחזר את הקבצים האלה.
ייצוא קובצי מדיה של משתמשים למכשיר
להגדיר מיקום ברירת מחדל מתאים לאחסון המדיה של המשתמש קבצים:
- המשתמשים יכולים לבחור אם לאפשר לאפליקציות אחרות לקרוא את קובצי המדיה שלהם או לא, באמצעות אחסון ספציפי לאפליקציה או נפח אחסון משותף.
- לאפשר למשתמשים לייצא קבצים מספריות ספציפיות לאפליקציה למיקום שגלוי לכולם. להשתמש באוספי התמונות, הסרטונים והאודיו של MediaStore כדי לייצא קובצי מדיה אל הגלריה של המכשיר.
שינוי או מחיקה של קובצי מדיה מרובים בפעולה אחת
שילוב לוגיקה על סמך גרסאות Android שהאפליקציה פועלת בהן.
מערכת ההפעלה Android 11
כדאי להשתמש בגישה הזו:
- יוצרים כוונה בהמתנה לבקשת הכתיבה או המחיקה של האפליקציה באמצעות
MediaStore.createWriteRequest()
אוMediaStore.createTrashRequest()
, ולאחר מכן מפעילים את הכוונה הזו כדי לבקש מהמשתמש הרשאה לערוך קבוצת קבצים. בודקים את התגובה של המשתמש:
- אם ההרשאה ניתנה, ממשיכים בפעולה של שינוי או מחיקה.
- אם ההרשאה לא ניתנה, הסבר למשתמש מדוע התכונה לאפליקציה שלך נדרשת ההרשאה.
מידע נוסף על ניהול קבוצות של מדיה קבצים באמצעות שזמינות ב-Android 11 ואילך.
פועלת ב-Android 10
אם האפליקציה מטרגטת את Android 10 (רמת API 29), אתם יכולים לבטל את ההסכמה לשימוש בהיקף אחסון ולהמשיך להשתמש בגישה ל-Android 9 ונמוכה יותר כדי לבצע את הפעולה הזו.
פועלת ב-Android מגרסה 9 ומטה
כדאי להשתמש בגישה הזו:
- בהתאם לשיטות המומלצות שמפורטות במאמר בקשה להרשאות לאפליקציה, מבקשים את ההרשאה
WRITE_EXTERNAL_STORAGE
. - משתמשים ב-API
MediaStore
כדי לשנות או למחוק את קובצי המדיה.
ייבוא של תמונה אחת שכבר קיימת
כשרוצים לייבא תמונה אחת שכבר קיימת (לדוגמה, כדי להשתמש בה כתמונה בפרופיל של משתמש), האפליקציה יכולה להשתמש בממשק המשתמש שלה לצורך הפעולה, או להשתמש בבורר של המערכת.
הצגת ממשק משתמש משלכם
כדאי להשתמש בגישה הזו:
- בהתאם לשיטות המומלצות שמתוארות במאמר בקשת הרשאות לאפליקציה,
לשלוח בקשה אל
READ_EXTERNAL_STORAGE
הרשאה. - משתמשים ב-API
query()
כדי לשלוח שאילתה לאוסף מדיה. - התוצאות יוצגו בממשק המשתמש המותאם אישית של האפליקציה שלך.
שימוש בבורר המערכת
משתמשים בכוונה ACTION_GET_CONTENT
, שבה המשתמש מתבקש לבחור תמונה לייבוא.
אם אתם רוצים לסנן את סוגי התמונות שבורר המערכת מציג
של משתמש לבחירה, אפשר להשתמש
setType()
או EXTRA_MIME_TYPES
.
צילום תמונה אחת
כשרוצים לצלם תמונה אחת לשימוש באפליקציה (לדוגמה, כדי להשתמש
כתמונה לפרופיל של משתמש), השתמשו
ACTION_IMAGE_CAPTURE
כוונה לבקש מהמשתמש לצלם תמונה באמצעות המצלמה של המכשיר. המערכת שומרת את התמונה שצולמה בטבלה MediaStore.Images
.
שיתוף קובצי מדיה עם אפליקציות אחרות
משתמשים ב-method insert()
כדי להוסיף רשומות ישירות ל-MediaStore. מידע נוסף זמין בקטע הוספת פריט במדריך לאחסון מדיה.
שיתוף קובצי מדיה עם אפליקציה ספציפית
משתמשים ברכיב FileProvider
של Android, כפי שמתואר במדריך הגדרת שיתוף קבצים.
גישה לקבצים מקוד או מספריות שמשתמשות בנתיבים ישירים של קבצים
לשלב לוגיקה על סמך גרסאות Android שבהן האפליקציה פועלת.
מערכת ההפעלה Android 11
כדאי להשתמש בגישה הזו:
- בהתאם לשיטות המומלצות שמתוארות במאמר בקשת הרשאות לאפליקציה,
לשלוח בקשה אל
READ_EXTERNAL_STORAGE
הרשאה. - לגשת לקבצים באמצעות נתיבים ישירים של קבצים.
מידע נוסף זמין בקטע בנושא פתיחת קובצי מדיה באמצעות נתיבי קבצים ישירים.
מערכת ההפעלה Android 10
אם האפליקציה שלכם מטרגטת את Android 10 (רמת API 29), עליכם לבטל את ההסכמה לאחסון מוגבל ולהמשיך להשתמש בגישה ל-Android 9 וגרסאות קודמות כדי לבצע את הפעולה הזו.
מערכת Android מגרסה 9 ומטה
כדאי להשתמש בגישה הזו:
- בהתאם לשיטות המומלצות שמתוארות במאמר בקשת הרשאות לאפליקציה,
לשלוח בקשה אל
WRITE_EXTERNAL_STORAGE
הרשאה. - לגשת לקבצים באמצעות נתיבים ישירים לקבצים.
טיפול בקבצים שאינם מדיה
בקטע הזה מתוארים כמה תרחישים לדוגמה נפוצים לטיפול בקובצי מדיה, ונסביר את הגישה ברמה גבוהה שאפשר להשתמש בה באפליקציה. בטבלה הבאה מופיע סיכום של כל אחד מהתרחישים לדוגמה, עם קישורים לכל אחד מהקטעים שמכילים פרטים נוספים.
תרחיש לדוגמה | סיכום |
---|---|
פתיחת קובץ מסמך | צריך להשתמש באותה גישה לכל הגרסאות של Android. |
כתיבה לקבצים ב- נפחי אחסון משניים | משתמשים בגישה אחת ל-Android 11. להשתמש בגישה שונה לשלב הקודם גרסאות Android. |
העברת קבצים קיימים ממיקום אחסון קודם | כשהדבר אפשרי, כדאי להעביר את הקבצים לאחסון מוגבל. ביטול ההסכמה לשימוש בהיקף אחסון ל-Android 10 במקרה הצורך. |
שיתוף תוכן עם אפליקציות אחרות | צריך להשתמש באותה גישה לכל הגרסאות של Android. |
אחסון במטמון של קבצים שאינם מדיה | יש להשתמש באותה גישה בכל הגרסאות של Android. |
ייצוא קבצים שאינם מדיה למכשיר | אם האפליקציה שלכם משתמשת בנפח האחסון הייעודי לאפליקציות, צריך להשתמש בגישה אחת. שימוש במשתנה אחר אם האפליקציה מפסיקה להשתמש בנפח אחסון בהיקף מסוים. |
פתיחת קובץ מסמך
משתמשים בכוונה ACTION_OPEN_DOCUMENT
כדי לבקש מהמשתמש לבחור קובץ לפתוח באמצעות הכלי של מערכת ההפעלה לבחירת תיקיות. אם רוצים לסנן את סוגי הקבצים שהכלי לבחירת קבצים של המערכת יציג למשתמש לבחירה, אפשר להשתמש ב-setType()
או ב-EXTRA_MIME_TYPES
.
לדוגמה, אפשר למצוא את כל קובצי ה-PDF, ODT ו-TXT באמצעות הקוד הבא:
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 )
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
כדאי להשתמש בגישה הזו:
- משתמשים במודל scoped storage.
- מטרגטים את Android 10 (רמת API 29) או גרסאות קודמות.
- מצהירים על ההרשאה
WRITE_EXTERNAL_STORAGE
. - לבצע אחד מסוגי הגישה הבאים:
- גישה לקובץ באמצעות ה-API של
MediaStore
. - גישה ישירה לנתיב הקובץ באמצעות ממשקי API כמו
File
אוfopen()
.
- גישה לקובץ באמצעות ה-API של
פועלות בגרסאות ישנות יותר
להשתמש ב-Storage Access Framework, שמאפשר למשתמשים לבחור את המיקום בנפח אחסון משני שבו האפליקציה יכולה לכתוב את הקובץ.
העברת קבצים קיימים ממיקום אחסון קודם
ספרייה נחשבת למיקום אחסון מדור קודם אם היא לא ספרייה ספציפית לאפליקציה או ספרייה ציבורית משותפת. אם האפליקציה יוצרת קבצים או משתמשת בהם במיקום אחסון מדור קודם, מומלץ להעביר את הקבצים של האפליקציה למיקומים שאפשר לגשת אליהם באמצעות אחסון מוגבל, ולבצע את השינויים הנדרשים באפליקציה כדי שתעבוד עם קבצים באחסון מוגבל.
שמירה על גישה למיקום האחסון הקודם לצורך העברת נתונים
לאפליקציה צריכה להיות גישה למיקום האחסון הקודם כדי להעביר את קובצי האפליקציה למיקומים שאפשר לגשת אליהם באמצעות אחסון מוגבל. הגישה שבה כדאי להשתמש תלויה ברמת ה-API המטורגטת של האפליקציה.
אם האפליקציה מטרגטת את Android 11
כדי לשמור על מודל האחסון הקודם, מגדירים את הדגל
preserveLegacyExternalStorage
לערךtrue
כדי שהאפליקציה תוכל להעביר את הנתונים של המשתמש כשהוא משדרג לגרסה החדשה של האפליקציה שמטרגטת את Android 11.להמשיך לבטל את ההסכמה לנפח אחסון בהיקף כדי לאפליקציה שלך תהיה אפשרות להמשיך לגשת לקבצים במיקום האחסון הקודם דרך מכשירי Android 10.
אם האפליקציה מטרגטת את Android 10
לבטל את ההסכמה לאחסון מוגבל כדי שיהיה קל יותר לשמור על התנהגות האפליקציה בגרסאות השונות של Android.
העברת נתוני האפליקציה
כשהאפליקציה מוכנה להעברה, יש להשתמש בשיטה הבאה:
- טירגוט ל-Android מגרסה 10 ומטה.
- לבטל את ההסכמה לשימוש בנפח האחסון הייעודי לאפליקציות כדי לאפליקציה תהיה גישה לקבצים שצריך להעביר.
-
פורסים קוד שמשתמש ב-API של
File
כדי להעביר קבצים מהמיקום הנוכחי שלהם ב-/sdcard/
למיקום שאפשר לגשת אליו באמצעות אחסון מוגדר-היקף:- מעבירים את כל קבצי האפליקציה הפרטיים לספרייה שמוחזרת על ידי השיטה
getExternalFilesDir()
. - מעבירים קבצים משותפים שאינם מדיה לתיקיית משנה ייעודית לאפליקציה בספרייה
Downloads/
.
- מעבירים את כל קבצי האפליקציה הפרטיים לספרייה שמוחזרת על ידי השיטה
- מסירים את ספריות האחסון הקודמות של האפליקציה מהספרייה
/sdcard/
.
אחרי שהמשתמשים מתקינים את הגרסה החדשה של האפליקציה, הם משלימים את הנתונים את תהליך ההעברה במכשירים שלהם. כדי לעקוב אחרי תהליך ההעברה בקרב בסיס המשתמשים, אפשר ליצור אירוע ב-Analytics.
אחרי שהמשתמשים יעבירו את הנתונים שלהם, תוכלו לפרסם עדכון נוסף לאפליקציה שבו תגדירו את Android 11 כיעד.
שיתוף תוכן עם אפליקציות אחרות
כדי לשתף את הקבצים של האפליקציה עם אפליקציה אחת אחרת, משתמשים ב-FileProvider
. אפליקציות שכולן צריכות לשתף
הקבצים בין שני הקבצים, מומלץ להשתמש בתוכן
ספק לכל אפליקציה, וגם
ולאחר מכן לסנכרן את הנתונים בזמן שהאפליקציות מתווספות לאוסף.
שמירת קבצים שאינם קובצי מדיה במטמון
הגישה שבה צריך להשתמש תלויה בסוג הקבצים שדרושים לכם במטמון.
- קבצים קטנים או קבצים שמכילים מידע רגיש: יש להשתמש ב-
Context#getCacheDir()
. - קבצים גדולים או קבצים שלא מכילים מידע רגיש: יש להשתמש ב-
Context#getExternalCacheDir()
.
ייצוא קבצים שאינם מדיה למכשיר
מגדירים מיקום ברירת מחדל מתאים לאחסון קבצים שאינם מדיה. לאפשר למשתמשים לייצא קבצים מספריות ספציפיות לאפליקציה למיקום שגלוי לכולם. שימוש בהורדות או אוספי מסמכים של MediaStore כדי לייצא קבצים שאינם מדיה אל במכשיר.
טיפול בקבצים ספציפיים לאפליקציה
במקרה שהאפליקציה יוצרת קבצים שאפליקציות אחרות לא צריכות לגשת אליהם, או אין לך גישה, ניתן לאחסן את הקבצים האלה מיקומי אחסון ספציפיים לאפליקציה.
ספריות אחסון פנימי
המערכת מונעת מאפליקציות אחרות לגשת למיקומים האלה, וב-Android 10 (רמת API 29) ואילך המיקומים האלה מוצפנים. המיקומים האלה מומלץ לאחסן מידע אישי רגיש שרק לאפליקציה שלך יש גישה אליו.
ספריות אחסון חיצוניות
אם אין מספיק מקום באחסון הפנימי לאחסון קבצים ספציפיים לאפליקציה, מומלץ להשתמש באחסון חיצוני במקום זאת. למרות שאפשר לבצע זאת באפליקציה אחרת כדי לגשת לספריות האלה אם לאפליקציה הזו יש את ההרשאות המתאימות, הקבצים שמאוחסנים בספריות האלה. מיועדים לשימוש באפליקציה בלבד.
ב-Android מגרסה 4.4 (רמת API 19) ואילך, האפליקציה שלך לא צריכה לבקש הרשאות שקשורות לאחסון לצורך גישה לספריות ספציפיות לאפליקציה בתוך אחסון.
כשהמשתמש מסיר את ההתקנה של האפליקציה, הקבצים שנשמרו באחסון הספציפי לאפליקציה: ולכן לא מומלץ להשתמש באחסון הזה כל נתון שהמשתמש מצפה שיישאר באופן בלתי תלוי באפליקציה.
ביטול ההסכמה לשימוש באחסון מוגבל זמנית
לפני שהאפליקציה שלכם תהיה תואמת באופן מלא לאחסון מוגבל, תוכלו לבטל את ההסכמה באופן זמני, גם בבדיקות וגם באפליקציה בסביבת הייצור.
ביטול ההסכמה בבדיקות
ב-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 זמין במאמרים הבאים: