天天看點

Android開發之重新整理圖檔到相冊 | 重新整理視訊到相冊的方法區分發廣播重新整理方法

我們很多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官方說明文檔

Android開發之重新整理圖檔到相冊 | 重新整理視訊到相冊的方法區分發廣播重新整理方法

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卡根目錄,然後在相冊進行顯示的看圖:

Android開發之重新整理圖檔到相冊 | 重新整理視訊到相冊的方法區分發廣播重新整理方法
Android開發之重新整理圖檔到相冊 | 重新整理視訊到相冊的方法區分發廣播重新整理方法
Android開發之重新整理圖檔到相冊 | 重新整理視訊到相冊的方法區分發廣播重新整理方法

感謝部落客提供老的重新整理圖檔和視訊到相冊的方法:部落客老API重新整理圖檔視訊到相冊的方法

上面有兩種重新整理圖檔和視訊的方法:分為API29以下和API29以上

個人建議使用新方法:MediaScannerConnection.scanFile方法說明

Google官方文檔将圖檔重新整理到相冊的方法:将圖檔添加到圖庫官方文檔

可檢視完整項目:儲存圖檔和視訊到相冊的方法

繼續閱讀