有爆料稱:自6月1日起,大量的樂視手機供應商聚集在朝陽區樂視大廈門口,口中高喊「樂視還錢!」這些供應商有的來自河南,有的來自成都。現場目擊者稱直到6月2日下午5點,樂視手機方面無人出面安撫一眾供應商。
大家早上好,新一周又開始啦!
本篇來自 cfy137000 的投稿,分享了如何在7.0下下載並安裝apk,希望對大家有所幫助。
cfy137000 的博客地址:
http://blog.csdn.net/cfy137000
1. 下載APK文件
使用 DownloadManager 來下載
在應用界面中展示下載進度
2. 安裝下載後的APK文件
DownloadManager 是 Android 提供的用於下載的類,使用起來比較簡單,它包含兩個靜態內部類 DownloadManager.Query 和 DownloadManager.Request;
DownloadManager.Request 用來請求一個下載,DownloadManager.Query 用來查詢下載信息
下載
DownloadManager對象 屬於系統服務,通過 getSystemService 來進行安裝
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
一般獲取完成後會變成全局變量,方便之後使用
2. 開始下載在使用 DownloadManager 進行下載的時候,就會用到 DownloadManager.Request
首先會創建出一個 DownloadManager.Request對象,在構造方法中接收 Uri,其實就是下載地址.
然後是文件的存放路徑,這裡需要說明,DownloadManager 下載的位置是不能放到內置存貯位置的,必須放到 Enviroment 中,這裡建議放到自己應用的文件夾,不要直接放到 SD卡 中,也就是通過 getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) 獲取到的路徑,該位置的文件是屬於應用自己的,在應用卸載時也會隨著應用一起被刪除掉,並且在使用該文件夾的時候,是不需要 SD卡 讀寫權限的
然後通過 request.setDestinationUri 來設置存儲位置,最後將請求加入到 downloadManager 中,會獲得一個 downloadID,這個 downloadID 比較重要,之後下載狀態,進度的查詢都靠這個 downloadID
進度查詢
在查詢下載進度的時候,會通過 downloadId 來指定查詢某一任務的具體進度:
在查詢進度的時候會使用到 DownloadManager.Query 這個類,在查詢的時候,也是使用的 Cursor,跟查詢資料庫是一樣的,進度信息會需要拿到文件的總大小,和當前大小,自己算一下,最後 Cursor對象 在使用過後不要忘記關閉了
下載完成下載完成後,DownloadManager 會發送一個廣播,並且會包含 downloadId 的信息:
註冊這個廣播接收者
其他
這裡需要注意一點,在下載完成後需要提升一下文件的讀寫權限,否則在安裝的時候會出現apk解析失敗的頁面,就是別人訪問不了我們的apk文件
chmod 是Linux下設置文件權限的命令,後面的三個數字每一個代表不同的用戶組
權限分為三種:讀(r=4),寫(w=2),執行(x=1)
那麼這三種權限就可以組成7種不同的權限,分別用1-7這幾個數字代表,例如7 = 4 + 2 + 1,那麼就代表該組用戶擁有可讀,可寫,可執行的權限;5 = 4 + 1,就代表可讀可執行權限
而三位數字就帶包,該登陸用戶,它所在的組,以及其他人
普通模式在7.0之前安裝的時候,只需要通過 隱式Intent 來跳轉,並且指定安裝的文件 Uri 即可
在Android7.0之後的版本運行上述代碼會出現 android.os.FileUriExposedException
「私有目錄被限制訪問」是指在 Android7.0 中為了提高私有文件的安全性,面向 Android N 或更高版本的應用私有目錄將被限制訪問。
而7.0的」 StrictMode API 政策」 是指禁止向你的應用外公開 file:// URI。 如果一項包含文件 file:// URI類型 的 Intent 離開你的應用,應用失敗,並出現 FileUriExposedException 異常。之前代碼用到的Uri.fromFile就是商城一個file://的Uri 在7.0之後,我們需要使用 FileProvider 來解決
第一步:在 AndroidManifest.xml 清單文件中註冊 provider
需要注意一下幾點:
第二步: 指定共享文件的目錄,需要在 res文件夾 中新建 xml 目錄,並且創建 file_paths
path=」「,是有特殊意義的,它代表根目錄,也就是說你可以向其它的應用共享根目錄及其子目錄下任何一個文件了。
第三步:使用 FileProvider
相較於之前的代碼,會把 Uri 改成使用 FiliProvider 創建的 Uri,並且添加 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 來對目標應用臨時授權該 Uri 所代表的文件,而且 getUriForFile 中的 authority 參數需要填寫清單文件中的 authorities 的值
兼容 7.0 的安裝代碼是不能在 7.0 之前的版本運行的,這個時候就需要進行版本的判斷了:
如果應用已經獲取了 root 權限了,那麼我們可以實現自動安裝,即不會出現應用安裝的頁面,會在後臺自己慢慢的安裝,這個時候使用的就是用代碼去寫命令行了
這個方法就是將命令寫入到手機的 shell 中,su 就代表 root 權限了,而命令執行成功的話,會返回0的,接下來是安裝命令
String command = "pm install -r " + mApkPath;
-r 代表強制安裝,否則如果手機中已有該應用的話就會安裝失敗了,值得注意的是,要想等待命令執行的結果這個過程是很漫長的,所以在使用命令的時候是需要放到主線程中的
在寫完整代碼的時候需要把下載的代碼寫到 Service 中,否則你的 downloadid 就得通過別的方式去存儲了,而查詢下載進度,也是需要一直去查了,那麼就需要寫一個循環,並且放到子線程中,我們用 RxJava 做會比較舒服
由於代碼偏多,我這邊就不貼出了,感興趣的朋友可以點擊最後 閱讀原文 查看,或者訪問下面地址, 下載源碼查看:
http://download.csdn.net/download/cfy137000/9820195
每天學習累了,看些搞笑的段子放鬆一下吧。關注最具娛樂精神的公眾號,每天都有好心情。
如果你有好的技術文章想和大家分享,歡迎向我的公眾號投稿,投稿具體細節請在公眾號主頁點擊「投稿」菜單查看。
歡迎長按下圖 -> 識別圖中二維碼或者掃一掃關注我的公眾號: