ARTICLES

How to get expansion APK files with downloader library and market licensing modules to work in Android Studio

Google gives an overview of what expansion APK files are along with some sample code.  However, getting started can be tricky.  Here is an easier to understand set of instructions for importing the necessary libraries as modules in Android Studio.

The following instructions were tested with Android Studio version 2.2.3 on a mac.  Note that on a mac the Android sdk folder is at /Library/Android/sdk/ or at /Users/[USER]/Library/Android/sdk/.

Download libraries

  • Android Studio…Preferences…Appearance & Behavior…System Settings…Android SDK.
  • Under SDK Tools, select “Google Play APK Expansion library” and “Google Play Licensing Library”.  Press Apply to install packages… Accept License and Install.

Import market_licensing library

  • File…New…Import Module…
  • Browse to /extras/google/market_licensing/library/, Press Open.
  • Rename Module name from library to market_licensing, Press Next, then Finish

Import downloader_library

  • Open the /extras/google/market_apk_expansion/downloader_library/project.properties file and delete the last line that reads “android.library.reference.1=../market_licensing.”
  • File…New…Import Module…
  • Browse to /extras/google/market_apk_expansion/downloader_library/, Press Open, then Next, then Finish

Source: http://stackoverflow.com/a/35663344/1431520

Import zip library

This step is optional.  If your expansion apk files are in a zip package then this library can be helpful.

  • File…New…Import Module…
  • Browse to /extras/google/market_apk_expansion/zip_file/, Press Open, then next, then Finish

Add user permissions

Add the following permissions to the AndroidManifest.xml. Note that the documentation only has the WRITE_EXTERNAL_STORAGE permission, but I couldn’t get it to work on my Galaxy S5 test device without the READ_EXTERNAL_STORAGE permission as well.

<!-- 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" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Also for API 23+ you need to request read/write permissions from the user during application runtime.  You will need to https://developer.android.com/training/permissions/requesting.html

Set up dependencies 

If you build now you may get the following error: “package com.google.android.vending.licensing does not exist”.  Resolve it with the following steps.

  • Right click the “downloader_library” module from your project view
  • Select “Open Module Settings”
  • Select “Dependencies” tab
  • Press plus sign + then select “3 Module Dependency”
  • Select “market_licensing” and press OK.

Incorporate downloader_sample code into your project

“Most of the time, Google Play downloads and saves your expansion files at the same time it downloads the APK to the device. However, in some cases Google Play cannot download the expansion files or the user might have deleted previously downloaded expansion files. To handle these situations, your app must be able to download the files itself when the main activity starts, using a URL provided by Google Play.”

The sample code to download the expansion APK files manually is at /extras/google/market_apk_expansion/download_sample/

Copy the source code files, rename them and modify them to meet your needs.  This includes SampleAlarmReceiver.java, SampleDownloaderActivity.java, and SampleDownloaderService.java.  Also copy layout file main.xml and merge the values file strings.xml with your own.

Set up dependencies (Part 2)

If you build now you may get the following error: “package com.google.android.vending.expansion.downloader does not exist”.  Resolve it with the following steps.

  1. Right click the “app” module from your project view
  2. Select “Open Module Settings”
  3. Select “Dependencies” tab
  4. Press plus sign + then select “3 Module Dependency”
  5. Select “downloader_library” and press OK.

If you decide to include a .zip file in your extension APK file you can use the zip_file library to access the contents as a virtual file system without unpacking the zip file.  If you previously imported the zip library you can repeat steps 4 and in step 5 select “zip_file” instead.  This should resolve the “package com.android.vending.expansion.zipfile does not exist” error.

If you keep the zip code you will also get the error “error: cannot find symbol class ZipEntryRO”.  Add the following import statement to your SampleDownloaderActivity.java file:

import static com.android.vending.expansion.zipfile.ZipResourceFile.ZipEntryRO;

Modify LicenseChecker.java to make Service Intent explicit

If you build now you may get the following error: “java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.android.vending.licensing.ILicensingService }“.

The root cause of the error is at line 150 of LicenseChecker.java in the market_licensing module.  You can press on the line number in the stack trace “at com.google.android.vending.licensing.LicenseChecker.checkAccess(LicenseChecker.java:150)” or navigate to the file.

add .setPackage("com.android.vending") to the end of the string parameter passed to the intent like so:

new String(
-    Base64.decode("Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U="))),
+    Base64.decode("Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U=")))
+    .setPackage("com.android.vending"), // this fixes 'IllegalArgumentException: Service Intent must be explicit'
     this, // ServiceConnection.

Change the minSdkVersion from 3 to 4 in the market_licensing/manifests/AndroidManifests.xml file

source: http://stackoverflow.com/a/29079160/1431520

Modify DownloaderService to fix WifiManagerLeak error

When you go to generate a signed APK you will get the error “Error:(575) Error: The WIFI_SERVICE must be looked up on the Application context or memory will leak on devices < Android N. Try changing  to .getApplicationContext()  [WifiManagerLeak]“.

The problem is in line 575 of the DownloaderService.java file within the downloader library.  Modify it as follows:

- mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+ mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

source: http://stackoverflow.com/a/42639000/1431520

Implementing the downloader service, alarm receiver and starting the download

Follow along with Google’s documentation at https://developer.android.com/google/play/expansion-files.html to implement the downloader service and alarm receiver.  Scroll down to the section titled “Implementing the downloader service“.

Create the .obb file

If the expansion file is only a single file you can just upload that by itself.  Otherwise if it is multiple files you can compress it into a .zip file and use the zip library above.  Or you can use the JOBB tool at https://developer.android.com/studio/command-line/jobb.html to create an unencrypted or an encrypted .obb file.  You can then use the StorageManager to decrypt the .obb file and mount it.

Testing

To test follow these instructions: https://developer.android.com/google/play/expansion-files.html#Testing.  To transfer the .obb APK file to your device follow these instructions: https://support.google.com/nexus/answer/2840804?hl=en

Upload Expansion APK to Google Play

Start a new release.  Sign and upload your regular APK file.  After the APK has uploaded, press the + button next to it and select the drop down menu under “Use expansion file”.  Upload a new file.  Select your zip or other expansion file and upload it.  Goggle will rename it and convert it to the .obb format.  For subsequent releases you will need to press the plus button again and select the previously uploaded expansion APK or upload a new one.



Our Products

Kitemetrics
Keyword level attribution for Apple Search Ads. Optimize your bids and increase your revenue. Sign up for free at kitemetrics.com.

White Noise and Deep Sleep Sounds
Calming and relaxing sounds that will help you sleep like a baby tonight.
Download for free from the App Store.
Get it on Google Play.