簡體   English   中英

從 Android Q 中的外部存儲訪問照片

[英]Access photos from external storage in Android Q

我最近將應用程序的目標版本升級到 API 29。由於 Android 10 中的范圍存儲,我使用 MediaStore API 來存儲和檢索外部應用程序中的圖像早些時候,我使用getExternalStoragePublicDirectory存儲通過相機拍攝的圖像,現在我使用MediaStore.Images.Media.EXTERNAL_CONTENT_URI將文件寫入外部存儲位置。

我現在面臨的問題是,當我打開我的應用程序並拍照時,它存儲在我給“myapp”的文件夾名稱下,我可以通過 Mediastore cursor 檢索我的圖像並將它們顯示在自定義庫中。 當我卸載我的應用程序'myapp'文件夾仍然存在。 當我再次安裝我的應用程序並嘗試從圖庫中讀取圖像時,cursor 沒有返回任何圖像。 但如果我再次拍照,那么我可以將它們加載到我的自定義畫廊。 自定義圖庫視圖只是屏幕底部的一行圖像,因此用戶無需瀏覽照片文件夾即可將圖像加載到應用程序。

這就是我將圖像存儲在 MediaStore 中的方式

內容值:

String RELATIVE_PATH = Environment.DIRECTORY_PICTURES + File.separator + "myApp";
final ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, generateImageName(new Date()));
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, RELATIVE_PATH);

生成名稱方法:

int sameSecondCount;
protected String generateName(Date now)
    {
        String result = formatter.format(now);

        long nowMillis = now.getTime();
        if (nowMillis / 1000 == lastMillis / 1000)
        {
            sameSecondCount++;
            result += "_" + sameSecondCount;
        }
        else
            sameSecondCount = 0;

        lastMillis = nowMillis;

        return result + PICTURE_EXTENSION_JPG;
    }
@WorkerThread
    private Uri writePictureToFile(ContentValues contentValues, byte[] bitmapBytes) throws IOException
    {
        final ContentResolver resolver = getApplication().getContentResolver();

        Uri uri = null;
        final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

        try
        {
            uri = resolver.insert(contentUri, contentValues);

            if (uri == null)
                throw new IOException("Failed to create new MediaStore record.");

            OutputStream stream = resolver.openOutputStream(uri);

            if (stream == null)
            {
                throw new IOException("Failed to get output stream.");
            }

            stream.write(bitmapBytes);
        }
        catch (IOException e)
        {
            // Delete the content from the media store
            if (uri != null)
                resolver.delete(uri, null, null);
            throw e;
        }
        return uri;
    } 

讀取圖像

{
                String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE + " in (?,?,?)";
                String[] args = new String[]{
                    MimeTypeMap.getSingleton().getMimeTypeFromExtension("jpg"),
                    MimeTypeMap.getSingleton().getMimeTypeFromExtension("png")};

                Cursor cursor = context.getContentResolver()
                    .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, selectionMimeType, selectionArgs,
                        orderBy + " DESC");
                if (cursor != null)
                {
                    int idColumnIndex = imageCursor.getColumnIndex(MediaStore.Images.Media._ID);
                    imageCursor.moveToFirst();
                    int imageCount = imageCursor.getCount();
                    for (int i = 0; i < imageCount && i < totalCount; i++)
                    {
                        final long imageId = imageCursor.getLong(idColumnIndex);
                        Uri uriImage = Uri.withAppendedPath(uriExternal, "" + imageId);
                        GalleryData galleryImageData = new GalleryImageData(imageId, uriImage); // Custom class with id and Uri
                        galleryViewModelList.add(galleryImageData);
                        imageCursor.moveToNext();
                    }
                    imageCursor.close();
                }

為什么當我重新安裝我的應用程序時,上述代碼沒有返回我存儲在 Mediastore 文件夾中的圖像。 是設計使然還是我遺漏了什么?

這些是我正在檢索的列,

final String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID, MediaStore.Images.Media.MIME_TYPE };
final String orderBy = MediaStore.Images.Media.DATE_TAKEN; ```

由於不清楚的原因,Android 10 將按時間分開的兩個應用程序安裝視為單獨的應用程序,這與兩個完全不同的應用程序沒有什么不同。

因此,一旦您的應用程序被卸載,它就會失去對它創建的所有文件的訪問權限……即使后來重新安裝了同一個應用程序。

因此,您需要像處理來自完全不相關的應用程序的文件一樣處理以前安裝的應用程序中的文件:請求READ_EXTERNAL_STORAGE以便能夠查詢它們並讀取它們的內容。 “讀取其內容”部分需要清單中<application>上的android:requestLegacyExternalStorage="true"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM