برای اینکه کاربران کنترل بیشتری بر روی فایلهای خود داشته باشند و به هم ریختگی فایلها محدود شود، اندروید 10 یک الگوی ذخیرهسازی جدید برای برنامهها به نام فضای ذخیرهسازی scoped معرفی کرد. فضای ذخیرهسازی Scoped نحوه ذخیره و دسترسی برنامهها به فایلها در حافظه خارجی دستگاه را تغییر میدهد. برای کمک به انتقال برنامه خود برای پشتیبانی از فضای ذخیرهسازی محدوده، بهترین روشها را برای موارد رایج استفاده از فضای ذخیرهسازی که در این راهنما بیان شده است، دنبال کنید. موارد استفاده به دو دسته تقسیم می شوند: مدیریت فایل های رسانه ای و مدیریت فایل های غیر رسانه ای .
برای کسب اطلاعات بیشتر در مورد نحوه ذخیره و دسترسی به فایل ها در اندروید، راهنمای آموزش ذخیره سازی را ببینید.
مدیریت فایل های رسانه ای
این بخش برخی از موارد استفاده رایج برای مدیریت فایل های رسانه ای (فایل های ویدیویی، تصویری و صوتی) را توضیح می دهد و رویکرد سطح بالایی که برنامه شما می تواند استفاده کند را توضیح می دهد. جدول زیر هر یک از این موارد استفاده را خلاصه میکند و به هر یک از بخشهایی که حاوی جزئیات بیشتر هستند پیوند دارد.
مورد استفاده | خلاصه |
---|---|
نمایش تمام فایل های تصویری یا ویدیویی | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
نمایش تصاویر یا ویدیوها از یک پوشه خاص | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
دسترسی به اطلاعات موقعیت مکانی از عکس ها | اگر برنامه شما از فضای ذخیرهسازی دامنهدار استفاده میکند، از یک رویکرد استفاده کنید. اگر برنامهتان از فضای ذخیرهسازی دامنهدار منصرف شد، از رویکرد دیگری استفاده کنید. |
مکان ذخیره سازی را برای دانلودهای جدید تعریف کنید | اگر برنامه شما از فضای ذخیرهسازی دامنهدار استفاده میکند، از یک رویکرد استفاده کنید. اگر برنامهتان از فضای ذخیرهسازی دامنهدار منصرف شد، از رویکرد دیگری استفاده کنید. |
فایل های رسانه ای کاربر را به یک دستگاه صادر کنید | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
چندین فایل رسانه ای را در یک عملیات تغییر دهید یا حذف کنید | از یک روش برای Android 11 استفاده کنید. برای Android 10، از فضای ذخیرهسازی محدوده خودداری کنید و به جای آن از رویکرد Android 9 و پایینتر استفاده کنید. |
یک تصویر واحد را وارد کنید که از قبل وجود دارد | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
گرفتن یک تصویر واحد | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
فایل های رسانه ای را با سایر برنامه ها به اشتراک بگذارید | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
فایل های رسانه ای را با یک برنامه خاص به اشتراک بگذارید | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
از کد یا کتابخانه هایی که از مسیرهای فایل مستقیم استفاده می کنند به فایل ها دسترسی پیدا کنید | از یک روش برای Android 11 استفاده کنید. برای Android 10، از فضای ذخیرهسازی محدوده خودداری کنید و به جای آن از رویکرد Android 9 و پایینتر استفاده کنید. |
نمایش فایل های تصویری یا ویدیویی از چندین پوشه
با استفاده از query()
API یک مجموعه رسانه را پرس و جو کنید . برای فیلتر یا مرتبسازی فایلهای رسانه، پارامترهای projection
، selection
، selectionArgs
و sortOrder
را تنظیم کنید.
نمایش تصاویر یا ویدیوها از یک پوشه خاص
از این رویکرد استفاده کنید:
- با پیروی از بهترین روشهای ذکر شده در درخواست مجوزهای برنامه ، مجوز
READ_EXTERNAL_STORAGE
را درخواست کنید. - فایل های رسانه ای را بر اساس مقدار
MediaColumns.DATA
بازیابی کنید، که شامل مسیر سیستم فایل مطلق به آیتم رسانه روی دیسک است.
توجه: هنگامی که به یک فایل رسانه ای موجود دسترسی دارید، می توانید از مقدار ستون DATA
در منطق خود استفاده کنید. به این دلیل که این مقدار دارای یک مسیر فایل معتبر است. با این حال، فرض نکنید که فایل همیشه در دسترس است. برای رسیدگی به هر گونه خطای ورودی/خروجی مبتنی بر فایل که ممکن است رخ دهد آماده باشید.
از طرف دیگر، برای ایجاد یا به روز رسانی یک فایل رسانه ای، از ستون DATA
استفاده نکنید. در عوض، از ستونهای DISPLAY_NAME
و RELATIVE_PATH
استفاده کنید.
دسترسی به اطلاعات موقعیت مکانی از عکس ها
اگر برنامه شما از فضای ذخیرهسازی دامنهدار استفاده میکند، مراحل موجود در بخش اطلاعات مکان در عکسها در راهنمای ذخیرهسازی رسانه را دنبال کنید.
مکان ذخیره سازی را برای دانلودهای جدید تعریف کنید
اگر برنامه شما از فضای ذخیرهسازی محدوده استفاده میکند، به مکانی که برای ذخیره فایلهای رسانهای که دانلود میکنید، توجه داشته باشید.
اگر برنامههای دیگر نیاز به دسترسی به فایلها دارند، از مجموعههای رسانهای تعریفشده برای دانلود یا مجموعه اسناد استفاده کنید.
در Android 11 و بالاتر، حتی اگر از DownloadManager
برای واکشی این فایلها استفاده کنید، فایلهای داخل فهرست راهنمای ویژه برنامه خارجی شما برای سایر برنامهها قابل دسترسی نیستند.
فایل های رسانه ای کاربر را به یک دستگاه صادر کنید
یک مکان پیش فرض مناسب برای ذخیره فایل های رسانه ای کاربر تعریف کنید:
- به کاربران امکان میدهد با استفاده از فضای ذخیرهسازی خاص برنامه یا فضای ذخیرهسازی مشترک ، انتخاب کنند که آیا فایلهای رسانهای خود را برای سایر برنامهها خوانا کنند یا نه.
- به کاربران اجازه میدهد فایلها را از دایرکتوریهای مخصوص برنامه به مکان عمومیتر در دسترستر صادر کنند. از تصاویر، ویدیوها و مجموعه های صوتی MediaStore برای صادر کردن فایل های رسانه ای به گالری دستگاه استفاده کنید.
چندین فایل رسانه ای را در یک عملیات تغییر دهید یا حذف کنید
منطق را بر اساس نسخه های اندرویدی که برنامه شما روی آن اجرا می شود، ترکیب کنید.
قابل اجرا بر روی اندروید 11
از این روش استفاده کنید:
- با استفاده از
MediaStore.createWriteRequest()
یاMediaStore.createTrashRequest()
یک intent معلق برای درخواست نوشتن یا حذف برنامه خود ایجاد کنید و سپس با فراخوانی آن intent از کاربر بخواهید اجازه ویرایش مجموعه ای از فایل ها را بدهد. پاسخ کاربر را ارزیابی کنید:
- اگر مجوز داده شد، عملیات تغییر یا حذف را ادامه دهید.
- اگر مجوز اعطا نشد، به کاربر توضیح دهید که چرا ویژگی در برنامه شما به مجوز نیاز دارد.
درباره نحوه مدیریت گروههای فایلهای رسانه با استفاده از این روشها که در Android 11 و بالاتر موجود است، بیشتر بیاموزید.
قابل اجرا بر روی اندروید 10
اگر برنامه شما Android 10 (سطح API 29) را هدف قرار میدهد، از فضای ذخیرهسازی انصراف دهید و به استفاده از رویکرد Android 9 و پایینتر برای انجام این عملیات ادامه دهید.
قابل اجرا در اندروید 9 یا پایین تر
از این رویکرد استفاده کنید:
- با پیروی از بهترین روشهای ذکر شده در درخواست مجوزهای برنامه ، مجوز
WRITE_EXTERNAL_STORAGE
را درخواست کنید. - از
MediaStore
API برای تغییر یا حذف فایل های رسانه استفاده کنید.
یک تصویر واحد را وارد کنید که از قبل وجود دارد
هنگامی که می خواهید یک تصویر واحد را وارد کنید که از قبل وجود دارد (مثلاً برای استفاده به عنوان عکس برای نمایه کاربر)، برنامه شما می تواند از رابط کاربری خود برای این عملیات استفاده کند یا می تواند از انتخابگر سیستم استفاده کند.
رابط کاربری خود را ارائه دهید
از این رویکرد استفاده کنید:
- با پیروی از بهترین روشهای ذکر شده در درخواست مجوزهای برنامه ، مجوز
READ_EXTERNAL_STORAGE
را درخواست کنید. - از
query()
API برای پرس و جو از یک مجموعه رسانه استفاده کنید. - نتایج را در رابط کاربری سفارشی برنامه خود نمایش دهید.
از انتخابگر سیستم استفاده کنید
از هدف ACTION_GET_CONTENT
استفاده کنید، که از کاربر میخواهد تصویری را برای وارد کردن انتخاب کند.
اگر میخواهید انواع تصاویری را که انتخابگر سیستم به کاربر ارائه میدهد فیلتر کنید، میتوانید از setType()
یا EXTRA_MIME_TYPES
استفاده کنید.
گرفتن یک تصویر واحد
هنگامی که می خواهید یک عکس بگیرید تا در برنامه خود استفاده کنید (مثلاً برای استفاده به عنوان عکس برای نمایه کاربر)، از هدف ACTION_IMAGE_CAPTURE
استفاده کنید تا از کاربر بخواهید با استفاده از دوربین دستگاه عکس بگیرد. سیستم عکس گرفته شده را در جدول MediaStore.Images
ذخیره می کند.
فایل های رسانه ای را با سایر برنامه ها به اشتراک بگذارید
از متد insert()
برای اضافه کردن رکوردها به طور مستقیم به MediaStore استفاده کنید. برای اطلاعات بیشتر، به بخش افزودن یک مورد از راهنمای ذخیره سازی رسانه مراجعه کنید.
فایل های رسانه ای را با یک برنامه خاص به اشتراک بگذارید
همانطور که در راهنمای اشتراکگذاری فایل راهاندازی توضیح داده شده است، از مؤلفه Android FileProvider
استفاده کنید.
از کد یا کتابخانه هایی که از مسیرهای فایل مستقیم استفاده می کنند به فایل ها دسترسی پیدا کنید
منطق را بر اساس نسخه های اندرویدی که برنامه شما روی آن اجرا می شود، ترکیب کنید.
قابل اجرا بر روی اندروید 11
از این رویکرد استفاده کنید:
- با پیروی از بهترین روشهای ذکر شده در درخواست مجوزهای برنامه ، مجوز
READ_EXTERNAL_STORAGE
را درخواست کنید. - با استفاده از مسیرهای فایل مستقیم به فایل ها دسترسی پیدا کنید.
برای اطلاعات بیشتر، به بخش نحوه باز کردن فایلهای رسانه با استفاده از مسیرهای فایل مستقیم مراجعه کنید.
قابل اجرا بر روی اندروید 10
اگر برنامه شما Android 10 (سطح API 29) را هدف قرار میدهد، از فضای ذخیرهسازی انصراف دهید و به استفاده از رویکرد Android 9 و پایینتر برای انجام این عملیات ادامه دهید.
قابل اجرا در اندروید 9 یا پایین تر
از این رویکرد استفاده کنید:
- با پیروی از بهترین روشهای ذکر شده در درخواست مجوزهای برنامه ، مجوز
WRITE_EXTERNAL_STORAGE
را درخواست کنید. - با استفاده از مسیرهای فایل مستقیم به فایل ها دسترسی پیدا کنید.
مدیریت فایل های غیر رسانه ای
این بخش برخی از موارد استفاده رایج برای مدیریت فایلهای غیر رسانهای را توضیح میدهد و رویکرد سطح بالایی که برنامه شما میتواند استفاده کند را توضیح میدهد. جدول زیر هر یک از این موارد استفاده را خلاصه میکند و به هر یک از بخشهایی که حاوی جزئیات بیشتر هستند پیوند دارد.
مورد استفاده | خلاصه |
---|---|
یک فایل سند باز کنید | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
روی فایلهای موجود در حجمهای ذخیرهسازی ثانویه بنویسید | از یک رویکرد برای اندروید 11 استفاده کنید. برای نسخه های قبلی اندروید از یک رویکرد متفاوت استفاده کنید. |
فایلهای موجود را از یک مکان ذخیرهسازی قدیمی منتقل کنید | در صورت امکان، فایلهای خود را به فضای ذخیرهسازی محدوده انتقال دهید. در صورت لزوم از فضای ذخیرهسازی محدود برای Android 10 انصراف دهید. |
اشتراک گذاری محتوا با سایر برنامه ها | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
کش فایل های غیر رسانه ای | از همین رویکرد برای همه نسخه های اندروید استفاده کنید. |
فایل های غیر رسانه ای را به دستگاه صادر کنید | اگر برنامه شما از فضای ذخیرهسازی دامنهدار استفاده میکند، از یک رویکرد استفاده کنید. اگر برنامهتان از فضای ذخیرهسازی دامنهدار منصرف شد، از رویکرد دیگری استفاده کنید. |
یک فایل سند باز کنید
از قصد 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
به اطلاعات مربوط به حجم ذخیره سازی داده شده دسترسی پیدا کنید.
منطق را بر اساس نسخه اندرویدی که برنامه شما روی آن اجرا می شود، وارد کنید.
قابل اجرا بر روی اندروید 11
از این رویکرد استفاده کنید:
- از مدل ذخیره سازی محدوده استفاده کنید.
- Android 10 (سطح API 29) یا پایینتر را هدف قرار دهید.
- مجوز
WRITE_EXTERNAL_STORAGE
را اعلام کنید. - یکی از انواع دسترسی های زیر را انجام دهید:
- دسترسی به فایل با استفاده از
MediaStore
API. - دسترسی مستقیم به مسیر فایل با استفاده از APIهایی مانند
File
یاfopen()
.
- دسترسی به فایل با استفاده از
در حال اجرا بر روی نسخه های قدیمی تر
از چارچوب دسترسی به فضای ذخیرهسازی استفاده کنید، که به کاربران امکان میدهد مکان را در یک حجم ذخیرهسازی ثانویه انتخاب کنند که برنامه شما میتواند فایل را بنویسد.
فایلهای موجود را از یک مکان ذخیرهسازی قدیمی منتقل کنید
دایرکتوری اگر دایرکتوری مخصوص برنامه یا دایرکتوری مشترک عمومی نباشد، یک مکان ذخیره سازی قدیمی در نظر گرفته می شود. اگر برنامه شما فایلهایی را در یک مکان ذخیرهسازی قدیمی ایجاد یا مصرف میکند، توصیه میکنیم فایلهای برنامه خود را به مکانهایی منتقل کنید که با فضای ذخیرهسازی محدوده قابل دسترسی هستند و تغییرات لازم در برنامه را برای کار با فایلهای موجود در فضای ذخیرهسازی محدوده انجام دهید.
دسترسی به مکان ذخیره سازی قدیمی را برای انتقال داده ها حفظ کنید
برنامه شما باید به مکان ذخیره سازی قدیمی دسترسی داشته باشد تا بتواند فایل های برنامه را به مکان هایی منتقل کند که با فضای ذخیره سازی محدوده قابل دسترسی هستند. رویکردی که باید استفاده کنید به سطح API هدف برنامه شما بستگی دارد.
اگر برنامه شما اندروید 11 را هدف قرار می دهد
برای حفظ مدل ذخیره سازی قدیمی، پرچم
preserveLegacyExternalStorage
را رویtrue
تنظیم کنید تا برنامه شما بتواند داده های کاربر را هنگام ارتقا به نسخه جدید برنامه شما که اندروید 11 را هدف قرار می دهد، منتقل کند.به انصراف از فضای ذخیرهسازی محدوده ادامه دهید تا برنامه شما بتواند همچنان به فایلهای شما در مکان ذخیرهسازی قدیمی در دستگاههای Android 10 دسترسی داشته باشد.
اگر برنامه شما اندروید 10 را هدف قرار می دهد
برای آسانتر کردن حفظ رفتار برنامهتان در سراسر نسخههای Android ، از فضای ذخیرهسازی محدوده خارج شوید .
انتقال داده های برنامه
وقتی برنامه شما آماده انتقال است، از روش زیر استفاده کنید:
- اندروید 10 یا پایینتر را هدف قرار دهید.
- از فضای ذخیرهسازی با محدوده انصراف دهید تا برنامه شما به فایلهایی که باید انتقال دهید دسترسی داشته باشد.
کدی را مستقر کنید که از
File
API برای انتقال فایلها از مکان فعلیشان در زیر/sdcard/
به مکانی که با فضای ذخیرهسازی محدوده قابل دسترسی است استفاده میکند:- هر فایل برنامه خصوصی را به دایرکتوری که با متد
getExternalFilesDir()
برگردانده شده است منتقل کنید. - فایلهای غیررسانهای به اشتراکگذاشتهشده را به یک زیرشاخه اختصاصی برنامه از دایرکتوری
Downloads/
منتقل کنید.
- هر فایل برنامه خصوصی را به دایرکتوری که با متد
- دایرکتوری های ذخیره سازی قدیمی برنامه خود را از پوشه
/sdcard/
حذف کنید.
پس از اینکه کاربران نسخه جدید برنامه شما را نصب کردند، فرآیند انتقال داده را در دستگاه های خود تکمیل می کنند. شما می توانید با ایجاد یک رویداد تحلیلی، روند مهاجرت را در پایگاه کاربر خود نظارت کنید.
پس از اینکه کاربران اطلاعات خود را انتقال دادند، بهروزرسانی دیگری را برای برنامه خود منتشر کنید، جایی که 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
این رفتار را انتخاب کنید. اگر روی دستگاهی آزمایش میکنید که اندروید 11 را اجرا میکند، میتوانید از پرچمهای سازگاری برنامه نیز برای آزمایش رفتار برنامه خود با یا بدون فضای ذخیرهسازی محدوده استفاده کنید .
منابع اضافی
برای اطلاعات بیشتر در مورد فضای ذخیره سازی اندروید، مطالب زیر را مشاهده کنید: