【问题标题】:How to save pdf file in a Media Store in Android 10 and above using JAVA?如何使用 JAVA 在 Android 10 及更高版本的媒体商店中保存 pdf 文件?
【发布时间】:2020-08-19 04:53:29
【问题描述】:

更新:

为了保存 PDF 文件:

在下面的答案部分。

为了保存位图文件:

@RequiresApi(api = Build.VERSION_CODES.Q)
@NonNull
private Uri saveBitmap(@NonNull final Context context, @NonNull final Bitmap bitmap,
                       @NonNull final Bitmap.CompressFormat format, @NonNull final String mimeType,
                       @NonNull final String displayName, @Nullable final String subFolder) throws IOException {
    String relativeLocation = Environment.DIRECTORY_PICTURES;

    if (!TextUtils.isEmpty(subFolder)) {
        relativeLocation += File.separator + subFolder;
    }

    final ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
    contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);

    final ContentResolver resolver = context.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) {
            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(format, 95, stream)) {
            throw new IOException("Failed to save bitmap.");
        }

        return uri;
    } catch (IOException e) {
        if (uri != null) {
            // Don't leave an orphan entry in the MediaStore
            resolver.delete(uri, null, null);
        }

        throw e;
    } finally {
        if (stream != null) {
            stream.close();
        }
    }
}

【问题讨论】:

    标签: java pdf mediastore android-external-storage scoped-storage


    【解决方案1】:

    在 android 10 及更高版本中保存 PDF 文件:

    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void savePdfAndLogUri() {
        try {
            InputStream in = getAssets().open("eliza.pdf");
            Uri savedFileUri = savePDFFile(MainActivity.this, in, "files/pdf", "eliza.pdf", "resume");
            Log.d("URI: ", savedFileUri.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    @RequiresApi(api = Build.VERSION_CODES.Q)
    @NonNull
    private Uri savePDFFile(@NonNull final Context context, @NonNull InputStream in,
                            @NonNull final String mimeType,
                            @NonNull final String displayName, @Nullable final String subFolder) throws IOException {
        String relativeLocation = Environment.DIRECTORY_DOCUMENTS;
    
        if (!TextUtils.isEmpty(subFolder)) {
            relativeLocation += File.separator + subFolder;
        }
        
        final ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName);
        contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
        contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation);
        contentValues.put(MediaStore.Video.Media.TITLE, "SomeName");
        contentValues.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
        contentValues.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
        final ContentResolver resolver = context.getContentResolver();
        OutputStream stream = null;
        Uri uri = null;
        
        try {
            final Uri contentUri = MediaStore.Files.getContentUri("external");
            uri = resolver.insert(contentUri, contentValues);
            ParcelFileDescriptor pfd;
            try {
                assert uri != null;
                pfd = getContentResolver().openFileDescriptor(uri, "w");
                assert pfd != null;
                FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
    
                byte[] buf = new byte[4 * 1024];
                int len;
                while ((len = in.read(buf)) > 0) {
    
                    out.write(buf, 0, len);
                }
                out.close();
                in.close();
                pfd.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            contentValues.clear();
            contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
            getContentResolver().update(uri, contentValues, null, null);
            stream = resolver.openOutputStream(uri);
            if (stream == null) {
                throw new IOException("Failed to get output stream.");
            }
            return uri;
        } catch (IOException e) {
            // Don't leave an orphan entry in the MediaStore
            resolver.delete(uri, null, null);
            throw e;
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
    }
    

    【讨论】:

    • 感谢这个 sn-p。但我认为,PDF 通常有application/pdf mimetype。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 2015-03-04
    • 2015-01-25
    • 2022-12-18
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多