美文网首页
MediaFileHelper 媒体类文件帮助类

MediaFileHelper 媒体类文件帮助类

作者: 面向星辰大海的程序员 | 来源:发表于2021-04-03 10:52 被阅读0次
    public static String AppFileDir = "FC";
    public static final int getImagePathFlag = 0;
    public static final int getVideoPathFlag = 1;
    public static final String ImageMineType = "image/jpeg";
    public static final String VideoMineType = "video/mp4";

/**
 * 保存Bitmap到本地相册
 */
public static void saveImageToPhotos(Context context, Bitmap bmp) {
    String fileName = System.currentTimeMillis() + ".jpg";
    Uri uri = null;
    try {
        uri = getImageUri(context, fileName, "image/jpeg");
        FileOutputStream fos = getOutputStream(context, uri);
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    } catch (Exception e) {
        e.printStackTrace();
        Log.i(TAG, "saveImageToPhotos: e=" + e.getMessage());
    }
    if (uri == null) {
        return;java
    }
   
}

获取输出流

public static FileOutputStream getOutputStream(@NonNull Context context, @NonNull Uri uri) throws FileNotFoundException {
    if (uri == null) {
        return null;
    }
    ParcelFileDescriptor fileDescriptor = context.getContentResolver().openFileDescriptor(uri, "w");
    FileOutputStream outputStream = new FileOutputStream(fileDescriptor.getFileDescriptor());
    return outputStream;
}
//创建获取私有目录
public static String createPrivateFilePath(Context context, String fileName, int flag) {
    String dirType = null;
    switch (flag) {
        case getImagePathFlag:
            dirType = Environment.DIRECTORY_PICTURES;
            break;
        case getVideoPathFlag:
            dirType = Environment.DIRECTORY_MOVIES;
            break;
        default:
            break;
    }
    File imageDir = context.getExternalFilesDir(dirType);
    if (!imageDir.exists()) {
        imageDir.mkdirs();
    }
    return imageDir.getAbsolutePath() + File.separator + fileName;
}
//创建获取私有目录
public static String createPrivateFileDirPath(Context context, int flag) {
    String dirType = null;
    switch (flag) {
        case getImagePathFlag:
            dirType = Environment.DIRECTORY_PICTURES;
            break;
        case getVideoPathFlag:
            dirType = Environment.DIRECTORY_MOVIES;
            break;
        default:
            break;
    }
    File imageDir = context.getExternalFilesDir(dirType);
    if (!imageDir.exists()) {
        imageDir.mkdirs();
    }
    return imageDir.getAbsolutePath();
}
//创建获取公有目录
public static String createPublicFileDirPath(Context context, int flag) {
    String dirType = null;
    switch (flag) {
        case getImagePathFlag:
            if (isDayuDengyuQ()) {
                Uri uri = getSaveToGalleryImageUri(context, "", ImageMineType);
                dirType = FileUtils.getRealPathFromUri(context, uri);
                dirType = dirType.substring(0, dirType.lastIndexOf(File.separator));
            } else {
                dirType = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + AppFileDir;
            }
            break;
        case getVideoPathFlag:
            if (isDayuDengyuQ()) {
                Uri uri = getSaveToGalleryVideoUri(context, "", VideoMineType);
                dirType = FileUtils.getRealPathFromUri(context, uri);
                dirType = dirType.substring(0, dirType.lastIndexOf(File.separator));
            } else {
                dirType = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + File.separator + AppFileDir;
            }
            break;
        default:
            break;
    }
    File fileDir = new File(dirType);
    if (!fileDir.exists()) {
        fileDir.mkdirs();
    }
    return fileDir.getAbsolutePath();
}
//获取应用私有文件Uri
public static Uri getPrivateFileUri(Context context, String fileName, int flag) {
    Uri uri = null;
    File file = null;
    if (fileName.contains(File.separator)) {
        file = new File(fileName);
    } else {
        file = new File(createPrivateFilePath(context, fileName, flag));
    }
    if (isDayuDengyuN()) {
        uri = FileProvider.getUriForFile(context, context.getPackageName(), file);//
    } else {
        uri = Uri.fromFile(file);
    }
    return uri;
}
public static void saveFileToPrivate(Context context, Uri uri, String fileName, SaveComplete complete, int flag) {
    String filePath = fileName;
    if (!fileName.contains(File.separator)) {
        filePath = createPrivateFilePath(context, fileName, flag);
    }
    String finalFilePath = filePath;
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Uri fileUri = (getPrivateFileUri(context, fileName, flag));
                Log.i(TAG, "fileUri=" + fileUri.toString());
                copyFile(context, uri, fileUri);
                if (complete != null) {
                    complete.onComplete(fileUri, finalFilePath);
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.i(TAG, "异常=" + e.getMessage());
                if (complete != null) {
                    complete.onFiled(e);
                }
            }
        }
    }).start();
}
public static void saveFileToPrivate(Context context, Bitmap bitmap, String fileName, SaveComplete complete) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                String fullFilePath = createPrivateFilePath(context, fileName, getImagePathFlag);
                Uri fileUri = (getPrivateFileUri(context, fullFilePath, getImagePathFlag));
                FileOutputStream fos = getOutputStream(context, fileUri);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                fos.flush();
                fos.close();
                if (!bitmap.isRecycled()) {
                    bitmap.recycle();
                }
                if (complete != null) {
                    complete.onComplete(fileUri, fullFilePath);
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.i(TAG, "异常=" + e.getMessage());
                if (complete != null) {
                    complete.onFiled(e);
                }
            }
        }
    }).start();
}
public static void saveFileToGallery(Context context, Uri uri, Uri targetUri, SaveComplete complete) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                copyFile(context, uri, targetUri);
                if (complete != null) {
                    complete.onComplete(targetUri, targetUri.getPath());
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.i(TAG, "异常=" + e.getMessage());
                if (complete != null) {
                    complete.onFiled(e);
                }
            }
        }
    }).start();
}
public static void saveFileToGallery(Context context, Bitmap bitmap, String fileName, SaveComplete complete) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Uri targetUri = (getImageUri(context, fileName, "image/jpeg"));
                FileOutputStream fos = getOutputStream(context, targetUri);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                fos.flush();
                fos.close();
                if (!bitmap.isRecycled()) {
                    bitmap.recycle();
                }
                if (complete != null) {
                    complete.onComplete(targetUri, targetUri.getPath());
                }
            } catch (Exception e) {
                e.printStackTrace();
                Log.i(TAG, "异常=" + e.getMessage());
                if (complete != null) {
                    complete.onFiled(e);
                }
            }
        }
    }).start();
}
public interface SaveComplete {
    void onComplete(Uri fileUri, String filePath);

    void onFiled(Exception e);
}
public static void copyFile(Context context, Uri uri, Uri copyUri) throws Exception {
    InputStream is = context.getContentResolver().openInputStream(uri);
    FileOutputStream fos = getOutputStream(context, copyUri);
    byte[] buffer = new byte[1024];
    int byteread;
    while (-1 != (byteread = is.read(buffer))) {
        fos.write(buffer, 0, byteread);
    }
    is.close();
    fos.flush();
    fos.close();
}
/**
 * 视频-----------
 * 此接口用于获取保存共享视频的输出流,推荐!!!
 * <p>
 * 在低于29的系统上采用getSaveToGalleryVideoUri的方式保存共享视频,会有文件名不能定制、视频保存类型是.3gp、视频保存在video文件夹等问题
 * 所以在低版本上采用文件路径的方式写入数据。在低于29的系统上采用文件路径的方式是没有问题的,因为在这些系统上没有分区存储的概念
 * 以及,getExternalStoragePublicDirectory函数可用
 *
 * @param context
 * @param videoName
 * @param mineType
 * @return
 * @throws FileNotFoundException
 */
public static Uri getVideoUri(@NonNull Context context, @NonNull String videoName, @NonNull String mineType) throws FileNotFoundException {
    //先在MediaStore中查询,有的话直接返回
    Uri uri = querySpecialVideoUri(context, videoName);
    if (uri != null) {
        return uri;
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        uri = getSaveToGalleryVideoUri(context, videoName, mineType);
        if (uri != null) {
            return uri;
        }
    } else {
        if (TextUtils.isEmpty(videoName)) {
            videoName = String.valueOf(System.currentTimeMillis());
        }
        //通过显示路径方式共享媒体的时候,是需要指定文件后缀,要不然下载文件会没有后缀名
        if (!TextUtils.isEmpty(mineType)) {
            String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mineType);
            if (videoName.contains(".")) {
                videoName = videoName.substring(0, videoName.indexOf(".")) + "." + extension;
            } else {
                videoName += "." + extension;
            }
        }
        /**
         * 直接路径的方式,组合出的文件路径,路径中的文件夹一定要存在,否则转成FileOutputStream的时候会报FileNotFoundException
         * 即便是通过DATA注册到MediaStore中,也是如此
         */
        String rootPath = getMediaPath(getVideoPathFlag);
        String videoPath = null;
        if (rootPath.endsWith(File.separator)) {
            videoPath = rootPath + videoName;
        } else {
            videoPath = rootPath + File.separator + videoName;
        }
        //通过DATA字段在MediaStore中注册一下
        ContentValues values = new ContentValues();
        values.put(MediaStore.Video.Media.DISPLAY_NAME, videoName);
        values.put(MediaStore.Video.Media.MIME_TYPE, mineType);
        values.put(MediaStore.Video.Media.DATA, videoPath);
        values.put(MediaStore.Video.Media.DATE_MODIFIED, System.currentTimeMillis() / 1000);
        uri = context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
        if (uri != null) {
            return uri;
        }
    }
    return null;
}
/**
 * 保存共享媒体资源,必须使用先在MediaStore创建表示视频保存信息的Uri,然后通过Uri写入视频数据的方式。
 * 在"分区存储"模型中,这是官方推荐的,因为在Android 10禁止通过File的方式访问媒体资源,Android 11又允许了
 * 从Android 10开始默认是分区存储模型
 * <p>
 * <p>
 * 说明:
 * 此方法中MediaStore默认的保存目录是/storage/emulated/0/video
 * 而Environment.DIRECTORY_MOVIES的目录是/storage/emulated/0/Movies
 *
 * @param context
 * @return
 */
public static Uri getSaveToGalleryVideoUri(Context context, String videoName, String mineType) {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Video.Media.DISPLAY_NAME, videoName);
    values.put(MediaStore.Video.Media.MIME_TYPE, mineType);
    values.put(MediaStore.Video.Media.DATE_MODIFIED, System.currentTimeMillis() / 1000);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        values.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES);
    }

    Uri uri = context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
    return uri;
}
public static Uri querySpecialVideoUri(Context context, String fileName) {
    Cursor cursor = context.getApplicationContext().getContentResolver().query(
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
            new String[]{MediaStore.Video.Media._ID},
            MediaStore.Video.Media.DISPLAY_NAME + " = ?",
            new String[]{fileName}, null
    );
    int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
    Uri contentUri = null;
    while (cursor.moveToNext()) {
        long id = cursor.getLong(idColumn);
        contentUri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id);
        Log.i(TAG, "videoUri=" + contentUri.toString());
        break;
    }
    return contentUri;
}
/**
 * 图片-----------
 */
public static Uri getImageUri(@NonNull Context context, @NonNull String imageName, @NonNull String mineType) throws FileNotFoundException {
    //先在MediaStore中查询,有的话直接返回
    Uri uri = querySpecialImageUri(context, imageName);
    if (uri != null) {
        return uri;
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        uri = getSaveToGalleryImageUri(context, imageName, mineType);
        if (uri != null) {
            return uri;
        }
    } else {
        if (TextUtils.isEmpty(imageName)) {
            imageName = String.valueOf(System.currentTimeMillis());
        }
        //通过显示路径方式共享媒体的时候,是需要指定文件后缀,要不然下载文件会没有后缀名
        if (!TextUtils.isEmpty(mineType)) {
            String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mineType);
            if (imageName.contains(".")) {
                imageName = imageName.substring(0, imageName.indexOf(".")) + "." + extension;
            } else {
                imageName += "." + extension;
            }
        }

        /**
         * 直接路径的方式,组合出的文件路径,路径中的文件夹一定要存在,否则转成FileOutputStream的时候会报FileNotFoundException
         * 即便是通过DATA注册到MediaStore中,也是如此
         */
        String rootPath = getMediaPath(getImagePathFlag);
        String imagePath = null;
        if (rootPath.endsWith(File.separator)) {
            imagePath = rootPath + imageName;
        } else {
            imagePath = rootPath + File.separator + imageName;
        }

        //通过DATA字段在MediaStore中注册一下
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DISPLAY_NAME, imageName);
        values.put(MediaStore.Images.Media.MIME_TYPE, mineType);
        values.put(MediaStore.Images.Media.DATA, imagePath);
        values.put(MediaStore.Images.Media.DATE_MODIFIED, System.currentTimeMillis() / 1000);
        uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        if (uri != null) {
            return uri;
        }
    }
    return null;
}
/**
 * 图片-----------
 */
public static Uri getSaveToGalleryImageUri(Context context, String imageName, String mineType) {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.DISPLAY_NAME, imageName);
    values.put(MediaStore.Images.Media.MIME_TYPE, mineType);
    values.put(MediaStore.Images.Media.DATE_MODIFIED, System.currentTimeMillis() / 1000);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + File.separator + AppFileDir);
    }
    Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    return uri;
}
//IMG_20200726_184657.jpg 传名字+后缀
public static Uri querySpecialImageUri(Context context, String fileName) {
    Cursor cursor = context.getApplicationContext().getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            new String[]{MediaStore.Images.Media._ID},
            MediaStore.Images.Media.DISPLAY_NAME + " = ?",
            new String[]{fileName},
            null
    );
    int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
    Uri contentUri = null;
    while (cursor.moveToNext()) {
        long id = cursor.getLong(idColumn);
        contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
        Log.i(TAG, "imageUri=" + contentUri.toString());
        break;
    }
    return contentUri;
}
private static String getMediaPath(int flag) {
    String dir = "";
    switch (flag) {
        case 0:
            dir = Environment.DIRECTORY_PICTURES;
            break;
        case 1:
            dir = Environment.DIRECTORY_MOVIES;
            break;
        default:
            break;
    }
    File path = Environment.getExternalStoragePublicDirectory(dir);
    if (!path.exists()) {
        path.mkdirs();
    }
    String pathStr = path.getAbsolutePath();
    File file = new File(pathStr);
    return file.getAbsolutePath();
}
public static boolean isDayuDengyuN() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
}

public static boolean isDayuDengyuQ() {
    return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
}

public static String getFileName(String fullPath) {
    if (fullPath == null) {
        return "";
    }
    return fullPath.substring(fullPath.lastIndexOf(File.separator) + 1);
}
public class FileUtils {
    /**
     * 根据Uri获取视频的绝对路径
     *
     * @param context 上下文对象
     * @param uri     视频的Uri
     * @return 如果Uri对应的视频存在, 那么返回该视频的绝对路径, 否则返回null
     */
    public static String getRealPathFromUri(Context context, Uri uri) {
        int sdkVersion = Build.VERSION.SDK_INT;
        if (sdkVersion >= 19) { // api >= 19
            return getRealPathFromUriAboveApi19(context, uri);
        } else { // api < 19
            return getRealPathFromUriBelowAPI19(context, uri);
        }
    }

    /**
     * 适配api19以下(不包括api19),根据uri获取视频的绝对路径
     *
     * @param context 上下文对象
     * @param uri     视频的Uri
     * @return 如果Uri对应的视频存在, 那么返回该视频的绝对路径, 否则返回null
     */
    private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
        return getDataColumn(context, uri, null, null);
    }

    /**
     * 适配api19及以上,根据uri获取视频的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    @SuppressLint("NewApi")
    private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
        String filePath = null;
        if (DocumentsContract.isDocumentUri(context, uri)) {
            // 如果是document类型的 uri, 则通过document id来进行处理
            String documentId = DocumentsContract.getDocumentId(uri);
            if (isMediaDocument(uri)) { // MediaProvider
                // 使用':'分割
                String id = documentId.split(":")[1];

                String selection = MediaStore.Video.Media._ID + "=?";
                String[] selectionArgs = {id};
                filePath = getDataColumn(context, MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                        selection, selectionArgs);
            } else if (isDownloadsDocument(uri)) {
//                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads" + "/public_downloads"), Long.valueOf(documentId));
                filePath = getDataColumn(context, uri, null, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // 如果是 content 类型的 Uri
            filePath = getDataColumn(context, uri, null, null);
        } else if ("file".equals(uri.getScheme())) {
            // 如果是 file 类型的 Uri,直接获取图片对应的路径
            filePath = uri.getPath();
        }
        return filePath;
    }

    /**
     * 获取数据库表中的 _data 列,即返回Uri对应的文件路径
     *
     * @return
     */
    private static String getDataColumn(Context context, Uri uri, String selection,
                                        String[] selectionArgs) {
        String path = null;

        String[] projection = new String[]{MediaStore.Video.Media.DATA};
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs
                    , null);
            if (cursor != null && cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
                path = cursor.getString(columnIndex);
            }
        } catch (Exception e) {
            if (cursor != null) {
                cursor.close();
            }
        }
        return path;
    }

    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is MediaProvider
     */
    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is DownloadsProvider
     */
    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }
}

相关文章

网友评论

      本文标题:MediaFileHelper 媒体类文件帮助类

      本文链接:https://www.haomeiwen.com/subject/ikzqkltx.html