如果扩展文件版本与apk版本代码不同,访问带有URI的APK扩展文件会导致崩溃
我的apk版本代码是版本3.使用它我使用的主扩展文件已加载apk版本代码1(文件名与main.1.ex.etc.eg.obb类似)。扩展文件在设备上正常下载。如果扩展文件版本与apk版本代码不同,访问带有URI的APK扩展文件会导致崩溃
扩展文件包含媒体文件,因此我使用Google Zip扩展库中的APEZProvider
与VideoView
一起播放。
调用VideoView.start()
会导致Nullpointer异常。
我迄今发现: 在APEZProvider.initIfNecessary()
返回主扩展文件版本3,而不是1。因此试图打开ZipResourceFile
(mAPKExtensionFile)返回null。 APEZProvider.openAssetFile()
导致NullPointerException
为mAPKExtensionFile
为null
。
APEZProvider
类在谷歌邮编扩展库
相关代码:
private boolean initIfNecessary() {
if (!mInit) {
Context ctx = getContext();
PackageManager pm = ctx.getPackageManager();
ProviderInfo pi = pm.resolveContentProvider(getAuthority(), PackageManager.GET_META_DATA);
PackageInfo packInfo;
try {
packInfo = pm.getPackageInfo(ctx.getPackageName(), 0);
} catch (NameNotFoundException e1) {
e1.printStackTrace();
return false;
}
int patchFileVersion;
int mainFileVersion;
int appVersionCode = packInfo.versionCode;
if (null != pi.metaData) {
mainFileVersion = pi.metaData.getInt("mainVersion", appVersionCode);
patchFileVersion = pi.metaData.getInt("patchVersion", appVersionCode);
} else {
mainFileVersion = patchFileVersion = appVersionCode;
}
try {
mAPKExtensionFile = APKExpansionSupport.getAPKExpansionZipFile(ctx, mainFileVersion, patchFileVersion);
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode)
throws FileNotFoundException {
initIfNecessary();
String path = uri.getEncodedPath();
if (path.startsWith("/")) {
path = path.substring(1);
}
return mAPKExtensionFile.getAssetFileDescriptor(path);
}
我不知道这行代码在上面:ProviderInfo pi = pm.resolveContentProvider(getAuthority(), PackageManager.GET_META_DATA);
这是正确的吗?
从PackageManager.resolveContentProvider()的Android参考。
公共抽象ProviderInfo resolveContentProvider(字符串名称,INT标志)
自:API等级1 查找其基本路径名的单个内容提供商。 参数
name:要查找的提供程序的名称。
flags:其他选项标志。目前应该始终为0.
有人可以确认如果我做错了什么或它是一个错误。
编辑:当我第一次上传我的应用程序时,一切都按预期工作 - 它只有当我更新apk导致发生此问题的不同版本代码时。
如果APK扩展文件的版本号与APK的版本号不匹配,则Zip文件提供程序类包含的元数据可放置在AndroidManifest.zip文件中。
<provider android:name=".APEZProvider"
android:authorities="my.application.authority"
android:exported="false"
android:multiprocess="true"
>
<meta-data android:name="mainVersion"
android:value="1"></meta-data>
<meta-data android:name="patchVersion"
android:value="2"></meta-data>
</provider>
你必须创建自己的供应商,并在您的清单
<provider android:authorities="com.myCompany.myAppName.provider.ZipFileContentProvider" android:name=".ZipFileContentProvider"></provider>
声明它来自
我的问题与链接的不一样。提供者已经被声明。只要apk版本代码和扩展文件版本相同,视频就可以与VideoView.setVideoURI()一起正常工作。如果apk版本代码与扩展文件版本不同,则不起作用。 – user1318455 2012-04-22 19:04:06
因为它不应该。您的版本代码需要与扩展文件名称匹配。 – Blundell 2012-04-22 19:20:02
如果您上传更新的apk,则可以使用上一个apk上传的扩展文件。在这种情况下,文件扩展版本与apk版本代码不同 - 除了通过URI访问视频外,其他所有功能都可以使用。对我来说,它看起来更像是一个APEZProvider问题。 – user1318455 2012-04-22 19:27:08
正如你说的,扩展文件的版本号可以是不同的应用程序版本。所以问题是,我怎么知道扩展文件的版本号?
这里的多种可能的答案之一:
有很多,你可以决定扩展文件版本 号的方式。一种简单的方法是在下载开始时通过使用APKExpansionPolicy类的getExpansionFileName(int index) 方法查询扩展文件名 来将版本保存在SharedPreferences 文件中。当您想要访问扩展文件时,您可以通过读取 SharedPreferences文件来获取版本代码。
有关从共享存储中读取的更多信息,请参阅 Data Storage文档。
作品!谢谢。这不应该更清楚地记录或我错过了明显的东西?同样对于pm.resolveContentProvider(),文档说标志应该是零,但是在APEZProvider类中不是这样。对此有何澄清? – user1318455 2012-06-10 11:30:31