4

我已经实现了 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
4

4 回答 4

7

我用谷歌搜索,发现我们必须制作 .zip,在http://developer.android.com/google/play/expansion-files.html0% (No compression)中提到

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

如何使用 winrar 制作 0% 压缩 zip?

在此处输入图像描述

这里看压缩方法

mac中的0%压缩zip

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

所以我们应该把这个 zip 上传到 Play 商店。

所以你不需要使用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();
            }
于 2013-09-23T07:25:21.313 回答
5

我已经解决了使用解压缩..

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();
    }
于 2013-03-01T05:13:05.247 回答
3

您的文件是否在 zip 文件的文件夹中?我问是因为我遇到了同样的问题,我的解决方案是在获取文件描述符时包含文件夹名称。

例如,我的扩展文件包含一个名为“视频”的文件夹。因此,要获得文件描述符,我必须这样做:

AssetFileDescriptor fd = expansionFile.getAssetFileDescriptor("Videos/" + videoName + ".mp4");
于 2013-02-27T21:06:58.733 回答
0

如果你使用setDataSource()你不应该在压缩文件时首先压缩文件,如文档中所说的那样(http://developer.android.com/google/play/expansion-files.html#ZipLib):

为了使其正常工作,您在创建 ZIP 包时不得对媒体文件执行额外的压缩。

于 2013-05-03T15:39:07.030 回答