I need to upload a .apk
but it exceeds the 50 MB limit.
I read about this on documentation and some questions but I'm having difficulty making this work.
Does anyone have some tutorials that explain how to do this (using Android Studio) and if there is some way to use Gradle to do this?
Set the input directory for creating an OBB file, or the output directory when extracting ( -dump ) an existing file. When creating an OBB file, the contents of the specified directory and all its sub-directories are included in the OBB file system. Specify the filename for the OBB file.
First, open the Android SDK Manager (Tools > SDK Manager), and under Appearance & Behavior > System Settings > Android SDK, select the SDK Tools tab to select and download: Google Play Licensing Library package. Google Play APK Expansion Library package.
An APK (Android Package Kit) is the file format for applications used on the Android operating system. APK files are compiled with Android Studio, which is the official integrated development environment (IDE) for building Android software. An APK file includes all of the software program's code and assets.
I've done this on a few projects, but I never figured out a simple way. The instructions at
http://developer.android.com/google/play/expansion-files.html
helped me get my head around the basics, but I found parts of the process (like "android update project") didn't work properly with Gradle.
The instructions below will help you set up your project with the required libraries. After that you can go back to the official docs and figure out what to do with all the stuff you just included.
Add these permissions to AndroidManifest.xml
<uses-permission android:name="com.android.vending.CHECK_LICENSE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
Add Play Services dependency to build.gradle
dependencies {
compile 'com.google.android.gms:play-services:4.0.30'
}
Open SDK Manager and install Google Play APK Expansion Library and Google Play Licensing Library.
Copy java source files from these folders into your project's source/main/java folder:
YOUR-ANDROID-SDK-FOLDER\extras\google\play_apk_expansion\zip_file\src
YOUR-ANDROID-SDK-FOLDER\extras\google\play_apk_expansion\downloader_library\src
YOUR-ANDROID-SDK-FOLDER\extras\google\play_licensing\library\src
Open
YOUR-ANDROID-SDK-FOLDER\extras\google\play_apk_expansion\downloader_library\res
Copy drawable-hdpi, drawable-mdpi and layout into your project's source/main/res folder.
For all files in the values folders, merge content from the file into the matching file in your project.
Create a class which extends android.content.BroadcastReceiver
Add something like this to your manifest:
<receiver android:name="mypackage.MyReceiver"/>
Create a class which extends com.google.android.vending.expansion.downloader.impl.DownloaderService
Add something like this to your manifest:
<service android:name="mypackage.MyDownloaderService"/>
Compile the project and look for errors relating to
import com.android.vending.expansion.downloader.R;
Import your own project resources here instead.
Here is some helfull information for people that end up here in this post since there are some things that changed in the way apk expansions work and also if you are using Android Studio to make the libraries work. So you will need the play services library and the downloader library. (and also the zip tools if you want to use a zip as expansion file and read files and movies directly from the zip without unpacking).
With these libraries it's pretty easy to implement the apk expansion download just make sure:
your activity (the one where you want to implement the downloading of the expansion pack when the downloading has not been done automatically) implements IDownloaderClient.
you set up the service & receiver and set them up in your manifest.
The BASE64_PUBLIC_KEY in the service class is correct. Upload the first apk => look in Services and API's in the developer console under your app => License code for this app.
This code is used to see if the expansion file can be found on the device:
boolean expansionFilesDelivered() {
for (XAPKFile xf : xAPKS) {
String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion);
Log.i(TAG, "Expansion filename " +fileName);
if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false))
return false;
}
return true;
}
It uses the class XAPKS wich represents an expansion file, be it either a main or patch file, having a certain filesize(bytes) and associated with a apk version (the one it was first added in).
private static class XAPKFile {
public final boolean mIsMain; // true
public final int mFileVersion; //example 4
public final long mFileSize; //example 126515695L
// example => main expansion that was first introduced in apk version 4 and is 126515695 bytes in size
XAPKFile(boolean isMain, int fileVersion, long fileSize) {
mIsMain = isMain;
mFileVersion = fileVersion;
mFileSize = fileSize;
}
}
Its also quite easy to read movie files and other stuff directly from the expansion file using the zip tools that google has provided (com.android.vending.zipfile).
First get the expansionfile using the methods provided in the library, the paremeters are integers that represent your main expansion apk version (the apk version where the expansion pack you need was first added) and the patch apk version.
ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(context, APKX_MAIN_APK, APKX_PATCH_APK);
Video
For playing video directly from this zipresourcefile:
AssetFileDescriptor a = expansionFile.getAssetFileDescriptor(pathToFileInsideZip);
Now from this assetFileDescriptor you can get a FileDescriptor and use this in your mediaplayer, the correct syntax to get your mediaplayer to play the video also needs the second and third parameter.. Be it the startoffset and length you can get from the AssetFileDescriptor.
player.setDataSource(a.getFileDescriptor(), a.getStartOffset(), a.getLength());
Other
For all the other stuff (like images) you can just get an inputstream of the zipresourcefile:
expansionFile.getInputStream(pathToFileInsideZip);`
ALSO make sure you don't compress the videos in the zip for this to work! for example not to compress .mp4 files:
zip -n .mp4 -r zipfile.zip . -x ".*" -x "*/.*"
NOTE 1
You can't use draft anymore as the link to get the expansion file won't be active yet. You have to upload a version to Alpha or Beta first with expansion file. (adding an expansion file is only possible from the second apk you upload and up) So make sure you see the apk expansion file listed when you click the details in the developer publish section under APK.
NOTE 2
If you are using android studio and want to make use of the downloader library don't just copy the package name and java files into your own app src directory. Import the downloader library in eclipse and choose export => gradle build files. Afterwards you can import the library as a module in android studio.
NOTE 3
Not sure of this but I also think it's neccesary to download the app atleast once through the play store and have access to it with the account on your test device. So if you are working with alpha create a google+ test group and add yourself or other test devices to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With