parent
2a79a72ff9
commit
41f0b8765f
|
@ -12,8 +12,8 @@ android {
|
|||
applicationId "com.zane.smapiinstaller"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 28
|
||||
versionCode 46
|
||||
versionName "1.5.5"
|
||||
versionCode 47
|
||||
versionName "1.5.6"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
|
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": 21,
|
||||
"version": 23,
|
||||
"contents": [
|
||||
{
|
||||
"type": "COMPAT",
|
||||
|
@ -14,16 +14,16 @@
|
|||
"name": "SMAPI for Galaxy Store",
|
||||
"assetPath": "compat/samsung_138/",
|
||||
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1",
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_16.zip",
|
||||
"hash": "20cf2ce515dcf05596d523387b244c9e14c235387db61545e7067835e5856626"
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_17.zip",
|
||||
"hash": "ac6cff4a1decb19fc01da7314e79483f2a77d34523665370d62f8bf69dcf09dc"
|
||||
},
|
||||
{
|
||||
"type": "COMPAT",
|
||||
"name": "SMAPI for Amazon Store",
|
||||
"assetPath": "compat/amazon_138/",
|
||||
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1",
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_6.zip",
|
||||
"hash": "f487f8f14fcdd0ee31ca4e3b731e6e9114bc4b43a50c930f651a939e927eeb5d"
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_7.zip",
|
||||
"hash": "8a63e326ab122df5157a6c70c6cac8b8669ec81701f687746b80b7a860578dbb"
|
||||
},
|
||||
{
|
||||
"type": "LOCALE",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": 21,
|
||||
"version": 23,
|
||||
"contents": [
|
||||
{
|
||||
"type": "COMPAT",
|
||||
|
@ -14,16 +14,16 @@
|
|||
"name": "SMAPI for Galaxy Store",
|
||||
"assetPath": "compat/samsung_138/",
|
||||
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1",
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_16.zip",
|
||||
"hash": "20cf2ce515dcf05596d523387b244c9e14c235387db61545e7067835e5856626"
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_17.zip",
|
||||
"hash": "ac6cff4a1decb19fc01da7314e79483f2a77d34523665370d62f8bf69dcf09dc"
|
||||
},
|
||||
{
|
||||
"type": "COMPAT",
|
||||
"name": "SMAPI for Amazon Store",
|
||||
"assetPath": "compat/amazon_138/",
|
||||
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1",
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_6.zip",
|
||||
"hash": "f487f8f14fcdd0ee31ca4e3b731e6e9114bc4b43a50c930f651a939e927eeb5d"
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_7.zip",
|
||||
"hash": "8a63e326ab122df5157a6c70c6cac8b8669ec81701f687746b80b7a860578dbb"
|
||||
},
|
||||
{
|
||||
"type": "LOCALE",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": 21,
|
||||
"version": 23,
|
||||
"contents": [
|
||||
{
|
||||
"type": "COMPAT",
|
||||
|
@ -14,16 +14,16 @@
|
|||
"name": "SMAPI untuk Galaxy Store",
|
||||
"assetPath": "compat/samsung_138/",
|
||||
"description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - terbaru, SMAPI 3.6.1",
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_16.zip",
|
||||
"hash": "20cf2ce515dcf05596d523387b244c9e14c235387db61545e7067835e5856626"
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_17.zip",
|
||||
"hash": "ac6cff4a1decb19fc01da7314e79483f2a77d34523665370d62f8bf69dcf09dc"
|
||||
},
|
||||
{
|
||||
"type": "COMPAT",
|
||||
"name": "SMAPI untuk Amazon Store",
|
||||
"assetPath": "compat/amazon_138/",
|
||||
"description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - terbaru, SMAPI 3.6.1",
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_6.zip",
|
||||
"hash": "f487f8f14fcdd0ee31ca4e3b731e6e9114bc4b43a50c930f651a939e927eeb5d"
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_7.zip",
|
||||
"hash": "8a63e326ab122df5157a6c70c6cac8b8669ec81701f687746b80b7a860578dbb"
|
||||
},
|
||||
{
|
||||
"type": "LOCAL",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": 21,
|
||||
"version": 23,
|
||||
"contents": [
|
||||
{
|
||||
"type": "COMPAT",
|
||||
|
@ -14,16 +14,16 @@
|
|||
"name": "SMAPI三星商店兼容包",
|
||||
"assetPath": "compat/samsung_138/",
|
||||
"description": "SMAPI三星商店兼容包, 适用版本1.4.4.138至今, SMAPI 3.6.1",
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_16.zip",
|
||||
"hash": "20cf2ce515dcf05596d523387b244c9e14c235387db61545e7067835e5856626"
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_17.zip",
|
||||
"hash": "ac6cff4a1decb19fc01da7314e79483f2a77d34523665370d62f8bf69dcf09dc"
|
||||
},
|
||||
{
|
||||
"type": "COMPAT",
|
||||
"name": "SMAPI亚马逊商店兼容包",
|
||||
"assetPath": "compat/amazon_138/",
|
||||
"description": "SMAPI亚马逊商店兼容包, 适用版本1.4.4.138至今, SMAPI 3.6.1",
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_6.zip",
|
||||
"hash": "f487f8f14fcdd0ee31ca4e3b731e6e9114bc4b43a50c930f651a939e927eeb5d"
|
||||
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_7.zip",
|
||||
"hash": "8a63e326ab122df5157a6c70c6cac8b8669ec81701f687746b80b7a860578dbb"
|
||||
},
|
||||
{
|
||||
"type": "LOCALE",
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.zane.smapiinstaller.constant.DialogAction;
|
|||
import com.zane.smapiinstaller.dto.AppUpdateCheckResultDto;
|
||||
import com.zane.smapiinstaller.entity.AppConfig;
|
||||
import com.zane.smapiinstaller.entity.FrameworkConfig;
|
||||
import com.zane.smapiinstaller.logic.ActivityResultHandler;
|
||||
import com.zane.smapiinstaller.logic.CommonLogic;
|
||||
import com.zane.smapiinstaller.logic.ConfigManager;
|
||||
import com.zane.smapiinstaller.logic.GameLauncher;
|
||||
|
@ -42,6 +43,7 @@ import java.io.File;
|
|||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
@ -97,6 +99,12 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
ActivityResultHandler.triggerListener(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package com.zane.smapiinstaller.logic;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import java9.util.function.BiConsumer;
|
||||
|
||||
public class ActivityResultHandler {
|
||||
public static int REQUEST_CODE_APP_INSTALL = 1001;
|
||||
|
||||
public static ConcurrentHashMap<Integer, BiConsumer<Integer, Intent>> listenerMap = new ConcurrentHashMap<>();
|
||||
|
||||
public static void registerListener(int requestCode, BiConsumer<Integer, Intent> listener) {
|
||||
listenerMap.put(requestCode, listener);
|
||||
}
|
||||
|
||||
public static void triggerListener(int requestCode, int resultCode, Intent data) {
|
||||
BiConsumer<Integer, Intent> biConsumer = listenerMap.get(requestCode);
|
||||
if(biConsumer != null) {
|
||||
biConsumer.accept(resultCode, data);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import android.content.pm.PackageManager;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.apksig.ApkSigner;
|
||||
|
@ -19,11 +20,14 @@ import com.google.common.collect.Iterables;
|
|||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.Files;
|
||||
import com.zane.smapiinstaller.BuildConfig;
|
||||
import com.zane.smapiinstaller.MainActivity;
|
||||
import com.zane.smapiinstaller.R;
|
||||
import com.zane.smapiinstaller.constant.Constants;
|
||||
import com.zane.smapiinstaller.constant.DialogAction;
|
||||
import com.zane.smapiinstaller.constant.ManifestPatchConstants;
|
||||
import com.zane.smapiinstaller.entity.ApkFilesManifest;
|
||||
import com.zane.smapiinstaller.entity.ManifestEntry;
|
||||
import com.zane.smapiinstaller.utils.DialogUtils;
|
||||
import com.zane.smapiinstaller.utils.FileUtils;
|
||||
import com.zane.smapiinstaller.utils.ZipUtils;
|
||||
|
||||
|
@ -126,13 +130,12 @@ public class ApkPatcher {
|
|||
return distFile.getAbsolutePath();
|
||||
} else if (advancedStage == 1) {
|
||||
File contentFolder = new File(externalFilesDir.getAbsolutePath() + "/StardewValley/Content");
|
||||
if(contentFolder.exists()) {
|
||||
if(!contentFolder.isDirectory()) {
|
||||
if (contentFolder.exists()) {
|
||||
if (!contentFolder.isDirectory()) {
|
||||
errorMessage.set(context.getString(R.string.error_directory_exists_with_same_filename, contentFolder.getAbsolutePath()));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
extract(0);
|
||||
}
|
||||
ZipUtils.removeEntries(sourceDir, "assets/Content", distFile.getAbsolutePath(), (progress) -> emitProgress((int) (progress * 0.05)));
|
||||
|
@ -189,7 +192,7 @@ public class ApkPatcher {
|
|||
List<ManifestEntry> manifestEntries = apkFilesManifest.getManifestEntries();
|
||||
errorMessage.set(null);
|
||||
List<ZipUtils.ZipEntrySource> entries = StreamSupport.stream(manifestEntries).map(entry -> {
|
||||
if(entry.isAdvanced() && !advanced) {
|
||||
if (entry.isAdvanced() && !advanced) {
|
||||
return null;
|
||||
}
|
||||
byte[] bytes;
|
||||
|
@ -209,11 +212,9 @@ public class ApkPatcher {
|
|||
errorMessage.set(StringUtils.stripToEmpty(errorMessage.get()) + "\n" + errorMsg);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if(StringUtils.equals(crc, entry.getPatchedCrc())){
|
||||
} else if (StringUtils.equals(crc, entry.getPatchedCrc())) {
|
||||
bytes = originBytes;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
String errorMsg = context.getString(R.string.error_patch_crc_incorrect, entry.getTargetPath(), crc);
|
||||
errorMessage.set(StringUtils.stripToEmpty(errorMessage.get()) + "\n" + errorMsg);
|
||||
return null;
|
||||
|
@ -402,6 +403,20 @@ public class ApkPatcher {
|
|||
* @param apkPath 安装包路径
|
||||
*/
|
||||
public void install(String apkPath) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
boolean haveInstallPermission = context.getPackageManager().canRequestPackageInstalls();
|
||||
if (!haveInstallPermission) {
|
||||
DialogUtils.showConfirmDialog(MainActivity.instance, R.string.confirm, R.string.request_unknown_source_permission, ((dialog, dialogAction) -> {
|
||||
if(dialogAction == DialogAction.POSITIVE) {
|
||||
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
|
||||
ActivityResultHandler.registerListener(ActivityResultHandler.REQUEST_CODE_APP_INSTALL, (resultCode, data) -> this.install(apkPath));
|
||||
MainActivity.instance.startActivityForResult(intent, ActivityResultHandler.REQUEST_CODE_APP_INSTALL);
|
||||
}
|
||||
}));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(fromFile(new File(apkPath)), "application/vnd.android.package-archive");
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
|
|
@ -104,6 +104,19 @@ public class DialogUtils {
|
|||
materialDialog.show();
|
||||
});
|
||||
}
|
||||
public static void showConfirmDialog(Activity context, int title, int message, BiConsumer<MaterialDialog, DialogAction> callback) {
|
||||
CommonLogic.runOnUiThread(context, (activity) -> {
|
||||
MaterialDialog materialDialog = new MaterialDialog(activity, MaterialDialog.getDEFAULT_BEHAVIOR()).title(title, null).message(message, null, null).positiveButton(R.string.confirm, null, dialog -> {
|
||||
callback.accept(dialog, DialogAction.POSITIVE);
|
||||
return null;
|
||||
}).negativeButton(R.string.cancel, null, dialog -> {
|
||||
callback.accept(dialog, DialogAction.NEGATIVE);
|
||||
return null;
|
||||
});
|
||||
DialogUtils.setCurrentDialog(materialDialog);
|
||||
materialDialog.show();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示确认对话框
|
||||
|
|
|
@ -81,4 +81,5 @@
|
|||
<string name="error_directory_exists_with_same_filename">%1$s不是一個文件夾, 請手動刪除該文件</string>
|
||||
<string name="error_patch_crc_incorrect">增量更新%1$s失敗: CRC (%2$s))</string>
|
||||
<string name="settings_rewrite_in_parallel">多線程重寫</string>
|
||||
<string name="request_unknown_source_permission">需要开启未知源权限以安装Mod框架,是否前往设置开启?</string>
|
||||
</resources>
|
||||
|
|
|
@ -81,4 +81,5 @@
|
|||
<string name="error_directory_exists_with_same_filename">%1$s不是一个文件夹, 请手动删除该文件</string>
|
||||
<string name="error_patch_crc_incorrect">增量更新%1$s失败: CRC (%2$s))</string>
|
||||
<string name="settings_rewrite_in_parallel">多线程重写</string>
|
||||
<string name="request_unknown_source_permission">需要开启未知源权限以安装Mod框架,是否前往设置开启?</string>
|
||||
</resources>
|
||||
|
|
|
@ -85,4 +85,5 @@
|
|||
<string name="error_directory_exists_with_same_filename">%1$s is not a directory, please delete it manually.</string>
|
||||
<string name="error_patch_crc_incorrect">Patch %1$s failed: CRC (%2$s))</string>
|
||||
<string name="settings_rewrite_in_parallel">Rewrite in Parallel</string>
|
||||
<string name="request_unknown_source_permission">Needs to switch unknown source permission on to install mod framework, open settings?</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue