Вопрос по android – Доступ к файлу расширения APK с помощью URI (с помощью библиотеки расширения Google Zip) вызывает сбой, если версия файла расширения отличается от версии кода apk
Мой код версии apk - версия 3. вместе с ним я использую основной файл расширения, который был загружен с кодом версии apk 1 (имя файла аналогично main.1.ex.etc.eg.obb). Файл расширения скачивается нормально на устройстве.
Файл расширения имеет медиа-файл, поэтому я используюAPEZProvider
из библиотеки расширения Google Zip, чтобы играть сVideoView
.
призваниеVideoView.start()
вызывает исключение Nullpointer.
Что я нашел до сих пор:
ВAPEZProvider.initIfNecessary()
возвращает версию основного файла расширения как 3 вместо 1. Таким образом, пытаясь открытьZipResourceFile
(mAPKExtensionFile) возвращает ноль.APEZProvider.openAssetFile()
причиныNullPointerException
какmAPKExtensionFile
являетсяnull
.
Соответствующий код отAPEZProvider
класс в библиотеке расширения Google Zip:
<code> 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); } </code>
Я не уверен в этой строке кода выше:ProviderInfo pi = pm.resolveContentProvider(getAuthority(), PackageManager.GET_META_DATA);
Это правильно?
Из ссылки на Android для PackageManager.resolveContentProvider ().
public abstract ProviderInfo resolContentProvider (имя строки, int flags)
С тех пор: API Уровень 1 Найдите одного поставщика контента по его базовому пути. параметры
name: имя провайдера для поиска.
флаги: дополнительные опции флагов. В настоящее время всегда должно быть 0.
Может кто-нибудь подтвердить, если я делаю что-то не так или это ошибка.
Изменить: все работает, как ожидалось, когда я загружаю свое приложение в первый раз - только когда я обновляю apk, в результате чего разные коды версий, эта проблема возникает.
Как вы хорошо сказали, номер версии файла расширения может отличаться от версии приложения. Итак, вопрос в том, как узнать номер версии файла расширения?
Вот один из множества возможных ответов:
ОтРуководство по файлам расширения APK:
There are many ways you could determine the expansion file version number. One simple way is to save the version in a SharedPreferences file when the download begins, by querying the expansion file name with the APKExpansionPolicy class's getExpansionFileName(int index) method. You can then get the version code by reading the SharedPreferences file when you want to access the expansion file.
For more information about reading from the shared storage, see the Data Storage documentation.
Класс провайдера Zip-файла содержит метаданные, которые можно поместить в файл 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>
Взято из: