如何在android中生成扩展文件?

如何在android中生成扩展文件?,android,apk,apk-expansion-files,Android,Apk,Apk Expansion Files,我有一个超过50MB的项目。我在原始文件夹中有一些图像和视频。如何生成扩展文件?我已经阅读了开发人员文档,但它对我来说并不清楚。它令人困惑。有人能帮我吗 我应该从项目中复制原始文件夹并粘贴到桌面上,然后用google文档中给出的名称格式压缩整个文件夹吗? 我有我的包名“com.my.package”,版本代码为1,主扩展文件。 我是否必须压缩整个原始文件夹并将名称命名为“main.1.com.my.package.zip” 创建此文件后,我需要从项目文件夹中删除原始文件夹,然后需要更改项目中的代

我有一个超过50MB的项目。我在原始文件夹中有一些图像和视频。如何生成扩展文件?我已经阅读了开发人员文档,但它对我来说并不清楚。它令人困惑。有人能帮我吗

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

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

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

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

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

你可以查看下面的链接

从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);

编辑:

检查链接处的教程


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


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

有两种类型的扩展文件,主文件和补丁文件。您可以将所有数据(图像/文件)放在一个文件夹中。随便说说
main.1.com.my.package
。 这里main表示它的主扩展文件。如果它的修补程序比命名它的修补程序.1…
1是您清单中的版本代码 而不是你的包裹名 压缩此文件并使用.obb扩展名重命名压缩后的文件。从末尾删除.zip,这样现在您的扩展文件就可以使用名称了
main.1.com.my.package.obb

您必须使用市场上的虚拟应用程序上载此文件。然后,您必须通过编码下载该文件(您可以从
sdk/extras/google/play\u apk\u expansion
中的下载库获取示例)
此文件在移动
mnt/sdcard/android/obb

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

如果使用扩展文件,则无法再从原始文件夹获取文件


我自己也成功地做到了这一点。希望对您有所帮助。

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

  • 首先,打开Android SDK管理器,展开Extras并下载:

    • 谷歌游戏授权库软件包
    • Google Play APK扩展库包
  • 在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" />  
    
  • 创建
    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();
            }
        }
    }
    
  • 如果扩展文件不可用,请从“活动”开始下载

    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);
    

  • 有关完整的详细信息和代码,请查看。

    可能与我使用的此代码重复。InputStream fileStream=expansionFile.getInputStream(“background/flower.png”);但我在flower.png上遇到了一个错误,错误是“flower”无法解析为变量。。足以让你摆脱扩展文件的困扰。随着proguard和资源的缩减,100 MB是一个很大的问题,除了大型应用程序和游戏外,大多数应用程序可能都是100 MB或更少。对于OBB的本地测试,我可以简单地将文件推送到设备上而不需要上传/下载部分吗??到目前为止,我还没有幸运地使OBB坐骑。我想知道是不是因为我跳过了上传和下载舞蹈。。。。我正在使用NDK。是的,通过将文件推送到obb文件夹,可以进行本地测试。但有些路由设备只能访问推送文件。。如果您已经检查了文件存在时不再次下载的条件,您可以测试应用程序。
    另一种方法是您创建自己的算法,将所有文件放在一个文件中。
    -什么类型的算法?如果您只是将文件放在一个.zip文件中,并在上传到Google Play时将其转换为.obb,那么您如何实现算法?此外,这个算法的目的到底是什么?@LunarWatcher有很多算法可以考虑或选择,可以将多个文件压缩或至少存储到一个文件中。其目的可以是更好的安全性/压缩。因此,该算法的目的是将多个文件存储在一个文件中,并将它们压缩到最小大小?@LunarWatcher这就是我写的“将所有文件放在一个文件中的算法”。压缩级别和算法是您需要选择的,如果您愿意的话。DexGuard也是一个不同的压缩工具,但我认为它在保护代码(反逆向工程)方面更好。由制作proguard的人创造的
    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);