2

I have project which is more than 50MB. I have some images and videos in raw folder. How can i generate the expansion file? i have gone through the developer document, but its not clear for me.Its confusing. Can anybody help me in this.

should i copy the raw folder from the project and paste it on the desktop and then zip that entire folder with the name format given in the google docs? ex: i have my package name "com.my.package", with version code 1 and main expansion file. do i have to zip the entire raw folder and give the name as "main.1.com.my.package.zip"

after creating this, i need to delete the raw folder from the project folder, and then i need to change the code in my project to access the files from the storage location. how can i do that?

I used the below code to access the files in raw folder. how can i change this to access the files from expansion files stored in SD-Card?

String path1 = "android.resource://" + getPackageName() + "/" + R.raw.e4;
Dhaval Parmar
  • 18,812
  • 8
  • 82
  • 177
user1903270
  • 77
  • 3
  • 14
  • possible duplicate of [Android expansion file](http://stackoverflow.com/questions/14139587/android-expansion-file) – Simon Apr 23 '13 at 05:38
  • I used this code . InputStream fileStream = expansionFile.getInputStream("background/flower.png"); But i am getting an error at flower.png, error is "flower" cannot be resolved to a variable. – user1903270 Apr 23 '13 at 06:30
  • [For those who worry about the 50 MB limit, it is now 100 MB](https://developer.android.com/google/play/expansion-files.html). Could be enough to get you out out of having expansion files. 100 MB is a lot with proguard and resource shrinking, most apps are probably 100 MB or less except the large apps and games – Zoe Jul 28 '17 at 19:32

4 Answers4

2

Try to reduce the size as much as possible. You can enable proguard in release mode.The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and methods with semantically obscure names. The result is a smaller sized .apk file that is more difficult to reverse engineer.

You can check the link below.

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

Reading from a ZIP file

When using the APK Expansion Zip Library, reading a file from your ZIP usually requires the following:

// 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

Edit:

Check the Tutorial at the link

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

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
  • DexGuard is also a different compression tool, but I think it is better at securing the code(anti-reverse engineering). Created by the same people who made proguard – Zoe May 09 '17 at 13:47
1

You could just zip the files into a single file, and if it's more than 2 GB, zip to 2 files (each up to 2GB).

An alternative is that you create your own algorithm for putting all of the files together into a single file.

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • `An alternative is that you create your own algorithm for putting all of the files together into a single file.` - What type of algorithm? If you just put the files in a single .zip file, and convert it to .obb on upload to Google Play, how is that something you implement an algorithm into? And besides, what exactly would be the purpose of this algorithm? – Zoe May 08 '17 at 14:16
  • @LunarWatcher There are plenty of algorithms you can think of or choose from, to compress or at least store multiple files into a single one. The purpose can be a better security/compression. – android developer May 08 '17 at 17:33
  • So the purpose of the algorithm is to store multiple files in one file, and compress them to a minimum size? – Zoe May 08 '17 at 18:03
  • 1
    @LunarWatcher That's what I wrote " algorithm for putting all of the files together into a single file" . Compression level and algorithm is what you need to choose, if you want. – android developer May 08 '17 at 20:40
0

There is 2 types of expansion files, main and patch. You can put your all data(images/files) in one folder. Name it like main.1.com.my.package. Here main indicates its main expansion file. If its patch than name it patch.1...
1 is version code in your manifest than your package name Zip this file and rename that zipped file with .obb extension. Remove .zip from end so now your expansion file is ready with name main.1.com.my.package.obb

You have to upload this file with dummy app on market. Than you have to download that file with coding(you can get sample from download library in sdk/extras/google/play_apk_expansion)
This file download on location in mobile mnt/sdcard/android/obb

Than you can use that file and unzip your files and save it at any other location and use it.

You can not get files from Raw folder anymore if you are using expansion file.

I have successfully done this myself. Hope it helps you.

Zoe
  • 27,060
  • 21
  • 118
  • 148
djk
  • 3,671
  • 9
  • 31
  • 40
  • For local testing of the obbs, can i simply adb push the file to the device without the uploading/downloading part?? So far I've had no luck in making the OBB mount. I'm trying to figure out if it's because I skipped the uploading and downloading dance.... I'm using NDK though. – kakyo Aug 14 '13 at 13:23
  • 1
    yes, local testing is possible by pushing file to obb folder. but some routes device has only that access to push file.. if you have checked condition for not downloading again if file is there, you can test app. – djk Aug 15 '13 at 05:02
0

Here are the steps required for setting up expansion files in Android:

  1. First, open the Android SDK Manager, expand Extras and download:

    • Google Play Licensing Library package
    • Google Play APK Expansion Library package
  2. Declare the following permissions in 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. Integrate libraries

    • Copy the source for the Downloader Library from <sdk>/extras/google/play_apk_expansion/downloader_library/src to your project.
    • Copy the sources from <sdk>/extras/google/play_licensing/library/src to your project.
    • Copy the sources from <sdk>/extras/google/google_market_apk_expansion/zip_file/ to your project.
  4. Now, create a new package named expansion and create DownloaderService.java inside the package.

    // 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. Create DownloaderServiceBroadcastReceiver.java extending BoradcastReceiver which will start the download service if the files need to downloaded.

    // 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. Start the download from your activity if expansion files are not available

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

For full details and code, take a look at How to Set Up Android App to Support Expansion Files.

Sapan Diwakar
  • 10,480
  • 6
  • 33
  • 43