I have an Android project with 3000 photo's that needs to be available offline. When I include all the photo's in the build, the build fails. When I remove some of them, the build succeeds.
I have put the photo's in two dynamic modules that download at install time.
Here is the gradle scan for reference: https://scans.gradle.com/s/nn6eo527qvge6
Is this purely a size issue and if so, how do I get around that?
Is this purely a size issue
Probably.
how do I get around that?
Start by moving your photos out of res/drawable-xxhdpi-v4/ and into assets/ and adjust your code that consumes the photos to match.
Then, see what the resulting APK size is and compare it with the size limits for your intended app distribution channel (e.g., 100MB limit for the Play Store). If you exceed that limit, you will need to work through alternative approaches (e.g., APK expansion files).
To expand on CommonsWare's answer, I think the way you should do this is not by using Dynamic Modules but by using asset delivery. It's kinda "marketed" as a "for games" thing, but it's not limited at all by that.
The idea behind asset-delivery is that you have a pack of assets (images in your case) that you need for your app to function.
This "pack" of assets can be requested at install time, or later "on demand". All this is confusing because Dynamic Delivery sounds very similar. However, as stated at the top of the asset-delivery page, they use Different APIs.
In all honestly, I haven't used Asset Delivery, so take it with a grain of salt, and keep the considerations at hand, for example (and I quote):
If the download is larger than 150 MB and the user is not on Wi-Fi, the download does not start until the user explicitly gives their consent to proceed with the download using a mobile data connection. Similarly, if the download is large and the user loses Wi-Fi, the download is paused and explicit consent is required to proceed using a mobile data connection.
Related
i just exported my game to use Play Asset delivery following this guide:
https://docs.unity3d.com/2021.1/Documentation/Manual/play-asset-delivery.html
in short
build app bundle enabled
split application binary also checked.
The exported aab size is 311mb and when uploading to google play it says:
base ----install_time ---30.1mb
UnityDataAssetPack ----install time ---264mb
But then when i download the app in any device, the file size is 846mb, more than double the expected size. Also it tries to download all at once, i thought that the dataassetpack was downloaded after the base one.
i'm using Unity 2021.1.16f1
Do you know any cause for this to happen, and how to fix it?
thank you very much!
You are comparing a "download size" to a "size on disk":
The size you see in the Play Console corresponds to the download size, which is compressed.
On the device, you see the size on disk where the data is stored uncompressed so it can be directly rendered without having to keep two copies of the same data (one compressed and one uncompressed), so that explains the discrepancy.
It seems that you have configured the modules to be install-time so they will be installed as part of the initial install. If you want them to be installed while the user is starting the game, you should configure them to be fast-follow. If you want to manually download them using the Play Core API, you should configure them to be on-demand. This is all explained in the page you linked in the Managing asset packs at runtime section.
That page also links to the Google documentation on the topic, which has a dedicated section for Unity -- which would be too long to copy here, so have a read and come back if you have more specific questions.
If you're only using Unity marking the AAB output type in the build settings, and not using Google's API to do your stuff via script, then it's correct. Unity has a bug when assembling bundles and will simply (at least) double the size of your app. Things will be doubled in your AAB, you'll see the stuff you had in streaming assets in split apks and also inside the base.apk. Unity's way is not reliable, it's quite wrong and Google's plain way for Unity also is not perfect, it will not work for every single project. I was able to get the hang of it, but in the end I wrote our own tool to create the asset packs, created our runtime implementation to use the API and also our build procedures to be called by our custom build class.
My suggestion is, squeeze the docs here https://developer.android.com/guide/playcore/asset-delivery/integrate-unity?language=api and build your custom solution.
Scenario:
I have an app with a lot of high res drawable images. I would like to deliver those assets with the build as opposed to via web/http/cdn.
Problem:
When uploading my .aab to google, I'm told that certain configurations will result in a build over the 150MB limit.
What I've tried:
I've extracted most of the large images to an install-time Dynamic Feature Module.
Using bundletool, I've simulated an xxxhdpi device on arm64 with two languages. The resulting base apks do not exceed 150MB. The Dynamic Feature Module apks ("packimages-*.apk") do, but as far as I can tell, that's not only ok, but that is Google's recommended way of reducing base apk size.
The limit on 150 MB is on the download size at installation time.
Since you mentioned that you configured the dynamic features to be "install-time", they will also be served at installation time and are thus counted towards the limit.
You may want to consider images that are needed at installation time (which you can leave in the base module) and images that can be downloaded at a later time (which you can put in an on-demand module) using the Play Core SDK.
I want to migrate my android app (~40 MB of the base apk) that uses an .obb file (~70 MB) to the Android App Bundle format. I know for sure that the resources inside the .obb file will be updated less frequently than the base part. Therefore, there is no need for the users to download a full app (40 + 70 = 110 MB) on each app update but only the changed part (~40 MB).
What can I use after the migration to provide the same experience (update only changed part) to the end users?
Ideally, these unchanged resources should be accessible through the AssetManager like they are located within the assets directory.
For now, I found the Play Asset Delivery feature that allows moving some resources to a separate module to deliver it to devices at different times (install time / right after the download / when needed).
I've implemented an install time module logic and tested it via the internal + alpha tests. Throughout the testing, I found out each app update forces Google Play to download the full app (~110 MB) instead of the changed part (~40 MB). I do not know whether this situation will change when I release an app to the "available for everyone" track and I could not find the information about it either. Therefore, the answer "an install time module will not be redownloaded if unchanged; here is the documentation describing this: <link>" is fully acceptable and is one of the most welcoming ones.
tldr; Yes, in production, the download size will be smaller.
When you publish an app to production (whether APK or App Bundle), Play will generate patches of your app between this version and the previous versions of your app, so that your users only download the difference between the two versions. The consequence is that if you don't modify the content of a dynamic module, users will still receive updates for the unchanged modules but the download size will be very small.
Note that in practice, it is possible that the first couple of users downloading the update may still get the full size.
I today released an Android application which includes some language-dependent MP3 files. My concern is that the more languages, the bigger the application size.
What would be your recommendation:
Release one application per language (not really easy to deal with, would have to release n apps each time I add new features to the software)
Provide a mechanism to download the MP3 files at first launch (would require an internet connection whereas the user may think he doesn't need one. It could bring frustration.)
Optimize the MP3 files (not that scalable if I have to support 10 languages)
[ ] fill the blank !
Hervé.
I'm a big fan of user-choice. As such, I might make the MP3 files optional, but on first run explain to the user that you have some language-dependant features and allow them to download them if they desire.
The reasons for this are many:
It keeps the file size low.
It is easily supportable with one distribution.
It allows you to extend/correct the language files independent of the software.
It is upfront, and gives the user the choice of language (even potentially multiple).
It allows the user to change the aural language without having to uninstall/reinstall or have duplicate installs.
There are many users (such as myself) who never speak to their phone, and never want to hear it speak to them. :) (Yes, I'm crazy)
Just a suggestion!
FuzzicalLogic
I'm creating an app with 3 different languages. Every language contains a separate audio file (8 mb each).
Is it possible to split/export the project to 3 different .apk files prior to release on Market? I really do not want to put everything in one .apk due to the 24+ mb file size.
I can see a few options...
Manually build each one, release them as separate products in the Market in each language, e.g. "MyApp English", "MyApp Francais" etc. You could limit which countries see each one, to reduce confusion.
Same as above, but use Ant to automate the Android build process, so you can have one project for the app, but easily build a version in any language. Ant is quite involved, but I'd that in about a day you could learn enough to get an Ant build script running for your project. Android has built-in command line tools to help, so it'll create an initial Ant script for you (look at the "android" command line tool).
Create a single app, and when it starts, ask the user to confirm the language they want, and then start the download. Ideally you'd download a little bit initially to allow the app to work, and download the rest in the background so they don't have to wait. 8MB is quite a lot of data, so beware people will data expensive data plans so I think it is polite to always ask their permission for the download.
If it were me I'd probably lean towards the last option as it's simpler to build one app, and with sucha big download, the user needs to be in control of the process. Bear in mind many people wouldn't download an 8MB app if they knew beforehand it is that big.