Вопрос по android – Доступ к файлу расширения APK с помощью URI (с помощью библиотеки расширения Google Zip) вызывает сбой, если версия файла расширения отличается от версии кода apk

3

Мой код версии 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, в результате чего разные коды версий, эта проблема возникает.

Ваш Ответ

3   ответа
0

Как вы хорошо сказали, номер версии файла расширения может отличаться от версии приложения. Итак, вопрос в том, как узнать номер версии файла расширения?

Вот один из множества возможных ответов:

ОтРуководство по файлам расширения 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.

14

Класс провайдера 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>
Работает! Благодарю. Разве это не было более четко задокументировано или я упустил что-то очевидное? Также для pm.resolveContentProvider () в документации сказано, что флаги должны быть нулевыми, но это не так в классе APEZProvider. Любое разъяснение по этому поводу? user1318455
2

Вы должны создать свой собственный провайдер и заявить об этом в своем манифесте

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

Взято из:

Где находится класс SampleZipfileProvider?

Мой вопрос не такой, как связанный. Поставщик уже объявлен. Видео отлично работает с VideoView.setVideoURI (), если код версии apk и версия файла расширения совпадают. Он не работает, если код версии apk отличается от версии файла расширения. user1318455
Потому что это не должно. Ваш код версии должен соответствовать имени файла расширения.
Если вы загрузили обновленный apk, вы можете использовать файл расширения, загруженный с более ранним apk. В этом случае версия расширения файла отличается от кода версии apk - и все работает, кроме доступа к видео через URI. Для меня это больше похоже на проблему APEZProvider. user1318455
Из того, что я прочитал в документации, они хотят, чтобы имя файла совпадало с кодом версии. Поэтому, когда я обновляю свое приложение, я просто обновляю его новым файлом патча. В своем первом комментарии вы говорите, что setVideoUri работает, но затем в следующем комментарии вы говорите, что он не работает: - /
Из документации: «Одним из значительных преимуществ использования файлов расширения в Google Play является возможность обновления приложения без повторной загрузки всех исходных ресурсов». а затем «Существующие пользователи получают только обновленный APK и новый файл расширения патча (сохраняя предыдущий основной файл расширения)». Основная версия файла останется прежней. И, как я уже сказал, все работает, как и ожидалось, даже с другой версией, кроме videoURI, которая не работает, как указано в коде выше. (setVideoURI работает только тогда, когда версия одинакова как для приложения, так и для файла расширения) user1318455

Похожие вопросы