by tony蒋
最近有客户投诉,有一款app store在Android 4.2中不能更新版本, 更新版本安装会失败,具体错误消息如下:
[html]
10-23 10:57:56.663: I/ActivityManager(391): START u0 {dat=file:///storage/emulated/0/Download/xxxmarket/1382493454155.tmp cmp=com.android.packageinstaller/.InstallAppProgress (has extras)} from pid 30530
10-23 10:57:56.764: W/InstallAppProgress(30530): Replacing package:com.xxx.market.sys.xxx.apl
10-23 10:57:56.827: W/ActivityManager(391): No content provider found for permission revoke: file:///storage/emulated/0/Download/xxxmarket/1382493454155.tmp
10-23 10:57:56.827: W/PackageManager(391): Can't install update of com.xxx.market.sys.xxx.apl update version 0 is older than installed version 116/pre>
奇怪的是,这种现象只出现在Android 4.2中。
我们版本更新的逻辑是, 启动一个AsynTask,下载最新的apk到内存里, 然后发intent给Android PackInstaller, 执行安装。
一开始调查怀疑是因为, 我们在内存里写文件用了以下代码,
[java]
tempFileStream = context.openFileOutput(LOCAL_TEMPFILENAME, Context.MODE_WORLD_READABLE);
writeResponse(response, tempFileStream);
Android 4.2中Context.MODE_WORLD_READABLE已经被废止了, 因此会出现文件读写无权限?!
后来我们强制把文件写到SD卡中, 发现一样无法读取安装。
这就奇怪了。
我注意到app中AndroidMainfest.xml配置versioncode的地方如下
@CopyRight 归于蒋彪, from 南湖边上的小木屋
[html]
android:versionName="@string/app_version_name" android:versionCode="@integer/app_version_code"
是交叉引用了其他配置文件中的信息,而不是直接写死。 会不会跟这个有关?
我尝试修改成直接写死,结果就成了。。。。。。。。。。。
对于原因, 我怀疑是, Android 4.2开始为了对应多用户机制, 加强了app直接文件访问的权限配置。
所有的app之间的数据共享都要基于ContentProvider, PackageInstaller作为Android的原生态app, 也没有权限去读取除AndroidManifest.xml以外的app信息。
本着严谨的学术作风, 我又调查了一下Android的源代码, 在Android专用来解析AndroidMainifest.xml的[android.content.res.Resources] , 看到了如下代码
[java]
// XXX note that for now we only work with compiled XML files.
// To support generic XML files we will need to manually parse
// out the attributes from the XML file (applying type information
// contained in the resources and such).
XmlBlock.Parser parser = (XmlBlock.Parser)set;
mAssets.retrieveAttributes(parser.mParseState, attrs,
array.mData, array.mIndices);
这块的注释,想必已经能说明问题了。