3

我的 apk 版本代码是版本 3。我正在使用加载了 apk 版本代码 1 的主扩展文件(文件名类似于 main.1.ex.etc.eg.obb)。扩展文件可以在设备上正常下载。

扩展文件有媒体文件,所以我使用APEZProviderGoogle Zip 扩展库中的VideoView.

调用VideoView.start()会导致 Nullpointer 异常。

到目前为止我发现了什么: InAPEZProvider.initIfNecessary()返回主扩展文件版本为 3 而不是 1。因此尝试打开ZipResourceFile(mAPKExtensionFile) 返回 null。APEZProvider.openAssetFile()导致NullPointerException原样。mAPKExtensionFile_null

APEZProviderGoogle Zip 扩展库中类的相关代码:

  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 导致出现此问题的不同版本代码时。

4

3 回答 3

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>
于 2012-06-05T23:39:44.503 回答
2

您必须创建自己的提供程序并在清单中声明它

 <provider android:authorities="com.myCompany.myAppName.provider.ZipFileContentProvider" android:name=".ZipFileContentProvider"></provider>

取自:

SampleZipfileProvider 类在哪里?

于 2012-04-20T21:54:54.577 回答
0

正如您所说,扩展文件版本号可以与应用程序版本不同。那么问题来了,怎么知道扩展文件的版本号呢?

这是多个可能的答案之一:

APK 扩展文件指南

您可以通过多种方式确定扩展文件的版本号。一种简单的方法是在下载开始时将版本保存在SharedPreferences 文件中,方法是使用 APKExpansionPolicy 类的 getExpansionFileName(int index) 方法查询扩展文件名。然后,当您要访问扩展文件时,您可以通过读取 SharedPreferences文件来获取版本代码。

有关从共享存储读取的更多信息,请参阅 数据存储文档。

于 2012-05-22T20:53:58.750 回答