华为手机不兼容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;
}

你可能感兴趣的:(华为手机不兼容URI的使用问题)