1. 程式人生 > >華為手機不相容URI的使用問題

華為手機不相容URI的使用問題

公司最近開展一個新的專案,需要加上版本自動更新的功能。在新版本上線時,有公司的外派同事反饋說在更新時,會直接奔潰。通過不斷的查詢發現,只有在華為部分手機出現了類似的問題(Mate8,P9都會)。這裡把問題記錄下

分析與解決

1 情形

自動更新使用了系統提供的DownloadManager,當下載完成時,通過廣播機制對下載完成事件進行廣播,action為DownloadManager.ACTION_DOWNLOAD_COMPLETE

Uri filepath = downloadManager.getUriForDownloadedFile(reference);
if (intent.getAction
() == DownloadManager.ACTION_DOWNLOAD_COMPLETE && filepath != null) { Intent intents = new Intent(); intents.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intents.setAction("android.intent.action.VIEW"); intents.addCategory("android.intent.category.DEFAULT"
); intents.setType("application/vnd.android.package-archive"); intents.setData(filepath); intents.setDataAndType(filepath, "application/vnd.android.package-archive"); context.startActivity(intents); System.exit(0); }

2 問題

下載檔案的uri(即filepath)不為空,但啟動安裝應用時,會發生奔潰現象

3 猜想

是否因為無法正確識別uri,導致系統奔潰?寫了一個例子,直接使用下載檔案的絕對路徑進行啟動,正常使用。

if (intent.getAction() == DownloadManager.ACTION_DOWNLOAD_COMPLETE
            && filepath != null) {

        Intent intents = new Intent();
        intents.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intents.setAction("android.intent.action.VIEW");
        intents.addCategory("android.intent.category.DEFAULT");
        intents.setType("application/vnd.android.package-archive");
        intents.setData(Uri.fromFile(new File(Tool.getFilePathByUri(
                context, filepath))));
        intents.setDataAndType(Uri.fromFile(new File(Tool.getFilePathByUri(
                context, filepath))),
                "application/vnd.android.package-archive");
        context.startActivity(intents);
        System.exit(0);
    }

4 驗證

呼叫系統的圖片選擇,會在onActivityResult中會返回圖片的URI,再通過URI去獲取圖片,也出現了奔潰的情況:華為的部分手機對於URI的相容有問題

5 總結

因為android開源,國內很多手機廠商會修改系統原始碼,對系統進行優化等,開發屬於自己的一套系統UI(不能算系統,只是在android的基礎上進行二次開發)。華為作為國內前幾位的手機開發商也不例外,開發了自己的EMUI系統,這難免會對系統進行調整和修改。鑑於這種情況,我們需要對應用進行多裝置的相容性測試,提高應用的穩定性。

URI與路徑的轉換

為了解決上邊出現的問題,需要setData傳入下載檔案的路徑,這就需要將URI轉換成路徑,這裡也給出相應的方法

public static String getFilePathByUri(final Context context, final Uri uri) {
    if (null == uri)
        return null;
    final String scheme = uri.getScheme();
    String data = null;
    if (scheme == null)
        data = uri.getPath();
    else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
        data = uri.getPath();
    } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
        Cursor cursor = context.getContentResolver().query(uri,
                new String[] { ImageColumns.DATA }, null, null, null);
        if (null != cursor) {
            if (cursor.moveToFirst()) {
                int index = cursor.getColumnIndex(ImageColumns.DATA);
                if (index > -1) {
                    data = cursor.getString(index);
                }
            }
            cursor.close();
        }
    }
    return data;
}