Skip to content

Commit

Permalink
1.6.4.9
Browse files Browse the repository at this point in the history
Check for mismatched version codes in splits and warn or show error where appropriate
Cleanup unused strings
Try to fix 'Fix for ReVanced' not working on some devices
  • Loading branch information
AbdurazaaqMohammed committed Aug 20, 2024
1 parent 6fdbbd9 commit a96bd14
Show file tree
Hide file tree
Showing 17 changed files with 186 additions and 100 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ android {
minSdk = 4
targetSdk = 35
versionCode = 29
versionName = "1.6.4.8"
versionName = "1.6.4.9"
multiDexEnabled = true
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,17 @@ public List<String> getListOfSplits(Uri splitAPKUri) throws IOException {
return splits;
}

public boolean isArch(String thisSplit) {
public static boolean isArch(String thisSplit) {
return thisSplit.contains("armeabi") || thisSplit.contains("arm64") || thisSplit.contains("x86") || thisSplit.contains("mips");
}

public static boolean isBaseApk(String name) {
return name.equals("base.apk")
|| !name.startsWith("config") && !name.startsWith("split"); // this is base.apk hopefully
}

public boolean shouldIncludeSplit(String name) {
return name.equals("base.apk")
|| !name.startsWith("config") && !name.startsWith("split") // this is base.apk hopefully
|| shouldIncludeLang(name) || shouldIncludeArch(name) || shouldIncludeDpi(name);
return isBaseApk(name) || shouldIncludeLang(name) || shouldIncludeArch(name) || shouldIncludeDpi(name);
}

public boolean shouldIncludeLang(String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

/** @noinspection deprecation*/
public class MainActivity extends Activity implements Merger.LogListener {
private static boolean ask;
private static boolean ask = true;
private static boolean showDialog;
private static boolean signApk;
private static boolean selectSplitsForDevice;
Expand Down Expand Up @@ -282,7 +282,7 @@ protected void onCreate(Bundle savedInstanceState) {
title.setTextColor(textColor);
title.setTextSize(25);
styleAlertDialog(
new AlertDialog.Builder(this).setCustomTitle(title).setView(l).setPositiveButton("Close", (dialog, which) -> dialog.dismiss()).create(), null);
new AlertDialog.Builder(this).setCustomTitle(title).setView(l).setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss()).create(), null);
});

findViewById(R.id.decodeButton).setOnClickListener(v -> {
Expand All @@ -295,7 +295,7 @@ protected void onCreate(Bundle savedInstanceState) {
properties.offset = new File(DialogConfigs.DEFAULT_DIR);
properties.extensions = new String[] {"apk", "zip", "apks", "aspk", "apks", "xapk", "apkm"};
FilePickerDialog dialog = new FilePickerDialog(MainActivity.this, properties, textColor, bgColor);
dialog.setTitle(rss.getString(R.string.choose_button_label));
dialog.setTitle(rss.getString(R.string.select));
dialog.setDialogSelectionListener(files -> {
urisAreSplitApks = !files[0].endsWith(".apk");
uris = new ArrayList<>();
Expand Down Expand Up @@ -522,7 +522,7 @@ protected Void doInBackground(Uri... uris) {
boolean splitApkContainsArch = false;
for (int i = 0; i < splits.size(); i++) {
final String thisSplit = splits.get(i);
if(!splitApkContainsArch && DeviceSpecsUtil.isArch(thisSplit)) {
if(!splitApkContainsArch && com.abdurazaaqmohammed.AntiSplit.main.DeviceSpecsUtil.isArch(thisSplit)) {
splitApkContainsArch = true;
}
if (DeviceSpecsUtil.shouldIncludeSplit(thisSplit)) splits.remove(thisSplit);
Expand All @@ -531,7 +531,7 @@ protected Void doInBackground(Uri... uris) {
boolean selectedSplitsContainsArch = false;
for (int i = 0; i < copy.size(); i++) {
final String thisSplit = copy.get(i);
if (DeviceSpecsUtil.isArch(thisSplit) && !splits.contains(thisSplit)) {
if (com.abdurazaaqmohammed.AntiSplit.main.DeviceSpecsUtil.isArch(thisSplit) && !splits.contains(thisSplit)) {
selectedSplitsContainsArch = true;
break;
}
Expand All @@ -540,7 +540,7 @@ protected Void doInBackground(Uri... uris) {
LogUtil.logMessage("Could not find device architecture, selecting all architectures");
for (int i = 0; i < splits.size(); i++) {
final String thisSplit = splits.get(i);
if(DeviceSpecsUtil.isArch(thisSplit)) splits.remove(thisSplit); // select all to be sure
if(com.abdurazaaqmohammed.AntiSplit.main.DeviceSpecsUtil.isArch(thisSplit)) splits.remove(thisSplit); // select all to be sure
}
}
}
Expand Down Expand Up @@ -732,7 +732,7 @@ protected void onPostExecute(String[] result) {
} else activity.startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(link)));
});
if(supportsDownloadManager) builder.setNeutralButton("Go to GitHub Release", (dialog, which) -> activity.startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse("https://github.com/AbdurazaaqMohammed/AntiSplit-M/releases/latest"))));
activity.styleAlertDialog(builder.setNegativeButton(rss.getString(R.string.cancel_button_label), (dialog, which) -> dialog.dismiss()).create(), null);
activity.styleAlertDialog(builder.setNegativeButton(rss.getString(R.string.cancel), (dialog, which) -> dialog.dismiss()).create(), null);
} else if (toast) activity.runOnUiThread(() -> Toast.makeText(activity, rss.getString(R.string.no_update_found), Toast.LENGTH_SHORT).show());
} catch (Exception ignored) { }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.abdurazaaqmohammed.AntiSplit.main;

public class MismatchedSplitsException extends Exception {
public MismatchedSplitsException(String cancelled) {
super(cancelled);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ protected void onCreate(Bundle savedInstanceState) {
* selected.
*/
positiveBtnNameStr = positiveBtnNameStr == null ?
com.abdurazaaqmohammed.AntiSplit.main.MainActivity.rss.getString(R.string.choose_button_label) : positiveBtnNameStr;
com.abdurazaaqmohammed.AntiSplit.main.MainActivity.rss.getString(R.string.select) : positiveBtnNameStr;
int size1 = MarkedItemList.getFileCount();
if (size1 == 0) {
select.setEnabled(false);
Expand Down Expand Up @@ -215,7 +215,7 @@ protected void onStart() {
super.onStart();
positiveBtnNameStr = (
positiveBtnNameStr == null ?
com.abdurazaaqmohammed.AntiSplit.main.MainActivity.rss.getString(R.string.choose_button_label) :
com.abdurazaaqmohammed.AntiSplit.main.MainActivity.rss.getString(R.string.select) :
positiveBtnNameStr
);
select.setText(positiveBtnNameStr);
Expand Down Expand Up @@ -417,7 +417,7 @@ public void show() {
} else {
super.show();
positiveBtnNameStr = positiveBtnNameStr == null ?
com.abdurazaaqmohammed.AntiSplit.main.MainActivity.rss.getString(R.string.choose_button_label) : positiveBtnNameStr;
com.abdurazaaqmohammed.AntiSplit.main.MainActivity.rss.getString(R.string.select) : positiveBtnNameStr;
select.setText(positiveBtnNameStr);
int size = MarkedItemList.getFileCount();
if (size == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public static ZipFileHeader read(RewindableInputStream inputStream) throws IOExc
int fileNameLength = IoUtils.readShort(inputStream, "ZipFileHeader.fileNameLength");
int extraLength = IoUtils.readShort(inputStream, "ZipFileHeader.extraLength");
builder.fileNameBytes = IoUtils.readBytes(inputStream, fileNameLength, "ZipFileHeader.fileName");
//builder.extraFieldBytes =
builder.extraFieldBytes =
IoUtils.readBytes(inputStream, extraLength, "ZipFileHeader.extra");
return builder.build();
}
Expand Down
120 changes: 101 additions & 19 deletions app/src/main/java/com/reandroid/apk/ApkBundle.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,20 @@
*/
package com.reandroid.apk;

import android.util.Log;
import static com.abdurazaaqmohammed.AntiSplit.main.MainActivity.rss;

import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.text.TextUtils;
import android.widget.TextView;

import com.abdurazaaqmohammed.AntiSplit.R;
import com.abdurazaaqmohammed.AntiSplit.main.DeviceSpecsUtil;
import com.abdurazaaqmohammed.AntiSplit.main.MainActivity;
import com.abdurazaaqmohammed.AntiSplit.main.MismatchedSplitsException;
import com.android.apksig.apk.ApkUtils;
import com.reandroid.apkeditor.merge.LogUtil;
import com.reandroid.archive.BlockInputSource;
import com.reandroid.archive.ZipEntryMap;
Expand All @@ -25,22 +37,32 @@
import com.reandroid.arsc.pool.TableStringPool;
import com.reandroid.arsc.pool.builder.StringPoolMerger;

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.zip.ZipFile;

public class ApkBundle implements Closeable {
private final Map<String, ApkModule> mModulesMap;
private APKLogger apkLogger;

public ApkBundle(){
this.mModulesMap=new HashMap<>();
}

public ApkModule mergeModules() throws IOException {
List<ApkModule> moduleList=getApkModuleList();
if(moduleList.size()==0){
if(moduleList.isEmpty()){
throw new FileNotFoundException("Nothing to merge, empty modules");
}
ApkModule result = new ApkModule(generateMergedModuleName(), new ZipEntryMap());
Expand Down Expand Up @@ -143,27 +165,87 @@ public List<ApkModule> getApkModuleList(){
return new ArrayList<>(mModulesMap.values());
}

public void loadApkDirectory(File dir, boolean recursive) throws IOException {
if(!dir.isDirectory()){
throw new FileNotFoundException("No such directory: "+dir);
public void loadApkDirectory(File dir, boolean recursive, Context context) throws IOException, MismatchedSplitsException, InterruptedException {
if(!dir.isDirectory()) throw new FileNotFoundException("No such directory: " + dir);
List<File> apkList = recursive ? ApkUtil.recursiveFiles(dir, ".apk") : ApkUtil.listFiles(dir, ".apk");
if(apkList.isEmpty()) throw new FileNotFoundException("No '*.apk' files in directory: " + dir);
LogUtil.logMessage("Found apk files: "+apkList.size());
int size = apkList.size();
int[] versionCodes = new int[size];
int base = -1;
for(int i = 0; i < size; i++){
File file = apkList.get(i);
try(ZipFile zf = new ZipFile(file);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
InputStream is = zf.getInputStream(zf.getEntry("AndroidManifest.xml"))) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) byteArrayOutputStream.write(buffer, 0, bytesRead);
versionCodes[i] = ApkUtils.getVersionCodeFromBinaryAndroidManifest(ByteBuffer.wrap(byteArrayOutputStream.toByteArray()));
if(DeviceSpecsUtil.isBaseApk(file.getName())) base = versionCodes[i];
} catch (Exception e) {
versionCodes[i] = -1;
}
}
List<File> apkList;
if(recursive){
apkList = ApkUtil.recursiveFiles(dir, ".apk");
}else {
apkList = ApkUtil.listFiles(dir, ".apk");
if(base == -1) load(apkList);
List<File> mismatchedDpis = new ArrayList<>();
StringBuilder mismatchedLangs = new StringBuilder();
for(int i = 0; i < size; i++) {
if(versionCodes[i] != base) {
File f = apkList.get(i);
String name = f.getName();
LogUtil.logMessage(name + rss.getString(R.string.mismatch_base));
if(DeviceSpecsUtil.isArch(name)) throw new MismatchedSplitsException("Error: Key (the app will not run without it) split (" + name + ") has a mismatched version code.");
if(name.contains("dpi")) mismatchedDpis.add(f);
else mismatchedLangs.append(", ").append(name);
}
}
if(apkList.size()==0){
throw new FileNotFoundException("No '*.apk' files in directory: "+dir);

apkList.removeAll(mismatchedDpis);
boolean hasDpi = false;
for(File f : apkList) {
if(f.getName().contains("dpi")) {
hasDpi = true;
break;
}
}
LogUtil.logMessage("Found apk files: "+apkList.size());
for(File file:apkList){
if(!hasDpi) throw new MismatchedSplitsException("Error: All DPI/resource splits selected have a mismatched version code.");
String s = mismatchedLangs.toString();
if(!TextUtils.isEmpty(s)) {
final CountDownLatch latch = new CountDownLatch(1);
TextView title = new TextView(context);
title.setText(rss.getString(R.string.warning));
title.setTextColor(MainActivity.textColor);
title.setTextSize(25);
TextView msg = new TextView(context);
msg.setText(rss.getString(R.string.mismatch, s.replaceFirst(", ", "")));
msg.setTextColor(MainActivity.textColor);
MainActivity act = ((MainActivity) context);
act.getHandler().post(() -> act.styleAlertDialog(new AlertDialog.Builder(context).setCustomTitle(title).setView(msg).setPositiveButton("OK", (dialog, which) -> {
for(String filename : s.split(", ")) {
File f = new File(dir, filename);
f.delete();
apkList.remove(f);
}
latch.countDown();
}).setNegativeButton(rss.getString(R.string.cancel), (dialog, which) -> {
act.startActivity(new Intent(act, MainActivity.class));
if(Build.VERSION.SDK_INT > 15) act.finishAffinity();
else act.finish();
latch.countDown();
}).create(), null));
latch.await();
}
load(apkList);
}

private void load(List<File> apkList) throws IOException {
for(File file : apkList) {
LogUtil.logMessage("Loading: "+file.getName());
String name = ApkUtil.toModuleName(file);
ApkModule module = ApkModule.loadApkFile(file, name);
addModule(module);
addModule(ApkModule.loadApkFile(file, ApkUtil.toModuleName(file)));
}
}

public void addModule(ApkModule apkModule){
apkModule.setLoadDefaultFramework(false);
String name = apkModule.getModuleName();
Expand Down
Loading

0 comments on commit a96bd14

Please sign in to comment.