My app requires a lot of image resources, so I've had to package them into an expansion file. I've got this working fine when I manually copy the expansion file to my emulator's shared storage. What's unclear to me is the whole download process.
In Google's (often frustrating) documentation, it says:
On most devices, Google Play downloads the expansion file(s) at the same time it downloads the APK, so your application has everything it needs when the user opens it for the first time. In some cases, however, your application must download the files from Google Play when your application starts.
My app will be free with a single expansion file. Can I actually rely on the expansion file being downloaded with the app? Or must I implement the downloader service to ensure that the expansion file is downloaded when the app starts?
What are the circumstances under which the expansion file would not be downloaded with the apk? I suppose that the user might erase or remove the shared storage volume onto which the expansion file was originally copied, so that might be a case I'd have to worry about.
Tell me I can be lazy! Come on! And then someone link to this question on a blog post lamenting the laziness of app developers. OK, OK, I won't get all defensive. I just want to understand the mechanics here, and yes I would rather avoid the extra headaches of implementing the downloader service. I'm not a full-time Android developer, and I've got other things to do!
Thanks
The play store will attempt to download the expansion files but network connections fail or time out etc
You should check the files are available when your app starts and manually download them if they are not.
If you don't allow for this eventuality then some users will be unable to use your app unless it will work without the expansion pack.
Related
I am currently developing an offline app with OSMDroid and I'm starting to ask myself some questions about the storage space the app is going to take.
Previously we had the MBTiles and the database stored at the root of the internal memory and we installed it apart from the app, but we judged it insecure and inconveniant.
Now, the files are compiled with the app and are installed on start-up in the private folder of the app itself.
Here's my question, does it mean that technically both files are duplicated because there is one version compiled in the app and one in the internal memory, thus taking more storage space?
Is there a better solution for this?
After multiple attempts to find a standard way to not duplicate the resources files, I found that I will have to use expansion files.
According to https://developer.android.com/google/play/expansion-files.html, APK files may not exceed 100MB, after that limit you have to use expansion files that will be downloaded with the installer from the play store.
Expansion files are already in a reachable location for OSMdroid so no need to copy them in the app's private folder.
However since my app might be for a restricted-public only and installation will be done manually, I thought of building a separate app that will install the app + expansion files to give less hassle to my clients.
I want to reduce my android apk file size, so I split some function source code and compile those code to a Jar file, it contain a dex file in the jar file. When android app need use those functions, the app download the jar file and load dex file from it.
But I found the Android Developer Program Policies said:
An app downloaded from Google Play may not modify, replace or update
its own APK binary code using any method other than Google Play's
update mechanism
My question is do I do this a violation?
Yes because you're basically updating your APK without the Google Play's update mechanism. If you truly wish to minimize the .apk file size, you can put your resources online and request them through a custom api.
For example: I developed an app which uses Google Earth marker and polygon coordinates, descriptions and other useful information that are stored on my webserver, online in a .kml file. Because I'm constantly updating the file with new markers and polygons, I don't want the user to download the .apk file with a huge filesize each time I update my resources. So that's why I stored my resources online which the user downloads while using my app and that keeps the .apk filesize to less than 3MB which is great for the people who download the app through the play store. Otherwise the filesize would have been 15MB+ with all the images and other resources with that keeps on growing by each minute.
Nonetheless, the user would have to download the resources one way or another but I do like your way of thinking though to keep the size of the .apk file low as possible.
I'm looking to packing a large sqlite database with an android app, about 200-300MB. From what I've read, my options are putting it in the assets folder, and coping it out at runtime, resulting in duplicate data, or downloading the database from the web at runtime. I don't want to create a webserver for this app, so I was thinking of creating a seperate app that just installs the database to get around the data duplication problem.
All of those are pretty crummy, and I was wondering if there is a better solution?
First, I don't think you are allowed to put a 200-300MB database in your assets folder and distribute it as a single apk, since the hard limit for an apk file size is (as per google's documentation) 50 MB and I doubt that your db will compress that far.. Google introduced the "APK expansion files" for packaging large files with your apk. You can read all about those here: http://developer.android.com/google/play/expansion-files.html
I think (but I have no experience with expansion files myself) that this will not fix the issue you mentioned about having to deal with duplicate data because of the requirement to copy out your database file, but at least this will help you in the sense that you won't have to host your database file on your own webserver. I quickly scanned the documentation on the link I gave above and it clearly states that you should NOT throw away the expansion files when you are done with them, so no help on that part.
Of course, for the "setting up your own webserver part": I wouldn't even bother setting up my own webserver. There are plenty of parties out there that provide you some file hosting service. Probably you will have to pay for the bandwidth, but hey.. if people download your db file a lot, that also means that your app is doing well ;-)
I test of apk expansion files. I created a test app with a 100 MB sqlite database, uploaded the apk and database to the play store. I then downloaded the app onto the phone, the database was downloaded at the same time. The database was automatically renamed and placed in the publicly accessible directory:
/storage/sdcard0/Android/obb/com.example.app/main.1.com.example.app.obb
The app was able to open the database without any problems, but required external read and write permissions. The new and original database are bit for bit, the same. This appears to be the best solution for my use case.
A few issues, the new android developer console does not support uploading expansion files, so the old one needs to be used. Google only allows 2 expansion files, so that may be an issue for some use cases. Google say that you must not rename or delete the file, and that your app must be able to download the file from Google itself if it wasn't automatically installed.
Docs say that APK size limit in Google Play is 50MB, with option for two 2GB expansion APKs.
However, I can find apps in Google Play store that are beyond this 50MB limitation (Gears & Guts for example is 371MB). I can download this game straight from Google Play itself without need for external downloaders. Do they have some extra feature as Top Developer to upload APKs over 50MB, or does Google Play just hide the fact that it's downloading expansion files rather than the APK itself?
Expansion files act kind of weird. To the user, they look like a normal app. A 50MB app with 150MB worth of expansion files will look like a 200MB download. Google Play will download the main app first. It will then download the main expansion file and then the patch expansion file. All in seemingly one lump sum.
However, it is possible for the download to be partial. I.E., the user can finish the main app download without the expansion files. As such, you MUST implement a custom downloader in order to retrieve the remaining files on the event the initial download fails. To make things a bit more complicated, sometimes the expansion files are not included in the initial download. I don't know what causes this, but I've seen it happen on rare occasions.
UPDATE: I just downloaded my APK again and Gears and Guts and they both show as one download but if you look at the status of the download in the status bar, it'll show that it's downloading an additional file.
I am using concept of Android Expansion which helps us to remove obstacle of 50mb limitation of Apk.
Following all the steps http://developer.android.com/guide/market/expansion-files.html
I understood that you need to follow file format like this [main|patch].<expansion-version>.<package-name>.obb and did the same.
And also Expansion files may be in (ZIP, PDF, MP4, etc.) format.
I uploaded additional expansion files while publishing apk on Google play. At the time of download apk I get all the additional in my Local(Advanced latest Device), But through code I am not able to get the expansable files of my application.
In code looking at the sampleDownloader code I came to know that it requires three parameter (int type, int expansionCode, long fileSize)
here type: main/patch expansionCode: integer value but I am just wondering how to give FileSize in Long(exact)? and second thing its show message like Download failed because the resource could not be found
Any idea?
Update
Done, all steps are shown here
Did you go through Downloading the Expansion Files? It mentions that
If the expansion files are not there with your Application downloaded from Android Market,
You have to perform Application Licensing to get your app's expansion file names, sizes, and URLs.
Perform a request using Google Play's Application Licensing to get your app's expansion file names, sizes, and URLs.
Use the URLs provided by Google Play to download the expansion files and save the expansion files.
UPDATE:
No, its not compulsory that Google Licensing only works with paid Application. There is a clear Note: defined in the Docs itself that any application may use licensing service to initiate the download of an APK expansion file. But, in that case your request will be only for expansion files and not for a check whether the user paid for the app or not.