Android笔记:AlbumSaver图片视频保存工具类
16lz
2021-01-25
背景
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的,网络挂了,供大家参考吧。
更多相关文章
- Android增加一个物理按键检测步骤
- android开发之Vitamio介绍以及常见问题
- Android(安卓)热修复(全网最简单的热修复讲解)
- Android(安卓)android studio 项目放在源码中编译
- Unable to execute dex: Multiple dex files define Lcom/loopj/
- Android(安卓)Studio与 Android(安卓)SDK的安装和配置(以及一些问
- 一对一视频直播系统Android补间动画-雷达扫描效果
- [Android] 移动端并行转码改造:音视频分离与视频分片
- Android视频解码及渲染