Downloadmanager實現app實現的升級下載使用


1、app升級下載現在不推薦使用downloadmanager下載:

原因有下面的幾個方面:

(1)三星note系列部分手機需要手動打開這個權限才能用這個功能,而有些國產手機更加nb了直接個閹割了(downloadmanager),所以考慮到手機的適配性,最后自己編寫app下載的后台代碼

2、但是這里還是對downloadmanager下載進行一些詳細的分析,很多下載的思路還是值得借鑒的

1、首先后台的apk的搭建

1、打開本地Tomcat服務器,放入一個Apk文件

 

apk存放在webapps/root目錄下

// 首先確保瀏覽器能夠訪問http://localhost:8080/123456.apk

下面我將內容大致分為以下幾個部分:

(1)App版本檢測

(2)Apk下載

(3)Apk更新安裝

(4)對以上功能進行封裝

基於以上4部分,我們逐一展開。

1.App版本檢測:

要實現App的更新下載,我們上面介紹了,前提是服務器要保存一個App的版本號(通常的方式是保存versionCode,當然你要對比versionName也沒關系)。當用戶去手動檢測版本,或者進入首頁自動檢測時,第一步是需要請求服務器的版本號,拿到版本號之后與當前App版本號(當前版本號可通過PackageInfo獲取)進行對比。服務器返回的版本號大於當前App版本號,證明App已經有更新,那么進入第2步。

2.Apk下載

Apk文件是保存在服務器的。我們可以通過Http流將其下載到本地手機,然后更新安裝。Android中下載的方式很多種:HttpUrlConnection,Retrofit,okHttp,以及Android原生的下載工具類DownLoadManager 等等。我們采用的方式是Google推薦的下載工具類DownLoadManager。關於DownLoadManager的使用其實很簡單,簡單概括如下:

(1)通過getSystemService獲取DownLoadManager。

(2)初始化DownLoadManager的Request,構建下載請求。

(3)調用DownLoadManager的enqueue異步發起請求,該方法返回值為標識當前下載任務的id,即downloadId。

(4)當下載完成后,系統會發出條件為android.intent.action.DOWNLOAD_COMPLETE的廣播,我們可以自定義廣播接受器,然后在onReceive中處理下載完成的邏輯即可。

詳細使用方式大家可以參考網上的教程,此處就不再贅述。

上面通過下載啰嗦了一堆。此時我們要想一個問題:當我們下載完成后,並沒有安裝。當用戶再次進入App時該如何操作?

有朋友會說,那就再去下載一次,然后繼續執行更新安裝呀!哈哈,這種方式是沒有錯誤的,但是如果用戶惡意行為,每次下載完成都不安裝,那我們豈不是每次都要去下載100次,1000次。。(然后手機boom!!!)這種方式肯定是不能采用的。那么我們該如何解決呢?

很簡單,當我們在下載之前,先去指定的文件夾下查看有木有已經下載好的Apk,並且該Apk的版本是高於本App的版本,此時我們就去執行安裝操作。如果上面條件不成立,此時再去執行下載操作。

3.Apk更新安裝

相信大家對於如何安裝一個Apk都比較熟悉吧,原理也是比較簡單的。

(1)通過downloadId獲取下載的Uri。

(2)將Uri設置到Itent的setDataAndType作為啟動條件。

(3)調用startActivity啟動對應Intent即可。

以上3步,即可完成App的更新功能。

整體的流程很清晰:

版本檢測 → Apk下載 (檢查是否存在未安裝的Apk) → Apk安裝 → 完成更新

下面,通過代碼來具體分析整個流程:

關於App版本檢測其實就是一個Http請求,不再多說。我們從Apk下載開始:

上面我們提到,在下載之前需要去檢測是否存在已經下載的Apk。通過什么獲取呢?沒錯,肯定是downloadId了。

1> 如果存在downloadId,那么我們通過downloadId獲取當前下載的狀態status。status分為成功,失敗兩種狀態。

(1)當status為成功狀態時,即已經下載完成,我們就通過downloadId獲取下載文件的Uri。然后可以通過Uri獲取PackageInfo,與當前App進行包名和版本號的對比,當包名相同,並且當前版本號是小於下載的Apk版本號兩個條件同時成立時,直接執行安裝操作。否則,執行remove,通過downloadId刪除下載任務以及文件,繼續執行下載。

(2)當status為失敗狀態時,即下載未完成,我們就直接執行重新下載即可。

2> 如果不存在downloadId,即沒有下載過Apk,執行下載即可。

 

下載完成后,系統會發出廣播,在廣播中,我們對比downloadId是否相同,相同情況下,直接通過downloadId獲取Uri,然后跳轉到安裝界面,提示用戶安裝即可:

 

所以,別忘了在下載之前要先將該大喇叭(廣播接受器)注冊。

 

最后,當我們安裝完成后,再次進入App,就將其已下載的Apk文件進行刪除(將該方法放在onCreate生命周期中即可):

 

上面通過downloadApk獲取下載文件的地址。downloadApk地址是在下載完成后廣播接收器中保存的。

通過上面的步驟,我們就完成了App更新下載安裝的全部工作。相信大家也有了更深的認識和理解。

下面博客:

http://chuansong.me/n/1090429551927

http://chuansong.me/n/1090429551927

也是對downloadManger做了詳細的解釋

接下來我們看下代碼

程序的框架如下所示:

 

package co.huiqu.webapp;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import co.huiqu.webapp.download.DownLoadUtils;
import co.huiqu.webapp.download.DownloadApk;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        //1.注冊下載廣播接收器
        DownloadApk.registerBroadcast(this);
        //2.apk按照成功之后再次進場到app刪除已存在的Apk
        DownloadApk.removeFile/**/(this);
        fab.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
       /*         String packageName = "com.android.providers.downloads";
                Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.setData(Uri.parse("package:" + packageName));
              startActivity(intent);*/

                //3.如果手機已經啟動下載程序,執行downloadApk。否則跳轉到設置界面
                if (DownLoadUtils.getInstance(getApplicationContext()).canDownload()) {
                    //DownloadApk.downloadApk(getApplicationContext(), "http://www.huiqu.co/public/download/apk/huiqu.apk", "Hobbees更新", "Hobbees");
                    DownloadApk.downloadApk(getApplicationContext(), "http://10.12.8.13:8080/123456.apk", "酷狗更新", "Hobbees下載");
                } else {
                    DownLoadUtils.getInstance(getApplicationContext()).skipToDownloadManager();
                }
            }
        });
    }

    @Override
    protected void onDestroy() {

        //4.反注冊廣播接收器
        DownloadApk.unregisterBroadcast(this);
        super.onDestroy();
    }
}

 

 sharePrefer的工具類代碼:

package co.huiqu.webapp.config;

import java.util.Set;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

/**
 * 
 * 保存系統信息
 * @author song
 * @date 2015年11月4日
 */
public class SystemParams {

    private static SystemParams instance;
    private static SharedPreferences sharedPrederences = null;

    private SystemParams() {
    }

    //在Application初始化
    public static void init(Context context) {
        sharedPrederences = context.getSharedPreferences("hobbees", Context.MODE_PRIVATE);
    }
    public static SystemParams getInstance() {
        
        if(instance == null) {
            synchronized (SystemParams.class) {
                if(instance == null) {
                     instance = new SystemParams();
                }
            }
        }
        return instance;
    }
    
    /**get**/
    public int getInt(String key){
        return sharedPrederences.getInt(key, 0);
    }
    
    public int getInt(String key,int defValue){
        return sharedPrederences.getInt(key, defValue);
    }    

    public float getFloat(String key){
        return sharedPrederences.getFloat(key, 0);
    }
    
    public float getFloat(String key,float defValue) {
        return sharedPrederences.getFloat(key, defValue);
    }    
    
    public long getLong(String key){
        return sharedPrederences.getLong(key, 0);
    }
    
    public long getLong(String key,long defValue) {
        return sharedPrederences.getLong(key, defValue);
    }        

    public String getString(String key){
        return sharedPrederences.getString(key, null);
    }
    
    public String getString(String key,String defValue) {
        return sharedPrederences.getString(key, defValue);
    }    
    
    public boolean getBoolean(String key){
        return sharedPrederences.getBoolean(key, false);
    }
    
    public boolean getBoolean(String key,boolean defValue) {
        return sharedPrederences.getBoolean(key, defValue);
    }
    
    /**set**/
    public void setInt(String key,int value) {
        Editor editor = sharedPrederences.edit();
        editor.putInt(key, value);
        editor.commit();
    }
    
    public void setFloat(String key,float value) {
        Editor editor = sharedPrederences.edit();
        editor.putFloat(key, value);
        editor.commit();
    }
    
    public void setLong(String key,long value) {
        Editor editor = sharedPrederences.edit();
        editor.putLong(key, value);
        editor.commit();
    }
    
    public void setString(String key,String value) {
        Editor editor = sharedPrederences.edit();
        editor.putString(key, value);
        editor.commit();
    }
    
    public void setBoolean(String key,boolean value) {
        Editor editor = sharedPrederences.edit();
        editor.putBoolean(key, value);
        editor.commit();
    }
    
    public void setSetString(String key,Set<String> values) {
        Editor editor = sharedPrederences.edit();
        editor.putStringSet(key, values);
        editor.commit();
    }
    
    public void remove(String key) {
        Editor editor = sharedPrederences.edit();
        editor.remove(key);
        editor.commit();
    }
    
    public void clear() {
        Editor editor = sharedPrederences.edit();
        editor.clear().commit();
    }
}

 

package co.huiqu.webapp.download;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.widget.Toast;

import co.huiqu.webapp.config.SystemParams;

/**
 * Created by Song on 2016/11/2.
 */
public class ApkInstallReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        long downloadApkId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
        if(intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
            Toast.makeText(context,"收到apk下載完成的廣播",Toast.LENGTH_LONG).show();

            int status =  DownLoadUtils.getInstance(context).checkStatus(downloadApkId);
            switch (status) {
                //下載暫停
                case DownloadManager.STATUS_PAUSED:
                    //獲得下載暫停的原因等信息
                    Toast.makeText(context,"暫停下載"+DownLoadUtils.getInstance(context).getPausedReason(downloadApkId),Toast.LENGTH_LONG).show();
                    break;
                //下載延遲
                case DownloadManager.STATUS_PENDING:
                    //獲得下載延遲的原因
                    break;
                //正在下載
                case DownloadManager.STATUS_RUNNING:
                    break;
                //下載完成
                case DownloadManager.STATUS_SUCCESSFUL:
                    //下載完成安裝APK
                    installApk(context, downloadApkId);
                    break;
                //下載失敗
                case DownloadManager.STATUS_FAILED:
                   // 獲得下載失敗的原因
                    Toast.makeText(context,"暫停下載"+DownLoadUtils.getInstance(context).getFailedReason(downloadApkId),Toast.LENGTH_LONG).show();
                    break;
            }


        }else if(DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(intent.getAction())){

            //點擊通知欄取消下載
            Toast.makeText(context,"通知欄被點擊",Toast.LENGTH_LONG).show();

        }
    }

    /**
     * 安裝apk
     */
    private void installApk(Context context,long downloadId) {

        long downId = SystemParams.getInstance().getLong(DownloadManager.EXTRA_DOWNLOAD_ID, -1L);
        if(downloadId == downId) {
            DownloadManager downManager= (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
            Uri downloadUri = downManager.getUriForDownloadedFile(downloadId);
            SystemParams.getInstance().setString("downloadApk",downloadUri.getPath());
            if (downloadUri != null) {
                Intent install= new Intent(Intent.ACTION_VIEW);
                install.setDataAndType(downloadUri, "application/vnd.android.package-archive");
                install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(install);
            } else {
                Toast.makeText(context, "下載失敗", Toast.LENGTH_SHORT).show();
            }
        }
    }


}
package co.huiqu.webapp.download;

import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import java.io.File;

import co.huiqu.webapp.config.SystemParams;

/**
 * Apk下載
 * Created by Song on 2016/11/2.
 */
public class DownloadApk {

    private static ApkInstallReceiver apkInstallReceiver;

    /**
     * 下載APK文件
     * @param context
     * @param url
     * @param title
     * @param appName
     */
    public static void downloadApk(Context context, String url, String title,final String appName) {

        //獲取存儲的下載ID
        long downloadId = SystemParams.getInstance().getLong(DownloadManager.EXTRA_DOWNLOAD_ID,-1L);
        if(downloadId != -1) {
            //存在downloadId
            DownLoadUtils downLoadUtils = DownLoadUtils.getInstance(context);
            //獲取當前狀態
            int status = downLoadUtils.getDownloadStatus(downloadId);
            if(DownloadManager.STATUS_SUCCESSFUL == status) {
                //狀態為下載成功
                //獲取下載路徑URI
                Uri downloadUri = downLoadUtils.getDownloadUri(downloadId);
                if(null != downloadUri) {
                    //存在下載的APK,如果兩個APK相同,啟動更新界面。否之則刪除,重新下載。
                    if(compare(getApkInfo(context,downloadUri.getPath()),context)) {
                        startInstall(context, downloadUri);
                        return;
                    } else {
                        //刪除下載任務以及文件
                        downLoadUtils.getDownloadManager().remove(downloadId);
                    }
                }
                start(context, url, title,appName);
            } else if(DownloadManager.STATUS_FAILED == status) {
                //下載失敗,重新下載
                start(context, url, title,appName);
            }else {
                Log.d(context.getPackageName(), "apk is already downloading");
            }
        } else {
            //不存在downloadId,沒有下載過APK
            start(context, url, title,appName);
        }
    }

    /**
     * 開始下載
     * @param context
     * @param url
     * @param title
     * @param appName
     */
    private static void start(Context context, String url, String title,String appName) {

        if(hasSDKCard()) {
            long id = DownLoadUtils.getInstance(context).download(url,
                    title, "下載完成后點擊打開", appName);
            SystemParams.getInstance().setLong(DownloadManager.EXTRA_DOWNLOAD_ID,id);
        } else {
            Toast.makeText(context,"手機未安裝SD卡,下載失敗",Toast.LENGTH_LONG).show();
        }
    }

    public static void registerBroadcast(Context context) {
        apkInstallReceiver = new ApkInstallReceiver();
        context.registerReceiver(apkInstallReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
        context.registerReceiver(apkInstallReceiver, new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED));
    }

    public static void unregisterBroadcast(Context context) {
        if(null != apkInstallReceiver) {
            context.unregisterReceiver(apkInstallReceiver);
        }
    }

    /**
     * 跳轉到安裝界面
     * @param context
     * @param uri
     */
    private static void startInstall(Context context, Uri uri) {

        Intent install = new Intent(Intent.ACTION_VIEW);
        install.setDataAndType(uri, "application/vnd.android.package-archive");
        install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(install);
    }


    /**
     * 獲取APK程序信息
     * @param context
     * @param path
     * @return
     */
    private static PackageInfo getApkInfo(Context context, String path) {

        PackageManager pm = context.getPackageManager();
        PackageInfo pi = pm.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
        if(null != pi) {
            return pi;
        }
        return null;
    }


    /**
     * 比較兩個APK的信息
     * @param apkInfo
     * @param context
     * @return
     */
    private static boolean compare(PackageInfo apkInfo,Context context) {

        if(null == apkInfo) {
            return false;
        }
        String localPackageName = context.getPackageName();
        if(localPackageName.equals(apkInfo.packageName)) {
            try {
                PackageInfo packageInfo = context.getPackageManager().getPackageInfo(localPackageName, 0);
                //比較當前APK和下載的APK版本號
                if (apkInfo.versionCode > packageInfo.versionCode) {
                    //如果下載的APK版本號大於當前安裝的APK版本號,返回true
                    return true;
                }
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 是否存在SD卡
     */
    private static boolean hasSDKCard() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    /**
     * 刪除已下載的文件
     */
    public static void removeFile(Context context) {
        String filePath = SystemParams.getInstance().getString("downloadApk",null);
        if(null != filePath) {
            File downloadFile = new File(filePath);
            if(null != downloadFile && downloadFile.exists()) {
                //刪除之前先判斷用戶是否已經安裝了,安裝了才刪除。
                if(!compare(getApkInfo(context,filePath),context)) {
                    downloadFile.delete();
                    Log.e("----", "已刪除");
                }
            }
        }
    }
}

 

package co.huiqu.webapp.download;

import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import java.io.File;

import co.huiqu.webapp.config.SystemParams;

/**
 * 封裝 DownLoadManager 下載
 * Created by Song on 2016/11/2.
 */
public class DownLoadUtils {

    private Context mContext;
    private DownloadManager mDownloadManager;
    private static volatile DownLoadUtils instance;

    private DownLoadUtils(Context context) {
        this.mContext = context.getApplicationContext();
        mDownloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    }

    /**
     * 獲取單例對象
     *
     * @param context
     * @return
     */
    public static DownLoadUtils getInstance(Context context) {

        if (instance == null) {
            synchronized (DownLoadUtils.class) {
                if (instance == null) {
                    instance = new DownLoadUtils(context);
                    return instance;
                }
            }
        }
        return instance;
    }

    /**
     * 下載
     *
     * @param uri
     * @param title
     * @param description
     * @param appName
     * @return downloadId
     */
    public long download(String uri, String title, String description, String appName) {

        //1.構建下載請求
        DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(uri));
        downloadRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
        downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        /**設置漫游狀態下是否可以下載*/
        downloadRequest.setAllowedOverRoaming(false);
        /**如果我們希望下載的文件可以被系統的Downloads應用掃描到並管理,
         我們需要調用Request對象的setVisibleInDownloadsUi方法,傳遞參數true.*/
        downloadRequest.setVisibleInDownloadsUi(true);
        //文件保存位置
        //file:///storage/emulated/0/Android/data/your-package/files/Download/appName.apk
        downloadRequest.setDestinationInExternalFilesDir(mContext, Environment.DIRECTORY_DOWNLOADS, appName + ".apk");
        // 設置一些基本顯示信息
        downloadRequest.setTitle(title);
        downloadRequest.setDescription(description);
        //req.setMimeType("application/vnd.android.package-archive");
        return mDownloadManager.enqueue(downloadRequest);//異步請求
    }

    /**
     * 獲取文件下載路徑
     *
     * @param downloadId
     * @return
     */
    public String getDownloadPath(long downloadId) {

        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        Cursor c = mDownloadManager.query(query);
        if (c != null) {
            try {
                if (c.moveToFirst()) {
                    return c.getString(c.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI));
                }
            } finally {
                c.close();
            }
        }

        return null;
    }

    /**
     * 獲取文件保存的地址
     *
     * @param downloadId
     * @return
     */
    public Uri getDownloadUri(long downloadId) {
        return mDownloadManager.getUriForDownloadedFile(downloadId);
    }

    public DownloadManager getDownloadManager() {
        return mDownloadManager;
    }

    /**
     * 獲取下載狀態
     *
     * @param downloadId
     * @return
     */
    public int getDownloadStatus(long downloadId) {

        DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
        Cursor c = mDownloadManager.query(query);
        if (c != null) {
            try {
                if (c.moveToFirst()) {
                    return c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
                }
            } finally {
                c.close();
            }
        }
        return -1;
    }

    /**
     * 判斷下載管理程序是否可用
     *
     * @return
     */
    public boolean canDownload() {

        try {
            int state = mContext.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
            if (state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
                    || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
                    || state == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 進入 啟用/禁用 下載管理程序界面
     */
    public void skipToDownloadManager() {

        String packageName = "com.android.providers.downloads";
        Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + packageName));
        mContext.startActivity(intent);
    }


    /**
     * 進入 啟用/禁用 下載管理程序界面
     */
    public int checkStatus(long downloadId) {
        DownloadManager.Query query = new DownloadManager.Query();
        //通過下載的id查找
        query.setFilterById(downloadId);
        Cursor c = mDownloadManager.query(query);
        int status = -1;
        if (c.moveToFirst()) {
            status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));

        }
        return status;
    }


    /**
     * 查詢當前下載暫停失敗的原因
     */

    public String getPausedReason(long downloadId) {
        DownloadManager.Query query = new DownloadManager.Query();
        //通過下載的id查找
        query.setFilterById(downloadId);
        query.setFilterByStatus(DownloadManager.STATUS_PAUSED);
        // Query the Download Manager for paused downloads.
        Cursor pausedDownloads = mDownloadManager.query(query);

        // Find the column indexes for the data we require.
        int reasonIdx = pausedDownloads.getColumnIndex(DownloadManager.COLUMN_REASON);
        int titleIdx = pausedDownloads.getColumnIndex(DownloadManager.COLUMN_TITLE);
        int fileSizeIdx =
                pausedDownloads.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
        int bytesDLIdx =
                pausedDownloads.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);

        // Iterate over the result Cursor.
        while (pausedDownloads.moveToNext()) {
            // Extract the data we require from the Cursor.
            String title = pausedDownloads.getString(titleIdx);
            int fileSize = pausedDownloads.getInt(fileSizeIdx);
            int bytesDL = pausedDownloads.getInt(bytesDLIdx);

            // Translate the pause reason to friendly text.
            int reason = pausedDownloads.getInt(reasonIdx);
            String reasonString = "Unknown";
            switch (reason) {
                case DownloadManager.PAUSED_QUEUED_FOR_WIFI:
                    reasonString = "Waiting for WiFi";
                    break;
                case DownloadManager.PAUSED_WAITING_FOR_NETWORK:
                    reasonString = "Waiting for connectivity";
                    break;
                case DownloadManager.PAUSED_WAITING_TO_RETRY:
                    reasonString = "Waiting to retry";
                    break;
                default:
                    break;
            }
            // Construct a status summary
            StringBuilder sb = new StringBuilder();
            sb.append(title).append("\n");
            sb.append(reasonString).append("\n");
            sb.append("Downloaded ").append(bytesDL).append(" / ").append(fileSize);

            return  sb.toString();
        }
        return "";
    }

    /**
     * 查詢當前下載暫停失敗的原因
     */

    public String getFailedReason(long downloadId) {
        DownloadManager.Query query = new DownloadManager.Query();
        //通過下載的id查找
        query.setFilterById(downloadId);
        query.setFilterByStatus(DownloadManager.STATUS_FAILED);
        // Query the Download Manager for paused downloads.
        Cursor pausedDownloads = mDownloadManager.query(query);

        // Find the column indexes for the data we require.
        int reasonIdx = pausedDownloads.getColumnIndex(DownloadManager.COLUMN_REASON);
        int titleIdx = pausedDownloads.getColumnIndex(DownloadManager.COLUMN_TITLE);
        int fileSizeIdx =
                pausedDownloads.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
        int bytesDLIdx =
                pausedDownloads.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);

        // Iterate over the result Cursor.
        while (pausedDownloads.moveToNext()) {
            // Extract the data we require from the Cursor.
            String title = pausedDownloads.getString(titleIdx);
            int fileSize = pausedDownloads.getInt(fileSizeIdx);
            int bytesDL = pausedDownloads.getInt(bytesDLIdx);

            // Translate the pause reason to friendly text.
            int reason = pausedDownloads.getInt(reasonIdx);
            String reasonString = "Unknown";
            switch (reason) {
                case DownloadManager.ERROR_HTTP_DATA_ERROR:
                    reasonString = "服務器異常";
                    break;
                case DownloadManager.ERROR_INSUFFICIENT_SPACE:
                    reasonString = "存儲空間不足";
                    break;
                case DownloadManager.ERROR_FILE_ERROR:
                    reasonString = "找不到該文件";
                    break;
                default:
                    break;
            }
            // Construct a status summary
            StringBuilder sb = new StringBuilder();
            sb.append(title).append("\n");
            sb.append(reasonString).append("\n");
            sb.append("Downloaded ").append(bytesDL).append(" / ").append(fileSize);

            return sb.toString();
        }
        return "";
    }

}

清單文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="co.huiqu.webapp">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <application
        android:name=".A"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".download.ApkInstallReceiver">
            <intent-filter>
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
                <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
            </intent-filter>
        </receiver>
    </application>
    <!--在SDCard中創建與刪除文件權限  -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <!-- 往SDCard寫入數據權限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!--  從SDCard讀取數據權限 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!--  訪問網絡權限 -->
    <uses-permission android:name="android.permission.INTERNET"/>

</manifest>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM