我們很多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官方文檔将圖檔重新整理到相冊的方法:将圖檔添加到圖庫官方文檔
可檢視完整項目:儲存圖檔和視訊到相冊的方法