Android DownLoadManager原生下載管理器的總結

由於需求所至,爲了保證文件下載的完整性,需要對文件進行安全校驗,故在此簡單的實現了下DownLoadManager下載文件並伴有 安全校驗的功能

需求簡述:

1:下載文件,保證文件下載的完整性需要有MD5校驗

2:不能重複下載文件(如果有文件,就不下載)

 

首先是是DownLoadManager對文件的下載,單個文件的下載問題不大,關鍵是多個文件同時下載,會出現信息匹配錯亂的問題

public class FileManager {
    private static String sdCard = Environment.getExternalStorageDirectory().toString();
    private static FileManager instance;
    private Context context;
    private static DownloadManager mDownLoadService;
    private static String mType;
    private static LongSparseArray<SourceBean> downloadQueue;


    private FileManager(Context context) {
        this.context = context;
        downloadQueue = new LongSparseArray<>();
    }

    public static FileManager getInatance(Context context) {
        if (instance == null) {
            instance = new FileManager(context);
        }
        return instance;
    }

    /**
     * 保存文件
     *
     * @param savePath
     * @param sourceBean
     */
    public void downFile(String savePath, SourceBean sourceBean) {
        String name = sourceBean.getName();
        String md5 = sourceBean.getMd5();
        String url = sourceBean.getUrl();
        File file = new File(savePath + name);
        if (file.exists() && md5.equals(getFileMD5(savePath + name))) {
            Log.i("xd----------", "文件存在,無需下載");
        } else if (file.exists() && !md5.equals(getFileMD5(savePath + name))) {
            file.delete();
            Log.i("xd----------", "文件以改變,需下載");
            downloadfile(savePath, sourceBean);
        } else {
            Log.i("xd----------", "沒有文件,需下載");
            downloadfile(savePath, sourceBean);
        }
    }

    /**
     * 從網絡端下載文件
     *
     * @param savePath
     * @param sourceBean
     */
    private void downloadfile(String savePath, SourceBean sourceBean) {
        String url = sourceBean.getUrl();
        String name = sourceBean.getName();
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
        //設置下載時網絡類型
       request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE);
        //下載時狀態欄是否顯示
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);
        //設置漫遊狀態下是否下載
        request.setAllowedOverRoaming(true);
        //設置允許MediaScanner掃描
        request.allowScanningByMediaScanner();
        //下載文件存放的路徑--file:///storage/emulated/0/test/
        mDownLoadService = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        mType = name.substring(name.length() - 4, name.length());
        name = name.substring(0, name.length() - 4).concat(".temp");
        Log.i("xd---", name);
       //根據需求改,我這邊是要下載多種類型的文件,故在此對其做了區分
        switch (mType) {
            case ".mp3":
                request.setDestinationInExternalPublicDir("/test/mp3/", name);
               //根據每個下載id保存下載文件的信息
                downloadQueue.append(mDownLoadService.enqueue(request), sourceBean);
                break;
            case ".gif":
                request.setDestinationInExternalPublicDir("/test/gif/", name);
               //根據每個下載id保存下載文件的信息
                downloadQueue.append(mDownLoadService.enqueue(request), sourceBean);
                break;
            case ".ttf":
                request.setDestinationInExternalPublicDir("/test/ttf/", name);
               //根據每個下載id保存下載文件的信息
                downloadQueue.append(mDownLoadService.enqueue(request), sourceBean);
                break;
        }
        IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        DownLoadCompleteReceiver receiver = new DownLoadCompleteReceiver();
        context.registerReceiver(receiver, intentFilter);


    }

    /**
     * 獲取文件路徑
     *
     * @param path
     * @param md5
     * @return
     */
    public String getFile(String path, String md5) {
        File file = new File(path);
        if (!file.exists()) {
            return "null";
        }
        if (!getFileMD5(path).equals(md5)) {
            return "null";
        }
        return path;
    }

    /**
     * 獲取文件的MD5碼
     *
     * @param path
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    public static String getFileMD5(String path) {
        File file = new File(path);
        if (!file.exists()) {
            return "null";
        }
        FileInputStream fis = null;
        MappedByteBuffer map = null;
        try {
            fis = new FileInputStream(path);
            map = fis.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
        } catch (IOException e) {
            e.printStackTrace();
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        md5.update(map);
        BigInteger bi = new BigInteger(1, md5.digest());
        String value = bi.toString(16).toUpperCase();
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return value;
    }


    public static class DownLoadCompleteReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
                DownloadManager.Query query = new DownloadManager.Query();
               //獲取下載的文件的所有id,並保存在一個 
                long[] ids = new long[downloadQueue.size()];
                for (int i = 0; i < downloadQueue.size(); i++) {
                    ids[i] = downloadQueue.keyAt(i);
                }
                query.setFilterById(ids);
                Cursor cursor = mDownLoadService.query(query);
                if (cursor != null) {
                    while (cursor.moveToNext()) {
                        int status = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
                        switch (status) {
                            case DownloadManager.STATUS_PENDING:
                                break;
                            case DownloadManager.STATUS_PAUSED:
                                break;
                            case DownloadManager.STATUS_RUNNING:
                                break;
                            case DownloadManager.STATUS_SUCCESSFUL:
                                SourceBean sourceBean = downloadQueue.get(cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID)));
//下載文件的路徑
                                String filePath = cursor.getString(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI));
                              //對路徑進行編碼處理(我的路徑亂碼了)
                                filePath = URLDecoder.decode(filePath);
                              //由於路徑是file:///格式,故對其進行了處理
                                filePath = filePath.substring(7, filePath.length());
                                String url = sourceBean.getUrl();
                                String newPath = null;
                                if (url.endsWith(".gif")) {
                                  //你要保存的文件路徑
                                    newPath = filePath.substring(0, filePath.length() - 5).concat(".gif");
                                } else if (url.endsWith(".ttf") || url.endsWith("TTF")) {
                                    newPath = filePath.substring(0, filePath.length() - 5).concat(".ttf");
                                } else if (url.endsWith(".mp3")) {
                                    newPath = filePath.substring(0, filePath.length() - 5).concat(".mp3");
                                }
                                String result = saveFile(sourceBean.getMd5(), filePath, newPath);
                                break;
                            case DownloadManager.STATUS_FAILED:
                                break;
                        }
                    }
                    cursor.close();
                }

            }

        }
    }

    /**
     * 判斷文件並,保存下載文件
     *
     * @param md5
     * @param filePath
     * @param newPath
     */
    private static String saveFile(String md5, String filePath, String newPath) {
        File file = new File(filePath);
        File newFile = new File(newPath);
        String fileMD5 = getFileMD5(filePath);

        if (!file.exists()) {
            return "null";
        } else if (!fileMD5.equals(md5)) {
            file.delete();
            return "null";
        } else if (file.renameTo(newFile)) {
            file.delete();
            return newPath;
        } else {
            file.delete();
            return "null";
        }

    }

}

由於文件信息比較多,所以我自定義了一個SourseBean類來保存

public class SourceBean {
    private String name;
    private String url;
    private String md5;

    public SourceBean(String name, String url, String md5) {
        this.name = name;
        this.url = url;
        this.md5 = md5;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getMd5() {
        return md5;
    }

    public void setMd5(String md5) {
        this.md5 = md5;
    }
}

下載文件建議在IntentService下進行,其也是在線程中執行的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章