对于外部存储中,APP私有目录下的图片或者视频,一般情况下,系统自带相册中是不会显示的,如果想要将其显示出来,可以通过下面的方法,对于适配Android 10的分区存储也是很方便的一种选择。
Android中的存储简单展示如下:这里说的APP私有目录,也就是指最下面部分。
下面是具体的方法
一、辅助工具类
package com.jlpay.partner.utils;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;
import java.io.File;
public class AlbumNotifyHelper {
public static final String TAG = AlbumNotifyHelper.class.getSimpleName();
///
// 下面是对外公开的重载的方法
///
public static void notifyScanDcim(Context context, String filePath) {
scanFile(context, filePath);
}
public static void insertVideoToMediaStore(Context context, String filePath, long dateTaken, long duration) {
insertVideoToMediaStore(context, filePath, dateTaken, 0, 0, duration);
}
public static void insertImageToMediaStore(Context context, String filePath, long createTime) {
insertImageToMediaStore(context, filePath, createTime, 0, 0);
}
///
// 扫描系统相册核心方法
///
/**
* 针对系统文件夹只需要扫描,不用插入内容提供者,不然会重复
*
* @param context 上下文
* @param filePath 文件路径
*/
public static void scanFile(Context context, String filePath) {
if (!checkFile(filePath)) {
return;
}
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(new File(filePath)));
context.sendBroadcast(intent);
}
///
// 非系统相册向MediaContent中插入数据,核心方法
///
/**
* 针对非系统文件夹下的文件,使用该方法
* 插入时初始化公共字段
*
* @param filePath 文件
* @param time ms
* @return ContentValues
*/
private static ContentValues initCommonContentValues(String filePath, long time) {
ContentValues values = new ContentValues();
File saveFile = new File(filePath);
long timeMillis = getTimeWrap(time);
values.put(MediaStore.MediaColumns.TITLE, saveFile.getName());
values.put(MediaStore.MediaColumns.DISPLAY_NAME, saveFile.getName());
values.put(MediaStore.MediaColumns.DATE_MODIFIED, timeMillis);
values.put(MediaStore.MediaColumns.DATE_ADDED, timeMillis);
values.put(MediaStore.MediaColumns.DATA, saveFile.getAbsolutePath());
values.put(MediaStore.MediaColumns.SIZE, saveFile.length());
return values;
}
/**
* 保存到照片到本地,并插入MediaStore以保证相册可以查看到,这是更优化的方法,防止读取的照片获取不到宽高
*
* @param context 上下文
* @param filePath 文件路径
* @param createTime 创建时间 <=0时为当前时间 ms
* @param width 宽度
* @param height 高度
*/
public static void insertImageToMediaStore(Context context, String filePath, long createTime, int width, int height) {
if (!checkFile(filePath))
return;
createTime = getTimeWrap(createTime);
ContentValues values = initCommonContentValues(filePath, createTime);
values.put(MediaStore.Images.ImageColumns.DATE_TAKEN, createTime);
values.put(MediaStore.Images.ImageColumns.ORIENTATION, 0);
values.put(MediaStore.Images.ImageColumns.ORIENTATION, 0);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
if (width > 0) values.put(MediaStore.Images.ImageColumns.WIDTH, 0);
if (height > 0) values.put(MediaStore.Images.ImageColumns.HEIGHT, 0);
}
values.put(MediaStore.MediaColumns.MIME_TYPE, getPhotoMimeType(filePath));
context.getApplicationContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
/**
* 保存到视频到本地,并插入MediaStore以保证相册可以查看到,这是更优化的方法,防止读取的视频获取不到宽高
*
* @param context 上下文
* @param filePath 文件路径
* @param createTime 创建时间 <=0时为当前时间 ms
* @param duration 视频长度 ms
* @param width 宽度
* @param height 高度
*/
public static void insertVideoToMediaStore(Context context, String filePath, long createTime, int width, int height, long duration) {
if (!checkFile(filePath))
return;
createTime = getTimeWrap(createTime);
ContentValues values = initCommonContentValues(filePath, createTime);
values.put(MediaStore.Video.VideoColumns.DATE_TAKEN, createTime);
if (duration > 0)
values.put(MediaStore.Video.VideoColumns.DURATION, duration);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
if (width > 0) values.put(MediaStore.Video.VideoColumns.WIDTH, width);
if (height > 0) values.put(MediaStore.Video.VideoColumns.HEIGHT, height);
}
values.put(MediaStore.MediaColumns.MIME_TYPE, getVideoMimeType(filePath));
context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
}
/**
* 是不是系统相册
*
* @param path
* @return
*/
private static boolean isSystemDcim(String path) {
return path.toLowerCase().contains("dcim") || path.toLowerCase().contains("camera");
}
/**
* 获取照片的mine_type
*
* @param path
* @return
*/
private static String getPhotoMimeType(String path) {
String lowerPath = path.toLowerCase();
if (lowerPath.endsWith("jpg") || lowerPath.endsWith("jpeg")) {
return "image/jpeg";
} else if (lowerPath.endsWith("png")) {
return "image/png";
} else if (lowerPath.endsWith("gif")) {
return "image/gif";
}
return "image/jpeg";
}
/**
* 获取video的mine_type,暂时只支持mp4,3gp
*
* @param path
* @return
*/
private static String getVideoMimeType(String path) {
String lowerPath = path.toLowerCase();
if (lowerPath.endsWith("mp4") || lowerPath.endsWith("mpeg4")) {
return "video/mp4";
} else if (lowerPath.endsWith("3gp")) {
return "video/3gp";
}
return "video/mp4";
}
/**
* 获得转化后的时间
*
* @param time
* @return
*/
private static long getTimeWrap(long time) {
if (time <= 0) {
return System.currentTimeMillis();
}
return time;
}
/**
* 检测文件存在
*
* @param filePath
* @return
*/
private static boolean checkFile(String filePath) {
//boolean result = FileUtil.fileIsExist(filePath);
boolean result = false;
File mFile = new File(filePath);
if (mFile.exists()) {
result = true;
}
Log.e(TAG, "文件不存在 path = " + filePath);
return result;
}
}
二、测试用例
private void demo() {
ArrayList<String> mListPathSysImg = new ArrayList<>();
if (mListPathSysImg.size() != 0) {
//下载成功,刷新系统图库 视频部分手机不支持显示
for (int i = 0; i < mListPathSysImg.size(); i++) {
String nDownLoadPath = mListPathSysImg.get(i);
String updateImgPath = FileUtil.getDownLoad() + nDownLoadPath.substring(nDownLoadPath.lastIndexOf("/"));
if (updateImgPath.contains(".LRV")) {
updateImgPath = updateImgPath.replace(".LRV", ".MP4");
AlbumNotifyHelper.insertVideoToMediaStore(this, updateImgPath, 0, 5000);
} else {
AlbumNotifyHelper.insertImageToMediaStore(this, updateImgPath, 0);
}
//Log.e("nDownLoadPath----more-->","nDownLoadPath="+nDownLoadPath+",updateImgPath="+updateImgPath);
}
mListPathSysImg.clear();
}
}