我的apk版本代码是版本3.使用它我使用的主扩展文件加载了apk版本代码1(文件名类似于main.1.ex.etc.eg.obb)。扩展文件在设备上下载得很好。
扩展文件包含媒体文件,因此我使用Google Zip扩展库中的APEZProvider
与VideoView
一起播放。
调用VideoView.start()
会导致Nullpointer异常。
到目前为止我发现了什么:
在APEZProvider.initIfNecessary()
中,将主扩展文件版本返回为3而不是1.因此,尝试打开ZipResourceFile
(mAPKExtensionFile)将返回null。 APEZProvider.openAssetFile()
导致NullPointerException
mAPKExtensionFile
为null
。
Google Zip扩展库中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参考。
public abstract ProviderInfo resolveContentProvider(String name,int flags)
自:API级别1 按基本路径名查找单个内容提供程序。 参数
name:要查找的提供程序的名称。
flags:附加选项标志。目前应始终为0。
有人可以确认我是做错了还是错误。
编辑:当我第一次上传我的应用程序时,一切都按预期工作 - 仅当我更新apk时导致出现此问题的不同版本代码。
答案 0 :(得分:14)
如果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>
答案 1 :(得分:2)
您必须创建自己的提供者并在清单中声明它
<provider android:authorities="com.myCompany.myAppName.provider.ZipFileContentProvider" android:name=".ZipFileContentProvider"></provider>
取自:
答案 2 :(得分:0)
正如您所说,扩展文件版本号可以与应用版本不同。所以问题是,我如何知道扩展文件的版本号?
以下是多个可能的答案之一:
您可以通过多种方式确定扩展文件版本 数。一种简单的方法是将版本保存在SharedPreferences中 下载开始时的文件,通过查询扩展文件名 使用APKExpansionPolicy类的getExpansionFileName(int index) 方法。然后,您可以通过阅读来获取版本代码 当您要访问扩展文件时,SharedPreferences文件。
有关从共享存储中读取的详细信息,请参阅 Data Storage文档。