访问和共享Android Q的内部/外部存储中Picture文件夹下的文件

问题描述 投票:0回答:1

[在存储管理方面,Android Q发生了许多重大变化,我的应用程序功能之一是允许用户在View之类的CardView项目中拍摄照片,然后为其创建Bitmap,将其保存到设备的大容量存储中。保存完成后,它将触发Intent.ACTION_SEND,因此用户可以将最近保存的图像和一些描述分享到社交应用,并使用GMail撰写电子邮件。

此代码段可以正常工作。

        try {
        //Get primary storage status
        String state = Environment.getExternalStorageState();
        File filePath = new File(view.getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" + "Shared");

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            try {
                if (filePath.mkdirs())
                    Log.d("Share Intent", "New folder is created.");
            } catch (Exception e) {
                e.printStackTrace();
                Crashlytics.logException(e);
            }
        }

        //Create a new file
        File imageFile = new File(filePath, UUID.randomUUID().toString() + ".png");

        //Create bitmap screen capture
        Bitmap bitmap = Bitmap.createBitmap(loadBitmapFromView(view));

        FileOutputStream outputStream = new FileOutputStream(imageFile);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);

        outputStream.flush();
        outputStream.close();

        Toast.makeText(view.getContext(), "Successfully save!", Toast.LENGTH_SHORT).show();

        shareToInstant(description, imageFile, view);


    } catch (IOException e) {
        e.printStackTrace();
        Crashlytics.logException(e);
    }

但是这会将图像文件保存到/storage/emulated/0/Android/data/YOUR_APP_PACKAGE_NAME/files/Pictures

我想要像大多数应用程序一样将它们保存在根目录/storage/emulated/0/Pictures中的默认“图片”文件夹中,以使图像更易暴露,并且图库易于查看和扫描。

为此,我将上面的代码段更改为此。

 //Create bitmap screen capture
    Bitmap bitmap = Bitmap.createBitmap(loadBitmapFromView(view));

    final String relativeLocation = Environment.DIRECTORY_PICTURES + "/" + view.getContext().getString(R.string.app_name);

    final ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, UUID.randomUUID().toString() + ".png");
    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
    contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);

    final ContentResolver resolver = view.getContext().getContentResolver();

    OutputStream stream = null;
    Uri uri = null;

    try {

        final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        uri = resolver.insert(contentUri, contentValues);

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

        stream = resolver.openOutputStream(uri);

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

        if (!bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)) {
            throw new IOException("Failed to save bitmap.");
        }

        //If we reach this part we're good to go
        Intent mediaScannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        File imageFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), contentValues.getAsString(MediaStore.MediaColumns.DISPLAY_NAME));
        Uri fileContentUri = Uri.fromFile(imageFile);
        mediaScannerIntent.setData(fileContentUri);
        view.getContext().sendBroadcast(mediaScannerIntent);

        shareToInstant(description, imageFile, view);

    } catch (IOException e) {
        if (uri != null) {
            // Don't leave an orphan entry in the MediaStore
            resolver.delete(uri, null, null);
        }
        e.printStackTrace();
        Crashlytics.logException(e);
    } finally {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
                Crashlytics.logException(e);
            }
        }
    }

[也可以工作,但无法将图像附加/共享到其他应用程序,例如GMail,据说Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)也已被弃用,所以我不知道现在应该怎么做,因为我已经为此进行了很多研究但没有运气。在此问题上找到了类似的情况。

这是我的FileProvider外观。

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external"
        path="." />
    <external-files-path
        name="external_files"
        path="." />
    <cache-path
        name="cache"
        path="." />
    <external-cache-path
        name="external_cache"
        path="." />
    <files-path
        name="files"
        path="." />
</paths>

这是我的意图共享代码段。

private static void shareToInstant(String content, File imageFile, View view) {

    Intent sharingIntent = new Intent(Intent.ACTION_SEND);
    sharingIntent.setType("image/png");
    sharingIntent.setType("text/plain");
    sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    sharingIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    sharingIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(view.getContext(), BuildConfig.APPLICATION_ID + ".provider", imageFile));
    sharingIntent.putExtra(Intent.EXTRA_TEXT, content);

    try {
        view.getContext().startActivity(Intent.createChooser(sharingIntent, "Share it Via"));
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(view.getContext(), R.string.unknown_error, Toast.LENGTH_SHORT).show();
    }
}
android mediastore android-fileprovider
1个回答
0
投票

[似乎您只需在FileProvider.getUriForFile(context, authority, file);中传递uri,仍然可以在Android Q中访问文件而无需resolver.insert(contentUri, contentValues);

© www.soinside.com 2019 - 2024. All rights reserved.