This library is developed based on AOSP structure of androidfw/ResourceTypes.h , to totally replace aapt/aapt2
- Resource table (resources.arsc)
- Binary xml files (AndroidManifest.xml & resource xml)
- Decodes resources to readable json
- Encodes/Builds sources in json format to binary resources
- Decodes resources to source code
- Encodes/Builds source XML to binary resources
1- Decoding resources to XML requires all source names should be un-obfuscated and valid
2- User of this lib is assumed to have good knowledge of android source XML syntax, thus during encoding/building it does not validate or throw XML syntax errors as often as aapt/aapt2. For example, you are allowed to set wrong values on some places and doesn't prevent from successful building. On AndroidManifest.xml you can set package="Wrong 😂 (package) name!" then you have to know such values are acceptable by android devices.
Check this tool developed using this library https://github.com/REAndroid/APKEditor
- Maven
repositories { mavenCentral() } dependencies { implementation("io.github.reandroid:ARSCLib:+") }- Jar
dependencies { implementation(files("$rootProject.projectDir/libs/ARSCLib.jar")) }git clone https://github.com/REAndroid/ARSCLib.git cd ARSCLib ./gradlew jar # Built jar will be placed ./build/libs/ARSCLib-x.x.x.jar Java example
import com.reandroid.apk.AndroidFrameworks; import com.reandroid.apk.ApkModule; import com.reandroid.apk.FrameworkApk; import com.reandroid.archive.ByteInputSource; import com.reandroid.arsc.chunk.PackageBlock; import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; import com.reandroid.arsc.chunk.xml.ResXmlAttribute; import com.reandroid.arsc.chunk.xml.ResXmlElement; import com.reandroid.arsc.coder.EncodeResult; import com.reandroid.arsc.coder.ValueCoder; import com.reandroid.arsc.value.Entry; import java.io.File; import java.io.IOException; public class ARSCLibExample { public static void createNewApk() throws IOException { ApkModule apkModule = new ApkModule(); TableBlock tableBlock = new TableBlock(); AndroidManifestBlock manifest = new AndroidManifestBlock(); apkModule.setTableBlock(tableBlock); apkModule.setManifest(manifest); FrameworkApk framework = apkModule.initializeAndroidFramework( AndroidFrameworks.getLatest().getVersionCode()); PackageBlock packageBlock = tableBlock.newPackage(0x7f, "com.example"); Entry appIcon = packageBlock.getOrCreate("", "drawable", "ic_launcher"); EncodeResult color = ValueCoder.encode("#006400"); appIcon.setValueAsRaw(color.valueType, color.value); Entry appNameDefault = packageBlock.getOrCreate("", "string", "app_name"); appNameDefault.setValueAsString("My Application"); Entry appNameDe = packageBlock.getOrCreate("-de", "string", "app_name"); appNameDe.setValueAsString("Meine Bewerbung"); Entry appNameRu = packageBlock.getOrCreate("-ru-rRU", "string", "app_name"); appNameRu.setValueAsString("Мое заявление"); manifest.setPackageName("com.example"); manifest.setVersionCode(100); manifest.setVersionName("1.0.0"); manifest.setIconResourceId(appIcon.getResourceId()); manifest.setCompileSdkVersion(framework.getVersionCode()); manifest.setCompileSdkVersionCodename(framework.getVersionName()); manifest.setPlatformBuildVersionCode(framework.getVersionCode()); manifest.setPlatformBuildVersionName(framework.getVersionName()); manifest.addUsesPermission("android.permission.INTERNET"); manifest.addUsesPermission("android.permission.READ_EXTERNAL_STORAGE"); //all appName entries created above have the same resource ids manifest.setApplicationLabel(appNameDefault.getResourceId()); ResXmlElement mainActivity = manifest.getOrCreateMainActivity("android.app.Activity"); ResXmlAttribute labelAttribute = mainActivity .getOrCreateAndroidAttribute(AndroidManifestBlock.NAME_label, AndroidManifestBlock.ID_label); labelAttribute.setValueAsString("Hello World"); //Android os requires at least one dex file on base apk ByteInputSource dummyDex = new ByteInputSource(new byte[0], "classes.dex"); apkModule.add(dummyDex); File outFile = new File("test_out.apk"); apkModule.writeApk(outFile); //Sign and install } }