From 07fe4a73e7c14576237bb4e621fccfb598af48d2 Mon Sep 17 00:00:00 2001 From: REAndroid Date: Mon, 27 Feb 2023 12:36:52 -0500 Subject: [PATCH] implement ResFile remove method --- .../java/com/reandroid/apk/ApkModule.java | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/reandroid/apk/ApkModule.java b/src/main/java/com/reandroid/apk/ApkModule.java index c1dd959..0b81e88 100644 --- a/src/main/java/com/reandroid/apk/ApkModule.java +++ b/src/main/java/com/reandroid/apk/ApkModule.java @@ -21,10 +21,12 @@ import com.reandroid.arsc.chunk.Chunk; import com.reandroid.arsc.chunk.PackageBlock; import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; +import com.reandroid.arsc.container.SpecTypePair; import com.reandroid.arsc.group.StringGroup; import com.reandroid.arsc.item.TableString; import com.reandroid.arsc.pool.TableStringPool; import com.reandroid.arsc.value.Entry; +import com.reandroid.arsc.value.ResConfig; import java.io.File; import java.io.IOException; @@ -46,6 +48,42 @@ public class ApkModule { this.mUncompressedFiles=new UncompressedFiles(); this.mUncompressedFiles.addPath(apkArchive); } + public void removeResFilesWithEntry(int resourceId) throws IOException { + removeResFilesWithEntry(resourceId, null, true); + } + public void removeResFilesWithEntry(int resourceId, ResConfig resConfig, boolean trimEntryArray) throws IOException { + List removedList = removeResFiles(resourceId, resConfig); + SpecTypePair specTypePair = null; + for(Entry entry:removedList){ + if(entry == null || entry.isNull()){ + continue; + } + if(trimEntryArray && specTypePair==null){ + specTypePair = entry.getTypeBlock().getParentSpecTypePair(); + } + entry.setNull(true); + } + if(specTypePair!=null){ + specTypePair.removeNullEntries(resourceId); + } + } + public List removeResFiles(int resourceId) throws IOException { + return removeResFiles(resourceId, null); + } + public List removeResFiles(int resourceId, ResConfig resConfig) throws IOException { + List results = new ArrayList<>(); + if(resourceId == 0 && resConfig==null){ + return results; + } + List resFileList = listResFiles(resourceId, resConfig); + APKArchive archive = getApkArchive(); + for(ResFile resFile:resFileList){ + results.addAll(resFile.getEntryList()); + String path = resFile.getFilePath(); + archive.remove(path); + } + return results; + } public List listDexFiles(){ List results=new ArrayList<>(); for(InputSource source:getApkArchive().listInputSources()){ @@ -170,6 +208,9 @@ public class ApkModule { getTableBlock().refresh(); } public List listResFiles() throws IOException { + return listResFiles(0, null); + } + public List listResFiles(int resourceId, ResConfig resConfig) throws IOException { List results=new ArrayList<>(); TableBlock tableBlock=getTableBlock(); TableStringPool stringPool= tableBlock.getTableStringPool(); @@ -180,16 +221,36 @@ public class ApkModule { continue; } for(TableString tableString:groupTableString.listItems()){ - List entryList = tableString.listReferencedResValueEntries(); + List entryList = filterResFileEntries( + tableString.listReferencedResValueEntries(), resourceId, resConfig); if(entryList.size()==0){ continue; } - ResFile resFile=new ResFile(inputSource, entryList); + ResFile resFile = new ResFile(inputSource, entryList); results.add(resFile); } } return results; } + private List filterResFileEntries(List entryList, int resourceId, ResConfig resConfig){ + if(resourceId == 0 && resConfig == null || entryList.size()==0){ + return entryList; + } + List results = new ArrayList<>(); + for(Entry entry:entryList){ + if(entry==null || entry.isNull()){ + continue; + } + if(resourceId!=0 && resourceId!=entry.getResourceId()){ + continue; + } + if(resConfig!=null && !resConfig.equals(entry.getResConfig())){ + continue; + } + results.add(entry); + } + return results; + } public String getPackageName() throws IOException { if(hasAndroidManifestBlock()){ return getAndroidManifestBlock().getPackageName();