|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 136 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 229 KiB |
|
After Width: | Height: | Size: 172 KiB |
|
After Width: | Height: | Size: 193 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 207 KiB |
|
After Width: | Height: | Size: 247 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 75 KiB |
@ -0,0 +1,15 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-11-14T19:29:26.954556Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\LENOVO\.android\avd\Pixel_9.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceTable">
|
||||
<option name="columnSorters">
|
||||
<list>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="API" />
|
||||
<option name="order" value="DESCENDING" />
|
||||
</ColumnSorterState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="1.9.23" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,323 @@
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State>
|
||||
<id>Abstraction issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>AccessibilityHTML</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>AiExcludeGemini</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android Lint: Accessibility</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android Lint: Compliance</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android Lint: Correctness</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android Lint: Internationalization</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android Lint: Interoperability</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android Lint: Performance</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android Lint: Security</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android Lint: Usability</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Assignment issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Best practisesGradle</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>C/C++</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Class metricsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Class structureJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>ClassNaming conventionsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Cloning issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Code maturityJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Code style issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>CodePlugin DevKit</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Compiler issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Control flow issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Data flowJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Declaration redundancyJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Description filePlugin DevKit</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>EditorConfig</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>EmbeddedPerformanceJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>EncapsulationJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Error handlingJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>FunctionsC/C++</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>GPathGroovy</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Gemini</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>General</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>GeneralC/C++</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Gradle</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Groovy</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>HTML</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>ImportsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Inheritance issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>InitializationJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Internationalization</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>InternationalizationJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>JNIAndroid</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>JUnit</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>JVM languages</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java 11Java language level migration aidsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java 21Java language level migration aidsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java 5Java language level migration aidsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java 7Java language level migration aidsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java 8Java language level migration aidsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java 9Java language level migration aidsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java interop issuesKotlin</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java language level issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java language level migration aidsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>JavaBeans issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>JavadocJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Kotlin</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>LoggingJVM languages</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>LoggingJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Markdown</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>MemoryJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Method metricsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>MethodNaming conventionsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>MigrationKotlin</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Modularization issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Naming conventionsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Nullability problemsProbable bugsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Numeric issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Objective-C</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Other problemsKotlin</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Packaging issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>PerformanceJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Plugin DevKit</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Plugin descriptorPlugin DevKit</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>PortabilityJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Probable bugsGradle</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Probable bugsGroovy</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Probable bugsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Probable bugsKotlin</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Properties files</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Properties filesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Redundant constructsKotlin</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Reflective accessJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>RegExp</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Resource managementJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>SecurityJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Serialization issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>ShrinkerAndroid</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Static Analysis ToolsC/C++</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Style issuesKotlin</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>StyleGroovy</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Test frameworksJVM languages</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Threading issuesGroovy</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Threading issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Unused codeC/C++</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Unused codeObjective-C</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Validity issuesGradle</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Verbose or redundant code constructsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>VisibilityJava</id>
|
||||
</State>
|
||||
</expanded-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings" defaultProject="true" />
|
||||
</project>
|
||||
@ -0,0 +1 @@
|
||||
/build
|
||||
@ -0,0 +1,57 @@
|
||||
{
|
||||
"agcgw_all": {
|
||||
"SG": "connect-dra.dbankcloud.cn",
|
||||
"SG_back": "connect-dra.hispace.hicloud.com",
|
||||
"CN": "connect-drcn.dbankcloud.cn",
|
||||
"CN_back": "connect-drcn.hispace.hicloud.com",
|
||||
"RU": "connect-drru.hispace.dbankcloud.ru",
|
||||
"RU_back": "connect-drru.hispace.dbankcloud.cn",
|
||||
"DE": "connect-dre.dbankcloud.cn",
|
||||
"DE_back": "connect-dre.hispace.hicloud.com"
|
||||
},
|
||||
"websocketgw_all": {
|
||||
"SG": "connect-ws-dra.hispace.dbankcloud.cn",
|
||||
"SG_back": "connect-ws-dra.hispace.dbankcloud.com",
|
||||
"CN": "connect-ws-drcn.hispace.dbankcloud.cn",
|
||||
"CN_back": "connect-ws-drcn.hispace.dbankcloud.com",
|
||||
"RU": "connect-ws-drru.hispace.dbankcloud.ru",
|
||||
"RU_back": "connect-ws-drru.hispace.dbankcloud.cn",
|
||||
"DE": "connect-ws-dre.hispace.dbankcloud.cn",
|
||||
"DE_back": "connect-ws-dre.hispace.dbankcloud.com"
|
||||
},
|
||||
"client": {
|
||||
"cp_id": "10086000906180465",
|
||||
"product_id": "461323198430990500",
|
||||
"client_id": "1818854794438158016",
|
||||
"client_secret": "2F4351B4753DE54BA6A16739AFB492E30A6E3E57E1ECA6247762FAF848C4CA7C",
|
||||
"project_id": "461323198430990500",
|
||||
"app_id": "115935909",
|
||||
"api_key": "DgEDAB2Z+c0etbzB2qi1rq7NbdcidEmy0V1PPV2OZitqiZzhE4baa0oD32QPg7Y5BnlsnTWFqW0v1VLhOSEhYJUPSJ2Qxu4NDIt+Lg==",
|
||||
"package_name": "com.translation.app"
|
||||
},
|
||||
"oauth_client": {
|
||||
"client_id": "115935909",
|
||||
"client_type": 1
|
||||
},
|
||||
"app_info": {
|
||||
"app_id": "115935909",
|
||||
"package_name": "com.translation.app"
|
||||
},
|
||||
"configuration_version": "3.0",
|
||||
"appInfos": [
|
||||
{
|
||||
"package_name": "com.translation.app",
|
||||
"client": {
|
||||
"app_id": "115935909"
|
||||
},
|
||||
"app_info": {
|
||||
"package_name": "com.translation.app",
|
||||
"app_id": "115935909"
|
||||
},
|
||||
"oauth_client": {
|
||||
"client_type": 1,
|
||||
"client_id": "115935909"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,131 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# ========== 基本规则 ==========
|
||||
-optimizations !code/simplification/cast,!field/*,!class/merging/*
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes Signature
|
||||
-keepattributes InnerClasses
|
||||
-keepattributes EnclosingMethod
|
||||
|
||||
# 保留行号信息用于调试
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# ========== 华为 HMS 混淆规则 ==========
|
||||
-keep class com.huawei.hianalytics.**{*;}
|
||||
-keep class com.huawei.updatesdk.**{*;}
|
||||
-keep class com.huawei.hms.**{*;}
|
||||
-keep class com.huawei.agconnect.**{*;}
|
||||
|
||||
# 保留 ML Kit 相关类
|
||||
-keep class com.huawei.hms.ml.**{*;}
|
||||
|
||||
# 保留 HMS 核心类
|
||||
-keep class * extends com.huawei.hms.common.api.Api.ApiOptions$HasOptions { *; }
|
||||
-keep class * extends com.huawei.hms.common.api.Api.ApiOptions$NotRequiredOptions { *; }
|
||||
-keep class * extends com.huawei.hms.common.api.Api.ApiOptions$Optional { *; }
|
||||
|
||||
# 保留 HMS 序列化类
|
||||
-keepclasseswithmembers class * implements com.huawei.hms.common.internal.safeparcel.SafeParcelable {
|
||||
public static final *** CREATOR;
|
||||
}
|
||||
|
||||
# ========== 文档处理库规则 ==========
|
||||
|
||||
# PDFBox 规则
|
||||
-keep class org.apache.pdfbox.** { *; }
|
||||
-keep class com.tom_roush.pdfbox.** { *; }
|
||||
|
||||
# Apache POI 规则
|
||||
-keep class org.apache.poi.** { *; }
|
||||
-keep class org.apache.xmlbeans.** { *; }
|
||||
-keep class schemas.microsoft.com.** { *; }
|
||||
-keep class org.openxmlformats.** { *; }
|
||||
|
||||
# ICU4J 规则
|
||||
-keep class com.ibm.icu.** { *; }
|
||||
|
||||
# Zip4j 规则
|
||||
-keep class net.lingala.zip4j.** { *; }
|
||||
|
||||
# ========== 网络库规则 ==========
|
||||
-keep class com.squareup.okhttp3.** { *; }
|
||||
-keep class okhttp3.** { *; }
|
||||
-keep class com.squareup.retrofit2.** { *; }
|
||||
-keep class retrofit2.** { *; }
|
||||
|
||||
-keepattributes RuntimeVisibleAnnotations
|
||||
-keepattributes RuntimeInvisibleAnnotations
|
||||
-dontwarn okhttp3.**
|
||||
-dontwarn retrofit2.**
|
||||
-keepclasseswithmembers class * {
|
||||
@retrofit2.http.* <methods>;
|
||||
}
|
||||
|
||||
# ========== 项目特定规则 ==========
|
||||
|
||||
# 保留数据类(用于 Room、Gson 等)
|
||||
-keep class com.translation.model.** { *; }
|
||||
-keep class com.translation.entity.** { *; }
|
||||
-keep class com.translation.service.** { *; }
|
||||
|
||||
# 保留构建配置字段
|
||||
-keepclassmembers class com.translation.BuildConfig {
|
||||
public static final *;
|
||||
}
|
||||
|
||||
# 保留 ViewBinding
|
||||
-keep class * extends androidx.viewbinding.ViewBinding {
|
||||
*;
|
||||
}
|
||||
|
||||
# 保留协程相关
|
||||
-keep class kotlinx.coroutines.** { *; }
|
||||
|
||||
# 保留 Glide 相关
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep class * extends com.bumptech.glide.module.AppGlideModule {
|
||||
<init>(...);
|
||||
}
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
|
||||
# 保留 Room 相关
|
||||
-keep class * extends androidx.room.RoomDatabase {
|
||||
*;
|
||||
}
|
||||
|
||||
# 保留序列化相关
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||
private void writeObject(java.io.ObjectOutputStream);
|
||||
private void readObject(java.io.ObjectInputStream);
|
||||
java.lang.Object writeReplace();
|
||||
java.lang.Object readResolve();
|
||||
}
|
||||
|
||||
# ========== 原生方法规则 ==========
|
||||
-keepclasseswithmembers class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# ========== 枚举规则 ==========
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
# ========== 泛型规则 ==========
|
||||
-keepattributes Signature
|
||||
|
||||
# ========== 资源规则 ==========
|
||||
-keepclassmembers class **.R$* {
|
||||
public static <fields>;
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.translation.app;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("com.translation.app", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.translation.app">
|
||||
|
||||
<!-- 权限声明 -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<!-- Android 13+ 分区存储权限 -->
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||
|
||||
<!-- 华为 HMS 所需权限 -->
|
||||
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<!-- 可选:如果需要获取设备信息 -->
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
|
||||
<!-- 添加必要的特性声明 -->
|
||||
<uses-feature
|
||||
android:name="android.hardware.microphone"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.wifi"
|
||||
android:required="false" />
|
||||
|
||||
<application
|
||||
android:name=".TranslationApp"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.TranslationApp"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="31"
|
||||
tools:ignore="GoogleAppIndexingWarning"
|
||||
tools:replace="android:allowBackup">
|
||||
|
||||
<!-- 华为 AGConnect 配置 -->
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.client.appid"
|
||||
android:value="appid=你的应用ID" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.huawei.agconnect.app"
|
||||
android:value="@string/agconnect_app_id" />
|
||||
|
||||
<!-- 华为 ML Kit 配置 -->
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.ml.enable_mlkit_log"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.ml.enable_mlkit_monitor"
|
||||
android:value="true" />
|
||||
|
||||
<!-- ML Kit 翻译服务配置 -->
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.ml.translate.enable_service"
|
||||
android:value="true" />
|
||||
|
||||
<!-- 华为分析服务配置 -->
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.analytics.globalKey.autoReportEnabled"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.analytics.globalKey.autoInitEnabled"
|
||||
android:value="true" />
|
||||
|
||||
<!-- HMS Core SDK 版本 -->
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.version"
|
||||
android:value="6.11.0.300" />
|
||||
|
||||
<!-- 修正 Activity 路径 -->
|
||||
<activity
|
||||
android:name="com.translation.activity.LoginActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.TranslationApp.Launcher"
|
||||
android:screenOrientation="portrait"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- 主翻译页面 -->
|
||||
<activity
|
||||
android:name="com.translation.activity.MainTranslationActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.TranslationApp"
|
||||
android:screenOrientation="portrait"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden" />
|
||||
|
||||
<!-- 历史记录页面 -->
|
||||
<activity
|
||||
android:name="com.translation.activity.HistoryActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.TranslationApp"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 标签管理页面 -->
|
||||
<activity
|
||||
android:name="com.translation.activity.TagManagementActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.TranslationApp"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 设置页面 -->
|
||||
<activity
|
||||
android:name="com.translation.activity.SettingsActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.TranslationApp"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 标签记录页面 -->
|
||||
<activity
|
||||
android:name="com.translation.activity.TagRecordsActivity"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.TranslationApp"
|
||||
android:screenOrientation="portrait" />
|
||||
|
||||
<!-- 文件提供者 -->
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<!-- HMS Core 服务组件 -->
|
||||
<service
|
||||
android:name="com.huawei.hms.opendevice.OpenDeviceService"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name="com.huawei.hms.support.api.push.service.HmsMsgService"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"fileName": "dictionary_de_zh.json",
|
||||
"fileContent": {
|
||||
"entries": [
|
||||
{"source": "Hallo", "target": "你好"},
|
||||
{"source": "Danke", "target": "谢谢"},
|
||||
{"source": "Entschuldigung", "target": "对不起"},
|
||||
{"source": "Auf Wiedersehen", "target": "再见"},
|
||||
{"source": "Ja", "target": "是"},
|
||||
{"source": "Nein", "target": "不"},
|
||||
{"source": "Ich", "target": "我"},
|
||||
{"source": "Du", "target": "你"},
|
||||
{"source": "Er", "target": "他"},
|
||||
{"source": "Sie", "target": "她"},
|
||||
{"source": "Wir", "target": "我们"},
|
||||
{"source": "Sie", "target": "他们"},
|
||||
{"source": "Zeit", "target": "时间"},
|
||||
{"source": "Heute", "target": "今天"},
|
||||
{"source": "Morgen", "target": "明天"},
|
||||
{"source": "Liebe", "target": "爱"},
|
||||
{"source": "Familie", "target": "家庭"},
|
||||
{"source": "Freund", "target": "朋友"},
|
||||
{"source": "Schule", "target": "学校"},
|
||||
{"source": "Arbeit", "target": "工作"},
|
||||
{"source": "Computer", "target": "电脑"},
|
||||
{"source": "Handy", "target": "手机"},
|
||||
{"source": "Auto", "target": "汽车"},
|
||||
{"source": "Geld", "target": "钱"},
|
||||
{"source": "Musik", "target": "音乐"},
|
||||
{"source": "Buch", "target": "书"},
|
||||
{"source": "Wasser", "target": "水"},
|
||||
{"source": "Essen", "target": "食物"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "hello", "target": "こんにちは"},
|
||||
{"source": "world", "target": "世界"},
|
||||
{"source": "thank you", "target": "ありがとう"},
|
||||
{"source": "sorry", "target": "すみません"},
|
||||
{"source": "goodbye", "target": "さようなら"},
|
||||
{"source": "yes", "target": "はい"},
|
||||
{"source": "no", "target": "いいえ"},
|
||||
{"source": "time", "target": "時間"},
|
||||
{"source": "today", "target": "今日"},
|
||||
{"source": "tomorrow", "target": "明日"},
|
||||
{"source": "love", "target": "愛"},
|
||||
{"source": "friend", "target": "友達"},
|
||||
{"source": "family", "target": "家族"},
|
||||
{"source": "school", "target": "学校"},
|
||||
{"source": "work", "target": "仕事"},
|
||||
{"source": "computer", "target": "コンピューター"},
|
||||
{"source": "phone", "target": "電話"},
|
||||
{"source": "car", "target": "車"},
|
||||
{"source": "money", "target": "お金"},
|
||||
{"source": "music", "target": "音楽"},
|
||||
{"source": "movie", "target": "映画"},
|
||||
{"source": "book", "target": "本"},
|
||||
{"source": "water", "target": "水"},
|
||||
{"source": "food", "target": "食べ物"},
|
||||
{"source": "coffee", "target": "コーヒー"},
|
||||
{"source": "tea", "target": "お茶"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "hello", "target": "你好"},
|
||||
{"source": "world", "target": "世界"},
|
||||
{"source": "translation", "target": "翻译"},
|
||||
{"source": "language", "target": "语言"},
|
||||
{"source": "learn", "target": "学习"},
|
||||
{"source": "work", "target": "工作"},
|
||||
{"source": "time", "target": "时间"},
|
||||
{"source": "today", "target": "今天"},
|
||||
{"source": "tomorrow", "target": "明天"},
|
||||
{"source": "thank you", "target": "谢谢"},
|
||||
{"source": "sorry", "target": "对不起"},
|
||||
{"source": "yes", "target": "是的"},
|
||||
{"source": "no", "target": "不"},
|
||||
{"source": "good", "target": "好"},
|
||||
{"source": "bad", "target": "坏"},
|
||||
{"source": "big", "target": "大"},
|
||||
{"source": "small", "target": "小"},
|
||||
{"source": "fast", "target": "快"},
|
||||
{"source": "slow", "target": "慢"},
|
||||
{"source": "hot", "target": "热"},
|
||||
{"source": "cold", "target": "冷"},
|
||||
{"source": "water", "target": "水"},
|
||||
{"source": "food", "target": "食物"},
|
||||
{"source": "love", "target": "爱"},
|
||||
{"source": "family", "target": "家庭"},
|
||||
{"source": "friend", "target": "朋友"},
|
||||
{"source": "school", "target": "学校"},
|
||||
{"source": "teacher", "target": "老师"},
|
||||
{"source": "student", "target": "学生"},
|
||||
{"source": "book", "target": "书"},
|
||||
{"source": "computer", "target": "电脑"},
|
||||
{"source": "phone", "target": "手机"},
|
||||
{"source": "car", "target": "汽车"},
|
||||
{"source": "house", "target": "房子"},
|
||||
{"source": "city", "target": "城市"},
|
||||
{"source": "country", "target": "国家"},
|
||||
{"source": "people", "target": "人民"},
|
||||
{"source": "government", "target": "政府"},
|
||||
{"source": "economy", "target": "经济"},
|
||||
{"source": "culture", "target": "文化"},
|
||||
{"source": "history", "target": "历史"},
|
||||
{"source": "science", "target": "科学"},
|
||||
{"source": "technology", "target": "技术"},
|
||||
{"source": "art", "target": "艺术"},
|
||||
{"source": "music", "target": "音乐"},
|
||||
{"source": "movie", "target": "电影"},
|
||||
{"source": "sports", "target": "体育"},
|
||||
{"source": "health", "target": "健康"},
|
||||
{"source": "hospital", "target": "医院"},
|
||||
{"source": "doctor", "target": "医生"},
|
||||
{"source": "money", "target": "钱"},
|
||||
{"source": "price", "target": "价格"},
|
||||
{"source": "market", "target": "市场"},
|
||||
{"source": "company", "target": "公司"},
|
||||
{"source": "job", "target": "工作"},
|
||||
{"source": "salary", "target": "工资"},
|
||||
{"source": "travel", "target": "旅行"},
|
||||
{"source": "airplane", "target": "飞机"},
|
||||
{"source": "train", "target": "火车"},
|
||||
{"source": "hotel", "target": "酒店"},
|
||||
{"source": "restaurant", "target": "餐厅"},
|
||||
{"source": "food", "target": "食物"},
|
||||
{"source": "drink", "target": "饮料"},
|
||||
{"source": "coffee", "target": "咖啡"},
|
||||
{"source": "tea", "target": "茶"},
|
||||
{"source": "fruit", "target": "水果"},
|
||||
{"source": "apple", "target": "苹果"},
|
||||
{"source": "banana", "target": "香蕉"},
|
||||
{"source": "orange", "target": "橙色"},
|
||||
{"source": "red", "target": "红色"},
|
||||
{"source": "blue", "target": "蓝色"},
|
||||
{"source": "green", "target": "绿色"},
|
||||
{"source": "yellow", "target": "黄色"},
|
||||
{"source": "black", "target": "黑色"},
|
||||
{"source": "white", "target": "白色"},
|
||||
{"source": "one", "target": "一"},
|
||||
{"source": "two", "target": "二"},
|
||||
{"source": "three", "target": "三"},
|
||||
{"source": "four", "target": "四"},
|
||||
{"source": "five", "target": "五"},
|
||||
{"source": "six", "target": "六"},
|
||||
{"source": "seven", "target": "七"},
|
||||
{"source": "eight", "target": "八"},
|
||||
{"source": "nine", "target": "九"},
|
||||
{"source": "ten", "target": "十"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"fileName": "dictionary_es_zh.json",
|
||||
"fileContent": {
|
||||
"entries": [
|
||||
{"source": "Hola", "target": "你好"},
|
||||
{"source": "Gracias", "target": "谢谢"},
|
||||
{"source": "Lo siento", "target": "对不起"},
|
||||
{"source": "Adiós", "target": "再见"},
|
||||
{"source": "Sí", "target": "是"},
|
||||
{"source": "No", "target": "不"},
|
||||
{"source": "Yo", "target": "我"},
|
||||
{"source": "Tú", "target": "你"},
|
||||
{"source": "Él", "target": "他"},
|
||||
{"source": "Ella", "target": "她"},
|
||||
{"source": "Nosotros", "target": "我们"},
|
||||
{"source": "Ellos", "target": "他们"},
|
||||
{"source": "Tiempo", "target": "时间"},
|
||||
{"source": "Hoy", "target": "今天"},
|
||||
{"source": "Mañana", "target": "明天"},
|
||||
{"source": "Amor", "target": "爱"},
|
||||
{"source": "Familia", "target": "家庭"},
|
||||
{"source": "Amigo", "target": "朋友"},
|
||||
{"source": "Escuela", "target": "学校"},
|
||||
{"source": "Trabajo", "target": "工作"},
|
||||
{"source": "Computadora", "target": "电脑"},
|
||||
{"source": "Teléfono", "target": "手机"},
|
||||
{"source": "Coche", "target": "汽车"},
|
||||
{"source": "Dinero", "target": "钱"},
|
||||
{"source": "Música", "target": "音乐"},
|
||||
{"source": "Libro", "target": "书"},
|
||||
{"source": "Agua", "target": "水"},
|
||||
{"source": "Comida", "target": "食物"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "bonjour", "target": "你好"},
|
||||
{"source": "merci", "target": "谢谢"},
|
||||
{"source": "désolé", "target": "对不起"},
|
||||
{"source": "au revoir", "target": "再见"},
|
||||
{"source": "oui", "target": "是"},
|
||||
{"source": "non", "target": "不"},
|
||||
{"source": "je", "target": "我"},
|
||||
{"source": "tu", "target": "你"},
|
||||
{"source": "il", "target": "他"},
|
||||
{"source": "elle", "target": "她"},
|
||||
{"source": "nous", "target": "我们"},
|
||||
{"source": "ils", "target": "他们"},
|
||||
{"source": "ceci", "target": "这个"},
|
||||
{"source": "cela", "target": "那个"},
|
||||
{"source": "quoi", "target": "什么"},
|
||||
{"source": "où", "target": "哪里"},
|
||||
{"source": "pourquoi", "target": "为什么"},
|
||||
{"source": "comment", "target": "如何"},
|
||||
{"source": "temps", "target": "时间"},
|
||||
{"source": "aujourd'hui", "target": "今天"},
|
||||
{"source": "demain", "target": "明天"},
|
||||
{"source": "hier", "target": "昨天"},
|
||||
{"source": "amour", "target": "爱"},
|
||||
{"source": "famille", "target": "家庭"},
|
||||
{"source": "ami", "target": "朋友"},
|
||||
{"source": "école", "target": "学校"},
|
||||
{"source": "travail", "target": "工作"},
|
||||
{"source": "manger", "target": "吃饭"},
|
||||
{"source": "eau", "target": "水"},
|
||||
{"source": "étudier", "target": "学习"},
|
||||
{"source": "chine", "target": "中国"},
|
||||
{"source": "france", "target": "法国"},
|
||||
{"source": "paris", "target": "巴黎"},
|
||||
{"source": "pékin", "target": "北京"},
|
||||
{"source": "pomme", "target": "苹果"},
|
||||
{"source": "banane", "target": "香蕉"},
|
||||
{"source": "thé", "target": "茶"},
|
||||
{"source": "café", "target": "咖啡"},
|
||||
{"source": "livre", "target": "书"},
|
||||
{"source": "ordinateur", "target": "电脑"},
|
||||
{"source": "téléphone", "target": "手机"},
|
||||
{"source": "voiture", "target": "汽车"},
|
||||
{"source": "argent", "target": "钱"},
|
||||
{"source": "musique", "target": "音乐"},
|
||||
{"source": "film", "target": "电影"},
|
||||
{"source": "grand", "target": "大"},
|
||||
{"source": "petit", "target": "小"},
|
||||
{"source": "bon", "target": "好"},
|
||||
{"source": "mauvais", "target": "坏"},
|
||||
{"source": "chaud", "target": "热"},
|
||||
{"source": "froid", "target": "冷"},
|
||||
{"source": "nouveau", "target": "新"},
|
||||
{"source": "vieux", "target": "旧"},
|
||||
{"source": "rouge", "target": "红色"},
|
||||
{"source": "bleu", "target": "蓝色"},
|
||||
{"source": "vert", "target": "绿色"},
|
||||
{"source": "blanc", "target": "白色"},
|
||||
{"source": "noir", "target": "黑色"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"fileName": "dictionary_it_zh.json",
|
||||
"fileContent": {
|
||||
"entries": [
|
||||
{"source": "Ciao", "target": "你好"},
|
||||
{"source": "Grazie", "target": "谢谢"},
|
||||
{"source": "Scusa", "target": "对不起"},
|
||||
{"source": "Arrivederci", "target": "再见"},
|
||||
{"source": "Sì", "target": "是"},
|
||||
{"source": "No", "target": "不"},
|
||||
{"source": "Io", "target": "我"},
|
||||
{"source": "Tu", "target": "你"},
|
||||
{"source": "Lui", "target": "他"},
|
||||
{"source": "Lei", "target": "她"},
|
||||
{"source": "Noi", "target": "我们"},
|
||||
{"source": "Loro", "target": "他们"},
|
||||
{"source": "Tempo", "target": "时间"},
|
||||
{"source": "Oggi", "target": "今天"},
|
||||
{"source": "Domani", "target": "明天"},
|
||||
{"source": "Amore", "target": "爱"},
|
||||
{"source": "Famiglia", "target": "家庭"},
|
||||
{"source": "Amico", "target": "朋友"},
|
||||
{"source": "Scuola", "target": "学校"},
|
||||
{"source": "Lavoro", "target": "工作"},
|
||||
{"source": "Computer", "target": "电脑"},
|
||||
{"source": "Telefono", "target": "手机"},
|
||||
{"source": "Macchina", "target": "汽车"},
|
||||
{"source": "Soldi", "target": "钱"},
|
||||
{"source": "Musica", "target": "音乐"},
|
||||
{"source": "Libro", "target": "书"},
|
||||
{"source": "Acqua", "target": "水"},
|
||||
{"source": "Cibo", "target": "食物"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "こんにちは", "target": "hello"},
|
||||
{"source": "世界", "target": "world"},
|
||||
{"source": "ありがとう", "target": "thank you"},
|
||||
{"source": "すみません", "target": "sorry"},
|
||||
{"source": "さようなら", "target": "goodbye"},
|
||||
{"source": "はい", "target": "yes"},
|
||||
{"source": "いいえ", "target": "no"},
|
||||
{"source": "時間", "target": "time"},
|
||||
{"source": "今日", "target": "today"},
|
||||
{"source": "明日", "target": "tomorrow"},
|
||||
{"source": "愛", "target": "love"},
|
||||
{"source": "友達", "target": "friend"},
|
||||
{"source": "家族", "target": "family"},
|
||||
{"source": "学校", "target": "school"},
|
||||
{"source": "仕事", "target": "work"},
|
||||
{"source": "コンピューター", "target": "computer"},
|
||||
{"source": "電話", "target": "phone"},
|
||||
{"source": "車", "target": "car"},
|
||||
{"source": "お金", "target": "money"},
|
||||
{"source": "音楽", "target": "music"},
|
||||
{"source": "映画", "target": "movie"},
|
||||
{"source": "本", "target": "book"},
|
||||
{"source": "水", "target": "water"},
|
||||
{"source": "食べ物", "target": "food"},
|
||||
{"source": "コーヒー", "target": "coffee"},
|
||||
{"source": "お茶", "target": "tea"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "こんにちは", "target": "你好"},
|
||||
{"source": "ありがとう", "target": "谢谢"},
|
||||
{"source": "すみません", "target": "对不起"},
|
||||
{"source": "さようなら", "target": "再见"},
|
||||
{"source": "はい", "target": "是"},
|
||||
{"source": "いいえ", "target": "不"},
|
||||
{"source": "私", "target": "我"},
|
||||
{"source": "あなた", "target": "你"},
|
||||
{"source": "彼", "target": "他"},
|
||||
{"source": "彼女", "target": "她"},
|
||||
{"source": "私たち", "target": "我们"},
|
||||
{"source": "彼ら", "target": "他们"},
|
||||
{"source": "これ", "target": "这个"},
|
||||
{"source": "それ", "target": "那个"},
|
||||
{"source": "何", "target": "什么"},
|
||||
{"source": "どこ", "target": "哪里"},
|
||||
{"source": "なぜ", "target": "为什么"},
|
||||
{"source": "時間", "target": "时间"},
|
||||
{"source": "今日", "target": "今天"},
|
||||
{"source": "明日", "target": "明天"},
|
||||
{"source": "昨日", "target": "昨天"},
|
||||
{"source": "愛", "target": "爱"},
|
||||
{"source": "家族", "target": "家庭"},
|
||||
{"source": "友達", "target": "朋友"},
|
||||
{"source": "学校", "target": "学校"},
|
||||
{"source": "仕事", "target": "工作"},
|
||||
{"source": "食事", "target": "吃饭"},
|
||||
{"source": "水", "target": "水"},
|
||||
{"source": "勉強", "target": "学习"},
|
||||
{"source": "中国", "target": "中国"},
|
||||
{"source": "日本", "target": "日本"},
|
||||
{"source": "東京", "target": "东京"},
|
||||
{"source": "北京", "target": "北京"},
|
||||
{"source": "りんご", "target": "苹果"},
|
||||
{"source": "バナナ", "target": "香蕉"},
|
||||
{"source": "お茶", "target": "茶"},
|
||||
{"source": "コーヒー", "target": "咖啡"},
|
||||
{"source": "本", "target": "书"},
|
||||
{"source": "コンピューター", "target": "电脑"},
|
||||
{"source": "携帯電話", "target": "手机"},
|
||||
{"source": "車", "target": "汽车"},
|
||||
{"source": "お金", "target": "钱"},
|
||||
{"source": "音楽", "target": "音乐"},
|
||||
{"source": "映画", "target": "电影"},
|
||||
{"source": "大きい", "target": "大"},
|
||||
{"source": "小さい", "target": "小"},
|
||||
{"source": "良い", "target": "好"},
|
||||
{"source": "悪い", "target": "坏"},
|
||||
{"source": "熱い", "target": "热"},
|
||||
{"source": "冷たい", "target": "冷"},
|
||||
{"source": "新しい", "target": "新"},
|
||||
{"source": "古い", "target": "旧"},
|
||||
{"source": "赤", "target": "红色"},
|
||||
{"source": "青", "target": "蓝色"},
|
||||
{"source": "緑", "target": "绿色"},
|
||||
{"source": "白", "target": "白色"},
|
||||
{"source": "黒", "target": "黑色"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "안녕하세요", "target": "你好"},
|
||||
{"source": "감사합니다", "target": "谢谢"},
|
||||
{"source": "죄송합니다", "target": "对不起"},
|
||||
{"source": "안녕히 가세요", "target": "再见"},
|
||||
{"source": "네", "target": "是"},
|
||||
{"source": "아니요", "target": "不"},
|
||||
{"source": "나", "target": "我"},
|
||||
{"source": "너", "target": "你"},
|
||||
{"source": "그", "target": "他"},
|
||||
{"source": "그녀", "target": "她"},
|
||||
{"source": "우리", "target": "我们"},
|
||||
{"source": "그들", "target": "他们"},
|
||||
{"source": "이것", "target": "这个"},
|
||||
{"source": "그것", "target": "那个"},
|
||||
{"source": "무엇", "target": "什么"},
|
||||
{"source": "어디", "target": "哪里"},
|
||||
{"source": "왜", "target": "为什么"},
|
||||
{"source": "시간", "target": "时间"},
|
||||
{"source": "오늘", "target": "今天"},
|
||||
{"source": "내일", "target": "明天"},
|
||||
{"source": "어제", "target": "昨天"},
|
||||
{"source": "사랑", "target": "爱"},
|
||||
{"source": "가족", "target": "家庭"},
|
||||
{"source": "친구", "target": "朋友"},
|
||||
{"source": "학교", "target": "学校"},
|
||||
{"source": "일", "target": "工作"},
|
||||
{"source": "식사", "target": "吃饭"},
|
||||
{"source": "물", "target": "水"},
|
||||
{"source": "공부", "target": "学习"},
|
||||
{"source": "중국", "target": "中国"},
|
||||
{"source": "한국", "target": "韩国"},
|
||||
{"source": "서울", "target": "首尔"},
|
||||
{"source": "베이징", "target": "北京"},
|
||||
{"source": "사과", "target": "苹果"},
|
||||
{"source": "바나나", "target": "香蕉"},
|
||||
{"source": "차", "target": "茶"},
|
||||
{"source": "커피", "target": "咖啡"},
|
||||
{"source": "책", "target": "书"},
|
||||
{"source": "컴퓨터", "target": "电脑"},
|
||||
{"source": "휴대폰", "target": "手机"},
|
||||
{"source": "자동차", "target": "汽车"},
|
||||
{"source": "돈", "target": "钱"},
|
||||
{"source": "음악", "target": "音乐"},
|
||||
{"source": "영화", "target": "电影"},
|
||||
{"source": "크다", "target": "大"},
|
||||
{"source": "작다", "target": "小"},
|
||||
{"source": "좋다", "target": "好"},
|
||||
{"source": "나쁘다", "target": "坏"},
|
||||
{"source": "뜨겁다", "target": "热"},
|
||||
{"source": "차갑다", "target": "冷"},
|
||||
{"source": "새로운", "target": "新"},
|
||||
{"source": "오래된", "target": "旧"},
|
||||
{"source": "빨간색", "target": "红色"},
|
||||
{"source": "파란색", "target": "蓝色"},
|
||||
{"source": "초록색", "target": "绿色"},
|
||||
{"source": "하얀색", "target": "白色"},
|
||||
{"source": "검은색", "target": "黑色"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"fileName": "dictionary_pt_zh.json",
|
||||
"fileContent": {
|
||||
"entries": [
|
||||
{"source": "Olá", "target": "你好"},
|
||||
{"source": "Obrigado", "target": "谢谢"},
|
||||
{"source": "Desculpe", "target": "对不起"},
|
||||
{"source": "Adeus", "target": "再见"},
|
||||
{"source": "Sim", "target": "是"},
|
||||
{"source": "Não", "target": "不"},
|
||||
{"source": "Eu", "target": "我"},
|
||||
{"source": "Você", "target": "你"},
|
||||
{"source": "Ele", "target": "他"},
|
||||
{"source": "Ela", "target": "她"},
|
||||
{"source": "Nós", "target": "我们"},
|
||||
{"source": "Eles", "target": "他们"},
|
||||
{"source": "Tempo", "target": "时间"},
|
||||
{"source": "Hoje", "target": "今天"},
|
||||
{"source": "Amanhã", "target": "明天"},
|
||||
{"source": "Amor", "target": "爱"},
|
||||
{"source": "Família", "target": "家庭"},
|
||||
{"source": "Amigo", "target": "朋友"},
|
||||
{"source": "Escola", "target": "学校"},
|
||||
{"source": "Trabalho", "target": "工作"},
|
||||
{"source": "Computador", "target": "电脑"},
|
||||
{"source": "Telefone", "target": "手机"},
|
||||
{"source": "Carro", "target": "汽车"},
|
||||
{"source": "Dinheiro", "target": "钱"},
|
||||
{"source": "Música", "target": "音乐"},
|
||||
{"source": "Livro", "target": "书"},
|
||||
{"source": "Água", "target": "水"},
|
||||
{"source": "Comida", "target": "食物"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
{
|
||||
"fileName": "dictionary_ru_zh.json",
|
||||
"fileContent": {
|
||||
"entries": [
|
||||
{"source": "Здравствуйте", "target": "你好"},
|
||||
{"source": "Спасибо", "target": "谢谢"},
|
||||
{"source": "Извините", "target": "对不起"},
|
||||
{"source": "До свидания", "target": "再见"},
|
||||
{"source": "Да", "target": "是"},
|
||||
{"source": "Нет", "target": "不"},
|
||||
{"source": "Я", "target": "我"},
|
||||
{"source": "Ты", "target": "你"},
|
||||
{"source": "Он", "target": "他"},
|
||||
{"source": "Она", "target": "她"},
|
||||
{"source": "Мы", "target": "我们"},
|
||||
{"source": "Они", "target": "他们"},
|
||||
{"source": "Время", "target": "时间"},
|
||||
{"source": "Сегодня", "target": "今天"},
|
||||
{"source": "Завтра", "target": "明天"},
|
||||
{"source": "Любовь", "target": "爱"},
|
||||
{"source": "Семья", "target": "家庭"},
|
||||
{"source": "Друг", "target": "朋友"},
|
||||
{"source": "Школа", "target": "学校"},
|
||||
{"source": "Работа", "target": "工作"},
|
||||
{"source": "Компьютер", "target": "电脑"},
|
||||
{"source": "Телефон", "target": "手机"},
|
||||
{"source": "Машина", "target": "汽车"},
|
||||
{"source": "Деньги", "target": "钱"},
|
||||
{"source": "Музыка", "target": "音乐"},
|
||||
{"source": "Книга", "target": "书"},
|
||||
{"source": "Вода", "target": "水"},
|
||||
{"source": "Еда", "target": "食物"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
{
|
||||
"fileName": "dictionary_zh_de.json",
|
||||
"fileContent": {
|
||||
"entries": [
|
||||
{"source": "你好", "target": "Hallo"},
|
||||
{"source": "谢谢", "target": "Danke"},
|
||||
{"source": "对不起", "target": "Entschuldigung"},
|
||||
{"source": "再见", "target": "Auf Wiedersehen"},
|
||||
{"source": "是", "target": "Ja"},
|
||||
{"source": "不", "target": "Nein"},
|
||||
{"source": "我", "target": "Ich"},
|
||||
{"source": "你", "target": "Du"},
|
||||
{"source": "他", "target": "Er"},
|
||||
{"source": "她", "target": "Sie"},
|
||||
{"source": "我们", "target": "Wir"},
|
||||
{"source": "他们", "target": "Sie"},
|
||||
{"source": "这个", "target": "Dies"},
|
||||
{"source": "那个", "target": "Das"},
|
||||
{"source": "什么", "target": "Was"},
|
||||
{"source": "哪里", "target": "Wo"},
|
||||
{"source": "为什么", "target": "Warum"},
|
||||
{"source": "如何", "target": "Wie"},
|
||||
{"source": "时间", "target": "Zeit"},
|
||||
{"source": "今天", "target": "Heute"},
|
||||
{"source": "明天", "target": "Morgen"},
|
||||
{"source": "昨天", "target": "Gestern"},
|
||||
{"source": "爱", "target": "Liebe"},
|
||||
{"source": "家庭", "target": "Familie"},
|
||||
{"source": "朋友", "target": "Freund"},
|
||||
{"source": "学校", "target": "Schule"},
|
||||
{"source": "工作", "target": "Arbeit"},
|
||||
{"source": "学习", "target": "Lernen"},
|
||||
{"source": "吃饭", "target": "Essen"},
|
||||
{"source": "喝水", "target": "Wasser trinken"},
|
||||
{"source": "睡觉", "target": "Schlafen"},
|
||||
{"source": "中国", "target": "China"},
|
||||
{"source": "美国", "target": "Amerika"},
|
||||
{"source": "日本", "target": "Japan"},
|
||||
{"source": "韩国", "target": "Korea"},
|
||||
{"source": "法国", "target": "Frankreich"},
|
||||
{"source": "德国", "target": "Deutschland"},
|
||||
{"source": "西班牙", "target": "Spanien"},
|
||||
{"source": "俄罗斯", "target": "Russland"},
|
||||
{"source": "苹果", "target": "Apfel"},
|
||||
{"source": "香蕉", "target": "Banane"},
|
||||
{"source": "水", "target": "Wasser"},
|
||||
{"source": "茶", "target": "Tee"},
|
||||
{"source": "咖啡", "target": "Kaffee"},
|
||||
{"source": "书", "target": "Buch"},
|
||||
{"source": "电脑", "target": "Computer"},
|
||||
{"source": "手机", "target": "Handy"},
|
||||
{"source": "汽车", "target": "Auto"},
|
||||
{"source": "房子", "target": "Haus"},
|
||||
{"source": "钱", "target": "Geld"},
|
||||
{"source": "音乐", "target": "Musik"},
|
||||
{"source": "电影", "target": "Film"},
|
||||
{"source": "大", "target": "Groß"},
|
||||
{"source": "小", "target": "Klein"},
|
||||
{"source": "好", "target": "Gut"},
|
||||
{"source": "坏", "target": "Schlecht"},
|
||||
{"source": "热", "target": "Heiß"},
|
||||
{"source": "冷", "target": "Kalt"},
|
||||
{"source": "新", "target": "Neu"},
|
||||
{"source": "旧", "target": "Alt"},
|
||||
{"source": "红色", "target": "Rot"},
|
||||
{"source": "蓝色", "target": "Blau"},
|
||||
{"source": "绿色", "target": "Grün"},
|
||||
{"source": "白色", "target": "Weiß"},
|
||||
{"source": "黑色", "target": "Schwarz"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "你好", "target": "Hello"},
|
||||
{"source": "谢谢", "target": "Thank you"},
|
||||
{"source": "再见", "target": "Goodbye"},
|
||||
{"source": "是", "target": "Yes"},
|
||||
{"source": "不", "target": "No"},
|
||||
{"source": "我", "target": "I"},
|
||||
{"source": "你", "target": "You"},
|
||||
{"source": "他", "target": "He"},
|
||||
{"source": "她", "target": "She"},
|
||||
{"source": "我们", "target": "We"},
|
||||
{"source": "他们", "target": "They"},
|
||||
{"source": "这个", "target": "This"},
|
||||
{"source": "那个", "target": "That"},
|
||||
{"source": "什么", "target": "What"},
|
||||
{"source": "哪里", "target": "Where"},
|
||||
{"source": "为什么", "target": "Why"},
|
||||
{"source": "如何", "target": "How"},
|
||||
{"source": "时间", "target": "Time"},
|
||||
{"source": "今天", "target": "Today"},
|
||||
{"source": "明天", "target": "Tomorrow"},
|
||||
{"source": "爱", "target": "Love"},
|
||||
{"source": "家", "target": "Home"},
|
||||
{"source": "学校", "target": "School"},
|
||||
{"source": "工作", "target": "Work"},
|
||||
{"source": "吃饭", "target": "Eat"},
|
||||
{"source": "喝水", "target": "Drink"},
|
||||
{"source": "学习", "target": "Study"},
|
||||
{"source": "朋友", "target": "Friend"},
|
||||
{"source": "家人", "target": "Family"},
|
||||
{"source": "中国", "target": "China"},
|
||||
{"source": "美国", "target": "America"},
|
||||
{"source": "英国", "target": "England"},
|
||||
{"source": "日本", "target": "Japan"},
|
||||
{"source": "韩国", "target": "Korea"},
|
||||
{"source": "法国", "target": "France"},
|
||||
{"source": "德国", "target": "Germany"},
|
||||
{"source": "俄罗斯", "target": "Russia"},
|
||||
{"source": "苹果", "target": "Apple"},
|
||||
{"source": "香蕉", "target": "Banana"},
|
||||
{"source": "水", "target": "Water"},
|
||||
{"source": "茶", "target": "Tea"},
|
||||
{"source": "咖啡", "target": "Coffee"},
|
||||
{"source": "书", "target": "Book"},
|
||||
{"source": "笔", "target": "Pen"},
|
||||
{"source": "电脑", "target": "Computer"},
|
||||
{"source": "手机", "target": "Phone"},
|
||||
{"source": "汽车", "target": "Car"},
|
||||
{"source": "房子", "target": "House"},
|
||||
{"source": "钱", "target": "Money"},
|
||||
{"source": "音乐", "target": "Music"},
|
||||
{"source": "电影", "target": "Movie"},
|
||||
{"source": "游戏", "target": "Game"},
|
||||
{"source": "运动", "target": "Sports"},
|
||||
{"source": "健康", "target": "Health"},
|
||||
{"source": "美丽", "target": "Beautiful"},
|
||||
{"source": "快乐", "target": "Happy"},
|
||||
{"source": "悲伤", "target": "Sad"},
|
||||
{"source": "大", "target": "Big"},
|
||||
{"source": "小", "target": "Small"},
|
||||
{"source": "好", "target": "Good"},
|
||||
{"source": "坏", "target": "Bad"},
|
||||
{"source": "快", "target": "Fast"},
|
||||
{"source": "慢", "target": "Slow"},
|
||||
{"source": "热", "target": "Hot"},
|
||||
{"source": "冷", "target": "Cold"},
|
||||
{"source": "新", "target": "New"},
|
||||
{"source": "旧", "target": "Old"},
|
||||
{"source": "高", "target": "High"},
|
||||
{"source": "低", "target": "Low"},
|
||||
{"source": "长", "target": "Long"},
|
||||
{"source": "短", "target": "Short"},
|
||||
{"source": "红色", "target": "Red"},
|
||||
{"source": "蓝色", "target": "Blue"},
|
||||
{"source": "绿色", "target": "Green"},
|
||||
{"source": "黄色", "target": "Yellow"},
|
||||
{"source": "白色", "target": "White"},
|
||||
{"source": "黑色", "target": "Black"},
|
||||
{"source": "一", "target": "One"},
|
||||
{"source": "二", "target": "Two"},
|
||||
{"source": "三", "target": "Three"},
|
||||
{"source": "四", "target": "Four"},
|
||||
{"source": "五", "target": "Five"},
|
||||
{"source": "六", "target": "Six"},
|
||||
{"source": "七", "target": "Seven"},
|
||||
{"source": "八", "target": "Eight"},
|
||||
{"source": "九", "target": "Nine"},
|
||||
{"source": "十", "target": "Ten"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
{
|
||||
"fileName": "dictionary_zh_es.json",
|
||||
"fileContent": {
|
||||
"entries": [
|
||||
{"source": "你好", "target": "Hola"},
|
||||
{"source": "谢谢", "target": "Gracias"},
|
||||
{"source": "对不起", "target": "Lo siento"},
|
||||
{"source": "再见", "target": "Adiós"},
|
||||
{"source": "是", "target": "Sí"},
|
||||
{"source": "不", "target": "No"},
|
||||
{"source": "我", "target": "Yo"},
|
||||
{"source": "你", "target": "Tú"},
|
||||
{"source": "他", "target": "Él"},
|
||||
{"source": "她", "target": "Ella"},
|
||||
{"source": "我们", "target": "Nosotros"},
|
||||
{"source": "他们", "target": "Ellos"},
|
||||
{"source": "这个", "target": "Este"},
|
||||
{"source": "那个", "target": "Ese"},
|
||||
{"source": "什么", "target": "Qué"},
|
||||
{"source": "哪里", "target": "Dónde"},
|
||||
{"source": "为什么", "target": "Por qué"},
|
||||
{"source": "如何", "target": "Cómo"},
|
||||
{"source": "时间", "target": "Tiempo"},
|
||||
{"source": "今天", "target": "Hoy"},
|
||||
{"source": "明天", "target": "Mañana"},
|
||||
{"source": "昨天", "target": "Ayer"},
|
||||
{"source": "爱", "target": "Amor"},
|
||||
{"source": "家庭", "target": "Familia"},
|
||||
{"source": "朋友", "target": "Amigo"},
|
||||
{"source": "学校", "target": "Escuela"},
|
||||
{"source": "工作", "target": "Trabajo"},
|
||||
{"source": "学习", "target": "Estudiar"},
|
||||
{"source": "吃饭", "target": "Comer"},
|
||||
{"source": "喝水", "target": "Beber agua"},
|
||||
{"source": "睡觉", "target": "Dormir"},
|
||||
{"source": "中国", "target": "China"},
|
||||
{"source": "美国", "target": "Estados Unidos"},
|
||||
{"source": "日本", "target": "Japón"},
|
||||
{"source": "韩国", "target": "Corea"},
|
||||
{"source": "法国", "target": "Francia"},
|
||||
{"source": "德国", "target": "Alemania"},
|
||||
{"source": "西班牙", "target": "España"},
|
||||
{"source": "俄罗斯", "target": "Rusia"},
|
||||
{"source": "苹果", "target": "Manzana"},
|
||||
{"source": "香蕉", "target": "Plátano"},
|
||||
{"source": "水", "target": "Agua"},
|
||||
{"source": "茶", "target": "Té"},
|
||||
{"source": "咖啡", "target": "Café"},
|
||||
{"source": "书", "target": "Libro"},
|
||||
{"source": "电脑", "target": "Computadora"},
|
||||
{"source": "手机", "target": "Teléfono"},
|
||||
{"source": "汽车", "target": "Coche"},
|
||||
{"source": "房子", "target": "Casa"},
|
||||
{"source": "钱", "target": "Dinero"},
|
||||
{"source": "音乐", "target": "Música"},
|
||||
{"source": "电影", "target": "Película"},
|
||||
{"source": "大", "target": "Grande"},
|
||||
{"source": "小", "target": "Pequeño"},
|
||||
{"source": "好", "target": "Bueno"},
|
||||
{"source": "坏", "target": "Malo"},
|
||||
{"source": "热", "target": "Caliente"},
|
||||
{"source": "冷", "target": "Frío"},
|
||||
{"source": "新", "target": "Nuevo"},
|
||||
{"source": "旧", "target": "Viejo"},
|
||||
{"source": "红色", "target": "Rojo"},
|
||||
{"source": "蓝色", "target": "Azul"},
|
||||
{"source": "绿色", "target": "Verde"},
|
||||
{"source": "白色", "target": "Blanco"},
|
||||
{"source": "黑色", "target": "Negro"}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "你好", "target": "Bonjour"},
|
||||
{"source": "谢谢", "target": "Merci"},
|
||||
{"source": "对不起", "target": "Désolé"},
|
||||
{"source": "再见", "target": "Au revoir"},
|
||||
{"source": "是", "target": "Oui"},
|
||||
{"source": "不", "target": "Non"},
|
||||
{"source": "我", "target": "Je"},
|
||||
{"source": "你", "target": "Tu"},
|
||||
{"source": "他", "target": "Il"},
|
||||
{"source": "她", "target": "Elle"},
|
||||
{"source": "我们", "target": "Nous"},
|
||||
{"source": "他们", "target": "Ils"},
|
||||
{"source": "这个", "target": "Ceci"},
|
||||
{"source": "那个", "target": "Cela"},
|
||||
{"source": "什么", "target": "Quoi"},
|
||||
{"source": "哪里", "target": "Où"},
|
||||
{"source": "为什么", "target": "Pourquoi"},
|
||||
{"source": "如何", "target": "Comment"},
|
||||
{"source": "时间", "target": "Temps"},
|
||||
{"source": "今天", "target": "Aujourd'hui"},
|
||||
{"source": "明天", "target": "Demain"},
|
||||
{"source": "昨天", "target": "Hier"},
|
||||
{"source": "爱", "target": "Amour"},
|
||||
{"source": "家庭", "target": "Famille"},
|
||||
{"source": "朋友", "target": "Ami"},
|
||||
{"source": "学校", "target": "École"},
|
||||
{"source": "工作", "target": "Travail"},
|
||||
{"source": "吃饭", "target": "Manger"},
|
||||
{"source": "喝水", "target": "Boire de l'eau"},
|
||||
{"source": "学习", "target": "Étudier"},
|
||||
{"source": "中国", "target": "Chine"},
|
||||
{"source": "法国", "target": "France"},
|
||||
{"source": "巴黎", "target": "Paris"},
|
||||
{"source": "北京", "target": "Pékin"},
|
||||
{"source": "苹果", "target": "Pomme"},
|
||||
{"source": "香蕉", "target": "Banane"},
|
||||
{"source": "水", "target": "Eau"},
|
||||
{"source": "茶", "target": "Thé"},
|
||||
{"source": "咖啡", "target": "Café"},
|
||||
{"source": "书", "target": "Livre"},
|
||||
{"source": "电脑", "target": "Ordinateur"},
|
||||
{"source": "手机", "target": "Téléphone portable"},
|
||||
{"source": "汽车", "target": "Voiture"},
|
||||
{"source": "钱", "target": "Argent"},
|
||||
{"source": "音乐", "target": "Musique"},
|
||||
{"source": "电影", "target": "Film"},
|
||||
{"source": "大", "target": "Grand"},
|
||||
{"source": "小", "target": "Petit"},
|
||||
{"source": "好", "target": "Bon"},
|
||||
{"source": "坏", "target": "Mauvais"},
|
||||
{"source": "热", "target": "Chaud"},
|
||||
{"source": "冷", "target": "Froid"},
|
||||
{"source": "新", "target": "Nouveau"},
|
||||
{"source": "旧", "target": "Vieux"},
|
||||
{"source": "红色", "target": "Rouge"},
|
||||
{"source": "蓝色", "target": "Bleu"},
|
||||
{"source": "绿色", "target": "Vert"},
|
||||
{"source": "白色", "target": "Blanc"},
|
||||
{"source": "黑色", "target": "Noir"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "你好", "target": "こんにちは"},
|
||||
{"source": "谢谢", "target": "ありがとう"},
|
||||
{"source": "对不起", "target": "すみません"},
|
||||
{"source": "再见", "target": "さようなら"},
|
||||
{"source": "是", "target": "はい"},
|
||||
{"source": "不", "target": "いいえ"},
|
||||
{"source": "我", "target": "私"},
|
||||
{"source": "你", "target": "あなた"},
|
||||
{"source": "他", "target": "彼"},
|
||||
{"source": "她", "target": "彼女"},
|
||||
{"source": "我们", "target": "私たち"},
|
||||
{"source": "他们", "target": "彼ら"},
|
||||
{"source": "这个", "target": "これ"},
|
||||
{"source": "那个", "target": "それ"},
|
||||
{"source": "什么", "target": "何"},
|
||||
{"source": "哪里", "target": "どこ"},
|
||||
{"source": "为什么", "target": "なぜ"},
|
||||
{"source": "如何", "target": "どのように"},
|
||||
{"source": "时间", "target": "時間"},
|
||||
{"source": "今天", "target": "今日"},
|
||||
{"source": "明天", "target": "明日"},
|
||||
{"source": "昨天", "target": "昨日"},
|
||||
{"source": "爱", "target": "愛"},
|
||||
{"source": "家庭", "target": "家族"},
|
||||
{"source": "朋友", "target": "友達"},
|
||||
{"source": "学校", "target": "学校"},
|
||||
{"source": "工作", "target": "仕事"},
|
||||
{"source": "吃饭", "target": "食事"},
|
||||
{"source": "喝水", "target": "水を飲む"},
|
||||
{"source": "学习", "target": "勉強"},
|
||||
{"source": "中国", "target": "中国"},
|
||||
{"source": "日本", "target": "日本"},
|
||||
{"source": "东京", "target": "東京"},
|
||||
{"source": "北京", "target": "北京"},
|
||||
{"source": "苹果", "target": "りんご"},
|
||||
{"source": "香蕉", "target": "バナナ"},
|
||||
{"source": "水", "target": "水"},
|
||||
{"source": "茶", "target": "お茶"},
|
||||
{"source": "咖啡", "target": "コーヒー"},
|
||||
{"source": "书", "target": "本"},
|
||||
{"source": "电脑", "target": "コンピューター"},
|
||||
{"source": "手机", "target": "携帯電話"},
|
||||
{"source": "汽车", "target": "車"},
|
||||
{"source": "钱", "target": "お金"},
|
||||
{"source": "音乐", "target": "音楽"},
|
||||
{"source": "电影", "target": "映画"},
|
||||
{"source": "大", "target": "大きい"},
|
||||
{"source": "小", "target": "小さい"},
|
||||
{"source": "好", "target": "良い"},
|
||||
{"source": "坏", "target": "悪い"},
|
||||
{"source": "热", "target": "熱い"},
|
||||
{"source": "冷", "target": "冷たい"},
|
||||
{"source": "新", "target": "新しい"},
|
||||
{"source": "旧", "target": "古い"},
|
||||
{"source": "红色", "target": "赤"},
|
||||
{"source": "蓝色", "target": "青"},
|
||||
{"source": "绿色", "target": "緑"},
|
||||
{"source": "白色", "target": "白"},
|
||||
{"source": "黑色", "target": "黒"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
{
|
||||
"entries": [
|
||||
{"source": "你好", "target": "안녕하세요"},
|
||||
{"source": "谢谢", "target": "감사합니다"},
|
||||
{"source": "对不起", "target": "죄송합니다"},
|
||||
{"source": "再见", "target": "안녕히 가세요"},
|
||||
{"source": "是", "target": "네"},
|
||||
{"source": "不", "target": "아니요"},
|
||||
{"source": "我", "target": "나"},
|
||||
{"source": "你", "target": "너"},
|
||||
{"source": "他", "target": "그"},
|
||||
{"source": "她", "target": "그녀"},
|
||||
{"source": "我们", "target": "우리"},
|
||||
{"source": "他们", "target": "그들"},
|
||||
{"source": "这个", "target": "이것"},
|
||||
{"source": "那个", "target": "그것"},
|
||||
{"source": "什么", "target": "무엇"},
|
||||
{"source": "哪里", "target": "어디"},
|
||||
{"source": "为什么", "target": "왜"},
|
||||
{"source": "如何", "target": "어떻게"},
|
||||
{"source": "时间", "target": "시간"},
|
||||
{"source": "今天", "target": "오늘"},
|
||||
{"source": "明天", "target": "내일"},
|
||||
{"source": "昨天", "target": "어제"},
|
||||
{"source": "爱", "target": "사랑"},
|
||||
{"source": "家庭", "target": "가족"},
|
||||
{"source": "朋友", "target": "친구"},
|
||||
{"source": "学校", "target": "학교"},
|
||||
{"source": "工作", "target": "일"},
|
||||
{"source": "吃饭", "target": "식사"},
|
||||
{"source": "喝水", "target": "물을 마시다"},
|
||||
{"source": "学习", "target": "공부"},
|
||||
{"source": "中国", "target": "중국"},
|
||||
{"source": "韩国", "target": "한국"},
|
||||
{"source": "首尔", "target": "서울"},
|
||||
{"source": "北京", "target": "베이징"},
|
||||
{"source": "苹果", "target": "사과"},
|
||||
{"source": "香蕉", "target": "바나나"},
|
||||
{"source": "水", "target": "물"},
|
||||
{"source": "茶", "target": "차"},
|
||||
{"source": "咖啡", "target": "커피"},
|
||||
{"source": "书", "target": "책"},
|
||||
{"source": "电脑", "target": "컴퓨터"},
|
||||
{"source": "手机", "target": "휴대폰"},
|
||||
{"source": "汽车", "target": "자동차"},
|
||||
{"source": "钱", "target": "돈"},
|
||||
{"source": "音乐", "target": "음악"},
|
||||
{"source": "电影", "target": "영화"},
|
||||
{"source": "大", "target": "크다"},
|
||||
{"source": "小", "target": "작다"},
|
||||
{"source": "好", "target": "좋다"},
|
||||
{"source": "坏", "target": "나쁘다"},
|
||||
{"source": "热", "target": "뜨겁다"},
|
||||
{"source": "冷", "target": "차갑다"},
|
||||
{"source": "新", "target": "새로운"},
|
||||
{"source": "旧", "target": "오래된"},
|
||||
{"source": "红色", "target": "빨간색"},
|
||||
{"source": "蓝色", "target": "파란색"},
|
||||
{"source": "绿色", "target": "초록색"},
|
||||
{"source": "白色", "target": "하얀색"},
|
||||
{"source": "黑色", "target": "검은색"}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,354 @@
|
||||
package com.translation.activity;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import com.translation.app.R;
|
||||
import com.translation.service.AuthService;
|
||||
|
||||
public class LoginActivity extends AppCompatActivity {
|
||||
private static final String TAG = "LoginActivity";
|
||||
|
||||
private EditText phoneEditText;
|
||||
private EditText passwordEditText;
|
||||
private Button loginButton;
|
||||
private TextView registerLink;
|
||||
private TextView agreementTextView;
|
||||
private CheckBox rememberPasswordCheckbox;
|
||||
|
||||
private AuthService authService;
|
||||
private Dialog registerDialog;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Log.d(TAG, "onCreate");
|
||||
setContentView(R.layout.activity_login);
|
||||
|
||||
authService = new AuthService(this);
|
||||
initializeViews();
|
||||
setupEventListeners();
|
||||
|
||||
// 检查是否已登录
|
||||
if (authService.isLoggedIn()) {
|
||||
Log.d(TAG, "用户已登录,自动跳转到主页面");
|
||||
openMainTranslationActivity();
|
||||
} else {
|
||||
// 自动填充上次登录的手机号
|
||||
autoFillLastLoginInfo();
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
Log.d(TAG, "initializeViews");
|
||||
phoneEditText = findViewById(R.id.phone_edit_text);
|
||||
passwordEditText = findViewById(R.id.password_edit_text);
|
||||
loginButton = findViewById(R.id.login_button);
|
||||
registerLink = findViewById(R.id.register_link);
|
||||
agreementTextView = findViewById(R.id.agreement_text);
|
||||
rememberPasswordCheckbox = findViewById(R.id.remember_password_checkbox);
|
||||
|
||||
// 设置记住密码复选框的初始状态
|
||||
rememberPasswordCheckbox.setChecked(authService.getRememberPassword());
|
||||
}
|
||||
|
||||
private void setupEventListeners() {
|
||||
Log.d(TAG, "setupEventListeners");
|
||||
|
||||
loginButton.setOnClickListener(v -> {
|
||||
Log.d(TAG, "登录按钮点击");
|
||||
handleLogin();
|
||||
});
|
||||
|
||||
registerLink.setOnClickListener(v -> {
|
||||
Log.d(TAG, "注册链接点击");
|
||||
showRegisterDialog();
|
||||
});
|
||||
|
||||
agreementTextView.setOnClickListener(v -> {
|
||||
Toast.makeText(this, "显示用户协议", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
// 记住密码复选框监听
|
||||
rememberPasswordCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
authService.setRememberPassword(isChecked);
|
||||
Log.d(TAG, "记住密码设置: " + isChecked);
|
||||
});
|
||||
|
||||
// 手机号输入监听,用于自动填充密码
|
||||
phoneEditText.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
String phoneNumber = s.toString().trim();
|
||||
if (phoneNumber.length() == 11 && authService.userExists(phoneNumber)) {
|
||||
// 自动填充已保存的密码
|
||||
String savedPassword = authService.getSavedPassword(phoneNumber);
|
||||
if (savedPassword != null) {
|
||||
passwordEditText.setText(savedPassword);
|
||||
Toast.makeText(LoginActivity.this, "已自动填充保存的密码", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示注册对话框
|
||||
*/
|
||||
private void showRegisterDialog() {
|
||||
registerDialog = new Dialog(this);
|
||||
registerDialog.setContentView(R.layout.dialog_register);
|
||||
registerDialog.setCancelable(true);
|
||||
registerDialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
|
||||
|
||||
// 初始化对话框中的视图
|
||||
EditText registerPhoneEditText = registerDialog.findViewById(R.id.register_phone_edit_text);
|
||||
EditText registerPasswordEditText = registerDialog.findViewById(R.id.register_password_edit_text);
|
||||
EditText registerConfirmPasswordEditText = registerDialog.findViewById(R.id.register_confirm_password_edit_text);
|
||||
Button cancelButton = registerDialog.findViewById(R.id.cancel_button);
|
||||
Button confirmRegisterButton = registerDialog.findViewById(R.id.confirm_register_button);
|
||||
TextView registerAgreementText = registerDialog.findViewById(R.id.register_agreement_text);
|
||||
|
||||
// 填充当前输入的手机号
|
||||
String currentPhone = phoneEditText.getText().toString().trim();
|
||||
if (!TextUtils.isEmpty(currentPhone)) {
|
||||
registerPhoneEditText.setText(currentPhone);
|
||||
}
|
||||
|
||||
// 取消按钮
|
||||
cancelButton.setOnClickListener(v -> {
|
||||
registerDialog.dismiss();
|
||||
});
|
||||
|
||||
// 确认注册按钮
|
||||
confirmRegisterButton.setOnClickListener(v -> {
|
||||
handleRegister(
|
||||
registerPhoneEditText.getText().toString().trim(),
|
||||
registerPasswordEditText.getText().toString().trim(),
|
||||
registerConfirmPasswordEditText.getText().toString().trim()
|
||||
);
|
||||
});
|
||||
|
||||
// 协议文本点击
|
||||
registerAgreementText.setOnClickListener(v -> {
|
||||
Toast.makeText(this, "显示用户协议", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
registerDialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动填充上次登录信息
|
||||
*/
|
||||
private void autoFillLastLoginInfo() {
|
||||
String lastLoginPhone = authService.getLastLoginPhone();
|
||||
if (!TextUtils.isEmpty(lastLoginPhone)) {
|
||||
phoneEditText.setText(lastLoginPhone);
|
||||
// 如果用户存在,自动填充密码
|
||||
if (authService.userExists(lastLoginPhone)) {
|
||||
String savedPassword = authService.getSavedPassword(lastLoginPhone);
|
||||
if (savedPassword != null) {
|
||||
passwordEditText.setText(savedPassword);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLogin() {
|
||||
Log.d(TAG, "=== handleLogin 开始 ===");
|
||||
|
||||
String phoneNumber = phoneEditText.getText().toString().trim();
|
||||
String password = passwordEditText.getText().toString().trim();
|
||||
|
||||
Log.d(TAG, "手机号: " + phoneNumber + ", 密码: " + password);
|
||||
|
||||
// 输入验证
|
||||
if (TextUtils.isEmpty(phoneNumber)) {
|
||||
Log.d(TAG, "手机号为空");
|
||||
Toast.makeText(this, "请输入手机号", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (phoneNumber.length() != 11) {
|
||||
Log.d(TAG, "手机号格式错误");
|
||||
Toast.makeText(this, "请输入正确的11位手机号", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(password)) {
|
||||
Log.d(TAG, "密码为空");
|
||||
Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (password.length() < 6) {
|
||||
Log.d(TAG, "密码长度不足");
|
||||
Toast.makeText(this, "密码长度至少6位", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查用户是否存在
|
||||
if (!authService.userExists(phoneNumber)) {
|
||||
Log.d(TAG, "用户未注册");
|
||||
Toast.makeText(this, "该手机号未注册,请先注册", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d(TAG, "准备调用 authService.login");
|
||||
loginButton.setEnabled(false);
|
||||
loginButton.setText("登录中...");
|
||||
|
||||
authService.login(phoneNumber, password, new AuthService.AuthCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Log.d(TAG, "=== AuthService.onSuccess 回调 ===");
|
||||
runOnUiThread(() -> {
|
||||
Log.d(TAG, "在UI线程中执行");
|
||||
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
|
||||
openMainTranslationActivity();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String errorMessage) {
|
||||
Log.e(TAG, "=== AuthService.onError: " + errorMessage);
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(LoginActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
|
||||
loginButton.setEnabled(true);
|
||||
loginButton.setText("登录");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Log.d(TAG, "=== handleLogin 结束 ===");
|
||||
}
|
||||
|
||||
private void handleRegister(String phoneNumber, String password, String confirmPassword) {
|
||||
Log.d(TAG, "=== handleRegister 开始 ===");
|
||||
|
||||
Log.d(TAG, "注册信息 - 手机号: " + phoneNumber + ", 密码: " + password + ", 确认密码: " + confirmPassword);
|
||||
|
||||
// 输入验证
|
||||
if (TextUtils.isEmpty(phoneNumber)) {
|
||||
Log.d(TAG, "手机号为空");
|
||||
Toast.makeText(this, "请输入手机号", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (phoneNumber.length() != 11) {
|
||||
Log.d(TAG, "手机号格式错误");
|
||||
Toast.makeText(this, "请输入正确的11位手机号", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(password)) {
|
||||
Log.d(TAG, "密码为空");
|
||||
Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (password.length() < 6) {
|
||||
Log.d(TAG, "密码长度不足");
|
||||
Toast.makeText(this, "密码长度至少6位", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password.equals(confirmPassword)) {
|
||||
Log.d(TAG, "密码不一致");
|
||||
Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查用户是否已存在
|
||||
if (authService.userExists(phoneNumber)) {
|
||||
Log.d(TAG, "用户已存在");
|
||||
Toast.makeText(this, "该手机号已注册,请直接登录", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d(TAG, "准备调用 authService.register");
|
||||
Button confirmButton = registerDialog.findViewById(R.id.confirm_register_button);
|
||||
confirmButton.setEnabled(false);
|
||||
confirmButton.setText("注册中...");
|
||||
|
||||
authService.register(phoneNumber, password, new AuthService.AuthCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
Log.d(TAG, "=== AuthService.onSuccess 回调 ===");
|
||||
runOnUiThread(() -> {
|
||||
Log.d(TAG, "在UI线程中执行");
|
||||
Toast.makeText(LoginActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
|
||||
|
||||
// 自动填充注册的信息到登录表单
|
||||
phoneEditText.setText(phoneNumber);
|
||||
passwordEditText.setText(password);
|
||||
|
||||
// 关闭对话框
|
||||
if (registerDialog != null && registerDialog.isShowing()) {
|
||||
registerDialog.dismiss();
|
||||
}
|
||||
|
||||
// 提示用户登录
|
||||
Toast.makeText(LoginActivity.this, "注册成功,请点击登录", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String errorMessage) {
|
||||
Log.e(TAG, "=== AuthService.onError: " + errorMessage);
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(LoginActivity.this, errorMessage, Toast.LENGTH_SHORT).show();
|
||||
if (registerDialog != null) {
|
||||
Button confirmButton = registerDialog.findViewById(R.id.confirm_register_button);
|
||||
confirmButton.setEnabled(true);
|
||||
confirmButton.setText("注册");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Log.d(TAG, "=== handleRegister 结束 ===");
|
||||
}
|
||||
|
||||
private void openMainTranslationActivity() {
|
||||
Log.d(TAG, "=== openMainTranslationActivity ===");
|
||||
try {
|
||||
Log.d(TAG, "创建Intent");
|
||||
Intent intent = new Intent(this, MainTranslationActivity.class);
|
||||
|
||||
Log.d(TAG, "启动Activity");
|
||||
startActivity(intent);
|
||||
Log.d(TAG, "结束当前Activity");
|
||||
finish();
|
||||
Log.d(TAG, "跳转完成");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "跳转异常: " + e.getMessage(), e);
|
||||
Toast.makeText(this, "跳转失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (registerDialog != null && registerDialog.isShowing()) {
|
||||
registerDialog.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,175 @@
|
||||
package com.translation.activity;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.translation.app.R;
|
||||
import com.translation.adapter.TagAdapter;
|
||||
import com.translation.app.AppState;
|
||||
import com.translation.model.Tag;
|
||||
import com.translation.service.TagService;
|
||||
import com.translation.util.StringUtil;
|
||||
import android.content.Intent;
|
||||
|
||||
public class TagManagementActivity extends AppCompatActivity {
|
||||
private RecyclerView tagRecyclerView;
|
||||
private Button newTagButton;
|
||||
private TagService tagService;
|
||||
private AppState appState;
|
||||
private TagAdapter tagAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_tags);
|
||||
|
||||
tagService = new TagService(this);
|
||||
appState = AppState.getInstance(this);
|
||||
|
||||
initializeViews();
|
||||
setupRecyclerView();
|
||||
setupEventListeners();
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
tagRecyclerView = findViewById(R.id.tag_recycler_view);
|
||||
newTagButton = findViewById(R.id.new_tag_button);
|
||||
|
||||
// 设置返回按钮
|
||||
findViewById(R.id.back_button).setOnClickListener(v -> onBackPressed());
|
||||
}
|
||||
|
||||
private void setupRecyclerView() {
|
||||
// 传入 tagService
|
||||
tagAdapter = new TagAdapter(appState.getTags(), tagService);
|
||||
tagRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
tagRecyclerView.setAdapter(tagAdapter);
|
||||
|
||||
// 设置标签点击监听器
|
||||
tagAdapter.setOnTagClickListener(new TagAdapter.OnTagClickListener() {
|
||||
@Override
|
||||
public void onTagClick(Tag tag) {
|
||||
openTagRecordsActivity(tag);
|
||||
}
|
||||
});
|
||||
|
||||
// 设置标签操作监听器
|
||||
tagAdapter.setOnTagOperationListener(new TagAdapter.OnTagOperationListener() {
|
||||
@Override
|
||||
public void onEditTag(Tag tag) {
|
||||
showEditTagDialog(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleteTag(Tag tag) {
|
||||
showDeleteTagDialog(tag);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开标签对应的翻译记录界面
|
||||
*/
|
||||
private void openTagRecordsActivity(Tag tag) {
|
||||
Intent intent = new Intent(this, TagRecordsActivity.class);
|
||||
intent.putExtra("tag_id", tag.getId());
|
||||
intent.putExtra("tag_name", tag.getName());
|
||||
startActivity(intent);
|
||||
|
||||
// 添加过渡动画
|
||||
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
|
||||
}
|
||||
|
||||
private void setupEventListeners() {
|
||||
newTagButton.setOnClickListener(v -> showNewTagDialog());
|
||||
}
|
||||
|
||||
private void showNewTagDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("新建标签");
|
||||
|
||||
View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_tag, null);
|
||||
builder.setView(dialogView);
|
||||
|
||||
androidx.appcompat.widget.AppCompatEditText tagNameEditText =
|
||||
dialogView.findViewById(R.id.tag_name_edit_text);
|
||||
|
||||
builder.setPositiveButton("创建", (dialog, which) -> {
|
||||
String tagName = tagNameEditText.getText().toString().trim();
|
||||
if (StringUtil.isEmpty(tagName)) {
|
||||
Toast.makeText(this, "请输入标签名称", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tagService.createTag(tagName)) {
|
||||
tagAdapter.updateData(appState.getTags());
|
||||
Toast.makeText(this, "标签创建成功", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(this, "标签已存在或创建失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNegativeButton("取消", null);
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void showEditTagDialog(Tag tag) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("编辑标签");
|
||||
|
||||
View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_tag, null);
|
||||
builder.setView(dialogView);
|
||||
|
||||
androidx.appcompat.widget.AppCompatEditText tagNameEditText =
|
||||
dialogView.findViewById(R.id.tag_name_edit_text);
|
||||
tagNameEditText.setText(tag.getName());
|
||||
|
||||
builder.setPositiveButton("保存", (dialog, which) -> {
|
||||
String newName = tagNameEditText.getText().toString().trim();
|
||||
if (StringUtil.isEmpty(newName)) {
|
||||
Toast.makeText(this, "请输入标签名称", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (tagService.updateTag(tag.getId(), newName)) {
|
||||
tagAdapter.updateData(appState.getTags());
|
||||
Toast.makeText(this, "标签更新成功", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(this, "标签更新失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNegativeButton("取消", null);
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void showDeleteTagDialog(Tag tag) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("删除标签");
|
||||
builder.setMessage("确定要删除标签 \"" + tag.getName() + "\" 吗?");
|
||||
|
||||
builder.setPositiveButton("删除", (dialog, which) -> {
|
||||
if (tagService.deleteTag(tag.getId())) {
|
||||
tagAdapter.updateData(appState.getTags());
|
||||
Toast.makeText(this, "标签删除成功", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(this, "标签删除失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNegativeButton("取消", null);
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
package com.translation.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.translation.app.R;
|
||||
import com.translation.adapter.HistoryAdapter;
|
||||
import com.translation.model.TranslationRecord;
|
||||
import com.translation.service.HistoryService;
|
||||
import com.translation.service.TagService;
|
||||
import java.util.List;
|
||||
|
||||
public class TagRecordsActivity extends AppCompatActivity {
|
||||
private RecyclerView recordsRecyclerView;
|
||||
private TextView titleTextView;
|
||||
private TextView emptyTextView;
|
||||
private HistoryService historyService;
|
||||
private TagService tagService;
|
||||
private HistoryAdapter historyAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_tag_records);
|
||||
|
||||
historyService = new HistoryService(this);
|
||||
tagService = new TagService(this);
|
||||
|
||||
initializeViews();
|
||||
loadTagRecords();
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
// 返回按钮
|
||||
Button backButton = findViewById(R.id.back_button);
|
||||
backButton.setOnClickListener(v -> onBackPressed());
|
||||
|
||||
titleTextView = findViewById(R.id.title_text_view);
|
||||
recordsRecyclerView = findViewById(R.id.records_recycler_view);
|
||||
emptyTextView = findViewById(R.id.empty_text_view);
|
||||
|
||||
// 设置布局管理器
|
||||
recordsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
}
|
||||
|
||||
private void loadTagRecords() {
|
||||
// 获取传递过来的标签信息
|
||||
int tagId = getIntent().getIntExtra("tag_id", -1);
|
||||
String tagName = getIntent().getStringExtra("tag_name");
|
||||
|
||||
if (tagId == -1 || tagName == null) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置标题
|
||||
titleTextView.setText("标签: " + tagName + " (" + getRecordsCount(tagName) + "条记录)");
|
||||
|
||||
// 获取该标签对应的翻译记录
|
||||
List<TranslationRecord> records = historyService.getRecordsByTag(tagName);
|
||||
|
||||
if (records.isEmpty()) {
|
||||
showEmptyState(tagName);
|
||||
} else {
|
||||
showRecords(records);
|
||||
}
|
||||
}
|
||||
|
||||
private int getRecordsCount(String tagName) {
|
||||
List<TranslationRecord> records = historyService.getRecordsByTag(tagName);
|
||||
return records != null ? records.size() : 0;
|
||||
}
|
||||
|
||||
private void showRecords(List<TranslationRecord> records) {
|
||||
emptyTextView.setVisibility(View.GONE);
|
||||
recordsRecyclerView.setVisibility(View.VISIBLE);
|
||||
|
||||
historyAdapter = new HistoryAdapter(records);
|
||||
recordsRecyclerView.setAdapter(historyAdapter);
|
||||
|
||||
// 设置点击监听器(查看详情)
|
||||
historyAdapter.setOnItemClickListener(new HistoryAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(TranslationRecord record) {
|
||||
showRecordDetail(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemLongClick(TranslationRecord record) {
|
||||
// 在标签记录界面不启用批量模式
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showEmptyState(String tagName) {
|
||||
recordsRecyclerView.setVisibility(View.GONE);
|
||||
emptyTextView.setVisibility(View.VISIBLE);
|
||||
emptyTextView.setText("标签 \"" + tagName + "\" 下暂无翻译记录");
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示记录详情
|
||||
*/
|
||||
private void showRecordDetail(TranslationRecord record) {
|
||||
// 复用 HistoryActivity 中的方法
|
||||
HistoryActivity historyActivity = new HistoryActivity();
|
||||
historyActivity.showRecordDetailDialog(this, record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.translation.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
public class TestActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// 不使用布局文件,直接创建视图
|
||||
TextView textView = new TextView(this);
|
||||
textView.setText("测试页面 - R.java 应该已经生成");
|
||||
setContentView(textView);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
package com.translation.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.translation.app.R;
|
||||
import com.translation.model.GrammarExtension;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GrammarExtensionAdapter extends RecyclerView.Adapter<GrammarExtensionAdapter.ViewHolder> {
|
||||
|
||||
private List<GrammarExtension> extensions;
|
||||
private OnExtensionClickListener listener;
|
||||
|
||||
public interface OnExtensionClickListener {
|
||||
void onApplyExtension(GrammarExtension extension);
|
||||
void onExtensionClicked(GrammarExtension extension);
|
||||
}
|
||||
|
||||
public GrammarExtensionAdapter(List<GrammarExtension> extensions, OnExtensionClickListener listener) {
|
||||
this.extensions = extensions;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_grammar_extension, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
GrammarExtension extension = extensions.get(position);
|
||||
|
||||
holder.originalText.setText(extension.getOriginalText());
|
||||
holder.extendedText.setText(extension.getExtendedText());
|
||||
holder.extensionTypeText.setText(extension.getExtensionType());
|
||||
holder.explanationText.setText(extension.getExplanation());
|
||||
|
||||
// 设置点击事件
|
||||
holder.applyButton.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onApplyExtension(extension);
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onExtensionClicked(extension);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return extensions.size();
|
||||
}
|
||||
|
||||
public void updateExtensions(List<GrammarExtension> newExtensions) {
|
||||
this.extensions = newExtensions;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView originalText;
|
||||
TextView extendedText;
|
||||
TextView extensionTypeText;
|
||||
TextView explanationText;
|
||||
Button applyButton;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
originalText = itemView.findViewById(R.id.original_text);
|
||||
extendedText = itemView.findViewById(R.id.extended_text);
|
||||
extensionTypeText = itemView.findViewById(R.id.extension_type_text);
|
||||
explanationText = itemView.findViewById(R.id.explanation_text);
|
||||
applyButton = itemView.findViewById(R.id.apply_extension_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package com.translation.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.translation.app.R;
|
||||
import com.translation.model.GrammarSuggestion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GrammarSuggestionAdapter extends RecyclerView.Adapter<GrammarSuggestionAdapter.ViewHolder> {
|
||||
|
||||
private List<GrammarSuggestion> suggestions;
|
||||
private OnSuggestionClickListener listener;
|
||||
|
||||
public interface OnSuggestionClickListener {
|
||||
void onApplySuggestion(GrammarSuggestion suggestion);
|
||||
void onSuggestionClicked(GrammarSuggestion suggestion);
|
||||
}
|
||||
|
||||
public GrammarSuggestionAdapter(List<GrammarSuggestion> suggestions, OnSuggestionClickListener listener) {
|
||||
this.suggestions = suggestions;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_grammar_suggestion, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
GrammarSuggestion suggestion = suggestions.get(position);
|
||||
|
||||
holder.originalText.setText(suggestion.getOriginalText());
|
||||
holder.suggestedText.setText(suggestion.getSuggestedText());
|
||||
holder.explanationText.setText(suggestion.getExplanation());
|
||||
holder.categoryTag.setText(suggestion.getCategory());
|
||||
holder.confidenceText.setText(String.format("%d%%匹配", (int)(suggestion.getConfidence() * 100)));
|
||||
|
||||
// 设置点击事件
|
||||
holder.applyButton.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onApplySuggestion(suggestion);
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onSuggestionClicked(suggestion);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return suggestions.size();
|
||||
}
|
||||
|
||||
public void updateSuggestions(List<GrammarSuggestion> newSuggestions) {
|
||||
this.suggestions = newSuggestions;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView originalText;
|
||||
TextView suggestedText;
|
||||
TextView explanationText;
|
||||
TextView categoryTag;
|
||||
TextView confidenceText;
|
||||
Button applyButton;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
originalText = itemView.findViewById(R.id.original_text);
|
||||
suggestedText = itemView.findViewById(R.id.suggested_text);
|
||||
explanationText = itemView.findViewById(R.id.explanation_text);
|
||||
categoryTag = itemView.findViewById(R.id.category_tag);
|
||||
confidenceText = itemView.findViewById(R.id.confidence_text);
|
||||
applyButton = itemView.findViewById(R.id.apply_suggestion_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,177 @@
|
||||
package com.translation.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.translation.app.R;
|
||||
import com.translation.model.TranslationRecord;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHolder> {
|
||||
private List<TranslationRecord> records;
|
||||
private List<Integer> selectedIds;
|
||||
private boolean isBatchMode;
|
||||
private OnItemClickListener itemClickListener;
|
||||
private SelectionListener selectionListener;
|
||||
|
||||
public HistoryAdapter(List<TranslationRecord> records) {
|
||||
this.records = records != null ? records : new ArrayList<>();
|
||||
this.selectedIds = new ArrayList<>();
|
||||
this.isBatchMode = false;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_history, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
TranslationRecord record = records.get(position);
|
||||
|
||||
holder.sourceText.setText(record.getSourceText());
|
||||
holder.targetText.setText(record.getTargetText());
|
||||
holder.languages.setText(record.getSourceLang() + " → " + record.getTargetLang());
|
||||
holder.timestamp.setText(record.getTimestamp());
|
||||
|
||||
// 批量模式处理
|
||||
if (isBatchMode) {
|
||||
holder.checkBox.setVisibility(View.VISIBLE);
|
||||
holder.checkBox.setChecked(selectedIds.contains(record.getId()));
|
||||
} else {
|
||||
holder.checkBox.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// 点击事件
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (isBatchMode) {
|
||||
toggleSelection(record.getId());
|
||||
notifyItemChanged(position);
|
||||
} else if (itemClickListener != null) {
|
||||
itemClickListener.onItemClick(record);
|
||||
}
|
||||
});
|
||||
|
||||
holder.itemView.setOnLongClickListener(v -> {
|
||||
if (!isBatchMode && itemClickListener != null) {
|
||||
itemClickListener.onItemLongClick(record);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// 复选框点击事件
|
||||
holder.checkBox.setOnClickListener(v -> {
|
||||
toggleSelection(record.getId());
|
||||
notifyItemChanged(position);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return records.size();
|
||||
}
|
||||
|
||||
public void setBatchMode(boolean batchMode) {
|
||||
isBatchMode = batchMode;
|
||||
if (!batchMode) {
|
||||
selectedIds.clear();
|
||||
notifySelectionChanged();
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
selectedIds.clear();
|
||||
for (TranslationRecord record : records) {
|
||||
selectedIds.add(record.getId());
|
||||
}
|
||||
notifySelectionChanged();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void clearSelection() {
|
||||
selectedIds.clear();
|
||||
notifySelectionChanged();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public List<Integer> getSelectedRecordIds() {
|
||||
return new ArrayList<>(selectedIds);
|
||||
}
|
||||
|
||||
public int getSelectedCount() {
|
||||
return selectedIds.size();
|
||||
}
|
||||
|
||||
public void toggleSelection(int recordId) {
|
||||
if (selectedIds.contains(recordId)) {
|
||||
selectedIds.remove(Integer.valueOf(recordId));
|
||||
} else {
|
||||
selectedIds.add(recordId);
|
||||
}
|
||||
notifySelectionChanged();
|
||||
}
|
||||
|
||||
private void notifySelectionChanged() {
|
||||
if (selectionListener != null) {
|
||||
selectionListener.onSelectionChanged(selectedIds.size());
|
||||
}
|
||||
}
|
||||
|
||||
public void updateData(List<TranslationRecord> newRecords) {
|
||||
this.records = newRecords != null ? newRecords : new ArrayList<>();
|
||||
selectedIds.clear();
|
||||
notifySelectionChanged();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||
this.itemClickListener = listener;
|
||||
}
|
||||
|
||||
public void setSelectionListener(SelectionListener listener) {
|
||||
this.selectionListener = listener;
|
||||
}
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(TranslationRecord record);
|
||||
void onItemLongClick(TranslationRecord record);
|
||||
}
|
||||
|
||||
public interface SelectionListener {
|
||||
void onSelectionChanged(int selectedCount);
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
CheckBox checkBox;
|
||||
TextView sourceText;
|
||||
TextView targetText;
|
||||
TextView languages;
|
||||
TextView timestamp;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
checkBox = itemView.findViewById(R.id.checkbox);
|
||||
sourceText = itemView.findViewById(R.id.source_text);
|
||||
targetText = itemView.findViewById(R.id.target_text);
|
||||
languages = itemView.findViewById(R.id.languages);
|
||||
timestamp = itemView.findViewById(R.id.timestamp);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取当前显示的记录列表
|
||||
*/
|
||||
public List<TranslationRecord> getCurrentList() {
|
||||
return records;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,107 @@
|
||||
package com.translation.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.translation.app.R;
|
||||
import com.translation.model.Tag;
|
||||
import com.translation.service.TagService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TagAdapter extends RecyclerView.Adapter<TagAdapter.ViewHolder> {
|
||||
private List<Tag> tags;
|
||||
private OnTagOperationListener operationListener;
|
||||
private OnTagClickListener tagClickListener;
|
||||
private TagService tagService;
|
||||
|
||||
public TagAdapter(List<Tag> tags, TagService tagService) {
|
||||
this.tags = tags != null ? tags : new ArrayList<>();
|
||||
this.tagService = tagService;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_tag, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
Tag tag = tags.get(position);
|
||||
|
||||
holder.tagName.setText(tag.getName());
|
||||
|
||||
// 实时查询关联记录数量
|
||||
int recordCount = tagService.getTagRecordCount(tag.getId());
|
||||
holder.recordCount.setText("关联记录: " + recordCount);
|
||||
|
||||
// 设置整个标签项的点击事件
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (tagClickListener != null) {
|
||||
tagClickListener.onTagClick(tag);
|
||||
}
|
||||
});
|
||||
|
||||
// 设置编辑按钮点击事件
|
||||
holder.editButton.setOnClickListener(v -> {
|
||||
if (operationListener != null) {
|
||||
operationListener.onEditTag(tag);
|
||||
}
|
||||
});
|
||||
|
||||
// 设置删除按钮点击事件
|
||||
holder.deleteButton.setOnClickListener(v -> {
|
||||
if (operationListener != null) {
|
||||
operationListener.onDeleteTag(tag);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return tags.size();
|
||||
}
|
||||
|
||||
public void updateData(List<Tag> newTags) {
|
||||
this.tags = newTags != null ? newTags : new ArrayList<>();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setOnTagOperationListener(OnTagOperationListener listener) {
|
||||
this.operationListener = listener;
|
||||
}
|
||||
|
||||
public void setOnTagClickListener(OnTagClickListener listener) {
|
||||
this.tagClickListener = listener;
|
||||
}
|
||||
|
||||
public interface OnTagOperationListener {
|
||||
void onEditTag(Tag tag);
|
||||
void onDeleteTag(Tag tag);
|
||||
}
|
||||
|
||||
public interface OnTagClickListener {
|
||||
void onTagClick(Tag tag);
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tagName;
|
||||
TextView recordCount;
|
||||
TextView editButton;
|
||||
TextView deleteButton;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
tagName = itemView.findViewById(R.id.tag_name);
|
||||
recordCount = itemView.findViewById(R.id.record_count);
|
||||
editButton = itemView.findViewById(R.id.edit_button);
|
||||
deleteButton = itemView.findViewById(R.id.delete_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,154 @@
|
||||
package com.translation.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.util.Log;
|
||||
|
||||
import com.huawei.hms.mlsdk.common.MLApplication;
|
||||
|
||||
public class HuaweiMLKitConfig {
|
||||
private static final String TAG = "HuaweiMLKitConfig";
|
||||
private static final String PREF_NAME = "huawei_mlkit_config";
|
||||
private static final String KEY_APP_ID = "app_id";
|
||||
private static final String KEY_INITIALIZED = "initialized";
|
||||
|
||||
private static HuaweiMLKitConfig instance;
|
||||
private final Context context;
|
||||
private final SharedPreferences preferences;
|
||||
private boolean isInitialized = false;
|
||||
|
||||
private HuaweiMLKitConfig(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.preferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public static synchronized HuaweiMLKitConfig getInstance(Context context) {
|
||||
if (instance == null) {
|
||||
instance = new HuaweiMLKitConfig(context);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化华为 ML Kit
|
||||
*/
|
||||
public boolean initialize(String appId) {
|
||||
try {
|
||||
if (appId == null || appId.trim().isEmpty()) {
|
||||
Log.e(TAG, "App ID 不能为空");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 设置华为 ML Kit 应用ID
|
||||
MLApplication.getInstance().setApiKey(appId.trim());
|
||||
|
||||
// 保存配置
|
||||
saveAppId(appId.trim());
|
||||
setInitialized(true);
|
||||
this.isInitialized = true;
|
||||
|
||||
Log.d(TAG, "华为 ML Kit 配置初始化成功");
|
||||
return true;
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "华为 ML Kit 配置初始化失败: " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从配置中恢复初始化
|
||||
*/
|
||||
public boolean restoreInitialization() {
|
||||
if (isInitialized()) {
|
||||
String savedAppId = getSavedAppId();
|
||||
if (savedAppId != null && !savedAppId.isEmpty()) {
|
||||
try {
|
||||
MLApplication.getInstance().setApiKey(savedAppId);
|
||||
this.isInitialized = true;
|
||||
Log.d(TAG, "华为 ML Kit 配置从保存状态恢复");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "恢复华为 ML Kit 配置失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 App ID
|
||||
*/
|
||||
private void saveAppId(String appId) {
|
||||
preferences.edit()
|
||||
.putString(KEY_APP_ID, appId)
|
||||
.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取保存的 App ID
|
||||
*/
|
||||
public String getSavedAppId() {
|
||||
return preferences.getString(KEY_APP_ID, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置初始化状态
|
||||
*/
|
||||
private void setInitialized(boolean initialized) {
|
||||
preferences.edit()
|
||||
.putBoolean(KEY_INITIALIZED, initialized)
|
||||
.apply();
|
||||
this.isInitialized = initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已初始化
|
||||
*/
|
||||
public boolean isInitialized() {
|
||||
return preferences.getBoolean(KEY_INITIALIZED, false) || this.isInitialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除配置
|
||||
*/
|
||||
public void clearConfig() {
|
||||
preferences.edit()
|
||||
.remove(KEY_APP_ID)
|
||||
.remove(KEY_INITIALIZED)
|
||||
.apply();
|
||||
this.isInitialized = false;
|
||||
Log.d(TAG, "华为 ML Kit 配置已清除");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置信息
|
||||
*/
|
||||
public String getConfigInfo() {
|
||||
boolean initialized = isInitialized();
|
||||
String appId = getSavedAppId();
|
||||
String appIdStatus = appId != null ? "已设置" : "未设置";
|
||||
|
||||
if (appId != null && appId.length() > 8) {
|
||||
appIdStatus = appId.substring(0, 4) + "****" + appId.substring(appId.length() - 4);
|
||||
}
|
||||
|
||||
return String.format("已初始化: %s, App ID: %s",
|
||||
initialized ? "是" : "否",
|
||||
appIdStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查华为移动服务是否可用
|
||||
*/
|
||||
public boolean isHmsAvailable() {
|
||||
try {
|
||||
// 检查 HMS Core 是否安装
|
||||
return com.huawei.hms.api.HuaweiApiAvailability.getInstance()
|
||||
.isHuaweiMobileServicesAvailable(context) == com.huawei.hms.api.ConnectionResult.SUCCESS;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "检查 HMS 可用性失败: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.translation.app;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// 直接跳转到登录页面
|
||||
startLoginActivity();
|
||||
}
|
||||
|
||||
private void startLoginActivity() {
|
||||
android.content.Intent intent = new android.content.Intent(this, com.translation.activity.LoginActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
package com.translation.app;
|
||||
|
||||
import android.app.Application;
|
||||
import android.util.Log;
|
||||
|
||||
public class TranslationApp extends Application {
|
||||
private static final String TAG = "TranslationApp";
|
||||
private HuaweiMLKitConfig huaweiConfig;
|
||||
private static TranslationApp instance;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
instance = this;
|
||||
|
||||
Log.d(TAG, "应用初始化开始");
|
||||
|
||||
// 初始化AppState
|
||||
AppState.getInstance(this);
|
||||
Log.d(TAG, "AppState 初始化完成");
|
||||
|
||||
// 初始化华为 ML Kit 配置
|
||||
initializeHuaweiMLKit();
|
||||
|
||||
Log.d(TAG, "应用初始化完成");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用实例
|
||||
*/
|
||||
public static TranslationApp getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化华为 ML Kit 服务
|
||||
*/
|
||||
private void initializeHuaweiMLKit() {
|
||||
try {
|
||||
huaweiConfig = HuaweiMLKitConfig.getInstance(this);
|
||||
|
||||
// 检查 HMS 可用性
|
||||
if (!huaweiConfig.isHmsAvailable()) {
|
||||
Log.w(TAG, "华为移动服务不可用,请安装 HMS Core");
|
||||
return;
|
||||
}
|
||||
|
||||
// 尝试从保存的配置恢复初始化0·
|
||||
if (huaweiConfig.restoreInitialization()) {
|
||||
Log.d(TAG, "华为 ML Kit 从保存的配置恢复初始化成功");
|
||||
} else {
|
||||
Log.w(TAG, "华为 ML Kit 需要手动初始化,请在设置中配置 App ID");
|
||||
}
|
||||
|
||||
Log.d(TAG, "华为 ML Kit 配置状态: " + huaweiConfig.getConfigInfo());
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "华为 ML Kit 初始化失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取华为 ML Kit 配置实例
|
||||
*/
|
||||
public HuaweiMLKitConfig getHuaweiMLKitConfig() {
|
||||
return huaweiConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动初始化华为 ML Kit
|
||||
*/
|
||||
public boolean initializeHuaweiMLKitWithAppId(String appId) {
|
||||
if (huaweiConfig != null) {
|
||||
return huaweiConfig.initialize(appId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查华为 ML Kit 是否可用
|
||||
*/
|
||||
public boolean isHuaweiMLKitAvailable() {
|
||||
return huaweiConfig != null && huaweiConfig.isInitialized() && huaweiConfig.isHmsAvailable();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取华为 ML Kit 状态信息
|
||||
*/
|
||||
public String getHuaweiMLKitStatus() {
|
||||
if (huaweiConfig != null) {
|
||||
return huaweiConfig.getConfigInfo();
|
||||
}
|
||||
return "华为 ML Kit 未初始化";
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除华为 ML Kit 配置
|
||||
*/
|
||||
public void clearHuaweiMLKitConfig() {
|
||||
if (huaweiConfig != null) {
|
||||
huaweiConfig.clearConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.translation.model;
|
||||
|
||||
public class GrammarExtension {
|
||||
private String originalText;
|
||||
private String extendedText;
|
||||
private String extensionType; // "时态变化", "语态变化", "句式变化"等
|
||||
private String explanation;
|
||||
private String usageExample;
|
||||
|
||||
public GrammarExtension(String originalText, String extendedText,
|
||||
String extensionType, String explanation) {
|
||||
this.originalText = originalText;
|
||||
this.extendedText = extendedText;
|
||||
this.extensionType = extensionType;
|
||||
this.explanation = explanation;
|
||||
}
|
||||
|
||||
public GrammarExtension(String originalText, String extendedText,
|
||||
String extensionType, String explanation, String usageExample) {
|
||||
this.originalText = originalText;
|
||||
this.extendedText = extendedText;
|
||||
this.extensionType = extensionType;
|
||||
this.explanation = explanation;
|
||||
this.usageExample = usageExample;
|
||||
}
|
||||
|
||||
// getters and setters
|
||||
public String getOriginalText() { return originalText; }
|
||||
public void setOriginalText(String originalText) { this.originalText = originalText; }
|
||||
|
||||
public String getExtendedText() { return extendedText; }
|
||||
public void setExtendedText(String extendedText) { this.extendedText = extendedText; }
|
||||
|
||||
public String getExtensionType() { return extensionType; }
|
||||
public void setExtensionType(String extensionType) { this.extensionType = extensionType; }
|
||||
|
||||
public String getExplanation() { return explanation; }
|
||||
public void setExplanation(String explanation) { this.explanation = explanation; }
|
||||
|
||||
public String getUsageExample() { return usageExample; }
|
||||
public void setUsageExample(String usageExample) { this.usageExample = usageExample; }
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.translation.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GrammarSuggestion {
|
||||
private String originalText;
|
||||
private String suggestedText;
|
||||
private String explanation;
|
||||
private String category;
|
||||
private double confidence;
|
||||
private String correctedText;
|
||||
|
||||
|
||||
public GrammarSuggestion(String originalText, String suggestedText,
|
||||
String explanation, String category, double confidence) {
|
||||
this.originalText = originalText;
|
||||
this.suggestedText = suggestedText;
|
||||
this.explanation = explanation;
|
||||
this.category = category;
|
||||
this.confidence = confidence;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public String getOriginalText() { return originalText; }
|
||||
public String getSuggestedText() { return suggestedText; }
|
||||
public String getExplanation() { return explanation; }
|
||||
public String getCategory() { return category; }
|
||||
public double getConfidence() { return confidence; }
|
||||
|
||||
public String getCorrectedText() {
|
||||
return correctedText;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.translation.model;
|
||||
|
||||
public class Tag {
|
||||
private int id;
|
||||
private String name;
|
||||
private String color;
|
||||
private int recordCount;
|
||||
|
||||
// 主要构造函数
|
||||
public Tag(int id, String name, int recordCount) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.recordCount = recordCount;
|
||||
this.color = generateDefaultColor(id); // 根据ID生成默认颜色
|
||||
}
|
||||
|
||||
// 可选:带颜色参数的构造函数
|
||||
public Tag(int id, String name, String color, int recordCount) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.color = color;
|
||||
this.recordCount = recordCount;
|
||||
}
|
||||
|
||||
// 根据ID生成默认颜色
|
||||
private String generateDefaultColor(int id) {
|
||||
String[] colors = {"#FF5733", "#33FF57", "#3357FF", "#F333FF", "#FF33F3", "#33FFF3"};
|
||||
return colors[id % colors.length];
|
||||
}
|
||||
|
||||
// Getter 和 Setter 方法
|
||||
public int getId() { return id; }
|
||||
public void setId(int id) { this.id = id; }
|
||||
|
||||
public String getName() { return name; }
|
||||
public void setName(String name) { this.name = name; }
|
||||
|
||||
public String getColor() { return color; }
|
||||
public void setColor(String color) { this.color = color; }
|
||||
|
||||
public int getRecordCount() { return recordCount; }
|
||||
public void setRecordCount(int recordCount) { this.recordCount = recordCount; }
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.translation.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TranslationRecord {
|
||||
private int id;
|
||||
private String sourceText;
|
||||
private String targetText;
|
||||
private String sourceLang;
|
||||
private String targetLang;
|
||||
private String timestamp;
|
||||
private List<String> tags;
|
||||
|
||||
public TranslationRecord(int id, String sourceText, String targetText,
|
||||
String sourceLang, String targetLang, String timestamp,
|
||||
List<String> tags) {
|
||||
this.id = id;
|
||||
this.sourceText = sourceText;
|
||||
this.targetText = targetText;
|
||||
this.sourceLang = sourceLang;
|
||||
this.targetLang = targetLang;
|
||||
this.timestamp = timestamp;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
// Getter 和 Setter 方法
|
||||
public int getId() { return id; }
|
||||
public void setId(int id) { this.id = id; }
|
||||
|
||||
public String getSourceText() { return sourceText; }
|
||||
public void setSourceText(String sourceText) { this.sourceText = sourceText; }
|
||||
|
||||
public String getTargetText() { return targetText; }
|
||||
public void setTargetText(String targetText) { this.targetText = targetText; }
|
||||
|
||||
public String getSourceLang() { return sourceLang; }
|
||||
public void setSourceLang(String sourceLang) { this.sourceLang = sourceLang; }
|
||||
|
||||
public String getTargetLang() { return targetLang; }
|
||||
public void setTargetLang(String targetLang) { this.targetLang = targetLang; }
|
||||
|
||||
public String getTimestamp() { return timestamp; }
|
||||
public void setTimestamp(String timestamp) { this.timestamp = timestamp; }
|
||||
|
||||
public List<String> getTags() { return tags; }
|
||||
public void setTags(List<String> tags) { this.tags = tags; }
|
||||
}
|
||||