Added Translation

This commit is contained in:
2022-08-14 11:50:25 +08:00
parent 0534ac3f71
commit e8fd581394
32 changed files with 573 additions and 29 deletions

View File

@@ -17,11 +17,15 @@ android {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled true
Properties buildPro = loadBuildPro()
buildConfigField "String", "API_APP_ID", buildPro['apiAppId']
buildConfigField "String", "API_APP_SECRET", buildPro['apiAppSecret']
}
signingConfigs {
release {
Properties buildPro = buildSign()
Properties buildPro = loadBuildPro()
storeFile file(buildPro['storeFile'])
storePassword buildPro['storePassword']
keyAlias buildPro['keyAlias']
@@ -61,9 +65,9 @@ android {
namespace 'com.fatapp.oxygentoolbox'
}
def buildSign() {
def loadBuildPro() {
Properties buildProperties = new Properties()
buildProperties.load(new FileInputStream(file("../keystore.properties")))
buildProperties.load(new FileInputStream(file("../build.properties")))
return buildProperties
}
@@ -75,11 +79,12 @@ aboutLibraries {
~'androidx.*',
~'org.jetbrains.*',
~"com.google.android.*",
~"com.google.guava:listenablefuture"
~"com.google.guava:listenablefuture",
~"com.squareup.okio:okio-jvm"
]
}
task exportLibrariesToJson(group: 'build', description: 'Generate libraries definitions json file', type: com.mikepenz.aboutlibraries.plugin.AboutLibrariesTask, dependsOn:'collectDependencies') {
task exportLibrariesToJson(group: 'build', description: 'Generate libraries definitions json file', type: com.mikepenz.aboutlibraries.plugin.AboutLibrariesTask, dependsOn: 'collectDependencies') {
resultDirectory = project.file('src/main/res/raw/')
variant = 'release'
}
@@ -95,7 +100,7 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.preference:preference:1.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.1'
@@ -105,4 +110,5 @@ dependencies {
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'com.github.KilleTom:BangScreenToolsMaster:v1.0.0'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
}

View File

@@ -1,12 +1,31 @@
package com.fatapp.oxygentoolbox;
import android.text.format.DateFormat;
import android.util.Log;
import org.junit.Test;
import java.io.IOException;
import java.util.Objects;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class Tester {
@Test
public void dateFormat() {
public void dateFormatTest() {
System.out.println(DateFormat.format("HH:mm:ss dd MMM E", System.currentTimeMillis()));
}
@Test
public void translationTest() {
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("http://translate.google.com/translate_a/single?client=gtx&dt=t&dj=1&ie=UTF-8&sl=auto&tl=zh_TW&q=calculate%26%26").build();
try (Response response = okHttpClient.newCall(request).execute()) {
Log.d("Translation", Objects.requireNonNull(response.body()).string());
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".App"
@@ -10,7 +12,9 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.OxygenToolbox.Default">
android:theme="@style/Theme.OxygenToolbox.Default"
android:usesCleartextTraffic="true"
tools:targetApi="m">
<activity
android:name=".SplashActivity"
android:exported="true"
@@ -43,6 +47,16 @@
<intent-filter>
<action android:name="oxygentoolbox.timescreen" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".tools.translation.MainActivity"
android:exported="false"
android:theme="@style/Theme.OxygenToolbox.Default">
<intent-filter>
<action android:name="oxygentoolbox.translation" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

View File

@@ -28,7 +28,7 @@
"cn": "\u7ffb\u8bd1",
"en": "Translation"
},
"activity": ""
"activity": "com.fatapp.oxygentoolbox.tools.translation.MainActivity"
}
]
}

View File

@@ -0,0 +1,224 @@
package com.fatapp.oxygentoolbox.tools.translation;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.fatapp.oxygentoolbox.R;
import com.fatapp.oxygentoolbox.tools.translation.util.ResponseListener;
import com.fatapp.oxygentoolbox.util.ResourceUtil;
import com.fatapp.oxygentoolbox.util.ToolsList;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.StringJoiner;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
private final String TOOL_NAME = ToolsList.getToolName(getClass().getName());
private final String URL_YOU_DAO = "http://fanyi.youdao.com/translate?&doctype=json&type=%s&i=%s";
private final String LANGUAGE_CHINESE = "ZH_CN";
private final String LANGUAGE_ENGLISH = "EN";
private final String LANGUAGE_JAPANESE = "JA";
private final String LANGUAGE_KOREAN = "KR";
private final String[] LANGUAGE_ITEMS = {LANGUAGE_CHINESE, LANGUAGE_ENGLISH, LANGUAGE_JAPANESE, LANGUAGE_KOREAN};
private final String[] CHINESE_ITEMS = {ResourceUtil.getString(R.string.tool_translation_language_chinese),
ResourceUtil.getString(R.string.tool_translation_language_english),
ResourceUtil.getString(R.string.tool_translation_language_japanese),
ResourceUtil.getString(R.string.tool_translation_language_korean)};
private final String[] OTHER_ITEMS = {ResourceUtil.getString(R.string.tool_translation_language_chinese)};
private String languageFrom = LANGUAGE_CHINESE;
private String languageTo = LANGUAGE_ENGLISH;
private ConstraintLayout constraintLayoutRoot;
private Toolbar toolbar;
private TextView textViewLanguageFrom;
private ImageView imageViewSwap;
private TextView textViewLanguageTo;
private EditText editTextFrom;
private TextView textViewTo;
private ImageView imageViewTranslate;
private ProgressBar progressBarInTranslation;
private void initView() {
constraintLayoutRoot = findViewById(R.id.constraint_layout_root);
toolbar = findViewById(R.id.toolbar);
textViewLanguageFrom = findViewById(R.id.text_view_language_from);
imageViewSwap = findViewById(R.id.image_view_swap);
textViewLanguageTo = findViewById(R.id.text_view_language_to);
editTextFrom = findViewById(R.id.edit_text_from);
textViewTo = findViewById(R.id.edit_text_to);
imageViewTranslate = findViewById(R.id.image_view_translate);
progressBarInTranslation = findViewById(R.id.progress_bar_in_translation);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tool_translation);
initView();
initLayout();
textViewLanguageFrom.setOnClickListener(view -> new MaterialAlertDialogBuilder(this)
.setTitle(ResourceUtil.getString(R.string.tool_translation_choose_language))
.setItems(languageTo.equals(LANGUAGE_CHINESE) ? CHINESE_ITEMS : OTHER_ITEMS, (dialogInterface, i) -> {
textViewLanguageFrom.setText(CHINESE_ITEMS[i]);
languageFrom = LANGUAGE_ITEMS[i];
})
.show());
textViewLanguageTo.setOnClickListener(view -> new MaterialAlertDialogBuilder(this)
.setTitle(ResourceUtil.getString(R.string.tool_translation_choose_language))
.setItems(languageFrom.equals(LANGUAGE_CHINESE) ? CHINESE_ITEMS : OTHER_ITEMS, (dialogInterface, i) -> {
textViewLanguageTo.setText(CHINESE_ITEMS[i]);
languageTo = LANGUAGE_ITEMS[i];
})
.show());
imageViewSwap.setOnClickListener(view -> {
AnimatedVectorDrawable animatedVectorDrawable = (AnimatedVectorDrawable) imageViewSwap.getDrawable();
animatedVectorDrawable.start();
String temp = languageFrom;
languageFrom = languageTo;
languageTo = temp;
temp = textViewLanguageFrom.getText().toString();
textViewLanguageFrom.setText(textViewLanguageTo.getText());
textViewLanguageTo.setText(temp);
});
editTextFrom.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
imageViewTranslate.setEnabled(charSequence.length() != 0);
}
@Override
public void afterTextChanged(Editable editable) {
}
});
textViewTo.setOnFocusChangeListener((view, b) -> ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(editTextFrom.getWindowToken(), 0));
imageViewTranslate.setEnabled(false);
imageViewTranslate.setOnClickListener(view -> translate());
}
private void initLayout() {
constraintLayoutRoot.setPadding(0, ResourceUtil.getStatusBarHeight(getWindow(), getApplicationContext()), 0, 0);
setSupportActionBar(toolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
Objects.requireNonNull(getSupportActionBar()).setTitle(TOOL_NAME);
}
private void translate() {
editTextFrom.setEnabled(false);
imageViewTranslate.setEnabled(false);
progressBarInTranslation.setVisibility(View.VISIBLE);
((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(editTextFrom.getWindowToken(), 0);
translateYouDao(languageFrom, languageTo, editTextFrom.getText().toString(), new ResponseListener() {
@Override
public void onResponse(int code, String responseBody) {
if (code == 200) {
try {
final JSONArray partArray = new JSONObject(responseBody).getJSONArray("translateResult");
final StringJoiner resultJoiner = new StringJoiner("\n");
for (int i = 0; i < partArray.length(); i++) {
final JSONArray sentenceArray = partArray.getJSONArray(i);
final StringJoiner sentenceJoiner = new StringJoiner(new JSONObject(responseBody).getString("type").toLowerCase().startsWith("zh") ? " " : "");
for (int j = 0; j < sentenceArray.length(); j++) {
sentenceJoiner.add(sentenceArray.getJSONObject(j).getString("tgt"));
}
resultJoiner.add(sentenceJoiner.toString());
}
textViewTo.setText(resultJoiner.toString());
editTextFrom.setEnabled(true);
imageViewTranslate.setEnabled(true);
progressBarInTranslation.setVisibility(View.INVISIBLE);
} catch (JSONException e) {
onFailed();
}
} else {
onFailed();
}
}
@Override
public void onFailed() {
textViewTo.setText(null);
editTextFrom.setEnabled(true);
imageViewTranslate.setEnabled(true);
progressBarInTranslation.setVisibility(View.INVISIBLE);
Snackbar.make(constraintLayoutRoot, "翻译失败", Snackbar.LENGTH_LONG).show();
}
});
}
private void translateYouDao(String from, String to, String text, @NonNull ResponseListener responseListener) {
if (from.equals(to)) {
responseListener.onFailed();
return;
}
new Thread() {
@Override
public void run() {
OkHttpClient okHttpClient = new OkHttpClient();
try {
Request request = new Request.Builder().url(String.format(URL_YOU_DAO, from.toUpperCase() + 2 + to.toUpperCase(), URLEncoder.encode(text, StandardCharsets.UTF_8.toString()))).build();
try (Response response = okHttpClient.newCall(request).execute()) {
int code = response.code();
String body = Objects.requireNonNull(response.body()).string();
runOnUiThread(() -> responseListener.onResponse(code, body));
} catch (IOException e) {
runOnUiThread(responseListener::onFailed);
}
} catch (UnsupportedEncodingException e) {
runOnUiThread(responseListener::onFailed);
}
}
}.start();
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
}

View File

@@ -0,0 +1,7 @@
package com.fatapp.oxygentoolbox.tools.translation.util;
public interface ResponseListener {
void onResponse(int code, String responseBody);
void onFailed();
}

View File

@@ -13,7 +13,9 @@ import com.fatapp.oxygentoolbox.R;
public class ToolsLauncher {
public static void launch(Activity activity, Context context, String launchActivity) {
try {
startActivity(context, new Intent(context, Class.forName(launchActivity)), ActivityOptions.makeSceneTransitionAnimation(activity).toBundle());
startActivity(context, new Intent(context, Class.forName(launchActivity))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
ActivityOptions.makeSceneTransitionAnimation(activity).toBundle());
} catch (ClassNotFoundException e) {
Toast.makeText(context, R.string.activity_class_not_found, Toast.LENGTH_LONG).show();
}

View File

@@ -1,5 +1,7 @@
package com.fatapp.oxygentoolbox.util;
import androidx.annotation.NonNull;
import com.fatapp.oxygentoolbox.util.json.ToolsJson;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@@ -116,4 +118,15 @@ public class ToolsList {
this.activity = activity;
}
}
public static String getToolName(@NonNull String className) {
for (Tool tool : toolList) {
for (Button button : tool.getButtonList()) {
if (button.getActivity().equals(className)) {
return button.getText();
}
}
}
return null;
}
}

View File

@@ -0,0 +1,33 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector
android:name="vector"
android:width="32dp"
android:height="32dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group
android:name="group"
android:pivotX="12"
android:pivotY="12">
<path
android:name="path"
android:pathData="M 6.99 11 L 3 15 L 6.99 19 L 6.99 16 L 14 16 L 14 14 L 6.99 14 L 6.99 11 Z M 21 9 L 17.01 5 L 17.01 8 L 10 8 L 10 10 L 17.01 10 L 17.01 13 L 21 9 Z"
android:fillColor="?attr/app_text_theme"/>
</group>
</vector>
</aapt:attr>
<target android:name="group">
<aapt:attr name="android:animation">
<objectAnimator
android:propertyName="rotation"
android:duration="300"
android:valueFrom="0"
android:valueTo="180"
android:valueType="floatType"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
</aapt:attr>
</target>
</animated-vector>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/fold_layout_background" />
<solid android:color="?attr/app_on_background_theme" />
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"/>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="?attr/app_background_theme" />
</shape>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/fold_layout_background" />
<solid android:color="?attr/app_on_background_theme" />
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"/>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/fold_layout_background" />
<solid android:color="?attr/app_on_background_theme" />
</shape>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/fold_layout_background" />
<solid android:color="?attr/app_on_background_theme" />
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/fold_layout_background" />
<solid android:color="?attr/app_on_background_theme" />
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/fold_layout_background" />
<solid android:color="?attr/app_on_background_theme" />
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>

View File

@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="56dp"
android:height="56dp"
android:autoMirrored="true"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="?attr/app_theme"
android:pathData="M 0 12 C 0 5.374 5.374 0 12 0 C 18.627 0 24 5.374 24 12 C 24 18.627 18.627 24 12 24 C 5.374 24 0 18.627 0 12 Z" />
<path
android:fillColor="?attr/app_on_theme"
android:pathData="M12.47,13.77l-1.35,-1.33 0.02,-0.02c0.93,-1.03 1.57,-2.21 1.97,-3.47L14.65,8.96L14.65,7.9h-3.71L10.94,6.83L9.88,6.83v1.06L6.16,7.9v1.06h5.93C11.73,9.97 11.18,10.95 10.41,11.8 9.92,11.25 9.51,10.65 9.19,10.02h-1.06c0.39,0.87 0.92,1.68 1.57,2.42l-2.7,2.66L7.76,15.85l2.65,-2.65 1.64,1.64 0.4,-1.08zM15.45,11.07h-1.06L12,17.44h1.06l0.59,-1.59h2.52L16.77,17.44h1.06l-2.39,-6.37zM14.06,14.79l0.86,-2.3L15.77,14.79h-1.72z" />
</vector>

View File

@@ -13,8 +13,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.OxygenToolbox.AppBarOverlay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar

View File

@@ -9,7 +9,7 @@
android:id="@+id/imageView"
android:layout_width="288dp"
android:layout_height="288dp"
android:contentDescription="LOGO"
android:contentDescription="Logo"
android:src="@drawable/ic_launcher"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@@ -14,7 +14,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:contentDescription="@string/tool_time_change_mode"
android:contentDescription="Change Mode"
android:padding="10dp"
android:src="@drawable/animation_light_to_dark_mode"
app:layout_constraintEnd_toEndOf="parent"

View File

@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraint_layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/app_background_theme"
tools:context=".tools.translation.MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.OxygenToolbox.AppBarOverlay"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.OxygenToolbox.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/app_bar_layout">
<LinearLayout
android:id="@+id/linear_layout_language"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/background_top_bottom_radius"
android:gravity="center"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/text_view_language_from"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/tool_translation_language_chinese"
android:textColor="?attr/app_theme"
android:textSize="16sp" />
<ImageView
android:id="@+id/image_view_swap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Swap"
android:padding="5dp"
android:src="@drawable/animation_swap_horizon" />
<TextView
android:id="@+id/text_view_language_to"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/tool_translation_language_english"
android:textColor="?attr/app_theme"
android:textSize="16sp" />
</LinearLayout>
<EditText
android:id="@+id/edit_text_from"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="10dp"
android:autofillHints="text"
android:background="@drawable/background_top_bottom_radius"
android:gravity="start|top"
android:hint="@string/tool_translation_please_enter_text"
android:inputType="textMultiLine"
android:maxLength="850"
android:paddingHorizontal="15dp"
android:paddingTop="15dp"
android:paddingBottom="30dp"
android:textColor="?attr/app_text_theme"
android:textSize="16sp"
app:layout_constraintTop_toBottomOf="@id/linear_layout_language" />
<TextView
android:id="@+id/edit_text_to"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="10dp"
android:autofillHints="text"
android:background="@drawable/background_top_bottom_radius"
android:gravity="start|top"
android:paddingHorizontal="15dp"
android:paddingTop="30dp"
android:paddingBottom="15dp"
android:textColor="?attr/app_text_theme"
android:textIsSelectable="true"
android:textSize="16sp"
app:layout_constraintTop_toBottomOf="@id/edit_text_from" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/background_round"
android:padding="5dp"
app:layout_constraintBottom_toTopOf="@id/edit_text_to"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/edit_text_from">
<ImageView
android:id="@+id/image_view_translate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:contentDescription="Translate"
android:focusable="true"
android:foreground="@drawable/foreground_ripple"
android:src="@drawable/ic_translate"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/progress_bar_in_translation"
android:layout_width="0dp"
android:layout_height="0dp"
android:indeterminateTint="?attr/app_on_theme"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -16,7 +16,7 @@
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/nav_header_desc"
android:contentDescription="Logo"
android:paddingTop="@dimen/nav_header_vertical_spacing"
app:srcCompat="@mipmap/ic_launcher_round" />

View File

@@ -32,5 +32,5 @@
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginHorizontal="10dp"
android:contentDescription="@string/arrow_icon" />
android:contentDescription="Arrow" />
</LinearLayout>

File diff suppressed because one or more lines are too long

View File

@@ -73,4 +73,8 @@
<string name="setting_search">查找</string>
<string name="setting_about">关于</string>
<string name="setting_about_oxygen_toolbox">关于 氧工具</string>
<string name="tool_translation_choose_language">选择语言</string>
<string name="tool_translation_please_enter_text">请输入内容……</string>
<string name="tool_translation_translation_failed">翻译失败</string>
</resources>

View File

@@ -73,4 +73,8 @@
<string name="setting_search">查找</string>
<string name="setting_about">关于</string>
<string name="setting_about_oxygen_toolbox">关于 氧工具</string>
<string name="tool_translation_choose_language">选择语言</string>
<string name="tool_translation_please_enter_text">请输入内容……</string>
<string name="tool_translation_translation_failed">翻译失败</string>
</resources>

View File

@@ -73,4 +73,8 @@
<string name="setting_search">查找</string>
<string name="setting_about">关于</string>
<string name="setting_about_oxygen_toolbox">关于 氧工具</string>
<string name="tool_translation_choose_language">选择语言</string>
<string name="tool_translation_please_enter_text">请输入内容……</string>
<string name="tool_translation_translation_failed">翻译失败</string>
</resources>

View File

@@ -8,7 +8,6 @@
<string name="navigation_drawer_close">Close navigation drawer</string>
<string name="nav_header_title" translatable="false">@string/app_full_name</string>
<string name="nav_header_subtitle" translatable="false">@string/app_desc</string>
<string name="nav_header_desc" translatable="false">@string/app_full_name</string>
<string name="menu_home">Home</string>
<string name="menu_home_tools">Tools</string>
@@ -22,8 +21,6 @@
<string name="shortcutLongLabel">Oxygen Toolbox</string>
<string name="shortcutShortLabel">Oxygen Toolbox</string>
<string name="arrow_icon" translatable="false"><![CDATA[>]]></string>
<string name="init_tools_failed">Failed to initialize tools</string>
<string name="activity_class_not_found">Can not load tool, it may be damaged</string>
@@ -108,5 +105,12 @@
<string name="setting_about_oxygen_toolbox_key" translatable="false">app_about</string>
<string name="tool_time_screen_colon" translatable="false">&#160;:&#160;</string>
<string name="tool_time_change_mode" translatable="false">Change Mode</string>
<string name="tool_translation_choose_language">Choose a language</string>
<string name="tool_translation_language_chinese" translatable="false">中文</string>
<string name="tool_translation_language_english" translatable="false">English</string>
<string name="tool_translation_language_japanese" translatable="false">日本</string>
<string name="tool_translation_language_korean" translatable="false">한국인</string>
<string name="tool_translation_please_enter_text">Please enter text…</string>
<string name="tool_translation_translation_failed">Translation Failed</string>
</resources>

View File

@@ -0,0 +1,22 @@
package com.fatapp.oxygentoolbox;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
public class Tester {
@Test
public void urlEncodeTest() throws UnsupportedEncodingException {
System.out.println(URLEncoder.encode(" ", StandardCharsets.UTF_8.toString()));
}
@Test
public void buildConfigTest() {
assertEquals(BuildConfig.API_APP_ID, "123456789");
assertEquals(BuildConfig.API_APP_SECRET, "abcdefg");
}
}