Android之DownloadManager實現(xiàn)軟件更新并自動安裝

為之于未有读处,治之于未亂尘分。

在Android開發(fā)中猜惋,軟件更新可以說是必不可少的,而隔壁的iOS喝著咖啡培愁,無情的嘲笑著這個他們不用再實現(xiàn)的功能著摔,因為蘋果會無情的拒絕所有包含軟件更新,哪怕是版本檢測的APP定续。作為苦逼的Android攻城獅谍咆,我們還是老老實實地研究一下如何實現(xiàn)軟件更新吧。

一私股、軟件升級的實現(xiàn)思路

  • 下載APK

    • 應用內(nèi)下載文件
      應用內(nèi)實現(xiàn)文件下載摹察,如果退出程序,下載將結(jié)束倡鲸。
    • Service下載文件
      利用Service實現(xiàn)文件后臺下載供嚎,不受程序是否退出的影響。
  • 安裝APK

    • 手動安裝
    • 自動安裝

對于用戶而言,后臺下載并自動安裝必然是一個好的使用體驗克滴。使用Service去實現(xiàn)文件下載的話逼争,還需要我們自己維護網(wǎng)絡請求,這可是非常麻煩又頭痛的事情偿曙,有沒有一個更方便快捷的方式呢氮凝?下面將介紹一種簡單粗暴的實現(xiàn)方法!

二望忆、DownloadManager實現(xiàn)文件下載

  • 使用DownloadManager實現(xiàn)APK下載
    通過DownloadManager來實現(xiàn)文件下載罩阵,我們就可以完全不用考慮網(wǎng)絡請求、異步問題了启摄,系統(tǒng)幫我們處理了所有事情稿壁,你可以繼續(xù)操作App,即便是退出程序也不會影響APK的下載歉备。
  /**
     * 下載新版本
     *
     * @param context
     * @param url
     */
public static void downLoadAPK(Context context, String url) {

       if (TextUtils.isEmpty(url)) {
           return;
       }

       try {
           String serviceString = Context.DOWNLOAD_SERVICE;
           final DownloadManager downloadManager = (DownloadManager) context.getSystemService(serviceString);

           Uri uri = Uri.parse(url);
           DownloadManager.Request request = new DownloadManager.Request(uri);
           request.allowScanningByMediaScanner();
           request.setVisibleInDownloadsUi(true);
           request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
           request.setMimeType("application/vnd.android.package-archive");

           File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/juyoubang/","juyoubang.apk");
           if (file.exists()){
               file.delete();
           }
           request.setDestinationInExternalPublicDir(Environment.getExternalStorageDirectory().getAbsolutePath()+"/juyoubang/", "juyoubang.apk");
           long refernece = downloadManager.enqueue(request);
           SharePreHelper.getIns().setLongData("refernece", refernece);
       } catch (Exception exception) {
           ToastUtils.init(context).show("更新失敗");
       }

   }

三傅是、自動安裝

這里的自動安裝是指下載完成后,自動彈出安裝界面,而不是靜默安裝APK。同時這里不得不提的一個大坑就是Android6.0這個分水嶺候生,6.0以后的實現(xiàn)方式有所不同肠牲。

  • 自定義Receiver接收系統(tǒng)廣播,實現(xiàn)軟件自動安裝迟隅。
    Android6.0之前的版本我們可以通過Intent的方式來實現(xiàn),但是我們會發(fā)現(xiàn)6.0之后的手機上,下載完成后沒有任何效果浆劲,解決辦法就是通過打開文件的形式實現(xiàn)自動安裝。
public class UpdataBroadcastReceiver extends BroadcastReceiver {

    @SuppressLint("NewApi")
    public void onReceive(Context context, Intent intent) {

        long myDwonloadID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
        long refernece = SharePreHelper.getIns().getLongData("refernece", 0);
        if (refernece != myDwonloadID) {
            return;
        }

        DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        Uri downloadFileUri = dManager.getUriForDownloadedFile(myDwonloadID);
        installAPK(context,downloadFileUri);
    }
    private void installAPK(Context context,Uri apk ) {
        if (Build.VERSION.SDK_INT < 23) {
            Intent intents = new Intent();
            intents.setAction("android.intent.action.VIEW");
            intents.addCategory("android.intent.category.DEFAULT");
            intents.setType("application/vnd.android.package-archive");
            intents.setData(apk);
            intents.setDataAndType(apk, "application/vnd.android.package-archive");
            intents.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intents);
        } else {
            File file = queryDownloadedApk(context);
            if (file.exists()) {
                openFile(file, context);
            }

        }
    }

    /**
     * 通過downLoadId查詢下載的apk哀澈,解決6.0以后安裝的問題
     * @param context
     * @return
     */
    public static File queryDownloadedApk(Context context) {
        File targetApkFile = null;
        DownloadManager downloader = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
        long downloadId = SharePreHelper.getIns().getLongData("refernece", -1);
        if (downloadId != -1) {
            DownloadManager.Query query = new DownloadManager.Query();
            query.setFilterById(downloadId);
            query.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL);
            Cursor cur = downloader.query(query);
            if (cur != null) {
                if (cur.moveToFirst()) {
                    String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                    if (!TextUtils.isEmpty(uriString)) {
                        targetApkFile = new File(Uri.parse(uriString).getPath());
                    }
                }
                cur.close();
            }
        }
        return targetApkFile;

    }

    private void openFile(File file, Context context) {
        Intent intent = new Intent();
        intent.addFlags(268435456);
        intent.setAction("android.intent.action.VIEW");
        String type = getMIMEType(file);
        intent.setDataAndType(Uri.fromFile(file), type);
        try {
            context.startActivity(intent);
        } catch (Exception var5) {
            var5.printStackTrace();
            Toast.makeText(context, "沒有找到打開此類文件的程序", Toast.LENGTH_SHORT).show();
        }

    }

    private String getMIMEType(File var0) {
        String var1 = "";
        String var2 = var0.getName();
        String var3 = var2.substring(var2.lastIndexOf(".") + 1, var2.length()).toLowerCase();
        var1 = MimeTypeMap.getSingleton().getMimeTypeFromExtension(var3);
        return var1;
    }

}
  
  • 最后記得在AndroidManifest.xml中注冊廣播
<receiver android:name=".receiver.UpdataBroadcastReceiver">
     <intent-filter>
          <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
          <!--<action android:name="android.intent.action.PACKAGE_INSTALL" />-->
     </intent-filter>
</receiver>
  • 還未實現(xiàn)功能:安裝成功后刪除apk文件牌借。

大功告成。

小插曲:當我把文件名稱"juyoubang.apk"寫成靜態(tài)常量來引用的時候割按,下載并安裝時膨报,會提示文件已損壞,無法安裝适荣,這讓我百思不得其解现柠。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市束凑,隨后出現(xiàn)的幾起案子晒旅,更是在濱河造成了極大的恐慌,老刑警劉巖汪诉,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件废恋,死亡現(xiàn)場離奇詭異谈秫,居然都是意外死亡,警方通過查閱死者的電腦和手機鱼鼓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門拟烫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人迄本,你說我怎么就攤上這事硕淑。” “怎么了嘉赎?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵置媳,是天一觀的道長。 經(jīng)常有香客問我公条,道長拇囊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任靶橱,我火速辦了婚禮寥袭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘关霸。我一直安慰自己传黄,他們只是感情好,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布队寇。 她就那樣靜靜地躺著膘掰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪英上。 梳的紋絲不亂的頭發(fā)上炭序,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天啤覆,我揣著相機與錄音苍日,去河邊找鬼。 笑死窗声,一個胖子當著我的面吹牛相恃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笨觅,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼拦耐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了见剩?” 一聲冷哼從身側(cè)響起杀糯,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎苍苞,沒想到半個月后固翰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狼纬,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年骂际,在試婚紗的時候發(fā)現(xiàn)自己被綠了疗琉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡歉铝,死狀恐怖盈简,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情太示,我是刑警寧澤柠贤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站类缤,受9級特大地震影響种吸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呀非,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一坚俗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岸裙,春花似錦猖败、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至剧董,卻和暖如春幢尚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背翅楼。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工尉剩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人毅臊。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓理茎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親管嬉。 傳聞我的和親對象是個殘疾皇子皂林,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,180評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)蚯撩,斷路器础倍,智...
    卡卡羅2017閱讀 134,665評論 18 139
  • 公司開發(fā)時候,應該最常用的就是APP升級功能胎挎,倒不是說的是熱修復等技術沟启,而是普通的檢測到服務器版本比本地手機版本高...
    青蛙要fly閱讀 4,559評論 12 86
  • DownloadManager實現(xiàn)下載美浦、安裝更新app功能 一款app必不可少的功能弦赖,就是自動檢測版本實現(xiàn)下載、安...
    一點愁閱讀 1,671評論 0 5
  • 有一朵黑玫瑰 它是愛人心頭的珍珠 我把玫瑰給了你 把自己變成了一朵黑 死在愛情的泥土里 做了一次風流的鬼 玫瑰已不...
    栗春初閱讀 310評論 0 3