我们很多app会有保存图片和保存视频,保存成功后一般在最近文件或者相册就能看到了,这个需要我们在保存文件后自行刷新到相册中,以前老版本方法通过广播刷新方法在API29中已经废弃了无法使用,咱们提供了新版本方法如下图:
//说明第一个参数上下文,第二个参数是文件路径例如:/storage/emulated/0/1621832516463_1181875151.mp4 第三个参数是文件类型,传空代表自行根据文件后缀判断刷新到相册
MediaScannerConnection.scanFile(context, new String[]{fileNamePath}, null, new MediaScannerConnection.OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
//刷新成功的回调方法
Log.e("资源刷新成功路径为", path)
}
});
看下Google官方说明文档
Google官方文档说明需要科学上网:MediaScannerConnection.scanFile方法说明
Google官方文档说明无需科学上网:MediaScannerConnection.scanFile方法说明
看下完整代码:
package cn.xiayiye5.xiayiye5library.utils;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* @author : xiayiye5
* @date : 2021/5/21 17:45
* 类描述 :
*/
public class DownLoadUtils {
public static final String IMG_URL = "https://ae01.alicdn.com/kf/Ua227945b506241af975a9b0a16d6df3bA.jpg";
public static final String VIDEO_URL = "https://www.w3school.com.cn/example/html5/mov_bbb.mp4";
private DownLoadUtils() {
}
public static DownLoadUtils getInstance() {
return SingleObject.DOWN_LOAD_UTILS;
}
private static class SingleObject {
private static final DownLoadUtils DOWN_LOAD_UTILS = new DownLoadUtils();
}
public void download(Activity activity, String url, String fileNamePath, String mediaType) {
try {
URL url1 = new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(30_000);
urlConnection.setReadTimeout(30_000);
int responseCode = urlConnection.getResponseCode();
if (responseCode == 200) {
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(fileNamePath);
readFile5(inputStream, fileOutputStream);
refreshApi29(activity, fileNamePath);
// refreshMinApi29(activity, fileNamePath, mediaType);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static ContentValues getVideoContentValues(File paramFile, long paramLong) {
ContentValues localContentValues = new ContentValues();
localContentValues.put(MediaStore.Video.Media.TITLE, paramFile.getName());
localContentValues.put(MediaStore.Video.Media.DISPLAY_NAME, paramFile.getName());
localContentValues.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
localContentValues.put(MediaStore.Video.Media.DATE_TAKEN, Long.valueOf(paramLong));
localContentValues.put(MediaStore.Video.Media.DATE_MODIFIED, Long.valueOf(paramLong));
localContentValues.put(MediaStore.Video.Media.DATE_ADDED, Long.valueOf(paramLong));
localContentValues.put(MediaStore.Video.Media.DATA, paramFile.getAbsolutePath());
localContentValues.put(MediaStore.Video.Media.SIZE, Long.valueOf(paramFile.length()));
return localContentValues;
}
/**
* 读写方式五
* 高效字节流方式一个字节一个字节的读写
*/
private void readFile5(InputStream fileInputStream, FileOutputStream fileOutputStream) {
try {
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//代表读取到的数据的底层int值
int ch = 0;
while ((ch = bufferedInputStream.read()) != -1) {
Log.e("下载资源", ch + "");
bufferedOutputStream.write(ch);
}
bufferedOutputStream.flush();
bufferedInputStream.close();
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 刷新图片和视频到相册低版本方法
*
* @param activity 当前页面
* @param fileNamePath 文件路径
* @param mediaType 刷新的文件类型
*/
private void refreshMinApi29(Activity activity, String fileNamePath, String mediaType) {
if (mediaType.contains("image")) {
File file = new File(fileNamePath);
// try {
// //将图片插入到相册
// MediaStore.Images.Media.insertImage(activity.getContentResolver(), file.getAbsolutePath(), file.getName(), null);
// } catch (FileNotFoundException e) {
// Log.i("Exception Msg", Log.getStackTraceString(e));
// }
// activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + fileNamePath)));
//将图片扫描到相册中显示
ContentResolver localContentResolver = activity.getContentResolver();
ContentValues localContentValues = getImageContentValues(file, System.currentTimeMillis());
localContentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, localContentValues);
Intent localIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
final Uri localUri = Uri.fromFile(file);
localIntent.setData(localUri);
activity.sendBroadcast(localIntent);
} else {
//刷新视频到相册方法二 API29以下的老方法,在API29中已弃用!
ContentResolver localContentResolver = activity.getContentResolver();
ContentValues localContentValues = getVideoContentValues(new File(fileNamePath), System.currentTimeMillis());
Uri localUri = localContentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, localContentValues);
activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri));
}
}
public static ContentValues getImageContentValues(File paramFile, long paramLong) {
ContentValues localContentValues = new ContentValues();
localContentValues.put("title", paramFile.getName());
localContentValues.put("_display_name", paramFile.getName());
localContentValues.put("mime_type", "image/jpeg");
localContentValues.put("datetaken", Long.valueOf(paramLong));
localContentValues.put("date_modified", Long.valueOf(paramLong));
localContentValues.put("date_added", Long.valueOf(paramLong));
localContentValues.put("orientation", Integer.valueOf(0));
localContentValues.put("_data", paramFile.getAbsolutePath());
localContentValues.put("_size", Long.valueOf(paramFile.length()));
return localContentValues;
}
/**
* 刷新视频到相册方法一 API通用方法包括API29及以上高版本方法
*
* @param activity 当前页面
* @param fileNamePath 文件路径
*/
private void refreshApi29(Activity activity, String fileNamePath) {
//刷新相册,mineTypes为null的话让系统自己根据文件后缀判断文件类型
MediaScannerConnection.scanFile(activity, new String[]{fileNamePath}, null, (path, uri) -> Log.e("资源刷新成功路径为", path));
//代表只刷新视频格式为mp4类型其它格式视频文件不刷新
// MediaScannerConnection.scanFile(activity, new String[]{fileNamePath}, new String[]{"video/mp4"}, (path, uri) -> Log.e("资源刷新成功路径为", path));
//代表刷新视频文件,只要是视频都刷新根据当前Android系统支持哪些视频格式进行刷新
// MediaScannerConnection.scanFile(activity, new String[]{fileNamePath}, new String[]{"video/*"}, (path, uri) -> Log.e("资源刷新成功路径为", path));
//代表只刷新图片格式为jpg的文件到相册中
// MediaScannerConnection.scanFile(activity, new String[]{fileNamePath}, new String[]{"image/jpg"}, (path, uri) -> Log.e("资源刷新成功路径为", path));
//代表刷新图片到相册只要是图片就会刷新
// MediaScannerConnection.scanFile(activity, new String[]{fileNamePath}, new String[]{"image/*"}, (path, uri) -> Log.e("资源刷新成功路径为", path));
}
}
调用上面工具类:
package cn.xiayiye5.xiayiye5library.activity;
import android.os.Environment;
import android.view.View;
import java.util.Random;
import cn.xiayiye5.xiayiye5library.R;
import cn.xiayiye5.xiayiye5library.utils.DownLoadUtils;
import cn.xiayiye5.xiayiye5library.utils.ThreadUtils;
/**
* @author : xiayiye5
* @date : 2021/5/21 17:36
* 类描述 : 下载图片视频刷新到相册的方法
*/
public class SaveVideoAndImgActivity extends BaseActivity {
@Override
protected int getLayoutView() {
return R.layout.activity_video_and_img;
}
@Override
protected void initId() {
}
@Override
protected void loadData() {
}
public void savePicture(View view) {
//下载图片之前记得开启读取sd卡权限
String fileNamePath = Environment.getExternalStorageDirectory() + "/" + System.currentTimeMillis() + "_" + new Random().nextInt(Integer.MAX_VALUE) + ".jpg";
ThreadUtils.getInstance().createThread(() -> DownLoadUtils.getInstance().download(SaveVideoAndImgActivity.this, DownLoadUtils.IMG_URL, fileNamePath, "image/jpg"));
// new Thread(() -> DownLoadUtils.getInstance().download(this, DownLoadUtils.IMG_URL, fileNamePath)).start();
}
public void saveVideo(View view) {
//下载视频之前记得开启读取sd卡权限
String fileNamePath = Environment.getExternalStorageDirectory() + "/" + System.currentTimeMillis() + "_" + new Random().nextInt(Integer.MAX_VALUE) + ".mp4";
ThreadUtils.getInstance().createThread(() -> DownLoadUtils.getInstance().download(SaveVideoAndImgActivity.this, DownLoadUtils.VIDEO_URL, fileNamePath, "video/mp4"));
// new Thread(() -> DownLoadUtils.getInstance().download(this, DownLoadUtils.VIDEO_URL, fileNamePath)).start();
}
}
我是将文件报讯到SD卡根目录,然后在相册进行显示的看图:
感谢博主提供老的刷新图片和视频到相册的方法:博主老API刷新图片视频到相册的方法
上面有两种刷新图片和视频的方法:分为API29以下和API29以上
个人建议使用新方法:MediaScannerConnection.scanFile方法说明
Google官方文档将图片刷新到相册的方法:将图片添加到图库官方文档
可查看完整项目:保存图片和视频到相册的方法