parent
f15d305661
commit
5cec14c4cb
|
@ -8,24 +8,31 @@ import android.os.Bundle;
|
|||
import android.os.Environment;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
import com.hjq.language.LanguagesManager;
|
||||
import com.lmntrx.android.library.livin.missme.ProgressDialog;
|
||||
import com.lzy.okgo.OkGo;
|
||||
import com.lzy.okgo.model.Response;
|
||||
import com.microsoft.appcenter.AppCenter;
|
||||
import com.microsoft.appcenter.analytics.Analytics;
|
||||
import com.microsoft.appcenter.crashes.Crashes;
|
||||
import com.zane.smapiinstaller.constant.AppConfigKey;
|
||||
import com.zane.smapiinstaller.constant.Constants;
|
||||
import com.zane.smapiinstaller.constant.DialogAction;
|
||||
import com.zane.smapiinstaller.dto.AppUpdateCheckResultDto;
|
||||
import com.zane.smapiinstaller.entity.AppConfig;
|
||||
import com.zane.smapiinstaller.entity.AppConfigDao;
|
||||
import com.zane.smapiinstaller.entity.DaoSession;
|
||||
import com.zane.smapiinstaller.entity.FrameworkConfig;
|
||||
import com.zane.smapiinstaller.logic.CommonLogic;
|
||||
import com.zane.smapiinstaller.logic.ConfigManager;
|
||||
import com.zane.smapiinstaller.logic.GameLauncher;
|
||||
import com.zane.smapiinstaller.logic.ModAssetsManager;
|
||||
import com.zane.smapiinstaller.utils.DialogUtils;
|
||||
import com.zane.smapiinstaller.utils.JSONUtil;
|
||||
import com.zane.smapiinstaller.utils.JsonCallback;
|
||||
import com.zane.smapiinstaller.utils.TranslateUtil;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -102,6 +109,41 @@ public class MainActivity extends AppCompatActivity {
|
|||
final NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
|
||||
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
|
||||
NavigationUI.setupWithNavController(navigationView, navController);
|
||||
checkAppUpdate();
|
||||
}
|
||||
|
||||
private void checkAppUpdate() {
|
||||
DaoSession daoSession = ((MainApplication) this.getApplication()).getDaoSession();
|
||||
AppConfigDao appConfigDao = daoSession.getAppConfigDao();
|
||||
AppConfig appConfig = appConfigDao.queryBuilder().where(AppConfigDao.Properties.Name.eq(AppConfigKey.IGNORE_UPDATE_VERSION_CODE)).build().unique();
|
||||
OkGo.<AppUpdateCheckResultDto>get(Constants.SELF_UPDATE_CHECK_SERVICE_URL).execute(new JsonCallback<AppUpdateCheckResultDto>(AppUpdateCheckResultDto.class) {
|
||||
@Override
|
||||
public void onSuccess(Response<AppUpdateCheckResultDto> response) {
|
||||
AppUpdateCheckResultDto dto = response.body();
|
||||
if (dto != null && CommonLogic.getVersionCode(MainActivity.this) < dto.getVersionCode()) {
|
||||
if(appConfig != null && StringUtils.equals(appConfig.getValue(), String.valueOf(dto.getVersionCode()))) {
|
||||
return;
|
||||
}
|
||||
DialogUtils.showConfirmDialog(toolbar, R.string.settings_check_for_updates,
|
||||
MainActivity.this.getString(R.string.app_update_detected, dto.getVersionName()), (dialog, which) -> {
|
||||
if (which == DialogAction.POSITIVE) {
|
||||
CommonLogic.openInPlayStore(MainActivity.this);
|
||||
}
|
||||
else {
|
||||
AppConfig config;
|
||||
if(appConfig != null) {
|
||||
config = appConfig;
|
||||
config.setValue(String.valueOf(dto.getVersionCode()));
|
||||
}
|
||||
else {
|
||||
config = new AppConfig(null, AppConfigKey.IGNORE_UPDATE_VERSION_CODE, String.valueOf(dto.getVersionCode()));
|
||||
}
|
||||
appConfigDao.insertOrReplace(config);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@OnClick(R.id.launch)
|
||||
|
@ -170,7 +212,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
selectTranslateServiceLogic();
|
||||
return true;
|
||||
case R.id.toolbar_update_check:
|
||||
updateCheckLogic();
|
||||
checkModUpdateLogic();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
@ -272,11 +314,14 @@ public class MainActivity extends AppCompatActivity {
|
|||
});
|
||||
}
|
||||
|
||||
private void updateCheckLogic() {
|
||||
private void checkModUpdateLogic() {
|
||||
ModAssetsManager modAssetsManager = new ModAssetsManager(toolbar);
|
||||
modAssetsManager.checkModUpdate((list) -> {
|
||||
if (list.isEmpty()) {
|
||||
CommonLogic.runOnUiThread(this, (activity) -> Toast.makeText(activity, R.string.no_update_text, Toast.LENGTH_SHORT).show());
|
||||
}
|
||||
try {
|
||||
NavController controller = Navigation.findNavController(toolbar);
|
||||
NavController controller = Navigation.findNavController(this, R.id.nav_host_fragment);
|
||||
controller.navigate(MobileNavigationDirections.actionNavAnyToModUpdateFragment(JSONUtil.toJson(list)));
|
||||
} catch (Exception e) {
|
||||
Crashes.trackError(e);
|
||||
|
|
|
@ -7,4 +7,6 @@ public class AppConfigKey {
|
|||
public static final String ACTIVE_TRANSLATOR = "ActiveTranslator";
|
||||
|
||||
public static final String MOD_LIST_SORT_BY = "ModListSortBy";
|
||||
|
||||
public static final String IGNORE_UPDATE_VERSION_CODE = "UpdateIgnoreVersionCode";
|
||||
}
|
||||
|
|
|
@ -74,4 +74,9 @@ public class Constants {
|
|||
* SMAPI更新服务
|
||||
*/
|
||||
public static final String UPDATE_CHECK_SERVICE_URL = "https://smapi.io/api/v" + SMAPI_VERSION + "/mods";
|
||||
|
||||
/**
|
||||
* 软件检查更新服务
|
||||
*/
|
||||
public static final String SELF_UPDATE_CHECK_SERVICE_URL = "http://zaneyork.cn/download/app_version.json";
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package com.zane.smapiinstaller.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AppUpdateCheckResultDto {
|
||||
/**
|
||||
* 版本号
|
||||
*/
|
||||
private long versionCode;
|
||||
/**
|
||||
* 版本名称
|
||||
*/
|
||||
private String versionName;
|
||||
}
|
|
@ -14,6 +14,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
|
@ -122,6 +123,7 @@ public class ModUpdateCheckRequestDto {
|
|||
}
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(of = "id")
|
||||
public static class ModInfo {
|
||||
private String id;
|
||||
private List<String> updateKeys;
|
||||
|
|
|
@ -7,7 +7,10 @@ import android.content.ClipboardManager;
|
|||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
@ -94,6 +97,7 @@ public class CommonLogic {
|
|||
|
||||
/**
|
||||
* 在UI线程执行操作
|
||||
*
|
||||
* @param activity activity
|
||||
* @param action 操作
|
||||
*/
|
||||
|
@ -267,4 +271,42 @@ public class CommonLogic {
|
|||
});
|
||||
view.startAnimation(animation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取版本号
|
||||
*
|
||||
* @return 当前应用的版本号
|
||||
*/
|
||||
public static long getVersionCode(Activity activity) {
|
||||
try {
|
||||
PackageManager manager = activity.getPackageManager();
|
||||
PackageInfo info = manager.getPackageInfo(activity.getPackageName(), 0);
|
||||
String version = info.versionName;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
return info.getLongVersionCode();
|
||||
}
|
||||
return info.versionCode;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在谷歌商店打开
|
||||
*
|
||||
* @param activity activity
|
||||
*/
|
||||
public static void openInPlayStore(Activity activity) {
|
||||
CommonLogic.doOnNonNull(activity, (context) -> {
|
||||
try {
|
||||
Intent intent = new Intent("android.intent.action.VIEW");
|
||||
intent.setData(Uri.parse("market://details?id=" + context.getPackageName()));
|
||||
intent.setPackage("com.android.vending");
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
} catch (Exception ex) {
|
||||
CommonLogic.openUrl(activity, "https://play.google.com/store/apps/details?id=" + context.getPackageName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import java9.util.Objects;
|
||||
import java9.util.function.Consumer;
|
||||
|
@ -52,6 +53,8 @@ public class ModAssetsManager {
|
|||
|
||||
private static final String TAG = "MANAGER";
|
||||
|
||||
private final AtomicBoolean checkUpdating = new AtomicBoolean(false);
|
||||
|
||||
public ModAssetsManager(View root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
@ -292,9 +295,13 @@ public class ModAssetsManager {
|
|||
}
|
||||
|
||||
public void checkModUpdate(Consumer<List<ModUpdateCheckResponseDto>> callback) {
|
||||
if(checkUpdating.get()) {
|
||||
return;
|
||||
}
|
||||
List<ModUpdateCheckRequestDto.ModInfo> list = StreamSupport.stream(findAllInstalledMods(false))
|
||||
.filter(mod -> mod.getUpdateKeys() != null && !mod.getUpdateKeys().isEmpty())
|
||||
.map(ModUpdateCheckRequestDto.ModInfo::fromModManifestEntry)
|
||||
.distinct()
|
||||
.filter(modInfo -> modInfo.getInstalledVersion() != null)
|
||||
.collect(Collectors.toList());
|
||||
Activity context = CommonLogic.getActivityFromView(root);
|
||||
|
@ -302,14 +309,22 @@ public class ModAssetsManager {
|
|||
if (gamePackageInfo == null) {
|
||||
return;
|
||||
}
|
||||
checkUpdating.set(true);
|
||||
try {
|
||||
ModUpdateCheckRequestDto requestDto = new ModUpdateCheckRequestDto(list, new ModUpdateCheckRequestDto.SemanticVersion(gamePackageInfo.versionName));
|
||||
OkGo.<List<ModUpdateCheckResponseDto>>post(Constants.UPDATE_CHECK_SERVICE_URL)
|
||||
.upJson(JSONUtil.toJson(requestDto))
|
||||
.execute(new JsonCallback<List<ModUpdateCheckResponseDto>>(new TypeReference<List<ModUpdateCheckResponseDto>>() {
|
||||
}) {
|
||||
@Override
|
||||
public void onError(Response<List<ModUpdateCheckResponseDto>> response) {
|
||||
super.onError(response);
|
||||
checkUpdating.set(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Response<List<ModUpdateCheckResponseDto>> response) {
|
||||
checkUpdating.set(false);
|
||||
List<ModUpdateCheckResponseDto> checkResponseDtos = response.body();
|
||||
if (checkResponseDtos != null) {
|
||||
List<ModUpdateCheckResponseDto> list = StreamSupport.stream(checkResponseDtos).filter(dto -> dto.getSuggestedUpdate() != null).collect(Collectors.toList());
|
||||
|
@ -318,6 +333,7 @@ public class ModAssetsManager {
|
|||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
checkUpdating.set(false);
|
||||
Crashes.trackError(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,11 +47,7 @@ public class AboutFragment extends Fragment {
|
|||
|
||||
@OnClick(R.id.button_gplay)
|
||||
void gplay() {
|
||||
try {
|
||||
CommonLogic.doOnNonNull(this.getActivity(), (activity) -> this.openPlayStore("market://details?id=" + activity.getPackageName()));
|
||||
} catch (Exception ex) {
|
||||
CommonLogic.doOnNonNull(this.getActivity(), (activity) -> CommonLogic.openUrl(activity, "https://play.google.com/store/apps/details?id=" + activity.getPackageName()));
|
||||
}
|
||||
CommonLogic.openInPlayStore(this.getActivity());
|
||||
}
|
||||
|
||||
private void openPlayStore(String url) {
|
||||
|
|
|
@ -50,15 +50,14 @@ public class ConfigEditFragment extends Fragment {
|
|||
View root = inflater.inflate(R.layout.fragment_config_edit, container, false);
|
||||
ButterKnife.bind(this, root);
|
||||
CommonLogic.doOnNonNull(this.getArguments(), arguments -> {
|
||||
editable = arguments.getBoolean("editable");
|
||||
configPath = arguments.getString("configPath");
|
||||
});
|
||||
if (!editable) {
|
||||
editText.setKeyListener(null);
|
||||
buttonConfigSave.setVisibility(View.INVISIBLE);
|
||||
buttonConfigCancel.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
if (configPath != null) {
|
||||
ConfigEditFragmentArgs args = ConfigEditFragmentArgs.fromBundle(arguments);
|
||||
editable = args.getEditable();
|
||||
if (!editable) {
|
||||
editText.setKeyListener(null);
|
||||
buttonConfigSave.setVisibility(View.INVISIBLE);
|
||||
buttonConfigCancel.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
configPath = args.getConfigPath();
|
||||
File file = new File(configPath);
|
||||
if (file.exists() && file.length() < Constants.TEXT_FILE_OPEN_SIZE_LIMIT) {
|
||||
String fileText = FileUtils.getFileText(file);
|
||||
|
@ -87,7 +86,7 @@ public class ConfigEditFragment extends Fragment {
|
|||
onConfigCancel();
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,38 +3,48 @@ package com.zane.smapiinstaller.ui.update;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.zane.smapiinstaller.R;
|
||||
import com.zane.smapiinstaller.dto.ModUpdateCheckResponseDto;
|
||||
import com.zane.smapiinstaller.entity.ModManifestEntry;
|
||||
import com.zane.smapiinstaller.logic.CommonLogic;
|
||||
import com.zane.smapiinstaller.logic.ModAssetsManager;
|
||||
import com.zane.smapiinstaller.utils.VersionUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import java9.util.Optional;
|
||||
import java9.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* {@link RecyclerView.Adapter} that can display a {@link ModUpdateCheckResponseDto.UpdateInfo}
|
||||
*
|
||||
* @author Zane
|
||||
*/
|
||||
public class ModUpdateAdapter extends RecyclerView.Adapter<ModUpdateAdapter.ViewHolder> {
|
||||
|
||||
private List<ModUpdateCheckResponseDto.UpdateInfo> updateInfoList;
|
||||
private final ImmutableListMultimap<String, ModManifestEntry> installedModMap;
|
||||
|
||||
public void setUpdateInfoList(List<ModUpdateCheckResponseDto.UpdateInfo> updateInfoList) {
|
||||
this.updateInfoList = updateInfoList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
private List<ModUpdateCheckResponseDto> updateInfoList;
|
||||
|
||||
public ModUpdateAdapter(List<ModUpdateCheckResponseDto.UpdateInfo> items) {
|
||||
public ModUpdateAdapter(List<ModUpdateCheckResponseDto> items) {
|
||||
updateInfoList = items;
|
||||
installedModMap = Multimaps.index(ModAssetsManager.findAllInstalledMods(), ModManifestEntry::getUniqueID);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.download_content_item, parent, false);
|
||||
.inflate(R.layout.updatable_mod_list_item, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
|
@ -48,16 +58,35 @@ public class ModUpdateAdapter extends RecyclerView.Adapter<ModUpdateAdapter.View
|
|||
return updateInfoList.size();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public ModUpdateCheckResponseDto.UpdateInfo updateInfo;
|
||||
class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public ModUpdateCheckResponseDto updateInfo;
|
||||
@BindView(R.id.text_view_mod_name)
|
||||
TextView textModName;
|
||||
@BindView(R.id.text_view_mod_version)
|
||||
TextView textModVersion;
|
||||
|
||||
public void setUpdateInfo(ModUpdateCheckResponseDto.UpdateInfo updateInfo) {
|
||||
public void setUpdateInfo(ModUpdateCheckResponseDto updateInfo) {
|
||||
this.updateInfo = updateInfo;
|
||||
String id = updateInfo.getId();
|
||||
Optional<ModManifestEntry> mod = StreamSupport.stream(installedModMap.get(id)).sorted((a, b) -> VersionUtil.compareVersion(a.getVersion(), b.getVersion())).findFirst();
|
||||
if (mod.isPresent()) {
|
||||
ModManifestEntry modManifestEntry = mod.get();
|
||||
textModName.setText(modManifestEntry.getName());
|
||||
CommonLogic.doOnNonNull(CommonLogic.getActivityFromView(textModName),
|
||||
activity -> textModVersion.setText(
|
||||
activity.getString(R.string.mod_version_update_text, modManifestEntry.getVersion(), updateInfo.getSuggestedUpdate().getVersion())
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public ViewHolder(View view) {
|
||||
super(view);
|
||||
ButterKnife.bind(this, itemView);
|
||||
}
|
||||
|
||||
@OnClick(R.id.button_update_mod)
|
||||
void onUpdateClick() {
|
||||
CommonLogic.doOnNonNull(CommonLogic.getActivityFromView(textModName), context -> CommonLogic.openUrl(context, updateInfo.getSuggestedUpdate().getUrl()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,9 +42,10 @@ public class ModUpdateFragment extends Fragment {
|
|||
Context context = view.getContext();
|
||||
RecyclerView recyclerView = (RecyclerView) view;
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(context));
|
||||
|
||||
CommonLogic.doOnNonNull(this.getArguments(), arguments -> {
|
||||
String updateInfoListJson = arguments.getString("updateInfoListJson", "[]");
|
||||
List<ModUpdateCheckResponseDto.UpdateInfo> updateInfos = JSONUtil.fromJson(updateInfoListJson, new TypeReference<List<ModUpdateCheckResponseDto.UpdateInfo>>() {
|
||||
String updateInfoListJson = ModUpdateFragmentArgs.fromBundle(arguments).getUpdateInfoListJson();
|
||||
List<ModUpdateCheckResponseDto> updateInfos = JSONUtil.fromJson(updateInfoListJson, new TypeReference<List<ModUpdateCheckResponseDto>>() {
|
||||
});
|
||||
ModUpdateAdapter adapter = new ModUpdateAdapter(updateInfos);
|
||||
recyclerView.setAdapter(adapter);
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.zane.smapiinstaller.utils;
|
|||
import android.app.Activity;
|
||||
import android.text.InputType;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.afollestad.materialdialogs.input.DialogInputExtKt;
|
||||
|
@ -188,20 +187,20 @@ public class DialogUtils {
|
|||
* 解散当前对话框
|
||||
*/
|
||||
public static void dismissDialog() {
|
||||
if (currentDialog != null) {
|
||||
if (currentDialog instanceof MaterialDialog) {
|
||||
MaterialDialog dialog = (MaterialDialog) currentDialog;
|
||||
if (dialog.isShowing()) {
|
||||
try {
|
||||
try {
|
||||
if (currentDialog != null) {
|
||||
if (currentDialog instanceof MaterialDialog) {
|
||||
MaterialDialog dialog = (MaterialDialog) currentDialog;
|
||||
if (dialog.isShowing()) {
|
||||
dialog.dismiss();
|
||||
} catch (Exception e) {
|
||||
Crashes.trackError(e);
|
||||
}
|
||||
} else if (currentDialog instanceof ProgressDialog) {
|
||||
ProgressDialog dialog = (ProgressDialog) currentDialog;
|
||||
dialog.dismiss();
|
||||
}
|
||||
} else if (currentDialog instanceof ProgressDialog) {
|
||||
ProgressDialog dialog = (ProgressDialog) currentDialog;
|
||||
dialog.dismiss();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Crashes.trackError(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="@drawable/horizontal_divider"
|
||||
android:orientation="vertical"
|
||||
android:showDividers="middle">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/text_view_mod_name"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_update_mod"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<Button
|
||||
android:id="@+id/button_update_mod"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:background="@drawable/global"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/text_view_mod_name"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<TextView
|
||||
android:id="@+id/text_view_mod_version"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
|
@ -17,7 +17,10 @@
|
|||
<fragment
|
||||
android:id="@+id/config_edit_fragment"
|
||||
android:name="com.zane.smapiinstaller.ui.config.ConfigEditFragment"
|
||||
android:label="@string/menu_config_edit" />
|
||||
android:label="@string/menu_config_edit" >
|
||||
<argument android:name="configPath" app:argType="string"/>
|
||||
<argument android:name="editable" android:defaultValue="true" app:argType="boolean"/>
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/nav_config"
|
||||
android:name="com.zane.smapiinstaller.ui.config.ConfigFragment"
|
||||
|
@ -58,6 +61,10 @@
|
|||
android:name="com.zane.smapiinstaller.ui.update.ModUpdateFragment"
|
||||
android:label="@string/settings_check_for_updates"
|
||||
tools:layout="@layout/fragment_mod_update_list">
|
||||
<argument
|
||||
android:name="updateInfoListJson"
|
||||
android:defaultValue="{}"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
<action
|
||||
android:id="@+id/action_nav_any_to_mod_update_fragment"
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="donation_methods">
|
||||
<item>支付寶</item>
|
||||
<item>微信</item>
|
||||
<item>QQ</item>
|
||||
<item>紅包碼</item>
|
||||
<item>捐贈列表</item>
|
||||
</string-array>
|
||||
<string-array name="languages">
|
||||
<item>自動</item>
|
||||
<item>English</item>
|
||||
<item>简体中文</item>
|
||||
<item>繁體中文</item>
|
||||
<item>한국어</item>
|
||||
<item>ไทย</item>
|
||||
<item>Español</item>
|
||||
<item>Français</item>
|
||||
<item>Português</item>
|
||||
<item>Bahasa Indonesia</item>
|
||||
</string-array>
|
||||
<string-array name="translators">
|
||||
<item>關閉</item>
|
||||
<item>谷歌</item>
|
||||
<item>有道</item>
|
||||
</string-array>
|
||||
<string-array name="mod_list_sort_by">
|
||||
<item>名稱(正序)</item>
|
||||
<item>名稱(倒序)</item>
|
||||
<item>日期(正序)</item>
|
||||
<item>日期(倒序)</item>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -1,70 +0,0 @@
|
|||
<resources>
|
||||
<string name="abort">中止</string>
|
||||
<string name="android_version_confirm">你的系統版本過老,可能會導致0Harmony無效,建議升級到安卓6及以上版本</string>
|
||||
<string name="app_name">SMAPI安裝器</string>
|
||||
<string name="button_compat">兼容性</string>
|
||||
<string name="button_donation_text">捐贈</string>
|
||||
<string name="button_gplay" >谷歌商店详情</string>
|
||||
<string name="button_install">安裝</string>
|
||||
<string name="button_logs">日誌</string>
|
||||
<string name="button_nexus">N網</string>
|
||||
<string name="button_qq_group_1_text">QQ群①: 860453392</string>
|
||||
<string name="button_qq_group_2_text">QQ群②: 1078428449</string>
|
||||
<string name="button_release">官網</string>
|
||||
<string name="cancel">取消</string>
|
||||
<string name="confirm">確認</string>
|
||||
<string name="confirm_delete_content">確定刪除該內容?</string>
|
||||
<string name="confirm_disable_mod">確定禁用該內容?</string>
|
||||
<string name="continue_text">繼續</string>
|
||||
<string name="download_unpack_success">已完成下載安裝</string>
|
||||
<string name="downloading">正在下載: %1$d KB / %2$d KB</string>
|
||||
<string name="duplicate_mod_found">發現該MOD存在多份拷貝,請從以下位置刪除重複MOD:%s</string>
|
||||
<string name="error">錯誤</string>
|
||||
<string name="error_depends_on_mod">%1$s依賴%2$s前置,請先安裝它</string>
|
||||
<string name="error_depends_on_mod_version" >%1$s依賴%2$s %3$s版本,請先更新它</string>
|
||||
<string name="error_failed_to_create_file">無法創建以下文件: %s</string>
|
||||
<string name="error_failed_to_download">無法下載目標資源</string>
|
||||
<string name="error_failed_to_repair">無法修復SMAPI環境</string>
|
||||
<string name="error_game_not_found">無法找到遊戲本體,你是否安裝了星露穀物語?</string>
|
||||
<string name="error_illegal_path">請輸入一個有效的路徑</string>
|
||||
<string name="error_no_supported_game_version">遊戲版本不支持,請更新版本或者下載兼容包</string>
|
||||
<string name="error_smapi_not_installed">SMAPI尚未安裝,請先點擊安裝按鈕</string>
|
||||
<string name="extracting_package">正在抽取安裝包</string>
|
||||
<string name="failed_to_patch_game">無法修改安裝包,請聯繫開發者獲取幫助</string>
|
||||
<string name="failed_to_process_manifest">無法處理AndroidManifest.xml文件</string>
|
||||
<string name="failed_to_sign_game">無法簽名安裝包,請聯繫開發者獲取幫助</string>
|
||||
<string name="failed_to_unpack_smapi_files">無法解包SMAPI環境</string>
|
||||
<string name="info">提示</string>
|
||||
<string name="input">輸入</string>
|
||||
<string name="input_mods_path">請輸入Mods路徑</string>
|
||||
<string name="install_progress_title">安裝進度</string>
|
||||
<string name="installing_package">正在安裝</string>
|
||||
<string name="locale_pack">語言包</string>
|
||||
<string name="menu_about">關於</string>
|
||||
<string name="menu_config">配置</string>
|
||||
<string name="menu_config_edit">編輯</string>
|
||||
<string name="menu_download">下載</string>
|
||||
<string name="menu_help">幫助</string>
|
||||
<string name="menu_install">安裝</string>
|
||||
<string name="nav_header_subtitle">ZaneYork@qq.com</string>
|
||||
<string name="nav_header_title">SMAPI安裝器</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="patching_package">正在安裝SMAPI補丁</string>
|
||||
<string name="progress">進度</string>
|
||||
<string name="save">保存</string>
|
||||
<string name="settings_check_for_updates">檢查更新</string>
|
||||
<string name="settings_developer_mode">開發者模式</string>
|
||||
<string name="settings_set_language">語言</string>
|
||||
<string name="settings_set_mod_path">設置Mods位置</string>
|
||||
<string name="settings_translation_service">翻譯服務</string>
|
||||
<string name="settings_verbose_logging">詳細日誌</string>
|
||||
<string name="signing_package">正在簽名安裝包</string>
|
||||
<string name="smapi_game_name">SMAPI星露穀物語</string>
|
||||
<string name="smapi_version">SMAPI版本: 3.4.1.1</string>
|
||||
<string name="text_install_tip1">注意:需要不低於1.4.5.138版本的遊戲本體</string>
|
||||
<string name="text_install_tip2">更新或安裝期間需要安裝遊戲本體</string>
|
||||
<string name="unpacking_smapi_files">正在解包</string>
|
||||
<string name="sort_by">排序方式</string>
|
||||
<string name="text_too_large">文本文件過大,無法打開</string>
|
||||
<string name="open_with">打開為</string>
|
||||
</resources>
|
|
@ -67,4 +67,6 @@
|
|||
<string name="sort_by">排序方式</string>
|
||||
<string name="text_too_large">文本文件過大,無法打開</string>
|
||||
<string name="open_with">打開為</string>
|
||||
<string name="no_update_text">所有MOD已是最新狀態</string>
|
||||
<string name="app_update_detected">檢測到新版本: %1$s</string>
|
||||
</resources>
|
||||
|
|
|
@ -67,4 +67,6 @@
|
|||
<string name="sort_by">排序方式</string>
|
||||
<string name="text_too_large">文本文件过大,无法打开</string>
|
||||
<string name="open_with">打开为</string>
|
||||
<string name="no_update_text">所有MOD已是最新状态</string>
|
||||
<string name="app_update_detected">检测到新版本: %1$s</string>
|
||||
</resources>
|
||||
|
|
|
@ -67,7 +67,10 @@
|
|||
|
||||
<string name="toast_redpacket_message" translatable="false">红包码已复制\n支付宝首页搜索“9188262” 立即领红包</string>
|
||||
<string name="icon_desc" translatable="false">icon</string>
|
||||
<string name="mod_version_update_text" translatable="false">%1$s -> %2$s</string>
|
||||
<string name="sort_by">Sort by</string>
|
||||
<string name="text_too_large">Text file is too large for editor</string>
|
||||
<string name="open_with">Open With</string>
|
||||
<string name="no_update_text">All mods are up to date</string>
|
||||
<string name="app_update_detected">New version detected: %1$s</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue