Java4Android之APP自動升級

來源:互聯網
上載者:User

標籤:java4android   自動升級   update   downloadmanager   

一個成熟的商業APP必須不斷的退出新的版本。那麼,不可能讓使用者自己去應用市場去下載新版本的應用,我們應該在應用內部提供自動升級的功能。自動升級其實包含兩個層面,一個是整個APP的升級,也就是下載新版本的APP,然後安裝替換掉現有的。還有一種升級是模組升級,這種升級一般採用靜默升級,就是使用者完全不知道。這個在我大迅雷裡面經常做的,拿各個渠道去試錯,對於一個互連網公司而言是再普通不過的了。而這些模組,肯定是諸如,解析庫,下載庫,播放庫,這些後台庫。。

不過今天,我要說的是APP的自動升級,模組的靜默升級我們下次有時間再說。

APP升級流程盜用別人的圖,來說明一下升級APP的整體流程。

對,這個圖是盜用別人的。因為,這就是APP升級的一般流程。所以,我們知道了,第一步,我們需要去伺服器查詢版本資訊,確定是不是要進行升級。到伺服器查詢版本資訊具體見代碼,
private static final class UpgradeLoader extends AsyncTask<Void, Void, UpdateInfo> {        private WeakReference<Activity> mContext;        private boolean mAuto;        private IUpgradeCheck mUpgradeCheckListener;        protected boolean mChecked;        public UpgradeLoader(Activity context, boolean auto, IUpgradeCheck listener) {            mContext = new WeakReference<Activity>(context);            mAuto = auto;            mUpgradeCheckListener = listener;        }        @Override        protected void onPreExecute() {            if (mUpgradeCheckListener != null) {                mUpgradeCheckListener.beforeCheck();            }        }        @Override        protected UpdateInfo doInBackground(Void... params) {            if (mUpgradeCheckListener != null) {                mUpgradeCheckListener.onCheck();            }            Context ctx = mContext.get();            String channel = "";            if (ctx != null) {                channel = Util.getChannelID(ctx);            }            return DataProxy.getInstance().getUpdateInfo(Util.getVersionName(MyApplication.sInstance),                    Util.getOSVersion(), channel); //去伺服器查詢版本資訊,這個是我們對http的一個封裝,在這裡,每個公司可以自己定義一些自己的地址和參數,非常簡單的。        }        @Override        protected void onPostExecute(UpdateInfo result) {//從伺服器查詢回來,決定要不要升級            if (mUpgradeCheckListener != null) {                mUpgradeCheckListener.afterCheck();            }            if (!isCancelled()) {                if (result == null) {                    if (!mAuto) {                        UIHelper.showToast(MyApplication.sInstance, "檢查更新失敗", Toast.LENGTH_SHORT);                    }                } else {                    switch (result.type) {                    case UpdateInfo.NO_UPGRADE:                        if (!mAuto) {                            UIHelper.showToast(KankanApplication.sInstance, "已經是最新版本,沒有更新", Toast.LENGTH_SHORT);                        }                        break;                    case UpdateInfo.UPDATE_NOT_TIPS:                        if (!mAuto) {                            buildDialog(result);                        } else {                            downloadApk(KankanApplication.sInstance, result.latestUrl);                        }                        break;                    case UpdateInfo.UPDATE_TIPS:                    case UpdateInfo.UPDATE_FOURCE:                        if (!(mAuto && PreferenceManager.instance(mContext.get()).isVerionSkiped(result.latestVersion))) {                            buildDialog(result);                        }                    default:                        break;                    }                }            }        }
注意上述代碼。我們僅僅是示意,所以不可能把所有代碼提供給大家學習。就是你第一步是去伺服器查詢版本資訊。然後確定要下載APK的時候,則會調用downloadApk函數。對APK進行下載。下載APK在網上,很多人提供了採用httpclient去下載APK的方法,我這裡給出另外一種思路。兩種方法都可以,建議採用我們的提供的,因為,這個是針對下載較大檔案的系統方法。
詳見代碼:
private static void downloadApk(Context context, String url) {        DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);        Uri uri = Uri.parse(url);        String scheme = uri.getScheme();        if (scheme == null || (!scheme.equals("http") && !scheme.equals("https"))) {            LOG.error("only supports http/https url={}", url);        } else {            try {                DownloadManager.Request down = new DownloadManager.Request(uri);                down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE                        | DownloadManager.Request.NETWORK_WIFI);                down.setShowRunningNotification(true);                down.setVisibleInDownloadsUi(true);                down.setDestinationInExternalFilesDir(context, null, APK_NAME);                manager.enqueue(down);//開始下載            } catch (Exception e) {                e.printStackTrace();                UIHelper.showToast(context, "下載應用失敗,請您去應用市場升級", Toast.LENGTH_LONG);            }        }    }
這樣,使用DownloadManager可以非常方便的實現APK的下載。如果想對這個類進行更加深入的瞭解,大家可以去查詢相關的資料。你可以查詢下載進度等等相關的資訊。
下載完成了,接下來就是要安裝了。我們需要一個事件去觸發安裝。做法是,我們應該監聽下載完成這件事情,下載完成之後,會有個廣播發生,當監聽到這個廣播的時候我們就開始安裝。安裝APK監聽下載完成,並安裝。
    public void onReceive(Context context, Intent intent) {        if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {//監聽下載完成            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);            if (id > -1) {                File file = queryFile(context, id);                if (file != null && file.exists()) {                    Intent startInent = new Intent();                    startInent.setAction(Intent.ACTION_VIEW);                    startInent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                    startInent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");                    context.startActivity(startInent);//安裝APK                }            }        }    }

至此,一個APK的自動升級就完成了。其實還有一些善後工作需要做的是,你需要刪除APK,刪除APK的方法應該是在安裝完成之後刪除,網上有說通過廣播監聽的方法來刪除,就是監聽到安裝完成之後刪除。這個大家去搜尋一下就可以。刪除APK檔案這裡,我還是給出點樣本:首先是要擷取應用的安裝狀態,通過廣播的形式
以下是和應用程式相關的Broadcast Action
ACTION_PACKAGE_ADDED 一個新應用程式套件已經安裝在裝置上,資料包括包名(最新安裝的包程式不能接收到這個廣播)
ACTION_PACKAGE_REPLACED 一個新版本的應用安裝到裝置,替換之前已經存在的版本
ACTION_PACKAGE_CHANGED 一個已存在的應用程式套件組合已經改變,包括包名
ACTION_PACKAGE_REMOVED 一個已存在的應用程式套件組合已經從裝置上移除,包括包名(正在被安裝的包程式不能接收到這個廣播)
ACTION_PACKAGE_RESTARTED 使用者重新開始一個包,包的所有進程將被殺死,所有與其聯絡的已耗用時間狀態應該被移除,包括包名(重新開始包程式不能接收到這個廣播)
ACTION_PACKAGE_DATA_CLEARED 使用者已經清楚一個包的資料,包括包名(清除包程式不能接收到這個廣播)

代碼實現 
在AndroidManifest.xml中定義廣播

<receiver android:name=".AppInstallReceiver"            android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.PACKAGE_ADDED" />                 <action android:name="android.intent.action.PACKAGE_REPLACED" />                <action android:name="android.intent.action.PACKAGE_REMOVED" />                <data android:scheme="package" />            </intent-filter>        </receiver>
然後是接收端:
public class AppInstallReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        PackageManager manager = context.getPackageManager();        if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {            String packageName = intent.getData().getSchemeSpecificPart();            Toast.makeText(context, "安裝成功"+packageName, Toast.LENGTH_LONG).show();        }        if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {            String packageName = intent.getData().getSchemeSpecificPart();            Toast.makeText(context, "卸載成功"+packageName, Toast.LENGTH_LONG).show();        }        if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {            String packageName = intent.getData().getSchemeSpecificPart();            Toast.makeText(context, "替換成功"+packageName, Toast.LENGTH_LONG).show();
<span style="white-space:pre"></span>doanloadApk.delete();//從SD中刪除剛剛下載的APK檔案        }    }}

好。APK自動升級就說道這裡。


有時間,給大家說一下模組的靜默升級的實現。



 

Java4Android之APP自動升級

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.