Android笔记:AlbumSaver图片视频保存工具类

背景

Android中,有时需要操作生成一些图片或者视频,但不是你生成保存了就可以的,如何让生成的图片或者视频文件让其他app应用或者自身及时检索到,也是需要考虑的一个问题,下面这段代码是摘自某sdk demo的源码,刷新媒体数据库的方式让其他app可以方便的读取到刚生成的图片或者视频文件,兼容各个Android版本。

代码块AlbumSaver

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 用于将视频保存到本地相册
 */
public class AlbumSaver {

    private static final String TAG = "AlbumSaver";
    public static final String VOLUME_EXTERNAL_PRIMARY = "external_primary";
    private static final String IS_PENDING = "is_pending";
    private static AlbumSaver sInstance;
    private final ContentResolver mContentResolver;
    private final Context mContext;
    private String mVideoOutputPath;
    private long mVideoDuration;
    private String mCoverImagePath;

    public static AlbumSaver getInstance(@NonNull Context context) {
        if (sInstance == null) {
            sInstance = new AlbumSaver(context);
        }
        return sInstance;
    }

    private AlbumSaver(@NonNull Context context) {
        mContext = context.getApplicationContext();
        mContentResolver = context.getApplicationContext().getContentResolver();
    }

    /**
     * 设置保存视频的信息
     *
     * @param videoPath 视频路径
     * @param duration  视频时长
     * @param coverPath 封面路径
     */
    public void setOutputProfile(String videoPath, long duration, String coverPath) {
        mVideoOutputPath = videoPath;
        mVideoDuration = duration;
        mCoverImagePath = coverPath;
    }

    /**
     * 插入到本地相册
     */
    public void saveVideoToDCIM() {
        if (Build.VERSION.SDK_INT >= 29) {
            saveVideoToDCIMOnAndroid10();
        } else {
            saveVideoToDCIMBelowAndroid10();
        }
    }

    private void saveVideoToDCIMBelowAndroid10() {
        File file = new File(mVideoOutputPath);
        if (file.exists()) {
            try {
                ContentValues values = initCommonContentValues(file);
                values.put(MediaStore.Video.VideoColumns.DATE_TAKEN, System.currentTimeMillis());
                values.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
                values.put(MediaStore.Video.VideoColumns.DURATION, mVideoDuration);
                mContext.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);

                if (mCoverImagePath != null) {
                    insertVideoThumb(file.getPath(), mCoverImagePath);
                }
                ToastUtil.toastShortMessage("视频已保存到手机相册");
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            Log.d(TAG, "file :" + mVideoOutputPath + " is not exists");
        }
    }

    /**
     * Android 10(Q) 保存视频文件到本地的方法
     */
    private void saveVideoToDCIMOnAndroid10() {
        File file = new File(mVideoOutputPath);
        if (file.exists()) {
            ContentValues values = new ContentValues();
            long currentTimeInSeconds = System.currentTimeMillis();
            values.put(MediaStore.MediaColumns.TITLE, file.getName());
            values.put(MediaStore.MediaColumns.DISPLAY_NAME, file.getName());
            values.put(MediaStore.MediaColumns.DATE_MODIFIED, currentTimeInSeconds);
            values.put(MediaStore.MediaColumns.DATE_ADDED, currentTimeInSeconds);
            values.put(MediaStore.MediaColumns.SIZE, file.length());
            values.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
            // 时长
            values.put(MediaStore.Video.VideoColumns.DURATION, mVideoDuration);
            values.put(MediaStore.Video.VideoColumns.DATE_TAKEN, System.currentTimeMillis());
            // Android 10 插入到图库标志位
            values.put(IS_PENDING, 1);

            Uri collection = MediaStore.Video.Media.getContentUri(VOLUME_EXTERNAL_PRIMARY);
            Uri item = mContext.getContentResolver().insert(collection, values);
            ParcelFileDescriptor pfd = null;
            FileOutputStream fos = null;
            FileInputStream fis = null;
            try {
                pfd = mContext.getContentResolver().openFileDescriptor(item, "w");
                // Write data into the pending image.
                fos = new FileOutputStream(pfd.getFileDescriptor());
                fis = new FileInputStream(file);
                byte[] data = new byte[1024];
                int length = -1;
                while ((length = fis.read(data)) != -1) {
                    fos.write(data, 0, length);
                }
                fos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (pfd != null) {
                    try {
                        pfd.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            // 插入成功后,更新状态,让其他 app 可以看到新的视频
            values.clear();
            values.put(IS_PENDING, 0);
            mContext.getContentResolver().update(item, values, null, null);

            ToastUtil.toastShortMessage("视频已保存到手机相册");
        } else {
            Log.d(TAG, "file :" + mVideoOutputPath + " is not exists");
        }
    }

    @NonNull
    private ContentValues initCommonContentValues(@NonNull File saveFile) {
        ContentValues values = new ContentValues();
        long currentTimeInSeconds = System.currentTimeMillis();
        values.put(MediaStore.MediaColumns.TITLE, saveFile.getName());
        values.put(MediaStore.MediaColumns.DISPLAY_NAME, saveFile.getName());
        values.put(MediaStore.MediaColumns.DATE_MODIFIED, currentTimeInSeconds);
        values.put(MediaStore.MediaColumns.DATE_ADDED, currentTimeInSeconds);
        values.put(MediaStore.MediaColumns.DATA, saveFile.getAbsolutePath());
        values.put(MediaStore.MediaColumns.SIZE, saveFile.length());
        return values;
    }

    /**
     * 插入视频缩略图
     *
     * @param videoPath
     * @param coverPath
     */
    private void insertVideoThumb(String videoPath, String coverPath) {
        //以下是查询上面插入的数据库Video的id(用于绑定缩略图)
        //根据路径查询
        Cursor cursor = mContentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
                new String[]{MediaStore.Video.Thumbnails._ID},//返回id列表
                String.format("%s = ?", MediaStore.Video.Thumbnails.DATA), //根据路径查询数据库
                new String[]{videoPath}, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                String videoId = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Thumbnails._ID));
                //查询到了Video的id
                ContentValues thumbValues = new ContentValues();
                thumbValues.put(MediaStore.Video.Thumbnails.DATA, coverPath);//缩略图路径
                thumbValues.put(MediaStore.Video.Thumbnails.VIDEO_ID, videoId);//video的id 用于绑定
                //Video的kind一般为1
                thumbValues.put(MediaStore.Video.Thumbnails.KIND, MediaStore.Video.Thumbnails.MINI_KIND);
                //只返回图片大小信息,不返回图片具体内容
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                Bitmap bitmap = BitmapFactory.decodeFile(coverPath, options);
                if (bitmap != null) {
                    thumbValues.put(MediaStore.Video.Thumbnails.WIDTH, bitmap.getWidth());//缩略图宽度
                    thumbValues.put(MediaStore.Video.Thumbnails.HEIGHT, bitmap.getHeight());//缩略图高度
                    if (!bitmap.isRecycled()) {
                        bitmap.recycle();
                    }
                }
                mContentResolver.insert(MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, thumbValues);//缩略图数据库
            }
            cursor.close();
        }
    }
}

结语

以上就是保存视频图片后刷新Android媒体数据的代码了,代码摘自腾讯某sdk demo,AlbumSaver工具类可以方便其他app及时读取到最新保存的图片视频。本来准备存gist的,网络挂了,供大家参考吧。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值