Чтение содержимого из файла расширения APK (из файла obb)

Я реализовал службу загрузки файлов расширения APK и все это с http://developer.android.com/google/play/expansion-files.html

Я могу загрузить файл расширения APK, и я могу увидеть этот файл, используя приведенный ниже код

try {
        ZipResourceFile expansionFile = APKExpansionSupport
                .getAPKExpansionZipFile(this, 3, 0);

        ZipEntryRO[] zip = expansionFile.getAllEntries();
        Log.e("", "" + zip[0].mFile.getAbsolutePath());
        Log.e("", "" + zip[0].mFileName);
        Log.e("", "" + zip[0].mZipFileName);
        Log.e("", "" + zip[0].mCompressedLength);

        AssetFileDescriptor fd = expansionFile
                .getAssetFileDescriptor(zip[0].mFileName);

        if (fd != null && fd.getFileDescriptor() != null) {
            MediaPlayer mp = new MediaPlayer();
            mp.setDataSource(fd.getFileDescriptor());
            mp.start();
        } else {
            Log.e("", "fd or fd.getFileDescriptor() is null");
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

У моего obb есть файл test.mp4, а мой код Log.e("", "" + zip[0].mFileName); печатает test.mp4.

Мой fd это null. Почему это null? Я пытаюсь решить, но не могу.

Я просто не могу прочитать ни один файл внутри файла obb.

Без ответа Доступ к файлам внутри файла расширения obb предлагает идею, но это не так работать на меня.

Шаги по созданию файла расширения APK сообщает о распаковке содержимого из obb и затем прочтите это. Это надежно и хорошо?

Мне нужно мнение о передовой практике.

Редактировать

Мой журнал

03-01 10:36:40.848: E/(27836): zip[0].isUncompressed() : false
03-01 10:36:40.848: E/(27836): mFile.getAbsolutePath() : /storage/sdcard0/Android/obb/smart.trigger/main.3.smart.trigger.obb
03-01 10:36:40.848: E/(27836): mFileName : test.mp4
03-01 10:36:40.848: E/(27836): mZipFileName : /storage/sdcard0/Android/obb/smart.trigger/main.3.smart.trigger.obb
03-01 10:36:40.848: E/(27836): mCompressedLength : 21657598

person Bhavesh Hirpara    schedule 24.01.2013    source источник


Ответы (4)


Я погуглил и обнаружил, что нам нужно создать .zip с 0% (No compression), который упоминается в http://developer.android.com/google/play/expansion-files.html

Tip: If you're packaging media files into a ZIP, you can use media playback calls on the files with offset and length controls (such as MediaPlayer.setDataSource() and SoundPool.load()) without the need to unpack your ZIP. In order for this to work, you must not perform additional compression on the media files when creating the ZIP packages. For example, when using the zip tool, you should use the -n option to specify the file suffixes that should not be compressed: zip -n .mp4;.ogg main_expansion media_files

ИЛИ Как сделать 0% сжатие zip-архива с помощью WinRAR?

введите описание изображения здесь

здесь смотрите метод сжатия

0% сжатие zip в mac

Create zip without compression on OS X from Terminal:
zip -r0 zipfilename.zip files-to-zip

поэтому нам нужно загрузить этот zip в игровой магазин.

поэтому вам не нужно использовать ZipHelper.java

просто используйте

ZipResourceFile expansionFile=null;

            try {
                expansionFile = APKExpansionSupport.getAPKExpansionZipFile(getApplicationContext(),3,0);

                     AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("test.mp4");
                     MediaPlayer mPlayer = new MediaPlayer();
                     mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                     mPlayer.setDataSource(fd.getFileDescriptor(),fd.getStartOffset(),fd.getLength());
                     mPlayer.prepare();
                     mPlayer.start();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
person Sanket Kachhela    schedule 23.09.2013
comment
Для тех, кто не хочет делать то же самое в Linux: zip -r -0 main.1.com.my.pkg.obb media_files / - person Yazon2006; 13.03.2017
comment
Привет, Санкет, Вы можете помочь мне создать файл obb? Мне это нужно для одного из приложений. - person Mitul Bhalia; 30.06.2017
comment
@MitulBhalia, я обновил свой ответ для Mac. пожалуйста, проверь это. - person Sanket Kachhela; 30.06.2017
comment
спасибо @SanketKachhela, но моя файловая структура немного отличается. Ниже представлена ​​структура аудио - ›1.mp3, 2.mp3 видео -› карты - ›1.mp4, 2.mp4 изображения -› test - ›1.png, 2.png -› test1 - ›1.png, 2 .png - ›test2 -› 1.png, 2.png - person Mitul Bhalia; 30.06.2017
comment
извините за беспорядок Позвольте мне сказать вам, что у меня есть все mp3-файлы в аудио-папке, затем все MP4-файлы в папках видео- ›карты, затем PNG-файлы - это 3 разные папки в папке изображений - person Mitul Bhalia; 30.06.2017

Решил разархивировать ..

ZipHelper.java

public class ZipHelper {
static boolean zipError = false;

public static boolean isZipError() {
    return zipError;
}

public static void setZipError(boolean zipError) {
    ZipHelper.zipError = zipError;
}

public static void unzip(String archive, File outputDir) {
    try {
        Log.d("control", "ZipHelper.unzip() - File: " + archive);
        ZipFile zipfile = new ZipFile(archive);
        for (Enumeration<? extends ZipEntry> e = zipfile.entries(); e
                .hasMoreElements();) {
            ZipEntry entry = (ZipEntry) e.nextElement();
            unzipEntry(zipfile, entry, outputDir);

        }
    } catch (Exception e) {
        Log.d("control", "ZipHelper.unzip() - Error extracting file "
                + archive + ": " + e);
        setZipError(true);
    }
}

private static void unzipEntry(ZipFile zipfile, ZipEntry entry,
        File outputDir) throws IOException {
    if (entry.isDirectory()) {
        createDirectory(new File(outputDir, entry.getName()));
        return;
    }

    File outputFile = new File(outputDir, entry.getName());
    if (!outputFile.getParentFile().exists()) {
        createDirectory(outputFile.getParentFile());
    }

    Log.d("control", "ZipHelper.unzipEntry() - Extracting: " + entry);
    BufferedInputStream inputStream = new BufferedInputStream(
            zipfile.getInputStream(entry));
    BufferedOutputStream outputStream = new BufferedOutputStream(
            new FileOutputStream(outputFile));

    try {
        IOUtils.copy(inputStream, outputStream);
    } catch (Exception e) {
        Log.d("control", "ZipHelper.unzipEntry() - Error: " + e);
        setZipError(true);
    } finally {
        outputStream.close();
        inputStream.close();
    }
}

private static void createDirectory(File dir) {
    Log.d("control",
            "ZipHelper.createDir() - Creating directory: " + dir.getName());
    if (!dir.exists()) {
        if (!dir.mkdirs())
            throw new RuntimeException("Can't create directory " + dir);
    } else
        Log.d("control",
                "ZipHelper.createDir() - Exists directory: "
                        + dir.getName());
}
}

использование

try {
        ZipResourceFile expansionFile = APKExpansionSupport
                .getAPKExpansionZipFile(this, 3, 0);

        ZipEntryRO[] zip = expansionFile.getAllEntries();
        Log.e("", "zip[0].isUncompressed() : " + zip[0].isUncompressed());
        Log.e("",
                "mFile.getAbsolutePath() : "
                        + zip[0].mFile.getAbsolutePath());
        Log.e("", "mFileName : " + zip[0].mFileName);
        Log.e("", "mZipFileName : " + zip[0].mZipFileName);
        Log.e("", "mCompressedLength : " + zip[0].mCompressedLength);

        File file = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "");
        ZipHelper.unzip(zip[0].mZipFileName, file);

        if (file.exists()) {
            Log.e("", "unzipped : " + file.getAbsolutePath());
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
person Bhavesh Hirpara    schedule 01.03.2013
comment
я получаю сообщение об ошибке IOUtils.copy(inputStream, outputStream); в ZipHelper.java, пожалуйста, помогите мне .. - person Sanket Kachhela; 21.09.2013
comment
Вы пробовали этот apache.petsads.us// commons / io / binaries / commons-io-2.4-bin.zip - person Bhavesh Hirpara; 21.09.2013
comment
еще один вопрос ... здесь пользователь может удалить файлы sdcard. так что есть любой другой альтернативный путь для распаковки этого файла расширения. - person Sanket Kachhela; 23.09.2013

Находятся ли ваши файлы в папке в zip-файле? Я спрашиваю, потому что у меня была такая же проблема, и моим решением было включить имя папки при получении дескриптора файла.

Например, мой файл расширения содержал одну папку с именем «Видео». Итак, чтобы получить дескриптор файла, мне пришлось сделать следующее:

AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("Videos/" + videoName + ".mp4");
person dnorcott    schedule 27.02.2013
comment
Если мой файл .obb содержит 10 разных файлов (.mp3, .jpg, ... и т. Д.) Как получить каждый файл ?. Могу ли я получить путь или ссылку на файл для каждого из них? - person Bhavesh Hirpara; 28.02.2013
comment
Я думаю, вы можете просто использовать getAllEntries (), как в предоставленном вами коде. Мне кажется, это сработает. Что дает вам mFile.getAbsolutePath ()? - person dnorcott; 28.02.2013

Если вы используете setDataSource(), вы не должны сжимать файлы при их архивировании в первую очередь, как сказано в документации (http://developer.android.com/google/play/expansion-files.html#ZipLib):

Чтобы это работало, вы не должны выполнять дополнительное сжатие мультимедийных файлов при создании ZIP-пакетов.

person Till    schedule 03.05.2013