Frivolous Musings
Some thoughts on politics/lit/tech/life itself
Editing an Android App
Problem: I have an app I like. I want to make a trivial change to the text in one screen. Emailed the developer, he said I could just edit the file in the assets
folder and sideload it (although he failed to see the point of the edit…)
Background: an APK is just a zipped archive, you can unzip it and edit the text files, then zip, rename to a .apk
extension and try install it (easiest is adb install /path/to/app.apk
). Since an Android app is compiled, most of the decompressed files will be binaries, but not all - some simple things are in plain text, including the ones I wanted to change.
Solved? Not quite. For security reasons, Android requires the app to be signed, so once I edited it and sent it back, it was lacking a signature and I got the error Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]
. OK, how do I sign it? The Android Studio docs have detailed instructions. I downloaded Android Studio, and hit a wall - the menu option Build > Generate Signed Bundle/APK
just didn’t exist on the menu. I looked at some online advice, but none of it helped. Anyway, I just wanted to generate a key pair, do I really need an entire IDE for that? Apparently not, the IDE is using a tool that comes with Java called jarsigner
but I wasn’t able to find this in my %JAVA\_HOME%
and also hit permission issues (I was using WSL on Windows which may have been part of the cause).
Anyway, I eventually found a “batteries included” repo claiming to do this for me. The signing worked, but the install still didn’t. Maybe this was because the repo was eight years old? I found a newer one which happily signed my APK, but installation still failed, with the error [INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: Failed to parse /data/app...AndroidManifest.xml]
. What was wrong the AndroidManifest.xml? I hadn’t touched it, and I couldn’t read it because it was compiled. (Here is a blog post from 2014, a more innocent time, which does what I did until here and succeeds.)
Time for the big guns. I downloaded Apktool, a reverse-engineering tool that tries to restore the source. I was warned that this can break complicated apps, but the one I was editing is pretty simple and survived the compilation. Starting with my original apk
file, I ran apktool d myapp.apk
, edited the file in the assets, had a quick look at the now-readable AndroidManifest.xml
(utterly ordinary, nothing of interest to see!), rebuilt the app with apktool b myapp.zip.out -o edited_app.apk
, and then tried to install. No good - no certificate! Signed the new apk
with uber-apk-signer
and tried again: this time it was rejected with a new error: [INSTALL_FAILED_UPDATE_INCOMPATIBLE]
. Looks like the problem is the old version existing on my phone. I uninstalled it, reran adb install
and hey presto - it worked!
If this sounds like a tedious and horrible exercise to you, you’re probably right. But somehow my brain is wired to find the lure of the solution greater than the frustration of the journey.
Summary:
- Merely unzipping and editing doesn’t work. Use
apktool
to reverse-engineer and a modern signing tool to generate a new signature - Uninstall the old version, and then
adb install
. (You’ll lose your old settings, this way, so be ready to restore them.) - If you want to distribute your app to other people via the Play Store, you’re beyond the scope of this post!