Skip to content

Commit dc9ded2

Browse files
committed
1. Improve compatibility
2. Fix install logic
1 parent a23388e commit dc9ded2

File tree

24 files changed

+182
-29
lines changed

24 files changed

+182
-29
lines changed

.idea/misc.xml

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ android {
1212
minSdkVersion 21
1313
//noinspection ExpiredTargetSdkVersion
1414
targetSdkVersion 30
15-
versionCode 76
16-
versionName "3.18.3.2"
15+
versionCode 77
16+
versionName "3.18.3.3"
1717

1818
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1919
multiDexEnabled true
1.5 KB
Binary file not shown.

app/src/main/assets/mods_manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
},
77
{
88
"assetPath":"mods/console-commands.zip",
9-
"Name": "Console Commands",
9+
"Name": "ConsoleCommands",
1010
"UniqueID": "SMAPI.ConsoleCommands"
1111
}
1212
]
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package androidx.documentfile.provider;
2+
3+
import android.content.ContentResolver;
4+
import android.content.Context;
5+
import android.database.Cursor;
6+
import android.net.Uri;
7+
import android.provider.DocumentsContract;
8+
import android.text.TextUtils;
9+
import android.util.Log;
10+
11+
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
15+
public class DocumentUtils {
16+
public interface IFileFilter {
17+
boolean accept(String name);
18+
}
19+
private static TreeDocumentFile findFile(Context context, TreeDocumentFile file, String name) {
20+
final ContentResolver resolver = context.getContentResolver();
21+
final Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(file.getUri(), DocumentsContract.getDocumentId(file.getUri()));
22+
Cursor c = null;
23+
try {
24+
c = resolver.query(childrenUri, new String[] {DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_DISPLAY_NAME}, null, null, null);
25+
while (c.moveToNext()) {
26+
final String documentName = c.getString(1);
27+
if (TextUtils.equals(name, documentName)) {
28+
final String documentId = c.getString(0);
29+
final Uri documentUri = DocumentsContract.buildDocumentUriUsingTree(file.getUri(), documentId);
30+
return new TreeDocumentFile(file, context, documentUri);
31+
}
32+
}
33+
} catch (Exception e) {
34+
Log.w("DocumentUtils", "Failed query: " + e);
35+
} finally {
36+
if (c != null) {
37+
c.close();
38+
}
39+
}
40+
return null;
41+
}
42+
public static DocumentFile findFile(Context context, DocumentFile documentFile, String name) {
43+
if (documentFile instanceof TreeDocumentFile)
44+
return findFile(context, (TreeDocumentFile)documentFile, name);
45+
return documentFile.findFile(name);
46+
}
47+
private static List<DocumentFile> filterFiles(Context context, TreeDocumentFile file, IFileFilter filter) {
48+
ContentResolver resolver = context.getContentResolver();
49+
Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(file.getUri(), DocumentsContract.getDocumentId(file.getUri()));
50+
List<DocumentFile> filtered = new ArrayList<>();
51+
Cursor c = null;
52+
try {
53+
c = resolver.query(childrenUri, new String[] {DocumentsContract.Document.COLUMN_DOCUMENT_ID, DocumentsContract.Document.COLUMN_DISPLAY_NAME}, null, null, null);
54+
while (c.moveToNext()) {
55+
String documentName = c.getString(1);
56+
String documentId = c.getString(0);
57+
Uri documentUri = DocumentsContract.buildDocumentUriUsingTree(file.getUri(), documentId);
58+
TreeDocumentFile child = new TreeDocumentFile(file, context, documentUri);
59+
if (child.isDirectory())
60+
filtered.addAll(filterFiles(context, child, filter));
61+
else if (filter.accept(documentName))
62+
filtered.add(child);
63+
}
64+
} catch (Exception e) {
65+
Log.w("DocumentUtils", "Failed query: " + e);
66+
} finally {
67+
if (c != null) {
68+
c.close();
69+
}
70+
}
71+
return filtered;
72+
}
73+
public static List<DocumentFile> filterFiles(Context context, DocumentFile documentFile, IFileFilter filter) {
74+
if (documentFile instanceof TreeDocumentFile)
75+
return filterFiles(context, (TreeDocumentFile)documentFile, filter);
76+
List<DocumentFile> filtered = new ArrayList<>();
77+
DocumentFile[] files = documentFile.listFiles();
78+
if (files != null) {
79+
for (DocumentFile file : files) {
80+
if (filter.accept(file.getName()))
81+
filtered.add(file);
82+
}
83+
}
84+
return filtered;
85+
}
86+
}

app/src/main/java/com/zane/smapiinstaller/logic/ApkPatcher.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ public Tuple2<String, String[]> extract(int advancedStage) {
173173
* 将指定APK文件重新打包,添加SMAPI,修改AndroidManifest.xml,同时验证版本是否正确
174174
*
175175
* @param apkPath APK文件路径
176-
* @param second
177176
* @param targetFile 目标文件
178177
* @param isAdvanced 是否高级模式
179178
* @return 是否成功打包

app/src/main/java/com/zane/smapiinstaller/logic/CommonLogic.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import androidx.annotation.RequiresApi;
2424
import androidx.documentfile.provider.DocumentFile;
25+
import androidx.documentfile.provider.DocumentUtils;
2526

2627
import com.afollestad.materialdialogs.MaterialDialog;
2728
import com.fasterxml.jackson.core.type.TypeReference;
@@ -275,27 +276,25 @@ public static boolean unpackSmapiFiles(Activity context, String apkPath, boolean
275276
if (CommonLogic.checkDataRootPermission(context)) {
276277
Uri targetDirUri = pathToTreeUri(Constants.TARGET_DATA_FILE_URI);
277278
DocumentFile documentFile = DocumentFile.fromTreeUri(context, targetDirUri);
278-
for (DocumentFile file : documentFile.listFiles()) {
279-
if (file.getName().equals("files")) {
280-
copyDocument(context, new File(basePath, "smapi-internal"), file);
281-
copyDocument(context, new File(basePath, "Mods"), file);
282-
}
279+
DocumentFile filesDoc = DocumentUtils.findFile(context, documentFile, "files");
280+
if(filesDoc != null) {
281+
copyDocument(context, new File(basePath, "smapi-internal"), filesDoc);
283282
}
284283
}
285284
return true;
286285
}
287286

288-
private static void copyDocument(Activity context, File src, DocumentFile dest) {
287+
public static void copyDocument(Activity context, File src, DocumentFile dest) {
289288
if (src.isDirectory()) {
290-
DocumentFile documentFile = dest.findFile(src.getName());
289+
DocumentFile documentFile = DocumentUtils.findFile(context, dest, src.getName());
291290
if (documentFile == null) {
292291
documentFile = dest.createDirectory(src.getName());
293292
}
294293
for (File file : src.listFiles()) {
295294
copyDocument(context, file, documentFile);
296295
}
297296
} else {
298-
DocumentFile documentFile = dest.findFile(src.getName());
297+
DocumentFile documentFile = DocumentUtils.findFile(context, dest, src.getName());
299298
if (documentFile == null) {
300299
documentFile = dest.createFile("application/x-binary", src.getName());
301300
}
@@ -512,7 +511,7 @@ public static void openPermissionSetting(Activity activity) {
512511
}
513512
}
514513

515-
public static boolean checkDataRootPermission(Activity context) {
514+
public static boolean checkDataRootPermission(Context context) {
516515
File pathFrom = new File(FileUtils.getStadewValleyBasePath(), "Android/data/" + Constants.TARGET_PACKAGE_NAME + "/files/");
517516
if (!pathFrom.exists()) {
518517
return false;

app/src/main/java/com/zane/smapiinstaller/logic/ModAssetsManager.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.app.Activity;
44
import android.content.pm.PackageInfo;
5+
import android.net.Uri;
56
import android.util.Log;
67
import android.view.View;
78
import android.widget.Toast;
@@ -45,6 +46,8 @@
4546
import java.util.function.Predicate;
4647
import java.util.stream.Collectors;
4748

49+
import androidx.documentfile.provider.DocumentFile;
50+
import androidx.documentfile.provider.DocumentUtils;
4851
import androidx.navigation.NavController;
4952
import androidx.navigation.Navigation;
5053

@@ -169,6 +172,7 @@ public boolean installDefaultMods() {
169172
}
170173
File modFolder = new File(FileUtils.getStadewValleyBasePath(), Constants.MOD_PATH);
171174
ImmutableListMultimap<String, ModManifestEntry> installedModMap = Multimaps.index(findAllInstalledMods(), ModManifestEntry::getUniqueID);
175+
List<File> unpackedMods = new ArrayList<>();
172176
for (ModManifestEntry mod : modManifestEntries) {
173177
if (installedModMap.containsKey(mod.getUniqueID())) {
174178
ImmutableList<ModManifestEntry> installedMods = installedModMap.get(mod.getUniqueID());
@@ -202,7 +206,9 @@ public boolean installDefaultMods() {
202206
}
203207
if (installedMods.size() > 0) {
204208
try {
205-
ZipUtil.unpack(context.getAssets().open(mod.getAssetPath()), new File(installedMods.get(0).getAssetPath()), (name) -> StringUtils.removeStart(name, mod.getName() + "/"));
209+
File targetFile = new File(installedMods.get(0).getAssetPath());
210+
ZipUtil.unpack(context.getAssets().open(mod.getAssetPath()), targetFile, (name) -> StringUtils.removeStart(name, mod.getName() + "/"));
211+
unpackedMods.add(targetFile);
206212
} catch (IOException e) {
207213
Log.e(TAG, "Install Mod Error", e);
208214
}
@@ -211,10 +217,25 @@ public boolean installDefaultMods() {
211217
}
212218
try {
213219
ZipUtil.unpack(context.getAssets().open(mod.getAssetPath()), modFolder);
220+
unpackedMods.add(new File(modFolder, mod.getName()));
214221
} catch (IOException e) {
215222
Log.e(TAG, "Install Mod Error", e);
216223
}
217224
}
225+
if (CommonLogic.checkDataRootPermission(context)) {
226+
Uri targetDirUri = CommonLogic.pathToTreeUri(Constants.TARGET_DATA_FILE_URI);
227+
DocumentFile documentFile = DocumentFile.fromTreeUri(context, targetDirUri);
228+
if(documentFile != null) {
229+
DocumentFile filesDoc = DocumentUtils.findFile(context, documentFile, "files");
230+
DocumentFile modsDoc = DocumentUtils.findFile(context, filesDoc, "Mods");
231+
if (modsDoc == null) {
232+
modsDoc = filesDoc.createDirectory("Mods");
233+
}
234+
for (File mod : unpackedMods) {
235+
CommonLogic.copyDocument(context, mod, modsDoc);
236+
}
237+
}
238+
}
218239
return true;
219240
}
220241

app/src/main/java/com/zane/smapiinstaller/ui/about/AboutFragment.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,15 @@ private void joinQQ() {
5959
case 1:
6060
CommonLogic.doOnNonNull(this.getContext(), (context) -> CommonLogic.openUrl(context, baseUrl + "kshK7BavcS2jXZ6exDvezc18ksLB8YsM"));
6161
break;
62-
default:
62+
case 2:
6363
CommonLogic.doOnNonNull(this.getContext(), (context) -> CommonLogic.openUrl(context, baseUrl + "zqsWYGBuAxPx0n9RI_ONs-7NA1Mm48QY"));
6464
break;
65+
case 3:
66+
CommonLogic.doOnNonNull(this.getContext(), (context) -> CommonLogic.openUrl(context, baseUrl + "uYnxVTCGlWuLbeb3XA3mDXoO0tlYhy3J"));
67+
break;
68+
default:
69+
CommonLogic.doOnNonNull(this.getContext(), (context) -> CommonLogic.openUrl(context, "https://s.zaneyork.cn:8443/s/qc"));
70+
break;
6571
}
6672
});
6773
}

app/src/main/java/com/zane/smapiinstaller/ui/install/InstallFragment.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public View onCreateView(@NonNull LayoutInflater inflater,
5757
binding.layoutAdvInstall.setVisibility(View.VISIBLE);
5858
}
5959
try {
60-
String firstLine = Files.asCharSource(new File(FileUtils.getStadewValleyBasePath(), Constants.LOG_PATH), StandardCharsets.UTF_8).readFirstLine();
60+
String firstLine = Files.asCharSource(FileUtils.docOverlayFetch(context, Constants.LOG_PATH), StandardCharsets.UTF_8).readFirstLine();
6161
if (StringUtils.isNoneBlank(firstLine)) {
6262
String versionString = RegExUtils.removePattern(firstLine, "\\[.+\\]\\s+");
6363
versionString = RegExUtils.removePattern(versionString, "\\s+with.+");
@@ -158,7 +158,6 @@ private void installLogic(boolean isAdv) {
158158
return;
159159
}
160160
ModAssetsManager modAssetsManager = new ModAssetsManager(binding.getRoot());
161-
DialogUtils.setProgressDialogState(binding.getRoot(), dialog, R.string.unpacking_smapi_files, 6);
162161
modAssetsManager.installDefaultMods();
163162

164163
DialogUtils.setProgressDialogState(binding.getRoot(), dialog, R.string.signing_package, null);

0 commit comments

Comments
 (0)