现在的位置: 首页 > 综合 > 正文

Android使用DownloadManager实现版本更新

2018年08月01日 ⁄ 综合 ⁄ 共 6618字 ⁄ 字号 评论关闭

需要添加的权限

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>

代码实现部分

获取服务端版本号与本地应用版本号比对的过程此处省略,下面是Activity中代码

//弹出版本更新提示框
Dialog dialog = new AlertDialog.Builder(context)
.setIcon(R.drawable.ic_launcher)
.setTitle("更新提示")
.setMessage(updateMessage())
.setPositiveButton("后台更新", new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface arg0, int arg1) {
        // TODO Auto-generated method stub
        Toast.makeText(context, "开始下载", 0).show();
        //下载Apk文件
        new ApkDownLoad(getApplicationContext(), APK_URL, "美丽说", "版本升级").execute();
    }
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface arg0, int arg1) {
        // TODO Auto-generated method stub
        arg0.cancel();
    }
})
.create();
dialog.show();

也可以将这段代码写在自定义Application类的OnCreate()方法中, 如果在Application中写入以上代码需要添加一个全局弹出Dialog的权限和属性。

//在dialog.show()之前添加
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

//系统权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

ApkDownLoad.java

public class ApkDownLoad {

    public static final String DOWNLOAD_FOLDER_NAME = "Download"; //Sd卡根目录文件夹名称
    public static final String DOWNLOAD_FILE_NAME   = "MeiLiShuo.apk"; //下载Apk名称
    public static final String APK_DOWNLOAD_ID = "apkDownloadId";

    private Context context;
    private String url;
    private String notificationTitle;
    private String notificationDescription;

    private DownloadManager downloadManager;
    private CompleteReceiver completeReceiver;

    /**
     * @param context 
     * @param url 下载apk的url
     * @param notificationTitle 通知栏标题
     * @param notificationDescription 通知栏描述
     */
    public ApkDownLoad(Context context, String url, String notificationTitle,
            String notificationDescription) {
        super();
        this.context = context;
        this.url = url;
        this.notificationTitle = notificationTitle;
        this.notificationDescription = notificationDescription;

        downloadManager = (DownloadManager)context.getSystemService(context.DOWNLOAD_SERVICE);
        completeReceiver = new CompleteReceiver();

        /** register download success broadcast **/
        context.registerReceiver(completeReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    public void execute() {

        //清除已下载的内容重新下载
        long downloadId = PreferencesUtils.getLong(context, APK_DOWNLOAD_ID);
        if(downloadId != -1){
            downloadManager.remove(downloadId); 
            PreferencesUtils.removeSharedPreferenceByKey(context, APK_DOWNLOAD_ID);
        }

        Request request = new Request(Uri.parse(url));
        //设置Notification中显示的文字
        request.setTitle(notificationTitle);
        request.setDescription(notificationDescription);
        //设置可用的网络类型
        request.setAllowedNetworkTypes(Request.NETWORK_MOBILE  | Request.NETWORK_WIFI); 
        //设置状态栏中显示Notification
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        //不显示下载界面  
        request.setVisibleInDownloadsUi(false); 
        //设置下载后文件存放的位置
        File folder = Environment.getExternalStoragePublicDirectory(DOWNLOAD_FOLDER_NAME);
        if (!folder.exists() || !folder.isDirectory()) {
            folder.mkdirs();
        }
        request.setDestinationInExternalPublicDir(DOWNLOAD_FOLDER_NAME, DOWNLOAD_FILE_NAME);
        //设置文件类型  
        MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();  
        String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url));  
        request.setMimeType(mimeString); 
        //保存返回唯一的downloadId
        PreferencesUtils.putLong(context, APK_DOWNLOAD_ID, downloadManager.enqueue(request));
    }

    class CompleteReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            /**
             * get the id of download which have download success, if the id is my id and it's status is successful,
             * then install it
             **/
            long completeDownloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
            long downloadId = PreferencesUtils.getLong(context, APK_DOWNLOAD_ID);

            if (completeDownloadId == downloadId) {

                // if download successful
                if (queryDownloadStatus(downloadManager, downloadId) == DownloadManager.STATUS_SUCCESSFUL) {

                    //clear downloadId
                    PreferencesUtils.removeSharedPreferenceByKey(context, APK_DOWNLOAD_ID);

                    //unregisterReceiver
                    context.unregisterReceiver(completeReceiver);

                    //install apk
                    String apkFilePath = new StringBuilder(Environment.getExternalStorageDirectory().getAbsolutePath())
                            .append(File.separator).append(DOWNLOAD_FOLDER_NAME).append(File.separator)
                            .append(DOWNLOAD_FILE_NAME).toString();
                    install(context, apkFilePath);
                }
            }
        }
    };

    /** 查询下载状态 */
    public static int queryDownloadStatus(DownloadManager downloadManager, long downloadId){
         int result = -1;
         DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
         Cursor c = null;
         try {
             c = downloadManager.query(query);
             if (c != null && c.moveToFirst()) {
                 result = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
             }
         } finally {
             if (c != null) {
                 c.close();
             }
         }
         return result;
    }

    /**
     * install app
     * 
     * @param context
     * @param filePath
     * @return whether apk exist
     */
    public static boolean install(Context context, String filePath) {
        Intent i = new Intent(Intent.ACTION_VIEW);
        File file = new File(filePath);
        if (file != null && file.length() > 0 && file.exists() && file.isFile()) {
            i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
            return true;
        }
        return false;
    }    
}

PreferencesUtils.java

public class PreferencesUtils {

    public static String PREFERENCE_NAME = "VersionUpdate";

    /**
     * put long preferences
     * 
     * @param context
     * @param key The name of the preference to modify
     * @param value The new value for the preference
     * @return True if the new values were successfully written to persistent storage.
     */
    public static boolean putLong(Context context, String key, long value) {
        SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = settings.edit();
        editor.putLong(key, value);
        return editor.commit();
    }

    /**
     * get long preferences
     * 
     * @param context
     * @param key The name of the preference to retrieve
     * @return The preference value if it exists, or -1. Throws ClassCastException if there is a preference with this
     *         name that is not a long
     * @see #getLong(Context, String, long)
     */
    public static long getLong(Context context, String key) {
        return getLong(context, key, -1);
    }

    /**
     * get long preferences
     * 
     * @param context
     * @param key The name of the preference to retrieve
     * @param defaultValue Value to return if this preference does not exist
     * @return The preference value if it exists, or defValue. Throws ClassCastException if there is a preference with
     *         this name that is not a long
     */
    public static long getLong(Context context, String key, long defaultValue) {
        SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        return settings.getLong(key, defaultValue);
    }

    /**
     * remove obj in preferences 
     * @param context
     * @param key
     * @return
     */
    public static boolean removeSharedPreferenceByKey(Context context, String key){
        SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = settings.edit();
        editor.remove(key);
        return editor.commit();
    }
}

抱歉!评论已关闭.