diff --git a/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java b/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java index 1bd5f7b5..88d27aa2 100644 --- a/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java +++ b/brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java @@ -230,6 +230,9 @@ public class Main { if (cli.hasOption("use-aapt2")) { apkOptions.useAapt2 = true; } + if (cli.hasOption("api") || cli.hasOption("api-level")) { + apkOptions.forceApi = Integer.parseInt(cli.getOptionValue("api")); + } if (cli.hasOption("o") || cli.hasOption("output")) { outFile = new File(cli.getOptionValue("o")); } else { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java index ae52459b..c2499924 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java @@ -416,7 +416,7 @@ public class Androlib { if (apkOptions.forceBuildAll || isModified(smaliDir, dex)) { LOGGER.info("Smaling " + folder + " folder into " + filename + "..."); dex.delete(); - SmaliBuilder.build(smaliDir, dex, mMinSdkVersion); + SmaliBuilder.build(smaliDir, dex, apkOptions.forceApi > 0 ? apkOptions.forceApi : mMinSdkVersion); } return true; } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java index b1ddb4a2..9fff0bd2 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkOptions.java @@ -29,6 +29,7 @@ public class ApkOptions { public boolean resourcesAreCompressed = false; public boolean useAapt2 = false; public boolean noCrunch = false; + public int forceApi = 0; public Collection doNotCompress; public String frameworkFolderLocation = null; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java index 6af075fc..8f9988bf 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/mod/SmaliMod.java @@ -29,14 +29,14 @@ import org.jf.smali.*; */ public class SmaliMod { - public static boolean assembleSmaliFile(String smali, DexBuilder dexBuilder, boolean verboseErrors, + public static boolean assembleSmaliFile(String smali, DexBuilder dexBuilder, int apiLevel, boolean verboseErrors, boolean printTokens, File smaliFile) throws IOException, RuntimeException, RecognitionException { InputStream is = new ByteArrayInputStream(smali.getBytes()); - return assembleSmaliFile(is, dexBuilder, verboseErrors, printTokens, smaliFile); + return assembleSmaliFile(is, dexBuilder, apiLevel, verboseErrors, printTokens, smaliFile); } - public static boolean assembleSmaliFile(InputStream is,DexBuilder dexBuilder, boolean verboseErrors, + public static boolean assembleSmaliFile(InputStream is,DexBuilder dexBuilder, int apiLevel, boolean verboseErrors, boolean printTokens, File smaliFile) throws IOException, RecognitionException { // copy our filestream into a tmp file, so we don't overwrite @@ -47,10 +47,10 @@ public class SmaliMod { IOUtils.copy(is, os); os.close(); - return assembleSmaliFile(tmp,dexBuilder, verboseErrors, printTokens); + return assembleSmaliFile(tmp,dexBuilder, apiLevel, verboseErrors, printTokens); } - public static boolean assembleSmaliFile(File smaliFile,DexBuilder dexBuilder, boolean verboseErrors, + public static boolean assembleSmaliFile(File smaliFile,DexBuilder dexBuilder, int apiLevel, boolean verboseErrors, boolean printTokens) throws IOException, RecognitionException { CommonTokenStream tokens; @@ -77,6 +77,7 @@ public class SmaliMod { } smaliParser parser = new smaliParser(tokens); + parser.setApiLevel(apiLevel); parser.setVerboseErrors(verboseErrors); smaliParser.smali_file_return result = parser.smali_file(); @@ -93,7 +94,7 @@ public class SmaliMod { treeStream.setTokenStream(tokens); smaliTreeWalker dexGen = new smaliTreeWalker(treeStream); - + dexGen.setApiLevel(apiLevel); dexGen.setVerboseErrors(verboseErrors); dexGen.setDexBuilder(dexBuilder); dexGen.smali_file(); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java index e61ba446..03c88db6 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/src/SmaliBuilder.java @@ -71,7 +71,7 @@ public class SmaliBuilder { if (fileName.endsWith(".smali")) { try { - if (!SmaliMod.assembleSmaliFile(inFile, dexBuilder, false, false)) { + if (!SmaliMod.assembleSmaliFile(inFile, dexBuilder, mApiLevel, false, false)) { throw new AndrolibException("Could not smali file: " + fileName); } } catch (IOException | RecognitionException ex) {