【我的Android进阶之旅】 解决bug: Expected file scheme in URI: content://downloads/my_downloads/12
2016-11-30 12:44
513 查看
一、错误描述
今天测试MM用HTC手机测试某个模块的时候crash了,抓log后发现是使用DownloadManager下载apk安装包然后自动安装的时候,抛了异常:java.lang.IllegalArgumentException: Expected file scheme in URI: content://downloads/my_downloads/12具体crash错误信息如下所示:
11-30 09:24:21.933 28279 28279 E AndroidRuntime: FATAL EXCEPTION: main 11-30 09:24:21.933 28279 28279 E AndroidRuntime: Process: com.xtc.watch, PID: 28279 11-30 09:24:21.933 28279 28279 E AndroidRuntime: java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.DOWNLOAD_COMPLETE flg=0x10 pkg=com.xtc.watch (has extras) } in com.xtc.watch.service.compatible.VersionCompatibleUpdateService$DownloadCompleteReceiver@33fa7ec 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:934) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at android.os.Looper.loop(Looper.java:168) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5885) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: Caused by: java.lang.IllegalArgumentException: Expected file scheme in URI: content://downloads/my_downloads/12 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at java.io.File.checkURI(File.java:223) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at java.io.File.<init>(File.java:175) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at com.xtc.watch.service.compatible.VersionCompatibleUpdateService.a(Unknown Source) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at com.xtc.watch.service.compatible.VersionCompatibleUpdateService.a(Unknown Source) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at com.xtc.watch.service.compatible.VersionCompatibleUpdateService$DownloadCompleteReceiver.onReceive(Unknown Source) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:915) 11-30 09:24:21.933 28279 28279 E AndroidRuntime: ... 7 more 11-30 09:24:21.939 1785 3503 E ActivityManager: App crashed! Process: com.xtc.watch
二、错误分析
进入File.java查看代码,/** * Constructs a new File using the path of the specified URI. {@code uri} * needs to be an absolute and hierarchical Unified Resource Identifier with * file scheme and non-empty path component, but with undefined authority, * query or fragment components. * * @param uri * the Unified Resource Identifier that is used to construct this * file. * @throws IllegalArgumentException * if {@code uri} does not comply with the conditions above. * @see #toURI * @see java.net.URI */ public File(URI uri) { // check pre-conditions checkURI(uri); this.path = fixSlashes(uri.getPath()); }
checkURI(URI uri)的源代码如下:
private static void checkURI(URI uri) { if (!uri.isAbsolute()) { throw new IllegalArgumentException("URI is not absolute: " + uri); } else if (!uri.getRawSchemeSpecificPart().startsWith("/")) { throw new IllegalArgumentException("URI is not hierarchical: " + uri); } if (!"file".equals(uri.getScheme())) { throw new IllegalArgumentException("Expected file scheme in URI: " + uri); } String rawPath = uri.getRawPath(); if (rawPath == null || rawPath.isEmpty()) { throw new IllegalArgumentException("Expected non-empty path in URI: " + uri); } if (uri.getRawAuthority() != null) { throw new IllegalArgumentException("Found authority in URI: " + uri); } if (uri.getRawQuery() != null) { throw new IllegalArgumentException("Found query in URI: " + uri); } if (uri.getRawFragment() != null) { throw new IllegalArgumentException("Found fragment in URI: " + uri); } }
原来就是下面这一段代码抛出的异常,如果uri不是以file开头的就抛异常IllegalArgumentException(“Expected file scheme in URI: ” + uri),
if (!"file".equals(uri.getScheme())) { throw new IllegalArgumentException("Expected file scheme in URI: " + uri); }
而我们的uri 是通过下面代码获取而来的
Uri downloadFileUri = manager.getUriForDownloadedFile(downId); File file = new File(new URI(downloadFileUri.toString()));
得到的uri信息为
content://downloads/my_downloads/12
因此就抛了该异常出来。
getUriForDownloadedFile(long id)源代码如下:
/** * Returns the {@link Uri} of the given downloaded file id, if the file is * downloaded successfully. Otherwise, null is returned. *<p> * If the specified downloaded file is in external storage (for example, /sdcard dir), * then it is assumed to be safe for anyone to read and the returned {@link Uri} corresponds * to the filepath on sdcard. * * @param id the id of the downloaded file. * @return the {@link Uri} of the given downloaded file id, if download was successful. null * otherwise. */ public Uri getUriForDownloadedFile(long id) { // to check if the file is in cache, get its destination from the database Query query = new Query().setFilterById(id); Cursor cursor = null; try { cursor = query(query); if (cursor == null) { return null; } if (cursor.moveToFirst()) { int status = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_STATUS)); if (DownloadManager.STATUS_SUCCESSFUL == status) { int indx = cursor.getColumnIndexOrThrow( Downloads.Impl.COLUMN_DESTINATION); int destination = cursor.getInt(indx); // TODO: if we ever add API to DownloadManager to let the caller specify // non-external storage for a downloaded file, then the following code // should also check for that destination. if (destination == Downloads.Impl.DESTINATION_CACHE_PARTITION || destination == Downloads.Impl.DESTINATION_SYSTEMCACHE_PARTITION || destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING || destination == Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE) { // return private uri return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id); } else { // return public uri String path = cursor.getString( cursor.getColumnIndexOrThrow(COLUMN_LOCAL_FILENAME)); return Uri.fromFile(new File(path)); } } } } finally { if (cursor != null) { cursor.close(); } } // downloaded file not found or its status is not 'successfully completed' return null; }
三、错误解决
将之前查找下载好的apk文件的代码Uri downloadFileUri = manager.getUriForDownloadedFile(downId); File file = new File(new URI(downloadFileUri.toString()));
改为通过downId来查询DownloadManager下载的数据库的记录,然后查找本地文件的路径,如下所示:
Cursor c = manager.query(new DownloadManager.Query().setFilterById(downId)); if(c != null){ c.moveToFirst(); int fileNameIdx = c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME); String fileName = c.getString(fileNameIdx); File file = new File(fileName); LogUtil.d(TAG, "安装文件:" + file.getAbsolutePath()); c.close(); }
安装apk的代码由
//自动安装apk Intent install = new Intent(Intent.ACTION_VIEW); install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive"); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(install);
改为
//自动安装apk Intent install = new Intent(Intent.ACTION_VIEW); //install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive"); install.setDataAndType(Uri.parse("file://" + fileName.toString()), "application/vnd.android.package-archive"); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(install);
这样通过查询本地真实的下载好apk的真实本地路径,然后再进行安装的话就不会报异常了。
参考文章:
http://blog.csdn.net/q445697127/article/details/40537945
http://www.xuebuyuan.com/2163407.html
http://www.2cto.com/kf/201502/376975.html
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/53404379
相关文章推荐
- Android 接收分享内容补:增加 ContentResolver.SCHEME_FILE 和 ContentResolver.SCHEME_CONTENT解决QQ浏览器分享
- AndroidManifest.xml file missing 的bug解决
- 【BUG】android.content.res.Resources$NotFoundException: File res/drawable-xxhdpi/toolbar_line.png from
- 我的Android进阶之旅------>解决Android Studio编译后安装apk报错:The APK file does not exist on disk
- Android 4.4从图库选择图片并裁剪,由于系统版本不同导致Uri的bug的简单解决方式
- Exception android.content.res.Resources$NotFoundException: File res/drawable/my.xml from drawable re
- 当在写android的xml文件中出现Unexpected text found in layout file: """的解决办法
- Eclipse中编译Android项目工程失败,提示: Error in an XML file: aborting build 解决办法
- 我的Android进阶之旅------>解决Jackson等第三方转换Json的开发包在开启混淆后转换的实体类数据都是null的bug
- 【Android进阶】Android里webview不支持input file的解决方法(上传按钮点击失效的原因)
- 我的Android进阶之旅------>解决:debug-stripped.ap_' specified for property 'resourceFile' does not exist.
- Android USB状态监控(解决scheme="file")
- 我的Android进阶之旅------>解决Bug:打开eclipse报错,发现了以元素 'd:skin' 开头的无效内容。此处不应含有子元素。
- JAVA中 错误代码是 the public type must be defined in its own file 解决方法 android开发 java编程
- 编写android程序时:Error in an XML file: aborting build"错误的解决办法
- Unity64 AStarPath 寻路失效 Bug解决 IOS64 IL2CPP - Bad date/time format in the zip file
- PANIC: Could not find *.ini file in $ANDROID_AVD_HOME (AVD启动问题)解决办法
- Android中file开头的uri转换为content开头的ur:
- 【Android进阶】Android里webview不支持input file的解决方法(上传按钮点击失效的原因)
- Android 解决ViewPager设置高度为wrap_content无效的方法 MyViewPager