@@ -16,13 +16,13 @@ This library is developed based on AOSP structure of androidfw/ResourceTypes.h ,
1616
1717##### _ NOTES:_
1818
19- _ 1- Decoding resources to XML requires all source names should be un-obfuscated and valid_
19+ _ 1- Decoding resources to XML requires all source names should be un-obfuscated and valid_
2020
21- _ 2- User of this lib is assumed to have good knowledge of android source XML syntax, thus
22- during encoding/building it does not validate or throw XML syntax errors as often as aapt/aapt2. For
23- example, you are allowed to set wrong values on some places and doesn't prevent from
24- successful building. On AndroidManifest.xml you can set ``` package="Wrong 😂 (package) name!" ```
25- then you have to know such values are acceptable by android devices._
21+ _ 2- User of this lib is assumed to have good knowledge of android source XML syntax, thus
22+ during encoding/building it does not validate or throw XML syntax errors as often as aapt/aapt2. For
23+ example, you are allowed to set wrong values on some places and doesn't prevent from
24+ successful building. On AndroidManifest.xml you can set ``` package="Wrong 😂 (package) name!" ```
25+ then you have to know such values are acceptable by android devices._
2626
2727
2828#### Example application
@@ -59,116 +59,84 @@ cd ARSCLib
5959
6060<details ><summary > <code ><b >See java example</b ></code ></summary >
6161
62- ``` java
63- import com.reandroid.arsc.chunk.TableBlock ;
62+ ``` java
63+ import com.reandroid.apk.AndroidFrameworks ;
64+ import com.reandroid.apk.ApkModule ;
65+ import com.reandroid.apk.FrameworkApk ;
66+ import com.reandroid.archive.APKArchive ;
67+ import com.reandroid.archive.ByteInputSource ;
6468import com.reandroid.arsc.chunk.PackageBlock ;
69+ import com.reandroid.arsc.chunk.TableBlock ;
6570import com.reandroid.arsc.chunk.xml.AndroidManifestBlock ;
66- import com.reandroid.arsc.chunk.xml.ResXmlElement ;
6771import com.reandroid.arsc.chunk.xml.ResXmlAttribute ;
72+ import com.reandroid.arsc.chunk.xml.ResXmlElement ;
73+ import com.reandroid.arsc.coder.EncodeResult ;
74+ import com.reandroid.arsc.coder.ValueCoder ;
75+ import com.reandroid.arsc.value.Entry ;
6876
69- public static void exampleManifest()throws IOException {
70- File inFile= new File (" AndroidManifest.xml" );
71-
72- // *** Loading AndroidManifest ***
73- AndroidManifestBlock manifestBlock= AndroidManifestBlock . load(inFile);
74-
75- System . out. println(" Package name: " + manifestBlock. getPackageName());
76-
77- List<String > usesPermissionList= manifestBlock. getUsesPermissions();
78- for (String usesPermission: usesPermissionList){
79- System . out. println(" Uses permission: " + usesPermission);
80- }
81-
82- // *** Modifying AndroidManifest ***
83- // Change package name
84- manifestBlock. setPackageName(" com.new.package-name" );
85- // Add uses-permission
86- manifestBlock. addUsesPermission(" android.permission.WRITE_EXTERNAL_STORAGE" );
87- // Modify version code
88- manifestBlock. setVersionCode(904 );
89- // Modify version name
90- manifestBlock. setVersionName(" 9.0.4" );
91-
92- // Modify xml attribute
93- List<ResXmlElement > activityList= manifestBlock. listActivities();
94- for (ResXmlElement activityElement: activityList){
95- ResXmlAttribute attributeName= activityElement. searchAttributeByResourceId(AndroidManifestBlock . ID_name );
96- System . out. println(" Old activity name: " + attributeName. getValueAsString());
97- attributeName. setValueAsString(" com.app.MyActivity" );
98- System . out. println(" New activity name: " + attributeName. getValueAsString());
99- break ;
100- }
101-
102- // Refresh to re-calculate offsets
103- manifestBlock. refresh();
104- // Save
105- File outFile= new File (" AndroidManifest_out.xml" );
106- manifestBlock. writeBytes(outFile);
107-
108- System . out. println(" Saved: " + outFile);
109- }
110-
111- ```
77+ import java.io.File ;
78+ import java.io.IOException ;
11279
80+ public class ARSCLibExample {
11381
82+ public static void createNewApk () throws IOException {
83+
84+ ApkModule apkModule = new ApkModule (" base" , new APKArchive ());
11485
115- ``` java
116- public static void exampleResourceTable() throws IOException {
117- File inFile= new File (" resources.arsc" );
86+ TableBlock tableBlock = new TableBlock ();
87+ AndroidManifestBlock manifest = new AndroidManifestBlock ();
11888
119- // *** Loading resource table ***
120- TableBlock tableBlock = TableBlock . load(inFile );
89+ apkModule . setTableBlock(tableBlock);
90+ apkModule . setManifest(manifest );
12191
122- Collection<PackageBlock > packageBlockList= tableBlock. listPackages();
123- System . out. println(" Packages count = " + packageBlockList. size());
124- for (PackageBlock packageBlock: packageBlockList){
125- System . out. println(" Package id = " + packageBlock. getId()
126- + " , name = " + packageBlock. getName());
127- }
92+ FrameworkApk framework = apkModule. initializeAndroidFramework(
93+ AndroidFrameworks . getLatest(). getVersionCode());
12894
129- // *** Modify resource table
130- // Change package name
131- for (PackageBlock packageBlock: packageBlockList){
132- String name = packageBlock. getName();
133- String newName = name + " .new-name" ;
134- packageBlock. setName(newName);
135- }
95+ PackageBlock packageBlock = tableBlock. newPackage(0x7f , " com.example" );
13696
137- // Refresh to re-calculate offsets
138- tableBlock. refresh();
139- // Save
140- File outFile= new File (" resources_out.arsc" );
141- tableBlock. writeBytes(outFile);
97+ Entry appIcon = packageBlock. getOrCreate(" " , " drawable" , " ic_launcher" );
14298
143- System . out . println( " Saved: " + outFile );
144- }
99+ EncodeResult color = ValueCoder . encode( " #006400 " );
100+ appIcon . setValueAsRaw(color . valueType, color . value);
145101
146- ```
102+ Entry appNameDefault = packageBlock. getOrCreate(" " , " string" , " app_name" );
103+ appNameDefault. setValueAsString(" My Application" );
147104
148- ``` java
149- public static void exampleLoadApk() throws IOException {
150- File inFile= new File (" test.apk" );
151- File outDir= new File (" test_out" );
105+ Entry appNameDe = packageBlock. getOrCreate(" -de" , " string" , " app_name" );
106+ appNameDe. setValueAsString(" Meine Bewerbung" );
152107
153- ApkModule apkModule= ApkModule . loadApkFile(inFile);
108+ Entry appNameRu = packageBlock. getOrCreate(" -ru-rRU" , " string" , " app_name" );
109+ appNameRu. setValueAsString(" Мое заявление" );
154110
155- ApkJsonDecoder decoder= new ApkJsonDecoder (apkModule);
156- outDir= decoder. writeToDirectory(outDir);
157- System . out. println(" Decoded to: " + outDir);
111+ manifest. setPackageName(" com.example" );
112+ manifest. setVersionCode(100 );
113+ manifest. setVersionName(" 1.0.0" );
114+ manifest. setIconResourceId(appIcon. getResourceId());
115+ manifest. setCompileSdkVersion(framework. getVersionCode());
116+ manifest. setCompileSdkVersionCodename(framework. getVersionName());
117+ manifest. setPlatformBuildVersionCode(framework. getVersionCode());
118+ manifest. setPlatformBuildVersionName(framework. getVersionName());
158119
159- // You can do any logical modification on any json files here
120+ manifest. addUsesPermission(" android.permission.INTERNET" );
121+ manifest. addUsesPermission(" android.permission.READ_EXTERNAL_STORAGE" );
160122
161- // To convert back json to apk
123+ // all appName entries created above have the same resource ids
124+ manifest. setApplicationLabel(appNameDefault. getResourceId());
162125
163- ApkJsonEncoder encoder= new ApkJsonEncoder ();
164- ApkModule encodedModule= encoder. scanDirectory(outDir);
126+ ResXmlElement mainActivity = manifest. getOrCreateMainActivity(" android.app.Activity" );
127+ ResXmlAttribute labelAttribute = mainActivity
128+ .getOrCreateAndroidAttribute(AndroidManifestBlock . NAME_label , AndroidManifestBlock . ID_label );
129+ labelAttribute. setValueAsString(" Hello World" );
165130
166- File outApk= new File (" test_out_re-encoded.apk" );
167- encodedModule. writeApk(outApk);
131+ // Android os requires at least one dex file on base apk
132+ ByteInputSource dummyDex = new ByteInputSource (new byte [0 ], " classes.dex" );
133+ apkModule. add(dummyDex);
168134
169- System . out. println(" Created apk: " + outApk);
135+ File outFile = new File (" test_out.apk" );
136+ apkModule. writeApk(outFile);
137+ // Sign and install
170138 }
171-
139+ }
172140```
173141</details >
174142
0 commit comments