android - 如果扩展文件版本与 apk 版本代码不同,则使用 URI(使用 Google Zip 扩展库)访问 APK 扩展文件会导致崩溃

标签 android

我的 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,因为 mAPKExtensionFilenull

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)抽象 ProviderInfo resolveContentProvider(字符串名称,整数标志)

自:API 级别 1 通过其基本路径名查找单个内容提供者。 参数

名称:要查找的提供程序的名称。

flags:额外的选项标志。当前应始终为 0。

有人可以确认我做错了什么还是错误。

编辑:当我第一次上传我的应用程序时,一切都按预期工作 - 只有当我更新 apk 导致不同的版本代码时,才会出现此问题。

最佳答案

Zip 文件提供程序类包含元数据,如果 APK 扩展文件的版本号与 APK 的版本号不匹配,您可以将这些元数据放入 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>

关于android - 如果扩展文件版本与 apk 版本代码不同,则使用 URI(使用 Google Zip 扩展库)访问 APK 扩展文件会导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10051213/

相关文章:

php - 如果两个源同时向 SQL 表添加条目,它们都会添加 'ADD UNIQUE' 吗?

android - 如何自定义设置可绘制位置CheckedTextView?

java - 新项目的公司域名错误

android - 居中 WRAP_CONTENT

android - 如何为 volley MultipartEntityBuilder 添加多个 Mime 类型

android - 在同一 Activity 中更改 View 时是否可以进行过渡动画?

android - 如何打开新 Activity 单击 ListView 中的项目?

android - 您如何遍历 View ID?

android - 如何成功地将我的 Android Studio 项目转移到我的闪存驱动器上?

java - Android viewBinder 在 simpleCursorAdapter 上显示图像