背景

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. Android增加一个物理按键检测步骤
  2. android开发之Vitamio介绍以及常见问题
  3. Android(安卓)热修复(全网最简单的热修复讲解)
  4. Android(安卓)android studio 项目放在源码中编译
  5. Unable to execute dex: Multiple dex files define Lcom/loopj/
  6. Android(安卓)Studio与 Android(安卓)SDK的安装和配置(以及一些问
  7. 一对一视频直播系统Android补间动画-雷达扫描效果
  8. [Android] 移动端并行转码改造:音视频分离与视频分片
  9. Android视频解码及渲染

随机推荐

  1. android手势操作&&实现滑动切换activity
  2. React-Native-StatusBar
  3. android 对pdf文件的下载、缓存、显示,包
  4. Android高手秘笈之自定义View的属性
  5. (三)Kotlin 高阶函数
  6. eclipse,android keystore
  7. Android(安卓)frameworks去掉熄屏前先变
  8. Android(安卓)Studio SVN配置忽略文件
  9. Android(安卓)软件安装程序(*.apk)的结构
  10. android安卓系统上运行jar文件