This commit is contained in:
REAndroid 2022-12-11 09:42:05 -05:00
parent 661073d9b4
commit b75cb1f163
18 changed files with 298 additions and 46 deletions

View File

@ -2,10 +2,93 @@
## Android binary resources read/write library ## Android binary resources read/write library
```java ```java
import com.reandroid.lib.arsc.chunk.TableBlock; import com.reandroid.lib.arsc.chunk.TableBlock;
import com.reandroid.lib.arsc.io.BlockReader; import com.reandroid.lib.arsc.chunk.PackageBlock;
import com.reandroid.lib.arsc.chunk.xml.AndroidManifestBlock;
import com.reandroid.lib.arsc.chunk.xml.ResXmlElement;
import com.reandroid.lib.arsc.chunk.xml.ResXmlAttribute;
public static void example() throws IOException{ public static void exampleManifest() throws IOException{
File inFile=new File("AndroidManifest.xml");
// *** Loading AndroidManifest ***
AndroidManifestBlock manifestBlock = AndroidManifestBlock.load(inFile);
System.out.println("Package name: "+manifestBlock.getPackageName());
List<String> usesPermissionList = manifestBlock.getUsesPermissions();
for(String usesPermission:usesPermissionList){
System.out.println("Uses permission: "+usesPermission);
}
// *** Modifying AndroidManifest ***
// Change package name
manifestBlock.setPackageName("com.new.package-name");
// Add uses-permission
manifestBlock.addUsesPermission("android.permission.WRITE_EXTERNAL_STORAGE");
// Modify version code
manifestBlock.setVersionCode(904);
// Modify version name
manifestBlock.setVersionName("9.0.4");
// Modify xml attribute
List<ResXmlElement> activityList = manifestBlock.listActivities();
for(ResXmlElement activityElement:activityList){
ResXmlAttribute attributeName = activityElement.searchAttributeByResourceId(AndroidManifestBlock.ID_name);
System.out.println("Old activity name: "+attributeName.getValueAsString());
attributeName.setValueAsString("com.app.MyActivity");
System.out.println("New activity name: "+attributeName.getValueAsString());
break;
}
// Refresh to re-calculate offsets
manifestBlock.refresh();
// Save
File outFile=new File("AndroidManifest_out.xml");
manifestBlock.writeBytes(outFile);
System.out.println("Saved: "+outFile);
}
```
```java
public static void exampleResourceTable() throws IOException{
File inFile=new File("resources.arsc");
// *** Loading resource table ***
TableBlock tableBlock=TableBlock.load(inFile);
Collection<PackageBlock> packageBlockList=tableBlock.listPackages();
System.out.println("Packages count = "+packageBlockList.size());
for(PackageBlock packageBlock:packageBlockList){
System.out.println("Package id = "+packageBlock.getId()
+", name = "+packageBlock.getName());
}
// *** Modify resource table
// Change package name
for(PackageBlock packageBlock:packageBlockList){
String name = packageBlock.getName();
String newName = name + ".new-name";
packageBlock.setName(newName);
}
// Refresh to re-calculate offsets
tableBlock.refresh();
// Save
File outFile=new File("resources_out.arsc");
tableBlock.writeBytes(outFile);
System.out.println("Saved: "+outFile);
}
```
```java
public static void exampleLoadApk() throws IOException{
File inFile=new File("test.apk"); File inFile=new File("test.apk");
File outDir=new File("test_out"); File outDir=new File("test_out");
@ -15,7 +98,7 @@
outDir=decoder.writeToDirectory(outDir); outDir=decoder.writeToDirectory(outDir);
System.out.println("Decoded to: "+outDir); System.out.println("Decoded to: "+outDir);
// You can do any logical modification on any json files // You can do any logical modification on any json files here
// To convert back json to apk // To convert back json to apk
@ -26,6 +109,8 @@
encodedModule.writeApk(outApk); encodedModule.writeApk(outApk);
System.out.println("Created apk: "+outApk); System.out.println("Created apk: "+outApk);
} }
``` ```
[Check implementation on APKEditor](https://github.com/REAndroid/APKEditor)

View File

@ -2,7 +2,7 @@
apply plugin: 'java-library' apply plugin: 'java-library'
group 'com.reandroid.lib.arsc' group 'com.reandroid.lib.arsc'
version '1.0.3' version '1.0.4'
java { java {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8

View File

@ -0,0 +1,7 @@
package com.reandroid.lib.apk;
public interface APKLogger {
void logMessage(String msg);
void logError(String msg, Throwable tr);
void logVerbose(String msg);
}

View File

@ -14,6 +14,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.*;
import java.util.zip.ZipEntry;
public class ApkModule { public class ApkModule {
private final String moduleName; private final String moduleName;
@ -22,6 +23,7 @@ public class ApkModule {
private TableBlock mTableBlock; private TableBlock mTableBlock;
private AndroidManifestBlock mManifestBlock; private AndroidManifestBlock mManifestBlock;
private final UncompressedFiles mUncompressedFiles; private final UncompressedFiles mUncompressedFiles;
private APKLogger apkLogger;
ApkModule(String moduleName, APKArchive apkArchive){ ApkModule(String moduleName, APKArchive apkArchive){
this.moduleName=moduleName; this.moduleName=moduleName;
this.apkArchive=apkArchive; this.apkArchive=apkArchive;
@ -72,6 +74,34 @@ public class ApkModule {
public void removeDir(String dirName){ public void removeDir(String dirName){
getApkArchive().removeDir(dirName); getApkArchive().removeDir(dirName);
} }
public void validateResourcesDir() throws IOException {
List<ResFile> resFileList = listResFiles();
Set<String> existPaths=new HashSet<>();
List<InputSource> sourceList = getApkArchive().listInputSources();
for(InputSource inputSource:sourceList){
existPaths.add(inputSource.getAlias());
}
for(ResFile resFile:resFileList){
String path=resFile.getFilePath();
String pathNew=resFile.validateTypeDirectoryName();
if(pathNew==null || pathNew.equals(path)){
continue;
}
if(existPaths.contains(pathNew)){
continue;
}
existPaths.remove(path);
existPaths.add(pathNew);
resFile.setFilePath(pathNew);
if(resFile.getInputSource().getMethod() == ZipEntry.STORED){
getUncompressedFiles().replacePath(path, pathNew);
}
logVerbose("Dir validated: '"+path+"' -> '"+pathNew+"'");
}
TableStringPool stringPool= getTableBlock().getTableStringPool();
stringPool.refreshUniqueIdMap();
getTableBlock().refresh();
}
public void setResourcesRootDir(String dirName) throws IOException { public void setResourcesRootDir(String dirName) throws IOException {
List<ResFile> resFileList = listResFiles(); List<ResFile> resFileList = listResFiles();
Set<String> existPaths=new HashSet<>(); Set<String> existPaths=new HashSet<>();
@ -88,9 +118,14 @@ public class ApkModule {
existPaths.remove(path); existPaths.remove(path);
existPaths.add(pathNew); existPaths.add(pathNew);
resFile.setFilePath(pathNew); resFile.setFilePath(pathNew);
if(resFile.getInputSource().getMethod() == ZipEntry.STORED){
getUncompressedFiles().replacePath(path, pathNew);
}
logVerbose("Root changed: '"+path+"' -> '"+pathNew+"'");
} }
TableStringPool stringPool= getTableBlock().getTableStringPool(); TableStringPool stringPool= getTableBlock().getTableStringPool();
stringPool.refreshUniqueIdMap(); stringPool.refreshUniqueIdMap();
getTableBlock().refresh();
} }
public List<ResFile> listResFiles() throws IOException { public List<ResFile> listResFiles() throws IOException {
List<ResFile> results=new ArrayList<>(); List<ResFile> results=new ArrayList<>();
@ -123,7 +158,7 @@ public class ApkModule {
if(pkg==null){ if(pkg==null){
return null; return null;
} }
return pkg.getPackageName(); return pkg.getName();
} }
public void setPackageName(String name) throws IOException { public void setPackageName(String name) throws IOException {
String old=getPackageName(); String old=getPackageName();
@ -137,13 +172,13 @@ public class ApkModule {
PackageArray pkgArray = tableBlock.getPackageArray(); PackageArray pkgArray = tableBlock.getPackageArray();
for(PackageBlock pkg:pkgArray.listItems()){ for(PackageBlock pkg:pkgArray.listItems()){
if(pkgArray.childesCount()==1){ if(pkgArray.childesCount()==1){
pkg.setPackageName(name); pkg.setName(name);
continue; continue;
} }
String pkgName=pkg.getPackageName(); String pkgName=pkg.getName();
if(pkgName.startsWith(old)){ if(pkgName.startsWith(old)){
pkgName=pkgName.replace(old, name); pkgName=pkgName.replace(old, name);
pkg.setPackageName(pkgName); pkg.setName(pkgName);
} }
} }
} }
@ -211,6 +246,24 @@ public class ApkModule {
this.loadDefaultFramework = loadDefaultFramework; this.loadDefaultFramework = loadDefaultFramework;
} }
public void setAPKLogger(APKLogger logger) {
this.apkLogger = logger;
}
private void logMessage(String msg) {
if(apkLogger!=null){
apkLogger.logMessage(msg);
}
}
private void logError(String msg, Throwable tr) {
if(apkLogger!=null){
apkLogger.logError(msg, tr);
}
}
private void logVerbose(String msg) {
if(apkLogger!=null){
apkLogger.logVerbose(msg);
}
}
public static ApkModule loadApkFile(File apkFile) throws IOException { public static ApkModule loadApkFile(File apkFile) throws IOException {
return loadApkFile(apkFile, ApkUtil.DEF_MODULE_NAME); return loadApkFile(apkFile, ApkUtil.DEF_MODULE_NAME);
} }

View File

@ -1,6 +1,7 @@
package com.reandroid.lib.apk; package com.reandroid.lib.apk;
import com.reandroid.archive.InputSource; import com.reandroid.archive.InputSource;
import com.reandroid.lib.arsc.chunk.TypeBlock;
import com.reandroid.lib.arsc.chunk.xml.ResXmlBlock; import com.reandroid.lib.arsc.chunk.xml.ResXmlBlock;
import com.reandroid.lib.arsc.value.EntryBlock; import com.reandroid.lib.arsc.value.EntryBlock;
import com.reandroid.lib.json.JSONObject; import com.reandroid.lib.json.JSONObject;
@ -18,6 +19,51 @@ public class ResFile {
this.inputSource=inputSource; this.inputSource=inputSource;
this.entryBlockList=entryBlockList; this.entryBlockList=entryBlockList;
} }
public String validateTypeDirectoryName(){
EntryBlock entryBlock=pickOne();
if(entryBlock==null){
return null;
}
String path=getFilePath();
String root="";
int i=path.indexOf('/');
if(i>0){
i++;
root=path.substring(0, i);
path=path.substring(i);
}
String name=path;
i=path.lastIndexOf('/');
if(i>0){
i++;
name=path.substring(i);
}
TypeBlock typeBlock=entryBlock.getTypeBlock();
String typeName=typeBlock.getTypeName()+typeBlock.getResConfig().getQualifiers();
return root+typeName+"/"+name;
}
private EntryBlock pickOne(){
List<EntryBlock> entryList = entryBlockList;
if(entryList.size()==0){
return null;
}
for(EntryBlock entryBlock:entryList){
if(!entryBlock.isNull() && entryBlock.isDefault()){
return entryBlock;
}
}
for(EntryBlock entryBlock:entryList){
if(!entryBlock.isNull()){
return entryBlock;
}
}
for(EntryBlock entryBlock:entryList){
if(entryBlock.isDefault()){
return entryBlock;
}
}
return entryList.get(0);
}
public String getFilePath(){ public String getFilePath(){
return getInputSource().getAlias(); return getInputSource().getAlias();
} }

View File

@ -243,7 +243,7 @@ public class ResourceIds {
return; return;
} }
if(pkg.id!=this.id){ if(pkg.id!=this.id){
throw new IllegalArgumentException("Different package id: "+this.id+"!="+pkg.id); throw new DuplicateException("Different package id: "+this.id+"!="+pkg.id);
} }
if(pkg.name!=null){ if(pkg.name!=null){
this.name = pkg.name; this.name = pkg.name;
@ -277,7 +277,7 @@ public class ResourceIds {
return; return;
} }
if(entry.getPackageId()!=this.id){ if(entry.getPackageId()!=this.id){
throw new IllegalArgumentException("Different package id: "+entry); throw new DuplicateException("Different package id: "+entry);
} }
byte typeId=entry.getTypeId(); byte typeId=entry.getTypeId();
Type type=typeMap.get(typeId); Type type=typeMap.get(typeId);
@ -400,7 +400,7 @@ public class ResourceIds {
return; return;
} }
if(this.id!= type.id){ if(this.id!= type.id){
throw new IllegalArgumentException("Different type ids: "+id+"!="+type.id); throw new DuplicateException("Different type ids: "+id+"!="+type.id);
} }
if(type.name!=null){ if(type.name!=null){
this.name=type.name; this.name=type.name;
@ -427,7 +427,7 @@ public class ResourceIds {
return; return;
} }
if(entry.getTypeId()!=this.id){ if(entry.getTypeId()!=this.id){
throw new IllegalArgumentException("Different type id: "+entry); throw new DuplicateException("Different type id: "+entry);
} }
short key=entry.getEntryId(); short key=entry.getEntryId();
Entry exist=entryMap.get(key); Entry exist=entryMap.get(key);
@ -435,7 +435,7 @@ public class ResourceIds {
if(Objects.equals(exist.name, entry.name)){ if(Objects.equals(exist.name, entry.name)){
return; return;
} }
throw new IllegalArgumentException("Duplicate entry exist: "+exist+", entry: "+entry); throw new DuplicateException("Duplicate entry exist: "+exist+", entry: "+entry);
} }
if(name == null){ if(name == null){
this.name = entry.typeName; this.name = entry.typeName;
@ -652,10 +652,10 @@ public class ResourceIds {
matcher= pattern.matcher(element); matcher= pattern.matcher(element);
} }
if(id==0){ if(id==0){
throw new IllegalArgumentException("Missing id: "+xmlElement); throw new DuplicateException("Missing id: "+xmlElement);
} }
if(name==null){ if(name==null){
throw new IllegalArgumentException("Missing name: "+xmlElement); throw new DuplicateException("Missing name: "+xmlElement);
} }
return new Entry(id, type, name); return new Entry(id, type, name);
} }
@ -684,6 +684,17 @@ public class ResourceIds {
| (entryId & 0xffff); | (entryId & 0xffff);
} }
} }
public static class DuplicateException extends IllegalArgumentException{
public DuplicateException(String message){
super(message);
}
public DuplicateException(String message, final Throwable cause) {
super(message, cause);
}
public DuplicateException(Throwable cause) {
super(cause.getMessage(), cause);
}
}
public static final String JSON_FILE_NAME ="resource-ids.json"; public static final String JSON_FILE_NAME ="resource-ids.json";
} }

View File

@ -27,7 +27,7 @@ public class TableBlockJson {
File infoFile=new File(pkgDir, PackageBlock.JSON_FILE_NAME); File infoFile=new File(pkgDir, PackageBlock.JSON_FILE_NAME);
JSONObject jsonObject=new JSONObject(); JSONObject jsonObject=new JSONObject();
jsonObject.put(PackageBlock.NAME_package_id, packageBlock.getId()); jsonObject.put(PackageBlock.NAME_package_id, packageBlock.getId());
jsonObject.put(PackageBlock.NAME_package_name, packageBlock.getPackageName()); jsonObject.put(PackageBlock.NAME_package_name, packageBlock.getName());
jsonObject.write(infoFile); jsonObject.write(infoFile);
for(SpecTypePair specTypePair: packageBlock.listAllSpecTypePair()){ for(SpecTypePair specTypePair: packageBlock.listAllSpecTypePair()){
for(TypeBlock typeBlock:specTypePair.getTypeBlockArray().listItems()){ for(TypeBlock typeBlock:specTypePair.getTypeBlockArray().listItems()){
@ -52,7 +52,7 @@ public class TableBlockJson {
private String getDirName(PackageBlock packageBlock){ private String getDirName(PackageBlock packageBlock){
StringBuilder builder=new StringBuilder(); StringBuilder builder=new StringBuilder();
builder.append(String.format("0x%02x", packageBlock.getId())); builder.append(String.format("0x%02x", packageBlock.getId()));
String name= packageBlock.getPackageName(); String name= packageBlock.getName();
if(name!=null){ if(name!=null){
builder.append('-'); builder.append('-');
builder.append(name); builder.append(name);

View File

@ -70,6 +70,10 @@ public class UncompressedFiles implements JSONConvert<JSONObject> {
return mExtensionList.contains(extension.substring(1)); return mExtensionList.contains(extension.substring(1));
} }
public boolean containsPath(String path){ public boolean containsPath(String path){
path=sanitizePath(path);
if(path==null){
return false;
}
return mPathList.contains(path); return mPathList.contains(path);
} }
public void addPath(ZipArchive zipArchive){ public void addPath(ZipArchive zipArchive){
@ -84,15 +88,31 @@ public class UncompressedFiles implements JSONConvert<JSONObject> {
addPath(inputSource.getAlias()); addPath(inputSource.getAlias());
} }
public void addPath(String path){ public void addPath(String path){
if(path==null || path.length()==0){ path=sanitizePath(path);
if(path==null){
return; return;
} }
path=path.replace(File.separatorChar, '/').trim();
while (path.startsWith("/")){
path=path.substring(1);
}
mPathList.add(path); mPathList.add(path);
} }
public void removePath(String path){
path=sanitizePath(path);
if(path==null){
return;
}
mPathList.remove(path);
}
public void replacePath(String path, String rep){
path=sanitizePath(path);
rep=sanitizePath(rep);
if(path==null||rep==null){
return;
}
if(!mPathList.contains(path)){
return;
}
mPathList.remove(path);
mPathList.add(rep);
}
public void addCommonExtensions(){ public void addCommonExtensions(){
for(String ext:COMMON_EXTENSIONS){ for(String ext:COMMON_EXTENSIONS){
addExtension(ext); addExtension(ext);
@ -146,6 +166,19 @@ public class UncompressedFiles implements JSONConvert<JSONObject> {
JSONObject jsonObject=new JSONObject(new FileInputStream(jsonFile)); JSONObject jsonObject=new JSONObject(new FileInputStream(jsonFile));
fromJson(jsonObject); fromJson(jsonObject);
} }
private static String sanitizePath(String path){
if(path==null || path.length()==0){
return null;
}
path=path.replace(File.separatorChar, '/').trim();
while (path.startsWith("/")){
path=path.substring(1);
}
if(path.length()==0){
return null;
}
return path;
}
public static final String JSON_FILE = "uncompressed-files.json"; public static final String JSON_FILE = "uncompressed-files.json";
public static final String NAME_paths = "paths"; public static final String NAME_paths = "paths";
public static final String NAME_extensions = "extensions"; public static final String NAME_extensions = "extensions";

View File

@ -113,8 +113,6 @@ public class PackageBlock extends BaseChunk implements BlockLoad, JSONConvert<JS
public void setName(String name){ public void setName(String name){
mPackageName.set(name); mPackageName.set(name);
} }
public TableBlock getTableBlock(){ public TableBlock getTableBlock(){
Block parent=getParent(); Block parent=getParent();
while(parent!=null){ while(parent!=null){
@ -125,13 +123,6 @@ public class PackageBlock extends BaseChunk implements BlockLoad, JSONConvert<JS
} }
return null; return null;
} }
public String getPackageName(){
return mPackageName.get();
}
public void setPackageName(String name){
mPackageName.set(name);
}
public TypeStringPool getTypeStringPool(){ public TypeStringPool getTypeStringPool(){
return mTypeStringPool; return mTypeStringPool;
} }

View File

@ -143,6 +143,9 @@ public class TableBlock extends BaseChunk implements JSONConvert<JSONObject> {
tableBlock.addFramework(Frameworks.getAndroid()); tableBlock.addFramework(Frameworks.getAndroid());
return tableBlock; return tableBlock;
} }
public static TableBlock load(File file) throws IOException{
return load(new FileInputStream(file));
}
public static TableBlock load(InputStream inputStream) throws IOException{ public static TableBlock load(InputStream inputStream) throws IOException{
TableBlock tableBlock=new TableBlock(); TableBlock tableBlock=new TableBlock();
tableBlock.readBytes(inputStream); tableBlock.readBytes(inputStream);

View File

@ -248,6 +248,16 @@ public class AndroidManifestBlock extends ResXmlBlock{
builder.append("}"); builder.append("}");
return builder.toString(); return builder.toString();
} }
public static boolean isAndroidManifestBlock(ResXmlBlock xmlBlock){
if(xmlBlock==null){
return false;
}
ResXmlElement root = xmlBlock.getResXmlElement();
if(root==null){
return false;
}
return TAG_manifest.equals(root.getTag());
}
public static AndroidManifestBlock load(File file) throws IOException { public static AndroidManifestBlock load(File file) throws IOException {
return load(new FileInputStream(file)); return load(new FileInputStream(file));
} }

View File

@ -23,7 +23,7 @@ public class ResXmlAttribute extends FixedBlockContainer
super(7); super(7);
mNamespaceReference =new IntegerItem(-1); mNamespaceReference =new IntegerItem(-1);
mNameReference =new IntegerItem(); mNameReference =new IntegerItem();
mValueStringReference =new IntegerItem(); mValueStringReference =new IntegerItem(-1);
mNameType=new ShortItem((short) 0x0008); mNameType=new ShortItem((short) 0x0008);
mReserved =new ByteItem(); mReserved =new ByteItem();
mValueTypeByte=new ByteItem(); mValueTypeByte=new ByteItem();
@ -42,7 +42,7 @@ public class ResXmlAttribute extends FixedBlockContainer
int getNamespaceReference(){ int getNamespaceReference(){
return mNamespaceReference.get(); return mNamespaceReference.get();
} }
void setNamespaceReference(int ref){ public void setNamespaceReference(int ref){
mNamespaceReference.set(ref); mNamespaceReference.set(ref);
} }
int getNameReference(){ int getNameReference(){
@ -112,7 +112,7 @@ public class ResXmlAttribute extends FixedBlockContainer
} }
return startNamespace.getPrefix(); return startNamespace.getPrefix();
} }
ResXmlStartNamespace getStartNamespace(){ public ResXmlStartNamespace getStartNamespace(){
ResXmlElement xmlElement=getParentResXmlElement(); ResXmlElement xmlElement=getParentResXmlElement();
if(xmlElement==null){ if(xmlElement==null){
return null; return null;
@ -131,6 +131,7 @@ public class ResXmlAttribute extends FixedBlockContainer
setValueStringReference(ref); setValueStringReference(ref);
if(getValueType()==ValueType.STRING){ if(getValueType()==ValueType.STRING){
setRawValue(ref); setRawValue(ref);
setValueStringReference(ref);
} }
return resXmlString; return resXmlString;
} }
@ -280,7 +281,7 @@ public class ResXmlAttribute extends FixedBlockContainer
} }
public void setValueAsBoolean(boolean val){ public void setValueAsBoolean(boolean val){
setValueType(ValueType.INT_BOOLEAN); setValueType(ValueType.INT_BOOLEAN);
int ref=val?0xffff:0; int ref=val?0xffffffff:0;
setRawValue(ref); setRawValue(ref);
setValueStringReference(-1); setValueStringReference(-1);
} }

View File

@ -149,7 +149,7 @@ public class ResXmlElement extends FixedBlockContainer implements JSONConvert<JS
} }
return null; return null;
} }
public Collection<ResXmlAttribute> listResXmlAttributes(){ public Collection<ResXmlAttribute> listAttributes(){
ResXmlStartElement startElement=getStartElement(); ResXmlStartElement startElement=getStartElement();
if(startElement!=null){ if(startElement!=null){
return startElement.listResXmlAttributes(); return startElement.listResXmlAttributes();

View File

@ -31,6 +31,14 @@ public class ResXmlStartElement extends BaseXmlChunk {
addChild(mClassAttribute); addChild(mClassAttribute);
addChild(mAttributeArray); addChild(mAttributeArray);
} }
public ResXmlAttribute getAttribute(int resourceId){
for(ResXmlAttribute attribute:listResXmlAttributes()){
if(resourceId==attribute.getNameResourceID()){
return attribute;
}
}
return null;
}
public ResXmlAttribute getAttribute(String uri, String name){ public ResXmlAttribute getAttribute(String uri, String name){
if(name==null){ if(name==null){
return null; return null;

View File

@ -25,8 +25,8 @@ public class ValueDecoder {
} }
String prefix=null; String prefix=null;
if(currentPackage!=null){ if(currentPackage!=null){
String name=currentPackage.getPackageName(); String name=currentPackage.getName();
String other=entryBlock.getPackageBlock().getPackageName(); String other=entryBlock.getPackageBlock().getName();
if(!name.equals(other)){ if(!name.equals(other)){
prefix=other+":"; prefix=other+":";
} }
@ -67,7 +67,7 @@ public class ValueDecoder {
is_attribute=true; is_attribute=true;
} }
if(is_reference || is_attribute){ if(is_reference || is_attribute){
String ref=buildReferenceValue(store, valueType, currentPackage.getPackageName(), data); String ref=buildReferenceValue(store, valueType, currentPackage.getName(), data);
if(ref!=null){ if(ref!=null){
return ref; return ref;
} }
@ -286,7 +286,7 @@ public class ValueDecoder {
return null; return null;
} }
for(PackageBlock packageBlock:allPkg){ for(PackageBlock packageBlock:allPkg){
String name=packageBlock.getPackageName(); String name=packageBlock.getName();
if(name!=null){ if(name!=null){
return name; return name;
} }
@ -307,7 +307,7 @@ public class ValueDecoder {
if(packageBlock==null){ if(packageBlock==null){
return null; return null;
} }
return packageBlock.getPackageName(); return packageBlock.getName();
} }
private static EntryGroup searchEntryGroup(EntryStore store, EntryBlock entryBlock, int resourceId){ private static EntryGroup searchEntryGroup(EntryStore store, EntryBlock entryBlock, int resourceId){
EntryGroup entryGroup=searchEntryGroup(entryBlock, resourceId); EntryGroup entryGroup=searchEntryGroup(entryBlock, resourceId);

View File

@ -3,6 +3,7 @@ package com.reandroid.lib.arsc.io;
import com.reandroid.lib.arsc.header.HeaderBlock; import com.reandroid.lib.arsc.header.HeaderBlock;
import java.io.*; import java.io.*;
import java.util.zip.ZipInputStream;
public class BlockReader extends InputStream { public class BlockReader extends InputStream {
@ -317,6 +318,9 @@ public class BlockReader extends InputStream {
while((len=in.read(buff))>0){ while((len=in.read(buff))>0){
result=add(result, buff, len); result=add(result, buff, len);
} }
if(!(in instanceof ZipInputStream)){
in.close();
}
return result; return result;
} }
private static byte[] add(byte[] arr1, byte[] arr2, int len){ private static byte[] add(byte[] arr1, byte[] arr2, int len){
@ -331,7 +335,7 @@ public class BlockReader extends InputStream {
} }
public static HeaderBlock readHeaderBlock(InputStream inputStream) throws IOException{ public static HeaderBlock readHeaderBlock(InputStream inputStream) throws IOException{
byte[] buffer=new byte[8]; byte[] buffer=new byte[8];
inputStream.read(buffer); inputStream.read(buffer, 0, 8);
inputStream.close(); inputStream.close();
BlockReader reader=new BlockReader(buffer); BlockReader reader=new BlockReader(buffer);
return reader.readHeaderBlock(); return reader.readHeaderBlock();

View File

@ -273,7 +273,7 @@ public class FrameworkTable extends TableBlock {
for(PackageBlock packageBlock:allPkg){ for(PackageBlock packageBlock:allPkg){
builder.append("\n "); builder.append("\n ");
builder.append(String.format("0x%02x", packageBlock.getId())); builder.append(String.format("0x%02x", packageBlock.getId()));
builder.append(":").append(packageBlock.getPackageName()); builder.append(":").append(packageBlock.getName());
} }
return builder.toString(); return builder.toString();
} }

View File

@ -333,7 +333,7 @@ public class EntryBlock extends Block implements JSONConvert<JSONObject> {
if(packageBlock==null){ if(packageBlock==null){
return null; return null;
} }
return packageBlock.getPackageName(); return packageBlock.getName();
} }
public SpecString getSpecString(){ public SpecString getSpecString(){
PackageBlock packageBlock=getPackageBlock(); PackageBlock packageBlock=getPackageBlock();