[英]Accessing APK expansion file with URI (with Google Zip Expansion Library) causes a crash if expansion file version is different from apk versioncode
我的 apk 版本代碼是版本 3。我正在使用加載了 apk 版本代碼 1 的主擴展文件(文件名類似於 main.1.ex.etc.eg.obb)。 擴展文件可以在設備上正常下載。
擴展文件有媒體文件,所以我使用 Google APEZProvider
擴展庫中的 APEZProvider 與VideoView
一起播放。
調用VideoView.start()
會導致 Nullpointer 異常。
到目前為止我發現了什么:在APEZProvider.initIfNecessary()
中返回主擴展文件版本 3 而不是 1。因此嘗試打開ZipResourceFile
(mAPKExtensionFile) 返回APEZProvider.openAssetFile()
導致NullPointerException
因為mAPKExtensionFile
是null
。
谷歌Zip擴展庫中APEZProvider
class的相關代碼:
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);
這個對嗎?
來自 Android 對 PackageManager.resolveContentProvider() 的參考。
公共抽象 ProviderInfo resolveContentProvider(字符串名稱,int 標志)
自:API 級別 1 通過其基本路徑名查找單個內容提供者。 參數
name:要查找的提供程序的名稱。
標志:附加選項標志。 當前應始終為 0。
有人可以確認我做錯了什么還是錯誤。
編輯:當我第一次上傳我的應用程序時,一切都按預期工作 - 只有當我更新導致不同版本代碼的 apk 時才會出現此問題。
Zip 文件提供程序 class 包含您可以在 AndroidManifest.zip 文件中放置的元數據,如果 APK 擴展文件的版本號與您的 APK 版本號不匹配。
<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 擴展文件指南:
您可以通過多種方式確定擴展文件版本號。 一種簡單的方法是在下載開始時將版本保存在SharedPreferences文件中,方法是使用 APKExpansionPolicy 類的 getExpansionFileName(int index) 方法查詢擴展文件名。 當你想訪問擴展文件時,你可以通過讀取SharedPreferences文件來獲取版本代碼。
有關從共享存儲讀取的更多信息,請參閱數據存儲文檔。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.