app更新是每一個android應用的标配了,大部分應用都會有更新提醒和apk下載下傳安裝(如果系統允許靜默安裝估計就沒有提醒這段了)。
以前的更新是自己寫http下載下傳或者通過系統提供的DownloadManager進行下載下傳。無意間發現bugly提供下載下傳更新服務而且免費(後來又提供了熱更新),就樂呵呵的接入了sdk,畢竟是大廠的東西,值得信賴。開始用的時候用的很穩定(估計是手機廠商還沒用上牛軋糖),後來就有人反應更新失敗,一直提示安裝,開始有些不相信直接讓使用者解除安裝重裝(還好使用者是公司自己人,是外人的話那就有解除安裝無安裝了)。
以前更新通過隐式調用系統安裝程式
1
2
3
4
<code> </code><code>Intent i = </code><code>new</code> <code>Intent(Intent.ACTION_VIEW);</code>
<code> </code><code>i.setDataAndType(Uri.fromFile(file), </code><code>"application/vnd.android.package-archive"</code><code>);</code>
<code> </code><code>i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);</code>
<code> </code><code>context.startActivity(i);</code>
這段代碼是通過intent設定資料和類型,然後通過context在新的task中啟動安裝apk的程式。
我們看到intent設定資料時,傳遞的是一個Uri,這個在API<24是沒有問題的,但在Android N已經禁止你對外公開file://URI.是以我們SDK的問題就出自Uri.fromFile(file)擷取uri的時候。
Android N已經給出明确解決方案,如果你的程式需要在應用間共享檔案,您應發送一項 content://URI,并授予 URI 臨時通路權限。進行此授權的最簡單方式是使用 FileProvider類。
首先在AndroidManifest中注冊FileProvider
代碼示例:
5
6
7
8
9
<code> </code><code><</code><code>provider</code>
<code> </code><code>android:name</code><code>=</code><code>"android.support.v4.content.FileProvider"</code>
<code> </code><code>android:authorities</code><code>=</code><code>"com.bugly.upgrade.demo.fileProvider"</code>
<code> </code><code>android:exported</code><code>=</code><code>"false"</code>
<code> </code><code>android:grantUriPermissions</code><code>=</code><code>"true"</code><code>></code>
<code> </code><code><</code><code>meta-data</code>
<code> </code><code>android:name</code><code>=</code><code>"android.support.FILE_PROVIDER_PATHS"</code>
<code> </code><code>android:resource</code><code>=</code><code>"@xml/provider_paths"</code><code>/></code>
<code> </code><code></</code><code>provider</code><code>></code>
這裡要注意一下,FileProvider是support-v4包裡面的,是以在你的程式必須要引入support-v4包。
我們可以看到在provider中需要配置相應的meta-data,這個是共享檔案的路徑,在res目錄下建立xml檔案夾并建立對應的xml檔案(如下面的provider_paths),如下所示:
<code><?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code> <code>encoding</code><code>=</code><code>"utf-8"</code><code>?></code>
<code> </code><code><</code><code>paths</code> <code>xmlns:android</code><code>=</code><code>"http://schemas.android.com/apk/res/android"</code><code>></code>
<code> </code><code><!-- /storage/emulated/0/Download/--></code>
<code> </code><code><</code><code>external-path</code> <code>name</code><code>=</code><code>"beta_external_apk"</code> <code>path</code><code>=</code><code>"Download/"</code><code>/></code>
<code> </code><code><!--/storage/emulated/0/Android/data/--></code>
<code> </code><code><</code><code>external-path</code> <code>name</code><code>=</code><code>"beta_external_apk2"</code> <code>path</code><code>=</code><code>"Android/data//"</code><code>/></code>
<code> </code><code></</code><code>paths</code><code>></code>
name表示一個URI路徑段,path表示指定要分享路徑的子目錄。這樣系統安裝程式就能通路下載下傳的apk檔案了。
由于手裡沒有7.0的裝置在優測上租個裝置(還好有一個小時的試用)測試了一下,完美解決。谷歌系統更新竟然不向下相容,這也是個坑。
程式設計路上真是一道坎一道坑。願世界永無bug,阿門。
本文轉自 xinsir999 51CTO部落格,原文連結:http://blog.51cto.com/xinsir/1911003,如需轉載請自行聯系原作者