How to Create a Flashable Zip for Android System Mods

If you’re an Android developer who wants to create apps intended for /system partition (such as root apps), there are certain instances where you’ll want to create a flashable .zip for your app. This is so that the app files can properly be installed to the /system partition.

A few other uses of flashable .zips include:

Instructing your users to mess around in the file system and manually move files is a time waster for everyone involved – creating a flashable .zip is a much more convenient route. This Appual’s guide will show you how to create a flashable zip for Android.

We will also show you an addon.d script, so that custom system changes will survive a dirty ROM flash – thus, users will not need to re-flash your zip for each update.

Requirements:

  • A root file explorer (MiXplorer, Solid Explorer)
  • ZipSigner (for signing zips) or the MiX Signer plug-in if you use MixPlorer
  • A Nandroid backup is highly recommended

You should also prepare all the files that are going into the zip – APKs, configs, boot animations, etc. Have everything organized before we begin, because this is a delicate process.

Template of a Custom Zip

If you want to download a template zip that you can customize to your own needs, or use it as a base for creating a flashable zip, you can grab them here:

  • TEMPLATE SCRIPT: DOWNLOAD LINK (basic commands / you have to add your custom values: apps, paths of ringtones, bootanimation…)
  • TEMPLATE ZIP: DOWNLOAD LINK (examples are always welcome to better understand an explanation. It can help to understand how to structure your files).

The template should be enough to start using a custom script.

You’ll need to remember these main paths, because these are the things in the /system partition that your flashable zips will typically target:

addon.d => backup script to survive a dirty flash (used by GApps package for instance) app and priv-app => system apps to add or remove etc => host file fonts => your font media => your bootanimation.zip media > audio > alarms => sounds for alarms media > audio > notifications => sounds for notifications media > audio > ringtones => sounds for ringtones media > audio > ui => sounds for various things such as low battery, unlock, camera,.. root of /system for build.prop file

Always remember that files removed from these paths will be re-installed after a dirty flash, and files that have been manually added will be removed. This is why its necessary to create a script that makes a backup of your /system mods.

Example of an Update-Script

ui_print("+-------------------------------------+"); ui_print("| CLEAN FLASH SCRIPT |"); ui_print("| |"); ui_print("| by Primokorn |"); ui_print("+-------------------------------------+"); run_program("/sbin/busybox", "umount", "/system"); run_program("/sbin/busybox", "mount", "/system"); ui_print(" "); ui_print("***Deleting bloatwares***"); delete_recursive( "/system/app/adaway.apk", "/system/app/AdAway", "/system/app/BasicDreams", "/system/app/BookmarkProvider", "/system/app/Calendar", "/system/app/CalendarWidget", "/system/app/CMFileManager", "/system/app/CMWallpapers", "/system/app/DeskClock", "/system/app/Eleven", "/system/app/Email", "/system/app/ExactCalculator", "/system/app/Exchange2", "/system/app/Gello", "/system/app/HexoLibre", "/system/app/Jelly", "/system/app/LiveWallpapersPicker", "/system/app/LockClock", "/system/app/messaging", "/system/app/MiXplorer", "/system/app/NexusLauncher", "/system/app/Phonograph", "/system/app/PhotoTable", "/system/app/PicoTts", "/system/app/PicoTTS", "/system/app/ResurrectionStats", "/system/app/SoundRecorder", "/system/app/Terminal", "/system/app/TugaBrowser", "/system/app/Wallpaper", "/system/app/WallpaperPickerGoogle", "/system/priv-app/AudioFX", "/system/priv-app/Chrome", "/system/priv-app/Gallery2", "/system/priv-app/MusicFX", "/system/priv-app/OnePlusCamera", "/system/priv-app/OnePlusGallery", "/system/priv-app/OnePlusMusic", "/system/priv-app/Recorder", "/system/priv-app/Screencast", "/system/priv-app/Snap", "/system/priv-app/SnapdragonCamera", "/system/priv-app/SnapdragonGallery", "/system/priv-app/WeatherManagerService", "/system/priv-app/WeatherProvider", "/system/priv-app/Tag" ); ui_print("Installing apps and mods, etc"); show_progress(8.800000, 5); package_extract_dir("system", "/system/"); ui_print("***Fixing permissions***"); set_perm(0, 0, 0755, "/system/addon.d/99-dirty.sh"); set_perm(0, 0, 0644, "/system/etc/gps.conf"); set_perm(0, 0, 0644, "/system/fonts/Roboto-Regular.ttf"); set_perm(0, 0, 0644, "/system/media/audio/ringtones/PlasticRing.ogg"); set_perm(0, 0, 0644, "/system/priv-app/Phonesky.apk"); set_perm(0, 0, 0644, "/system/priv-app/microG.apk"); set_perm(0, 0, 0644, "/system/priv-app/Gsam.apk"); set_perm(0, 0, 0644, "/system/priv-app/BBS.apk"); set_perm(0, 0, 0644, "/system/priv-app/V4A-Magisk.apk"); run_program("/sbin/busybox", "mount", "/data"); package_extract_dir("data", "/data/"); set_perm(0, 0, 0755, "/data/local/afscript.sh"); show_progress(8.800000, 5); run_program("/sbin/busybox", "umount", "/data"); run_program("/sbin/busybox", "umount", "/system"); ui_print(" "); ui_print("Done."); ui_print("Ready to reboot.");

Note: ui_print(” “); is for text message. These lines don’t do anything.

You should always unmount and re-mount the partition before working on it.

run_program("/sbin/busybox", "umount", "/system"); run_program("/sbin/busybox", "mount", "/system");

To remove system components / apps, put a comma at the end of each line, except the last one.

delete_recursive( "/system/app/adaway.apk", "/system/app/AdAway", ........................ "/system/priv-app/WeatherProvider", "/system/priv-app/Tag" );

Extract the system files you want to install.

package_extract_dir("system", "/system/");  Set the file permissions.  set_perm(0, 0, 0755, "/system/addon.d/99-dirty.sh"); .............. set_perm(0, 0, 0644, "/system/priv-app/V4A-Magisk.apk");

Do the same thing but for the /data folder. So you will mount the partition, extract the data you want to add, and set the permissions.

run_program("/sbin/busybox", "mount", "/data"); package_extract_dir("data", "/data/"); set_perm(0, 0, 0755, "/data/local/afscript.sh");

Next you will unmount the modified partitions.

run_program("/sbin/busybox", "umount", "/data"); run_program("/sbin/busybox", "umount", "/system");

Example of Addon.D script

#!/sbin/sh #  # /system/addon.d/99-dirty.sh # /system is formatted and reinstalled, then thes files are restored. #  . /tmp/backuptool.functions  list_files() { cat <<EOF addon.d/99-dirty.sh fonts/Roboto-Regular.ttf media/audio/ringtones/PlasticRing.ogg priv-app/BBS.apk priv-app/Gsam.apk priv-app/microG.apk priv-app/PhoneSky.apk priv-app/V4A-Magisk.apk etc/gps.conf etc/hosts EOF }  case "$1" in backup) list_files | while read FILE DUMMY; do backup_file $S/"$FILE" done ;; restore) list_files | while read FILE REPLACEMENT; do R="" [ -n "$REPLACEMENT" ] && R="$S/$REPLACEMENT" [ -f "$C/$S/$FILE" ] && restore_file $S/"$FILE" "$R" done rm -rf /system/app/adaway.apk rm -rf /system/app/AdAway rm -rf /system/app/BasicDreams rm -rf /system/app/BookmarkProvider rm -rf /system/app/Calendar rm -rf /system/app/CalendarWidget rm -rf /system/app/CMFileManager rm -rf /system/app/CMWallpapers rm -rf /system/app/DeskClock rm -rf /system/app/Eleven rm -rf /system/app/Email rm -rf /system/app/ExactCalculator rm -rf /system/app/Exchange2 rm -rf /system/app/Gello rm -rf /system/app/HexoLibre rm -rf /system/app/Jelly rm -rf /system/app/LatinIME rm -rf /system/app/LiveWallpapersPicker rm -rf /system/app/LockClock rm -rf /system/app/messaging rm -rf /system/app/MiXplorer rm -rf /system/app/NexusLauncher rm -rf /system/app/Nova.apk rm -rf /system/app/Phonograph rm -rf /system/app/PhotoTable rm -rf /system/app/PicoTts rm -rf /system/app/PicoTTS rm -rf /system/app/ResurrectionStats rm -rf /system/app/SoundRecorder rm -rf /system/app/Terminal rm -rf /system/app/TugaBrowser rm -rf /system/app/Wallpaper rm -rf /system/app/WallpaperPickerGoogle rm -rf /system/priv-app/AudioFX rm -rf /system/priv-app/Chrome rm -rf /system/priv-app/Gallery2 rm -rf /system/priv-app/LatinIME rm -rf /system/priv-app/MusicFX rm -rf /system/priv-app/OnePlusCamera rm -rf /system/priv-app/OnePlusGallery rm -rf /system/priv-app/OnePlusMusic rm -rf /system/priv-app/Recorder rm -rf /system/priv-app/Screencast rm -rf /system/priv-app/SnapdragonCamera rm -rf /system/priv-app/SnapdragonGallery rm -rf /system/priv-app/Snap rm -rf /system/priv-app/Trebuchet rm -rf /system/priv-app/WeatherManagerService rm -rf /system/priv-app/WeatherProvider rm -rf /system/priv-app/Tag ;; pre-backup) # Stub ;; post-backup) # Stub ;; pre-restore) # Stub ;; post-restore) # Stub ;; esac

Create a list of files you want to keep after a dirty flash.

list_files() { cat <<EOF addon.d/99-dirty.sh fonts/Roboto-Regular.ttf media/audio/ringtones/PlasticRing.ogg priv-app/BBS.apk priv-app/Gsam.apk priv-app/microG.apk priv-app/PhoneSky.apk priv-app/V4A-Magisk.apk etc/gps.conf etc/hosts EOF }

RM -RF the files you don’t want to be installed after a dirty flash (system files you removed in your modification that will be re-installed from a dirty flash)

rm -rf /system/app/adaway.apk rm -rf /system/app/AdAway rm -rf /system/app/BasicDreams rm -rf /system/app/BookmarkProvider ................................................ rm -rf /system/priv-app/WeatherProvider rm -rf /system/priv-app/Tag ;;

How to Create a Flashable Android Zip

 

We’ll be using MiXplorer for this, as it’s the best root explorer and file manager for Android, hands down.

  1. First select all your folders that will be included in the zip, and choose Archive.
  2. Confirm the creation of your archive file, give it a name and choose Store.
  3. Your flashable zip will be created, so select the zip file and then Sign it (using MiX signer plugin)
  4. Now select TestKey to just check it for signature errors.
  5. You can now flash the zip – recommend moving it to /SDcard for easily finding it from custom recovery.

Final Notes

Your flashable zip needs to be installed after a clean flash, or after wiping the /system partition and doing a dirty flash of your ROM. The updater-script will remove and add the system files you specified in your script – but leave the addon.d script alone, because it will do its job without any interference from you.

After your first installation, thoroughly check the /system partition to make sure everything is correct – files are removed, etc. Maybe you had a typo in a file name and it wasn’t removed, it happens.

ABOUT THE AUTHOR

Kamil Anwar


Kamil is a certified MCITP, CCNA (W), CCNA (S) and a former British Computer Society Member with over 9 years of experience Configuring, Deploying and Managing Switches, Firewalls and Domain Controllers also an old-school still active on FreeNode.
Page was generated in 3.378965139389