Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More info functions: locales, languages, configurations, strings #132

Merged
merged 1 commit into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 70 additions & 10 deletions src/main/java/com/reandroid/apkeditor/info/Info.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,16 @@
import com.reandroid.arsc.coder.ReferenceString;
import com.reandroid.arsc.coder.ValueCoder;
import com.reandroid.arsc.model.ResourceEntry;
import com.reandroid.arsc.value.*;
import com.reandroid.dex.model.DexDirectory;
import com.reandroid.utils.CompareUtil;
import com.reandroid.utils.HexUtil;
import com.reandroid.arsc.value.AttributeDataFormat;
import com.reandroid.arsc.value.Entry;
import com.reandroid.arsc.value.ResValue;
import com.reandroid.arsc.value.ValueType;
import com.reandroid.utils.collection.CollectionUtil;
import com.reandroid.utils.collection.ComputeIterator;

import java.io.*;
import java.util.*;
import java.util.function.Function;

public class Info extends CommandExecutor<InfoOptions> {
private InfoWriter mInfoWriter;
Expand Down Expand Up @@ -100,8 +99,12 @@ private void print(ApkModule apkModule) throws IOException {

printXmlTree(apkModule);
printXmlStrings(apkModule);
printStrings(apkModule);
listFiles(apkModule);
listXmlFiles(apkModule);
printConfigurations(apkModule);
printLanguages(apkModule);
printLocales(apkModule);
}
private void printSourceFile() throws IOException {
InfoOptions options = getOptions();
Expand Down Expand Up @@ -357,15 +360,25 @@ private void printAppClass(ApkModule apkModule) throws IOException {
}
private void printXmlStrings(ApkModule apkModule) throws IOException {
InfoOptions options = getOptions();
String xmlStrings = options.xmlStrings;
if (xmlStrings == null) {
List<String> xmlStrings = options.xmlStrings;
if (xmlStrings.isEmpty()) {
return;
}
InfoWriter infoWriter = getInfoWriter();
ResXmlDocument document = apkModule.loadResXmlDocument(xmlStrings);
document.setApkFile(null);
document.setPackageBlock(null);
infoWriter.writeStringPool(xmlStrings, document.getStringPool());
for (String path : xmlStrings) {
ResXmlDocument document = apkModule.loadResXmlDocument(path);
document.setApkFile(null);
document.setPackageBlock(null);
infoWriter.writeStringPool(path, document.getStringPool());
}
}
private void printStrings(ApkModule apkModule) throws IOException {
InfoOptions options = getOptions();
if (!options.strings || !apkModule.hasTableBlock()) {
return;
}
InfoWriter infoWriter = getInfoWriter();
infoWriter.writeStringPool(TableBlock.FILE_NAME, apkModule.getTableBlock().getStringPool());
}
private void printXmlTree(ApkModule apkModule) throws IOException {
InfoOptions options = getOptions();
Expand Down Expand Up @@ -405,6 +418,53 @@ private void listXmlFiles(ApkModule apkModule) throws IOException {
}
getInfoWriter().writeArray("CompiledXmlFiles", names.toArray(new String[0]));
}
private void printConfigurations(ApkModule apkModule) throws IOException {
InfoOptions options = getOptions();
if (!options.configurations || !apkModule.hasTableBlock()) {
return;
}
Iterator<ResConfig> iterator = apkModule.getTableBlock().getResConfigs();
List<String> qualifiers = CollectionUtil.toUniqueList(
ComputeIterator.of(iterator, config -> {
String qualifier = config.getQualifiers();
if (qualifier.length() != 0) {
qualifier = qualifier.substring(1);
}
return qualifier;
}));

qualifiers.sort(CompareUtil.getComparableComparator());

getInfoWriter().writeArray("configurations", qualifiers.toArray(new String[0]));
}
private void printLanguages(ApkModule apkModule) throws IOException {
InfoOptions options = getOptions();
if (!options.languages || !apkModule.hasTableBlock()) {
return;
}
Iterator<ResConfig> iterator = apkModule.getTableBlock().getResConfigs();
List<String> languages = CollectionUtil.toUniqueList(
ComputeIterator.of(iterator, ResConfig::getLanguage));

languages.sort(CompareUtil.getComparableComparator());

getInfoWriter().writeArray("languages", languages.toArray(new String[0]));
}
private void printLocales(ApkModule apkModule) throws IOException {
InfoOptions options = getOptions();
if (!options.locales || !apkModule.hasTableBlock()) {
return;
}
Iterator<ResConfig> iterator = apkModule.getTableBlock().getResConfigs();
List<String> locales = CollectionUtil.toUniqueList(
ComputeIterator.of(iterator, ResConfig::getLocale));

locales.remove("");

locales.sort(CompareUtil.getComparableComparator());

getInfoWriter().writeArray("locales", locales.toArray(new String[0]));
}
private String getValueOfName(ResXmlElement element){
ResXmlAttribute attribute = element
.searchAttributeByResourceId(AndroidManifest.ID_name);
Expand Down
41 changes: 38 additions & 3 deletions src/main/java/com/reandroid/apkeditor/info/InfoOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,51 +37,85 @@ public class InfoOptions extends OptionsWithFramework {

@ChoiceArg(name = "-t", description = "info_print_types", values = {TYPE_TEXT, TYPE_JSON, TYPE_XML})
public String type = TYPE_TEXT;

@OptionArg(name = "-v", description = "info_verbose_mode", flag = true)
public boolean verbose = false;

@OptionArg(name = "-package", description = "info_package_name", flag = true)
public boolean packageName = false;

@OptionArg(name = "-version-code", description = "info_app_version_code", flag = true)
public boolean versionCode = false;

@OptionArg(name = "-version-name", description = "info_app_version_name", flag = true)
public boolean versionName = false;

@OptionArg(name = "-min-sdk-version", description = "info_min_sdk_version", flag = true)
public boolean minSdkVersion = false;

@OptionArg(name = "-target-sdk-version", description = "info_target_sdk_version", flag = true)
public boolean targetSdkVersion = false;

@OptionArg(name = "-app-name", description = "info_app_name", flag = true)
public boolean appName = false;

@OptionArg(name = "-app-icon", description = "info_app_icon", flag = true)
public boolean appIcon = false;

@OptionArg(name = "-app-round-icon", description = "info_app_icon_round", flag = true)
public boolean appRoundIcon = false;

@OptionArg(name = "-permissions", description = "info_permissions", flag = true)
public boolean permissions = false;

@OptionArg(name = "-app-class", description = "info_app_class_name", flag = true)
public boolean appClass = false;

@OptionArg(name = "-activities", description = "info_activities", flag = true)
public boolean activities = false;

@OptionArg(name = "-res", description = "info_res")
public final List<String> resList = new ArrayList<>();

@OptionArg(name = "-resources", description = "info_resources", flag = true)
public boolean resources = false;

@OptionArg(name = "-filter-type", description = "info_filter_type")
public final List<String> typeFilterList = new ArrayList<>();

@OptionArg(name = "-dex", description = "info_dex", flag = true)
public boolean dex = false;

@OptionArg(name = "-signatures", description = "info_signatures", flag = true)
public boolean signatures = false;

@OptionArg(name = "-signatures-base64", description = "info_signatures_base64", flag = true)
public boolean signatures_base64 = false;

@OptionArg(name = "-xmlstrings", description = "info_xml_strings")
public String xmlStrings;
public List<String> xmlStrings = new ArrayList<>();

@OptionArg(name = "-strings", description = "info_strings", flag = true)
public boolean strings = false;

@OptionArg(name = "-xmltree", description = "info_xml_tree")
public final List<String> xmlTree = new ArrayList<>();

@OptionArg(name = "-list-files", description = "info_list_files", flag = true)
public boolean listFiles = false;

@OptionArg(name = "-list-xml-files", description = "info_list_xml_files", flag = true)
public boolean listXmlFiles = false;

@OptionArg(name = "-configurations", description = "info_configurations", flag = true)
public boolean configurations = false;

@OptionArg(name = "-languages", description = "info_languages", flag = true)
public boolean languages = false;

@OptionArg(name = "-locales", description = "info_locales", flag = true)
public boolean locales = false;

public InfoOptions(){
super();
}
Expand Down Expand Up @@ -148,8 +182,9 @@ private boolean isDefault() {
boolean flagsChanged = activities || appClass || appIcon || appName || appRoundIcon ||
dex || minSdkVersion || packageName || permissions || targetSdkVersion ||
resources || signatures || signatures_base64 || versionCode || versionName ||
listFiles || listXmlFiles || xmlStrings != null;
listFiles || listXmlFiles || configurations || languages || locales || strings;

return !flagsChanged && resList.isEmpty() && typeFilterList.isEmpty() && xmlTree.isEmpty();
return !flagsChanged && resList.isEmpty() && typeFilterList.isEmpty() &&
xmlTree.isEmpty() && xmlStrings.isEmpty();
}
}
6 changes: 5 additions & 1 deletion src/main/resources/strings/strings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ info_example_2=[Specify output and type]\n java -jar APKEditor.jar info -i path
info_example_3=[Print only specific type]\n java -jar APKEditor.jar info -i path/input.apk -resources -filter-type drawable
info_filter_type=Prints only the specified resource type names\n *This applies only when flag '-resources' used.\n *Can be multiple.
info_invalid_output_extension=Invalid file extension! Expected '%s', '%s'
info_configurations=Print the configurations in the APK.
info_languages=Print the languages in the APK.
info_locales=Print the locales in the APK.
info_list_files=List files inside apk.
info_list_xml_files=List compiled xml files inside apk.
info_min_sdk_version=Minimum SDK version.
Expand All @@ -74,10 +77,11 @@ info_res=Prints resource entries specified by either of\:\n 1) Hex or decimal r
info_resources=Prints all resources
info_signatures=Prints signature information.
info_signatures_base64=Prints signature information with base64 certificates.
info_strings=Print the contents of the resource table string pool in the APK.
info_target_sdk_version=Target SDK version.
info_verbose_mode=Verbose mode.
info_xml_tree=Prints the compiled xmls in the given assets.\n *Can be multiple
info_xml_strings=Print the strings of the given compiled xml assets.
info_xml_strings=Print the strings of the given compiled xml assets.\n *Can be multiple
input_path=Input path.
invalid_sig_parameter_combination=Invalid parameter combination!\nSignatures directory provided but missing: -t sig
invalid_type_format=Invalid <%s> string '%s'
Expand Down