美文网首页
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