| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- package com.datarecovery.master.utils;
- import android.content.ContentResolver;
- import android.content.ContentValues;
- import android.content.Context;
- import android.net.Uri;
- import android.os.Build;
- import android.os.ParcelFileDescriptor;
- import android.provider.MediaStore;
- import androidx.annotation.IntDef;
- import androidx.annotation.RequiresApi;
- import com.atmob.common.runtime.ContextUtil;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- /**
- * 用于保存文件到公共存储空间
- */
- public class MediaStoreHelper {
- public static final int TYPE_IMAGE = 1;
- public static final int TYPE_VIDEO = 2;
- public static final int TYPE_AUDIO = 3;
- public static final int TYPE_FILES = 4;
- public static final int TYPE_DOWNLOADS = 5;
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({TYPE_IMAGE, TYPE_VIDEO, TYPE_AUDIO, TYPE_FILES, TYPE_DOWNLOADS})
- @interface MediaType {
- }
- public static void saveToSharedStorage(@MediaType int mediaType, File file, String fileName) throws Exception {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- saveToSharedStorage(mediaType, java.nio.file.Files.newInputStream(file.toPath()), fileName);
- } else {
- saveToSharedStorage(mediaType, new FileInputStream(file), fileName);
- }
- }
- public static void saveToSharedStorage(@MediaType int mediaType, InputStream inputStream, String fileName) throws Exception {
- // Add a media item that other apps don't see until the item is
- // fully written to the media store.
- Context applicationContext = ContextUtil.getContext().getApplicationContext();
- ContentResolver resolver = applicationContext.getContentResolver();
- Media targetMedia = getTargetMedia(mediaType);
- // Find all media files on the primary external storage device.
- Uri mediaCollection = targetMedia.getMediaCollection();
- ContentValues mediaDetails = new ContentValues();
- mediaDetails.put(targetMedia.displayName(), fileName);
- // lock media file until it's fully written.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- mediaDetails.put(targetMedia.isPending(), 1);
- }
- Uri mediaContentUri = resolver.insert(mediaCollection, mediaDetails);
- if (mediaContentUri == null) {
- throw new IllegalStateException("Failed to create new media item.");
- }
- // "w" for write.
- try (ParcelFileDescriptor pfd =
- resolver.openFileDescriptor(mediaContentUri, "w", null);
- InputStream is = inputStream;
- FileOutputStream fos = pfd == null ? null : new FileOutputStream(pfd.getFileDescriptor())
- ) {
- if (fos == null) {
- throw new IllegalStateException("Failed to open new media item.");
- }
- // Write data into the pending media file.
- byte[] buf = new byte[8192];
- int len;
- while ((len = is.read(buf)) > 0) {
- fos.write(buf, 0, len);
- }
- fos.flush();
- } finally {
- // finished, release the "pending" status.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- mediaDetails.clear();
- mediaDetails.put(targetMedia.isPending(), 0);
- resolver.update(mediaContentUri, mediaDetails, null, null);
- }
- }
- }
- private static Media getTargetMedia(int mediaType) {
- switch (mediaType) {
- case TYPE_IMAGE:
- return new Image();
- case TYPE_VIDEO:
- return new Video();
- case TYPE_AUDIO:
- return new Audio();
- case TYPE_FILES:
- return new Files();
- case TYPE_DOWNLOADS:
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return new Downloads();
- }
- return new Files();
- default:
- throw new IllegalArgumentException("Unknown media type: " + mediaType);
- }
- }
- private static class Image implements Media {
- @Override
- public Uri getMediaCollection() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return MediaStore.Images.Media
- .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
- } else {
- return MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- }
- }
- @Override
- public String displayName() {
- return MediaStore.Images.Media.DISPLAY_NAME;
- }
- @Override
- public String isPending() {
- return MediaStore.Images.Media.IS_PENDING;
- }
- }
- private static class Video implements Media {
- @Override
- public Uri getMediaCollection() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return MediaStore.Video.Media
- .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
- } else {
- return MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
- }
- }
- @Override
- public String displayName() {
- return MediaStore.Video.Media.DISPLAY_NAME;
- }
- @Override
- public String isPending() {
- return MediaStore.Video.Media.IS_PENDING;
- }
- }
- private static class Audio implements Media {
- @Override
- public Uri getMediaCollection() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return MediaStore.Audio.Media
- .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
- } else {
- return MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
- }
- }
- @Override
- public String displayName() {
- return MediaStore.Audio.Media.DISPLAY_NAME;
- }
- @Override
- public String isPending() {
- return MediaStore.Audio.Media.IS_PENDING;
- }
- }
- private static class Files implements Media {
- @Override
- public Uri getMediaCollection() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
- return MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
- } else {
- return MediaStore.Files.getContentUri("external");
- }
- }
- @Override
- public String displayName() {
- return MediaStore.Files.FileColumns.DISPLAY_NAME;
- }
- @Override
- public String isPending() {
- return MediaStore.Files.FileColumns.IS_PENDING;
- }
- }
- private static class Downloads implements Media {
- @RequiresApi(api = Build.VERSION_CODES.Q)
- @Override
- public Uri getMediaCollection() {
- return MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
- }
- @Override
- public String displayName() {
- return MediaStore.Downloads.DISPLAY_NAME;
- }
- @Override
- public String isPending() {
- return MediaStore.Downloads.IS_PENDING;
- }
- }
- private interface Media {
- Uri getMediaCollection();
- String displayName();
- String isPending();
- }
- }
|