Goal: Have an app that can update itself on a custom/rooted ROM in Android 13 by saving the APK locally, then having an app install it without user interaction.
Solution: Use an intention as described in the second answer here.
What no longer works:
Originally this was a question because after a lot of time I only found out-of-date answers. Android keeps on increasing security and deprecating old APIs. Here's a list of rabbit holes to avoid.
- Install with exec(),
su
, andpm install
- Granting the app
android.permission.ACCESS_SUPERUSER
and similar permissions - Forcing ROM into permissive mode at compile to avoid SELINUX blocking access
Approach 1 fails because you will get Caused by: java.io.IOException: error=13, Permission denied
. First you need to move the APK into a tmp dir. However when you try to run su
you get the exception. You need to be su
for pm install -r -d foobar.apk
to work. This used to be the most common way that people installed a new apk. Even if there were no issues with it I would recommend using the answer above as its less of a hack.
Approach 2 seems to be just out of date and Android has moved on.
Approach 3 is an attempt to get around the su
issue. It's unclear if SELINUX is really what was causing the exception to be thrown and maybe someone can clarify what's going on. SELINUX is what was blamed and a lot of people spent a lot of time trying to create custom rules.
To get something that worked I attempted to force the device into permissive mode. Using compile time flags doesn't work BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
and Google needs to update the instructions. I could write more here, but it's a black hole. Looking at logs there was no indication SELINUX was blocking 'su'.