【问题标题】:How to generate expansion files in android?如何在android中生成扩展文件?
【发布时间】:2013-04-23 05:27:37
【问题描述】:

我有超过 50MB 的项目。我在 raw 文件夹中有一些图像和视频。如何生成扩展文件?我已经浏览了开发人员文档,但对我来说并不清楚。它令人困惑。任何人都可以帮助我吗?

我应该从项目中复制原始文件夹并将其粘贴到桌面上,然后使用谷歌文档中给出的名称格式压缩整个文件夹吗? 例如:我的包名称为“com.my.package”,版本代码为 1 和主扩展文件。 我是否必须压缩整个原始文件夹并将名称命名为“main.1.com.my.package.zip”

创建后,我需要从项目文件夹中删除原始文件夹,然后我需要更改项目中的代码以从存储位置访问文件。我该怎么做?

我使用以下代码访问原始文件夹中的文件。如何更改此设置以访问存储在 SD 卡中的扩展文件中的文件?

String path1 = "android.resource://" + getPackageName() + "/" + R.raw.e4;

【问题讨论】:

  • Android expansion file 的可能重复项
  • 我使用了这个代码。 InputStream fileStream = expansionFile.getInputStream("background/flower.png");但我在flower.png 收到错误,错误是“flower”无法解析为变量。
  • For those who worry about the 50 MB limit, it is now 100 MB。足以让您摆脱扩展文件。 100 MB 对于 proguard 和资源缩减来说已经很多了,大多数应用程序可能在 100 MB 或更少,除了大型应用程序和游戏

标签: android apk apk-expansion-files


【解决方案1】:

尽量减小尺寸。您可以在发布模式下启用 proguard。ProGuard 工具通过删除未使用的代码并使用语义模糊名称重命名类、字段和方法来缩小、优化和混淆您的代码。 结果是 .apk 文件更小,更难进行逆向工程

您可以查看下面的链接。

http://developer.android.com/google/play/expansion-files.html#ZipLib

从 ZIP 文件中读取

使用 APK 扩展 Zip 库时,从 ZIP 读取文件通常需要以下内容:

// Get a ZipResourceFile representing a merger of both the main and patch files
ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(appContext,
    mainVersion, patchVersion);

// Get an input stream for a known file inside the expansion file ZIPs
InputStream fileStream = expansionFile.getInputStream(pathToFileInsideZip);

http://developer.android.com/google/play/expansion-files.html#StorageLocation

http://developer.android.com/google/play/expansion-files.html

编辑:

在链接中查看教程

http://ankitthakkar90.blogspot.in/2013/01/apk-expansion-files-in-android-with.html

【讨论】:

  • DexGuard 也是一种不同的压缩工具,但我认为它更擅长保护代码(反逆向工程)。由制作 proguard 的同一个人创建
【解决方案2】:

您可以将文件压缩成一个文件,如果超过 2 GB,则压缩成 2 个文件(每个文件最多 2GB)。

另一种方法是创建自己的算法,将所有文件放在一个文件中。

【讨论】:

  • An alternative is that you create your own algorithm for putting all of the files together into a single file. - 什么类型的算法?如果您只是将文件放在一个 .zip 文件中,并在上传到 Google Play 时将其转换为 .obb,那么您如何实现算法呢?此外,这个算法的目的到底是什么?
  • @LunarWatcher 您可以考虑或选择很多算法,以压缩或至少将多个文件存储到一个文件中。目的可以是更好的安全性/压缩性。
  • 那么算法的目的就是将多个文件存储在一个文件中,并压缩到最小大小?
  • @LunarWatcher 这就是我写的“将所有文件放在一个文件中的算法”。如果需要,您需要选择压缩级别和算法。
【解决方案3】:

以下是在 Android 中设置扩展文件所需的步骤:

  1. 首先,打开Android SDK Manager,展开Extras并下载:

    • Google Play 许可库包
    • Google Play APK 扩展库包
  2. 在 AndroidManifest.xml 中声明以下权限

    <!-- Required to access Google Play Licensing -->  
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
    
    <!-- Required to download files from Google Play -->  
    <uses-permission android:name="android.permission.INTERNET" />
    
    <!-- Required to keep CPU alive while downloading files (NOT to keep screen awake) -->  
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    
    <!-- Required to poll the state of the network connection  
        and respond to changes -->
    <uses-permission  
        android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    <!-- Required to check whether Wi-Fi is enabled -->  
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    
    <!-- Required to read and write the expansion files on shared storage -->  
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
    
  3. 集成库

    • 将下载器库的源代码从&lt;sdk&gt;/extras/google/play_apk_expansion/downloader_library/src 复制到您的项目中。
    • &lt;sdk&gt;/extras/google/play_licensing/library/src 的源代码复制到您的项目中。
    • &lt;sdk&gt;/extras/google/google_market_apk_expansion/zip_file/ 的源代码复制到您的项目中。
  4. 现在,创建一个名为扩展的新包,并在包内创建DownloaderService.java

    // DownloaderService.java
    public class DownloaderService extends com.google.android.vending.expansion.downloader.impl.DownloaderService {  
        public static final String BASE64_PUBLIC_KEY = "<<YOUR PUBLIC KEY HERE>>"; // TODO Add public key
        private static final byte[] SALT = new byte[]{1, 4, -1, -1, 14, 42, -79, -21, 13, 2, -8, -11, 62, 1, -10, -101, -19, 41, -12, 18}; // TODO Replace with random numbers of your choice
    
        @Override
        public String getPublicKey() {
            return BASE64_PUBLIC_KEY;
        }
    
        @Override
        public byte[] getSALT() {
            return SALT;
        }
    
        @Override
        public String getAlarmReceiverClassName() {
            return DownloaderServiceBroadcastReceiver.class.getName();
        }
    }
    
  5. 创建DownloaderServiceBroadcastReceiver.java扩展BoradcastReceiver,如果需要下载文件,它将启动下载服务。

    // DownloaderServiceBroadcastReceiver.java
    public class DownloaderServiceBroadcastReceiver extends android.content.BroadcastReceiver {  
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent, DownloaderService.class);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    
  6. 如果扩展文件不可用,则从您的活动开始下载

    Intent launchIntent = MainActivity.this.getIntent();
    Intent intentToLaunchThisActivityFromNotification = new Intent(MainActivity.this, MainActivity.this.getClass());
    intentToLaunchThisActivityFromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intentToLaunchThisActivityFromNotification.setAction(launchIntent.getAction());
    
    if (launchIntent.getCategories() != null) {
        for (String category : launchIntent.getCategories()) {
            intentToLaunchThisActivityFromNotification.addCategory(category);
        }
    }
    
    // Build PendingIntent used to open this activity from notification
    PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intentToLaunchThisActivityFromNotification, PendingIntent.FLAG_UPDATE_CURRENT);
    // Request to start the download
    int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this, pendingIntent, DownloaderService.class);
    

有关完整的详细信息和代码,请查看How to Set Up Android App to Support Expansion Files

【讨论】:

    【解决方案4】:

    有两种类型的扩展文件,主要和补丁。您可以将所有数据(图像/文件)放在一个文件夹中。把它命名为 main.1.com.my.package。 这里 main 表示它的主要扩展文件。如果它的补丁比命名为patch.1...
    1 是清单中的版本代码 比你的包名 压缩此文件并将该压缩文件重命名为 .obb 扩展名。从末尾删除 .zip,现在您的扩展文件已准备好名称 main.1.com.my.package.obb

    您必须使用市场上的虚拟应用程序上传此文件。比您必须使用编码下载该文件(您可以从 sdk/extras/google/play_apk_expansion 的下载库中获取示例)
    此文件在手机mnt/sdcard/android/obb的位置下载

    您可以使用该文件并解压缩文件并将其保存在任何其他位置并使用它。

    如果您正在使用扩展文件,您将无法再从 Raw 文件夹中获取文件。

    我自己已经成功地做到了这一点。希望对你有帮助。

    【讨论】:

    • 对于 obbs 的本地测试,我可以简单地将文件 adb 推送到设备而无需上传/下载部分吗?到目前为止,我在制作 OBB 坐骑时还没有运气。我想知道是不是因为我跳过了上传和下载的舞蹈……不过我正在使用 NDK。
    • 是的,可以通过将文件推送到 obb 文件夹进行本地测试。但是某些路由设备只有对推送文件的访问权限..如果您检查了如果文件存在则不再下载的条件,您可以测试应用程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 2016-10-23
    • 2013-01-11
    • 2019-06-08
    • 2018-05-12
    相关资源
    最近更新 更多