update text translate

This commit is contained in:
Simon 2024-07-11 17:54:19 +08:00
parent 9310c79e20
commit 4e66e7f84d
41 changed files with 1383 additions and 1322 deletions

View File

@ -6,12 +6,17 @@
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.CAMERA" />
<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" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
<application
android:allowBackup="true"
@ -23,6 +28,13 @@
android:supportsRtl="true"
android:theme="@style/Theme.Alltrans"
tools:targetApi="31">
<service
android:name=".allservice.SusService"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="mediaProjection" />
<activity
android:name=".viewui.QuickSetActivity"
android:exported="false" />

View File

@ -0,0 +1,156 @@
package com.assimilate.alltrans
import android.app.ActivityManager
import android.app.Application
import android.content.Context
import android.os.Build
import android.webkit.WebView
import com.assimilate.alltrans.common.Language
import com.assimilate.alltrans.common.LanguagesConstants
class MyApp : Application() {
init {
instance = this
}
private var sl: Language? = null
private var tl: Language? = null
companion object {
private var instance: MyApp? = null
fun applicationContext(): Context {
return instance!!.applicationContext
}
fun getSourceLanguageCode(): String {
return instance?.getSourceLanguageCode() ?: "zh"
}
fun getSourceLanguage(): String {
return instance?.getSourceLanguage() ?: "English"
}
fun getSourceSpeechCode(): String {
return instance?.getSourceSpeechCode() ?: "en-GB"
}
fun getTargetLanguageCode(): String {
return instance?.getTargetLanguageCode() ?: "en"
}
fun getTargetLanguage(): String {
return instance?.getTargetLanguage() ?: "English"
}
fun getTargetSpeechCode(): String {
return instance?.getTargetSpeechCode() ?: "en-GB"
}
fun setSourceLanguage(language: Language) {
instance?.setSourceLanguage(language)
}
fun setTargetLanguage(language: Language) {
instance?.setTargetLanguage(language)
}
}
override fun onCreate() {
super.onCreate()
initLanguage()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val processName = getUniqueProcessName()
if (processName != null && processName != packageName) {
WebView.setDataDirectorySuffix(processName)
}
}
}
private fun getUniqueProcessName(): String? {
val pid = android.os.Process.myPid()
val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
for (processInfo in manager.runningAppProcesses) {
if (processInfo.pid == pid) {
return processInfo.processName
}
}
return null
}
object Config {
const val openSusViewMode: String = "open_sus_view"
}
private fun initLanguage() {
// 拿到最近一次的翻译情况分别设置最近一次的并赋值setSourceLanguage|setTargetLanguage
// 以下是默认情况
val languages: ArrayList<Language> = LanguagesConstants.getInstance().getList(applicationContext)
if (languages.isNotEmpty()) {
for (language in languages) {
if ("Afrikaans" == language.language) {
tl = language
break
}
}
for (language in languages) {
if ("English" == language.language) {
sl = language
break
}
}
}
}
private fun getSourceLanguageCode(): String {
if (sl == null) {
return "en"
}
return sl!!.languageCode
}
private fun getSourceLanguage(): String {
if (sl == null) {
return "English"
}
return sl!!.language
}
private fun getSourceSpeechCode(): String {
if (sl == null) {
return "en-GB"
}
return sl!!.speechCode
}
private fun getTargetLanguageCode(): String {
if (tl == null) {
return "en"
}
return tl!!.languageCode
}
private fun getTargetLanguage(): String {
if (tl == null) {
return "English"
}
return tl!!.language
}
private fun getTargetSpeechCode(): String {
if (tl == null) {
return "en-GB"
}
return tl!!.speechCode
}
private fun setSourceLanguage(language: Language) {
sl = language
}
private fun setTargetLanguage(language: Language) {
tl = language
}
}

View File

@ -1,33 +0,0 @@
package com.assimilate.alltrans.adapters;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import java.util.ArrayList;
public class ContainerAdapter extends FragmentStateAdapter {
private final ArrayList<Fragment> fragments;
public ContainerAdapter(@NonNull FragmentActivity fragmentActivity, @NonNull ArrayList<Fragment> list) {
super(fragmentActivity);
this.fragments = new ArrayList<>();
if (!list.isEmpty()) {
this.fragments.addAll(list);
}
}
@NonNull
@Override
public Fragment createFragment(int position) {
return fragments.get(position);
}
@Override
public int getItemCount() {
return fragments.size();
}
}

View File

@ -0,0 +1,275 @@
package com.assimilate.alltrans.allservice
import android.app.*
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.PixelFormat
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.media.ImageReader
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.*
import android.util.DisplayMetrics
import android.util.Log
import android.view.*
import androidx.core.app.NotificationCompat
import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.TextRecognitionProcessor
import com.assimilate.alltrans.common.VisionImageProcessor
import com.assimilate.alltrans.databinding.SusControlViewBinding
import com.assimilate.alltrans.databinding.LayoutSusGlobalBinding
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
import java.io.IOException
class SusService : Service() {
private var imageProcessor: VisionImageProcessor? = null
private lateinit var mediaProjectionManager: MediaProjectionManager
private lateinit var mediaProjection: MediaProjection
private lateinit var virtualDisplay: VirtualDisplay
private lateinit var displayMetrics: DisplayMetrics
private lateinit var windowManager: WindowManager
private lateinit var floatingView: View
private lateinit var globalView: View
private lateinit var bindingSusControl: SusControlViewBinding
private lateinit var bindingSubGlobal: LayoutSusGlobalBinding
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
mediaProjectionManager =
getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
displayMetrics = DisplayMetrics()
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay?.getMetrics(displayMetrics)
initSusView()
startForeground(1, createNotification())
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val resultCode = intent?.getIntExtra("resultCode", Activity.RESULT_OK)
val data: Intent? = intent?.getParcelableExtra("data")
if (resultCode != null && data != null) {
startScreenshot(resultCode, data)
}
return START_NOT_STICKY
}
private fun initSusView() {
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
bindingSusControl = SusControlViewBinding.inflate(LayoutInflater.from(this))
floatingView = bindingSusControl.root
val layoutParams = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_PHONE
},
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
layoutParams.gravity = Gravity.TOP or Gravity.LEFT
layoutParams.x = 0
layoutParams.y = 100
windowManager.addView(floatingView, layoutParams)
// 设置点击事件
bindingSusControl.tvSusGlobal.setOnClickListener {
// 处理全局翻译点击事件
addGlobalView()
}
bindingSusControl.tvSusCopy.setOnClickListener {
// 处理复制文本点击事件
}
bindingSusControl.tvSusPhoto.setOnClickListener {
// 处理照片翻译点击事件
}
bindingSusControl.tvSusDistrict.setOnClickListener {
// 处理地区翻译点击事件
}
bindingSusControl.ivSusHome.setOnClickListener {
// 处理返回主页点击事件
}
bindingSusControl.ivSusMove.setOnClickListener {
// 处理移动窗口点击事件
}
bindingSusControl.ivSusMove.setOnTouchListener(object : View.OnTouchListener {
private var startX = 0f
private var startY = 0f
private var touchX = 0f
private var touchY = 0f
override fun onTouch(v: View, event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
startX = layoutParams.x.toFloat()
startY = layoutParams.y.toFloat()
touchX = event.rawX
touchY = event.rawY
return true
}
MotionEvent.ACTION_MOVE -> {
layoutParams.x = (startX + (event.rawX - touchX)).toInt()
layoutParams.y = (startY + (event.rawY - touchY)).toInt()
windowManager.updateViewLayout(floatingView, layoutParams)
return true
}
MotionEvent.ACTION_UP -> return true
}
return false
}
})
}
private fun addGlobalView() {
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
bindingSubGlobal = LayoutSusGlobalBinding.inflate(LayoutInflater.from(this))
globalView = bindingSubGlobal.root
imageProcessor = TextRecognitionProcessor(
this,
ChineseTextRecognizerOptions.Builder().build()
)
val layoutParams = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_PHONE
},
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
layoutParams.gravity = Gravity.TOP or Gravity.LEFT
layoutParams.x = 0
layoutParams.y = 100
windowManager.addView(globalView, layoutParams)
}
override fun onDestroy() {
super.onDestroy()
if (floatingView.isAttachedToWindow) {
windowManager.removeView(floatingView)
}
if (::globalView.isInitialized && globalView.isAttachedToWindow) {
windowManager.removeView(globalView)
}
}
private fun createNotification(): Notification {
val notificationChannelId = "FOREGROUND_SERVICE_CHANNEL"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelName = "Foreground Service Channel"
val chan = NotificationChannel(
notificationChannelId,
channelName,
NotificationManager.IMPORTANCE_NONE
)
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(chan)
}
val builder = NotificationCompat.Builder(this, notificationChannelId)
.setContentTitle("悬浮窗服务")
.setContentText("悬浮窗服务正在运行")
.setSmallIcon(R.drawable.ic_close)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setCategory(Notification.CATEGORY_SERVICE)
return builder.build()
}
private fun tryReloadAndDetectInImage(bitmap: Bitmap) {
try {
// Clear the overlay first
bindingSubGlobal.susGraphicOverlay.clear()
if (imageProcessor != null) {
bindingSubGlobal.susGraphicOverlay.setImageSourceInfo(
bitmap.width,
bitmap.height,
false
)
imageProcessor!!.processBitmap(bitmap, bindingSubGlobal.susGraphicOverlay)
} else {
Log.e(
"SusService",
"Null imageProcessor, please check adb logs for imageProcessor creation error"
)
}
} catch (e: IOException) {
Log.e("SusService", "Error retrieving saved image")
}
}
fun startScreenshot(resultCode: Int, data: Intent?) {
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data!!)
val imageReader = ImageReader.newInstance(
displayMetrics.widthPixels,
displayMetrics.heightPixels,
PixelFormat.RGBA_8888,
2
)
virtualDisplay = mediaProjection.createVirtualDisplay(
"Screenshot",
displayMetrics.widthPixels,
displayMetrics.heightPixels,
displayMetrics.densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
imageReader.surface,
null,
null
)
// 初始化 globalView
addGlobalView()
Handler(Looper.getMainLooper()).postDelayed({
val image = imageReader.acquireLatestImage()
if (image != null) {
val planes = image.planes
val buffer = planes[0].buffer
val pixelStride = planes[0].pixelStride
val rowStride = planes[0].rowStride
val rowPadding = rowStride - pixelStride * displayMetrics.widthPixels
val bitmap = Bitmap.createBitmap(
displayMetrics.widthPixels + rowPadding / pixelStride,
displayMetrics.heightPixels,
Bitmap.Config.ARGB_8888
)
bitmap.copyPixelsFromBuffer(buffer)
image.close()
bindingSubGlobal.preview.setImageBitmap(bitmap)
tryReloadAndDetectInImage(bitmap)
}
stopSelf()
}, 1000)
}
}

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.common;
@ -41,11 +26,15 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
/** Utils functions for bitmap conversions. */
/**
* Utils functions for bitmap conversions.
*/
public class BitmapUtils {
private static final String TAG = "BitmapUtils";
/** Converts NV21 format byte buffer to bitmap. */
/**
* Converts NV21 format byte buffer to bitmap.
*/
@Nullable
public static Bitmap getBitmap(ByteBuffer data, FrameMetadata metadata) {
data.rewind();
@ -68,7 +57,9 @@ public class BitmapUtils {
return null;
}
/** Converts a YUV_420_888 image from CameraX API to a bitmap. */
/**
* Converts a YUV_420_888 image from CameraX API to a bitmap.
*/
@RequiresApi(VERSION_CODES.LOLLIPOP)
@Nullable
@ExperimentalGetImage
@ -85,7 +76,9 @@ public class BitmapUtils {
return getBitmap(nv21Buffer, frameMetadata);
}
/** Rotates a bitmap if it is converted from a bytebuffer. */
/**
* Rotates a bitmap if it is converted from a bytebuffer.
*/
private static Bitmap rotateBitmap(
Bitmap bitmap, int rotationDegrees, boolean flipX, boolean flipY) {
Matrix matrix = new Matrix();
@ -221,7 +214,9 @@ public class BitmapUtils {
return ByteBuffer.wrap(out);
}
/** Checks if the UV plane buffers of a YUV_420_888 image are in the NV21 format. */
/**
* Checks if the UV plane buffers of a YUV_420_888 image are in the NV21 format.
*/
private static boolean areUVPlanesNV21(Plane[] planes, int width, int height) {
int imageSize = width * height;

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.common;

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.common;

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.common;

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.common;

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.common;

View File

@ -1,5 +0,0 @@
package com.assimilate.alltrans.common;
public enum Sort {
language, languageCode, speechCode;
}

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.common

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.common

View File

@ -1,18 +1,3 @@
/*
* Copyright 2020 Google LLC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.assimilate.alltrans.curview;

View File

@ -0,0 +1,26 @@
package com.assimilate.alltrans.curview
import android.view.View
import android.view.WindowManager
class SusView : View.OnClickListener {
private var windowManager: WindowManager? = null
private var layoutParams: WindowManager.LayoutParams? = null
companion object {
}
override fun onClick(v: View?) {
TODO("Not yet implemented")
}
private fun initView() {
}
}

View File

@ -1,297 +0,0 @@
package com.assimilate.alltrans.fragments;
import androidx.fragment.app.Fragment;
public class TranslateCameraFragment extends Fragment {
// private ActivityResultLauncher<Intent> activityLauncher;
// private ActivityResultLauncher<String> permissionLauncher;
//
// private FragmentTranslateCameraBinding mBinding;
//
// private TextToSpeech tts;
//
// private boolean translating = false;
// private boolean adLoading = false; // 广告是否处于加载中
// private boolean collectCurrent = false;
// private String sourceText = ""; // 可能会有一种屌毛翻译完成后先去输入框删几个字符然后再去点击收藏按钮所以每次翻译前备份一下
//
// @Override
// public void onCreate(@Nullable Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// activityLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
// @Override
// public void onActivityResult(ActivityResult result) {
// if (Activity.RESULT_OK == result.getResultCode() && null != result.getData()) {
// Intent data = result.getData();
// String recognizedText = data.getStringExtra("recognizedText");
// if (!TextUtils.isEmpty(recognizedText)) {
// mBinding.inputText.setText(recognizedText);
// translate(recognizedText);
// }
// }
// }
// });
// permissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() {
// @Override
// public void onActivityResult(Boolean result) {
// if (result.booleanValue()) {
// launchCameraApi();
// } else {
// Widget.makeToast(getActivity(), "permission denied");
// }
// }
// });
//
// translating = false;
// adLoading = false;
// collectCurrent = false;
//
// tts = new TextToSpeech(getActivity(), new TextToSpeech.OnInitListener() {
// @Override
// public void onInit(int status) {
// if (null != tts && TextToSpeech.SUCCESS == status)
// tts.setLanguage(Locale.getDefault());
// }
// });
// }
//
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// mBinding = FragmentTranslateCameraBinding.inflate(getLayoutInflater());
//
// // 朗读原文
// mBinding.speakSource.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// String speech = mBinding.result.getText().toString().trim();
// if (!TextUtils.isEmpty(speech)) {
// if (null != tts
// && TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(Locale.getDefault())) {
// tts.speak(speech, 0, null, null);
// }
// }
// }
// });
// // 清空翻译输入框与结果文本
// mBinding.clear.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// mBinding.result.setText("");
// mBinding.inputText.setText("");
//
// reset();
// }
// });
// // 朗读译文
// mBinding.speakTarget.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// String speech = mBinding.result.getText().toString().trim();
// if (!translating && !TextUtils.isEmpty(speech)) {
// if (null != tts
// && TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(Locale.getDefault())) {
// tts.speak(speech, 0, null, null);
// }
// }
// }
// });
// // 分享译文
// mBinding.shareTrans.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// if (translating) {
// Widget.makeToast(getActivity(), "Translating...");
// return;
// }
//
// final String share = mBinding.result.getText().toString().trim();
// if (!TextUtils.isEmpty(share)) {
// Intent intent = new Intent(Intent.ACTION_SEND);
// intent.setType("text/plain");
// intent.putExtra(Intent.EXTRA_TEXT, share);
// startActivity(Intent.createChooser(intent, "Share " + getString(R.string.app_name)));
// }
// }
// });
// // 复制到粘贴板
// mBinding.copyTrans.setOnClickListener(new View.OnClickListener() {
// private final String tip = "Copied to clipboard!";
// @Override
// public void onClick(View v) {
// final String share = mBinding.result.getText().toString().trim();
// if (!translating && !TextUtils.isEmpty(share)) {
// ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
// ClipData clipData = ClipData.newPlainText("targetValue", share);
// clipboardManager.setPrimaryClip(clipData);
// Widget.makeToast(getActivity(), tip);
// }
// }
// });
// // 收藏按钮翻译中禁止收藏, 无原文禁止收藏无译文禁止收藏
// mBinding.collectTrans.setOnClickListener(new View.OnClickListener() {
// private DbTranslation dbTranslation;
//
// @Override
// public void onClick(View v) {
// if (translating) return;
//
// final String sourceTxt = sourceText;
// if (TextUtils.isEmpty(sourceTxt)) return;
//
// if (collectCurrent) {
// collectCurrent = false;
// getDbTranslation(getActivity()).collectJust(false);
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collecttrans);
// } else {
// collectCurrent = true;
// getDbTranslation(getActivity()).collectJust(true);
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collectedtrans);
// }
// }
//
// private DbTranslation getDbTranslation(Context context) {
// if (null == dbTranslation) {
// dbTranslation = new DbTranslation(context);
// }
// return dbTranslation;
// }
// });
//
// mBinding.changeLanguage.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// launchLanguageSet();
// }
// });
//
// return mBinding.getRoot();
// }
//
// @Override
// public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
// super.onViewCreated(view, savedInstanceState);
// }
//
// @Override
// public void onResume() {
// super.onResume();
//
// // 每次回来可能会更新
// mBinding.languageSource.setText(TranslateWordApp.getSourceLanguage());
// mBinding.languageTarget.setText(TranslateWordApp.getTargetLanguage());
// mBinding.sourceLanguage2.setText(TranslateWordApp.getSourceLanguage());
// mBinding.targetLanguage2.setText(TranslateWordApp.getTargetLanguage());
//
// // TODO: 可以判断是否需要再次请求原生广告
// }
//
// @Override
// public void onStop() {
// super.onStop();
//
// if (null != tts) tts.stop();
// }
//
// @Override
// public void onDestroy() {
// super.onDestroy();
// if (null != tts) tts.shutdown();
// }
//
// public void launchCamera() {
// if (withCameraPermission()) {
// launchCameraApi();
// } else {
// if (null != permissionLauncher) {
// permissionLauncher.launch(Manifest.permission.CAMERA);
// }
// }
// }
//
// private void launchCameraApi() {
// if (null != activityLauncher) {
// activityLauncher.launch(new Intent(getActivity(), TranslateCameraActivity.class));
// }
// }
//
// private void translate(@NonNull final String text) {
// // step1. 叫用户检查网络连接
// if (translating) {
// // 第一次点击翻译按钮后 可能会延迟响应结果翻译期间再次点击翻译按钮无效
// Logger.d("log", "translating(not post data)...");
// return;
// }
// Logger.d("log", "translating...");
// reset();
//
// translating = true;
// final HashMap<String, String> param = new HashMap<>();
// param.put("sourceLanguage", TranslateWordApp.getSourceLanguageCode());
// param.put("translationLanguage", TranslateWordApp.getTargetLanguageCode());
// param.put("text", text);
//
// sourceText = text;
// mBinding.result.setText("translating...");
// Translator<GoogleTranslator.GoogleTranslateCallback> translator = new GoogleTranslator();
// translator.translate(param, new GoogleTranslator.GoogleTranslateCallback() {
// @Override
// public void onResponse(String val) {
// translating = false;
//
// if (!TextUtils.isEmpty(val)) {
// TranslateMainActivity activity = null;
// if (getActivity() instanceof TranslateMainActivity) {
// activity = (TranslateMainActivity) getActivity();
// }
// if (null != activity) {
// activity.runOnUiThread(new Runnable() {
// @Override
// public void run() {
// mBinding.result.setText(val);
// addLog(val);
// }
// });
// }
// }
// }
//
// private void addLog(String targetTxt) {
// FragmentActivity activity = getActivity();
// if (null != activity) {
// DbTranslation dbTranslation = new DbTranslation(activity);
// Translations translations = new Translations(TranslateWordApp.getSourceLanguage(), sourceText, TranslateWordApp.getTargetLanguage(), targetTxt);
// dbTranslation.addTranslation(translations);
// }
// }
// });
// }
//
// private void reset() {
// // 归位收藏图片
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collecttrans);
// // 归位收藏备份文本
// sourceText = "";
// // 设置当前未处于收藏状态
// collectCurrent = false;
// // 当前不处于翻译状态
// translating = false;
// }
//
// private boolean withCameraPermission() {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// FragmentActivity activity = getActivity();
// if (null == activity) return false;
// return ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
// } else {
// return true;
// }
// }
//
// private void launchLanguageSet() {
// Intent intent = new Intent(getActivity(), TranslateChangeLanguageActivity.class);
// getActivity().startActivity(intent);
// }
//
//
}

View File

@ -1,280 +0,0 @@
package com.assimilate.alltrans.fragments;
import androidx.fragment.app.Fragment;
public class TranslateTextFragment extends Fragment {
// private FragmentTranslateTextBinding mBinding;
//
// private TextToSpeech tts;
//
// private boolean translating = false;
// private boolean adLoading = false; // 广告是否处于加载中
// private boolean collectCurrent = false;
//
// private String sourceText = ""; // 可能会有一种屌毛翻译完成后先去输入框删几个字符然后再去点击收藏按钮所以每次翻译前备份一下
//
// @Override
// public void onCreate(@Nullable Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
//
// translating = false;
// adLoading = false;
// collectCurrent = false;
//
// tts = new TextToSpeech(getActivity(), new TextToSpeech.OnInitListener() {
// @Override
// public void onInit(int status) {
// if (null != tts && TextToSpeech.SUCCESS == status)
// tts.setLanguage(Locale.getDefault());
// }
// });
// }
//
// @SuppressLint("ClickableViewAccessibility")
// @Override
// public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// mBinding = FragmentTranslateTextBinding.inflate(getLayoutInflater());
//
// // 朗读原文
// mBinding.speakSource.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// String speech = mBinding.result.getText().toString().trim();
// if (!TextUtils.isEmpty(speech)) {
// if (null != tts
// && TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(Locale.getDefault())) {
// tts.speak(speech, 0, null, null);
// }
// }
// }
// });
// // 清空翻译输入框与结果文本
// mBinding.clear.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// mBinding.result.setText("");
// mBinding.inputText.setText("");
//
// reset();
// }
// });
// // 输入enter键后直接翻译 & 关闭软件盘与失去光标闪烁
// mBinding.inputText.setOnTouchListener((view1, motionEvent) -> {
// mBinding.inputText.setCursorVisible(true);
// return false;
// });
// mBinding.inputText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
// @Override
// public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
// if (i == EditorInfo.IME_ACTION_SEARCH) {
// hiddenSoftKeyboard();
// final String text = mBinding.inputText.getText().toString();
// if (!TextUtils.isEmpty(text)) {
// translate(text);
// }
// return true;
// }
// return false;
// }
//
// private void hiddenSoftKeyboard() {
// final FragmentActivity activity = getActivity();
// final IBinder binder = mBinding.inputText.getWindowToken();
// if (null != activity && null != binder) {
// InputMethodManager inputMethodManager =
// (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
// boolean hideSoftInputFromWindow =
// inputMethodManager.hideSoftInputFromWindow(binder, InputMethodManager.HIDE_NOT_ALWAYS);
// if (hideSoftInputFromWindow) {
// mBinding.inputText.setCursorVisible(false);
// }
// }
// }
// });
//
// // 朗读译文
// mBinding.speakTarget.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// String speech = mBinding.result.getText().toString().trim();
// if (!translating && !TextUtils.isEmpty(speech)) {
// if (null != tts
// && TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(Locale.getDefault())) {
// tts.speak(speech, 0, null, null);
// }
// }
// }
// });
// // 分享译文
// mBinding.shareTrans.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// if (translating) {
// Widget.makeToast(getActivity(), "Translating...");
// return;
// }
//
// final String share = mBinding.result.getText().toString().trim();
// if (!TextUtils.isEmpty(share)) {
// Intent intent = new Intent(Intent.ACTION_SEND);
// intent.setType("text/plain");
// intent.putExtra(Intent.EXTRA_TEXT, share);
// startActivity(Intent.createChooser(intent, "Share " + getString(R.string.app_name)));
// }
// }
// });
// // 复制到粘贴板
// mBinding.copyTrans.setOnClickListener(new View.OnClickListener() {
// private final String tip = "Copied to clipboard!";
// @Override
// public void onClick(View v) {
// final String share = mBinding.result.getText().toString().trim();
// if (!translating && !TextUtils.isEmpty(share)) {
// ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
// ClipData clipData = ClipData.newPlainText("targetValue", share);
// clipboardManager.setPrimaryClip(clipData);
// Widget.makeToast(getActivity(), tip);
// }
// }
// });
// // 收藏按钮翻译中禁止收藏, 无原文禁止收藏无译文禁止收藏
// mBinding.collectTrans.setOnClickListener(new View.OnClickListener() {
// private DbTranslation dbTranslation;
//
// @Override
// public void onClick(View v) {
// if (translating) return;
//
// final String sourceTxt = sourceText;
// if (TextUtils.isEmpty(sourceTxt)) return;
//
// if (collectCurrent) {
// collectCurrent = false;
// getDbTranslation(getActivity()).collectJust(false);
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collecttrans);
// } else {
// collectCurrent = true;
// getDbTranslation(getActivity()).collectJust(true);
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collectedtrans);
// }
// }
//
// private DbTranslation getDbTranslation(Context context) {
// if (null == dbTranslation) {
// dbTranslation = new DbTranslation(context);
// }
// return dbTranslation;
// }
// });
//
// mBinding.changeLanguage.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// launchLanguageSet();
// }
// });
//
// return mBinding.getRoot();
// }
//
// @Override
// public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
// super.onViewCreated(view, savedInstanceState);
// }
//
// @Override
// public void onResume() {
// super.onResume();
//
// // 每次回来可能会更新
// mBinding.languageSource.setText(TranslateWordApp.getSourceLanguage());
// mBinding.languageTarget.setText(TranslateWordApp.getTargetLanguage());
// mBinding.sourceLanguage2.setText(TranslateWordApp.getSourceLanguage());
// mBinding.targetLanguage2.setText(TranslateWordApp.getTargetLanguage());
//
// // TODO: 可以判断是否需要再次请求原生广告
// }
//
// @Override
// public void onStop() {
// super.onStop();
// if (null != tts) tts.stop();
// }
//
// @Override
// public void onDestroy() {
// super.onDestroy();
// if (null != tts) tts.shutdown();
// }
//
// private void translate(@NonNull final String text) {
// // step1. 叫用户检查网络连接
// if (translating) {
// // 第一次点击翻译按钮后 可能会延迟响应结果翻译期间再次点击翻译按钮无效
// Logger.d("log", "translating(not post data)...");
// return;
// }
// Logger.d("log", "translating...");
// reset();
//
// translating = true;
// final HashMap<String, String> param = new HashMap<>();
// param.put("sourceLanguage", TranslateWordApp.getSourceLanguageCode());
// param.put("translationLanguage", TranslateWordApp.getTargetLanguageCode());
// param.put("text", text);
//
// sourceText = text;
// mBinding.result.setText("translating...");
// Translator<GoogleTranslator.GoogleTranslateCallback> translator = new GoogleTranslator();
// translator.translate(param, new GoogleTranslator.GoogleTranslateCallback() {
// @Override
// public void onResponse(String val) {
// translating = false;
//
// if (!TextUtils.isEmpty(val)) {
// TranslateMainActivity activity = null;
// if (getActivity() instanceof TranslateMainActivity) {
// activity = (TranslateMainActivity) getActivity();
// }
// if (null != activity) {
// activity.runOnUiThread(new Runnable() {
// @Override
// public void run() {
// mBinding.result.setText(val);
// addLog(val);
// }
// });
// }
// }
// }
//
// private void addLog(String targetTxt) {
// FragmentActivity activity = getActivity();
// if (null != activity) {
// DbTranslation dbTranslation = new DbTranslation(activity);
// Translations translations = new Translations(TranslateWordApp.getSourceLanguage(), sourceText, TranslateWordApp.getTargetLanguage(), targetTxt);
// dbTranslation.addTranslation(translations);
// }
// }
// });
// }
//
// private void reset() {
// // 归位收藏图片
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collecttrans);
// // 归位收藏备份文本
// sourceText = "";
// // 设置当前未处于收藏状态
// collectCurrent = false;
// // 当前不处于翻译状态
// translating = false;
// }
//
// private void launchLanguageSet() {
// Intent intent = new Intent(getActivity(), TranslateChangeLanguageActivity.class);
// getActivity().startActivity(intent);
// }
//
//
}

View File

@ -1,285 +0,0 @@
package com.assimilate.alltrans.fragments;
import androidx.fragment.app.Fragment;
// https://play.google.com/store/apps/details?id=com.google.android.tts
public class TranslateVoiceFragment extends Fragment {
// private FragmentTranslateVoiceBinding mBinding;
// private ActivityResultLauncher<Intent> launcher;
//
// private TextToSpeech tts;
//
// private boolean translating = false;
// private boolean adLoading = false; // 广告是否处于加载中
// private boolean collectCurrent = false;
//
// private String sourceText = ""; // 可能会有一种屌毛翻译完成后先去输入框删几个字符然后再去点击收藏按钮所以每次翻译前备份一下
//
// @Override
// public void onCreate(@Nullable Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
//
// translating = false;
// adLoading = false;
// collectCurrent = false;
//
// tts = new TextToSpeech(getActivity(), new TextToSpeech.OnInitListener() {
// @Override
// public void onInit(int status) {
// if (null != tts && TextToSpeech.SUCCESS == status)
// tts.setLanguage(Locale.getDefault());
// }
// });
//
// launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
// @Override
// public void onActivityResult(ActivityResult result) {
// Intent data = result.getData();
// if (Activity.RESULT_OK == result.getResultCode() && null != data) {
// String speech = data.getStringArrayListExtra("android.speech.extra.RESULTS").get(0);
// if (!TextUtils.isEmpty(speech)) {
// mBinding.inputText.setText(speech);
// translate(speech);
// }
// }
// }
// });
// }
//
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// mBinding = FragmentTranslateVoiceBinding.inflate(getLayoutInflater());
//
// // 朗读原文
// mBinding.speakSource.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// String speech = mBinding.result.getText().toString().trim();
// if (!TextUtils.isEmpty(speech)) {
// if (null != tts
// && TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(Locale.getDefault())) {
// tts.speak(speech, 0, null, null);
// }
// }
// }
// });
// // 清空翻译输入框与结果文本
// mBinding.clear.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// mBinding.result.setText("");
// mBinding.inputText.setText("");
//
// reset();
// }
// });
// // 说话完成后自动翻译
// mBinding.startSpeak.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// Intent speech_intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
// speech_intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 5000); // 设置5秒的静默时间
// speech_intent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 5000); // 设置5秒的可能完全静默时间
//
// speech_intent.putExtra("android.speech.extra.LANGUAGE_MODEL", TranslateWordApp.getSourceLanguage());
// speech_intent.putExtra("android.speech.extra.LANGUAGE", TranslateWordApp.getSourceLanguageCode());
// speech_intent.putExtra("android.speech.extra.LANGUAGE_PREFERENCE", TranslateWordApp.getSourceLanguage());
// try {
// if (null != launcher) launcher.launch(speech_intent);
// } catch (ActivityNotFoundException ea) {
// Widget.makeToast(getActivity(), "Something went wrong.");
// }
// }
// });
//
// // 朗读译文
// mBinding.speakTarget.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// String speech = mBinding.result.getText().toString().trim();
// if (!translating && !TextUtils.isEmpty(speech)) {
// if (null != tts
// && TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(Locale.getDefault())) {
// tts.speak(speech, 0, null, null);
// }
// }
// }
// });
// // 分享译文
// mBinding.shareTrans.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// if (translating) {
// Widget.makeToast(getActivity(), "Translating...");
// return;
// }
//
// final String share = mBinding.result.getText().toString().trim();
// if (!TextUtils.isEmpty(share)) {
// Intent intent = new Intent(Intent.ACTION_SEND);
// intent.setType("text/plain");
// intent.putExtra(Intent.EXTRA_TEXT, share);
// startActivity(Intent.createChooser(intent, "Share " + getString(R.string.app_name)));
// }
// }
// });
// // 复制到粘贴板
// mBinding.copyTrans.setOnClickListener(new View.OnClickListener() {
// private final String tip = "Copied to clipboard!";
// @Override
// public void onClick(View v) {
// final String share = mBinding.result.getText().toString().trim();
// if (!translating && !TextUtils.isEmpty(share)) {
// ClipboardManager clipboardManager = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
// ClipData clipData = ClipData.newPlainText("targetValue", share);
// clipboardManager.setPrimaryClip(clipData);
// Widget.makeToast(getActivity(), tip);
// }
// }
// });
// // 收藏按钮翻译中禁止收藏, 无原文禁止收藏无译文禁止收藏
// mBinding.collectTrans.setOnClickListener(new View.OnClickListener() {
// private DbTranslation dbTranslation;
//
// @Override
// public void onClick(View v) {
// if (translating) return;
//
// final String sourceTxt = sourceText;
// if (TextUtils.isEmpty(sourceTxt)) return;
//
// if (collectCurrent) {
// collectCurrent = false;
// getDbTranslation(getActivity()).collectJust(false);
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collecttrans);
// } else {
// collectCurrent = true;
// getDbTranslation(getActivity()).collectJust(true);
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collectedtrans);
// }
// }
//
// private DbTranslation getDbTranslation(Context context) {
// if (null == dbTranslation) {
// dbTranslation = new DbTranslation(context);
// }
// return dbTranslation;
// }
// });
//
// mBinding.changeLanguage.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View v) {
// launchLanguageSet();
// }
// });
//
// return mBinding.getRoot();
// }
//
// @Override
// public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
// super.onViewCreated(view, savedInstanceState);
//
// }
//
// @Override
// public void onResume() {
// super.onResume();
//
// mBinding.languageSource.setText(TranslateWordApp.getSourceLanguage());
// mBinding.languageTarget.setText(TranslateWordApp.getTargetLanguage());
// mBinding.sourceLanguage2.setText(TranslateWordApp.getSourceLanguage());
// mBinding.targetLanguage2.setText(TranslateWordApp.getTargetLanguage());
//
// // TODO: 可以判断是否需要再次请求原生广告
// }
//
// @Override
// public void onStop() {
// super.onStop();
// if (null != tts) tts.stop();
// }
//
// @Override
// public void onDestroy() {
// super.onDestroy();
// if (null != tts) tts.shutdown();
// if (null != launcher) {
// launcher.unregister();
// launcher = null;
// }
// }
//
// private void translate(@NonNull final String text) {
// // step1. 叫用户检查网络连接
// if (translating) {
// // 第一次点击翻译按钮后 可能会延迟响应结果翻译期间再次点击翻译按钮无效
// Logger.d("log", "translating(not post data)...");
// return;
// }
// Logger.d("log", "translating...");
// reset();
//
// translating = true;
// final HashMap<String, String> param = new HashMap<>();
// param.put("sourceLanguage", TranslateWordApp.getSourceLanguageCode());
// param.put("translationLanguage", TranslateWordApp.getTargetLanguageCode());
// param.put("text", text);
//
// sourceText = text;
// mBinding.result.setText("translating...");
// Translator<GoogleTranslator.GoogleTranslateCallback> translator = new GoogleTranslator();
// translator.translate(param, new GoogleTranslator.GoogleTranslateCallback() {
// @Override
// public void onResponse(String val) {
// translating = false;
//
// if (!TextUtils.isEmpty(val)) {
// TranslateMainActivity activity = null;
// if (getActivity() instanceof TranslateMainActivity) {
// activity = (TranslateMainActivity) getActivity();
// }
// if (null != activity) {
// activity.runOnUiThread(new Runnable() {
// @Override
// public void run() {
// mBinding.result.setText(val);
// addLog(val);
// }
// });
// }
// }
// }
//
// private void addLog(String targetTxt) {
// FragmentActivity activity = getActivity();
// if (null != activity) {
// DbTranslation dbTranslation = new DbTranslation(activity);
// Translations translations = new Translations(TranslateWordApp.getSourceLanguage(), sourceText, TranslateWordApp.getTargetLanguage(), targetTxt);
// dbTranslation.addTranslation(translations);
// }
// }
// });
// }
//
// private void reset() {
// // 归位收藏图片
// mBinding.collectTrans.setImageResource(R.mipmap.trw_ic_collecttrans);
// // 归位收藏备份文本
// sourceText = "";
// // 设置当前未处于收藏状态
// collectCurrent = false;
// // 当前不处于翻译状态
// translating = false;
// }
//
// private void launchLanguageSet() {
// Intent intent = new Intent(getActivity(), TranslateChangeLanguageActivity.class);
// getActivity().startActivity(intent);
// }
//
}

View File

@ -115,7 +115,6 @@ public class DbTranslation extends SQLiteOpenHelper {
}
/**
* 是否收藏刚刚那条翻译
* @param collect 收藏不收藏
*/
public boolean collectJust(boolean collect) {

View File

@ -6,6 +6,9 @@ import android.speech.tts.TextToSpeech;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.assimilate.alltrans.R;
@ -26,7 +29,7 @@ public class HistoryActivity extends AppCompatActivity {
public final static String COMMAND_COLLECTION = "remove-collection";
public final static String COMMAND_HISTORY = "remove-history";
private TextToSpeech tts;
private ActivityHistoryBinding mBinding;
private ActivityHistoryBinding binding;
private HashSet<Long> ids; // 通过id 删除数据库文件
private HashSet<Integer> items; // 通许index 删除界面上面的数据
private boolean operationCollection = false;
@ -34,18 +37,19 @@ public class HistoryActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = ActivityHistoryBinding.inflate(getLayoutInflater());
setContentView(mBinding.getRoot());
binding = ActivityHistoryBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(26, systemBars.top, 26, systemBars.bottom);
return insets;
});
ids = new HashSet<>();
items = new HashSet<>();
String extra = getIntent().getStringExtra(COMMAND);
if (COMMAND_COLLECTION.equals(extra)) {
operationCollection = true;
} else {
operationCollection = false;
}
operationCollection = COMMAND_COLLECTION.equals(extra);
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
@ -58,16 +62,16 @@ public class HistoryActivity extends AppCompatActivity {
ArrayList<Translations> translations = new ArrayList<>();
if (operationCollection) {
// 查出收藏的翻译记录
mBinding.tvFuncTrans.setText("Collect");
mBinding.ivFuncTrans.setImageResource(R.mipmap.ic_launcher);
binding.tvFuncTrans.setText("Collect");
binding.ivFuncTrans.setImageResource(R.drawable.ic_add);
ArrayList<Translations> list = new DbTranslation(this).getTranslations(true);
if (null != list && !list.isEmpty()) {
translations.addAll(list);
}
} else {
// 查出所有的翻译记录
mBinding.tvFuncTrans.setText("History");
mBinding.ivFuncTrans.setImageResource(R.mipmap.ic_launcher);
binding.tvFuncTrans.setText("History");
binding.ivFuncTrans.setImageResource(R.drawable.ic_add);
ArrayList<Translations> list = new DbTranslation(this).getTranslations(false);
if (null != list && !list.isEmpty()) {
translations.addAll(list);
@ -104,15 +108,15 @@ public class HistoryActivity extends AppCompatActivity {
private void updateBtn() {
if (ids.isEmpty()) {
mBinding.remove.setImageResource(R.mipmap.ic_launcher);
binding.remove.setVisibility(View.INVISIBLE);
} else {
mBinding.remove.setImageResource(R.mipmap.ic_launcher);
binding.remove.setVisibility(View.VISIBLE);
}
}
});
final LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mBinding.remove.setOnClickListener(new View.OnClickListener() {
binding.remove.setOnClickListener(new View.OnClickListener() {
private DbTranslation dbTranslation;
@Override
@ -142,7 +146,7 @@ public class HistoryActivity extends AppCompatActivity {
adapter.updateSet(integerArrayList);
items.clear();
}
mBinding.remove.setImageResource(R.mipmap.ic_launcher);
binding.remove.setVisibility(View.VISIBLE);
}
private DbTranslation getDbTranslation(Context context) {
@ -153,8 +157,8 @@ public class HistoryActivity extends AppCompatActivity {
}
});
mBinding.histories.setLayoutManager(layoutManager);
mBinding.histories.setAdapter(adapter);
binding.histories.setLayoutManager(layoutManager);
binding.histories.setAdapter(adapter);
}
@Override

View File

@ -1,15 +1,22 @@
package com.assimilate.alltrans.viewui
import android.os.Bundle
import android.util.Log
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.LanguageAdapter
import com.assimilate.alltrans.common.Language
import com.assimilate.alltrans.common.LanguagesConstants
import com.assimilate.alltrans.databinding.ActivityLanguageChangeBinding
class LanguageChangeActivity : AppCompatActivity() {
private lateinit var binding: ActivityLanguageChangeBinding
private var lastTranslateLanguage = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLanguageChangeBinding.inflate(layoutInflater)
@ -20,5 +27,44 @@ class LanguageChangeActivity : AppCompatActivity() {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
initList()
initClick()
}
private fun initClick() {
binding.tvChangeSource.setOnClickListener {
lastTranslateLanguage = false
}
binding.tvChangeTarget.setOnClickListener {
lastTranslateLanguage = true
}
}
private fun initList() {
val languages: ArrayList<Language> = LanguagesConstants.getInstance().getList(
this
)
if (languages.isNotEmpty()) {
val adapter =
LanguageAdapter(
this, languages
) { _, language ->
Log.d("fsdafsdfd", language.language)
if (lastTranslateLanguage) {
MyApp.setTargetLanguage(language)
onBackPressed()
} else {
MyApp.setSourceLanguage(language)
}
binding.tvChangeSource.text = MyApp.getSourceLanguage()
binding.tvChangeTarget.text = MyApp.getTargetLanguage()
}
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.listLanguages.setLayoutManager(layoutManager)
binding.listLanguages.setAdapter(adapter)
}
}
}

View File

@ -1,18 +1,44 @@
package com.assimilate.alltrans.viewui
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.ClipDescription
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.os.Bundle
import android.speech.RecognizerIntent
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.view.View
import android.widget.EditText
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.allservice.SusService
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private var launcher: ActivityResultLauncher<Intent>? = null
private lateinit var binding: ActivityMainBinding
private lateinit var lcm: LocalBroadcastManager
private lateinit var mediaProjectionManager: MediaProjectionManager
private val REQUEST_CODE_SCREEN_CAPTURE = 1001
override fun onCreate(savedInstanceState: Bundle?) {
@ -23,12 +49,84 @@ class MainActivity : AppCompatActivity() {
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
v.setPadding(26, systemBars.top + 26, 26, systemBars.bottom)
insets
}
initSet()
initClick()
registerResult()
}
private fun registerResult() {
launcher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
val data = result.data
if (result.resultCode == RESULT_OK && data != null) {
val speech =
data.getStringArrayListExtra("android.speech.extra.RESULTS")?.get(0)
if (!TextUtils.isEmpty(speech)) {
binding.etText.setText(speech)
}
}
}
}
private fun startScreenCapture() {
val captureIntent = mediaProjectionManager.createScreenCaptureIntent()
startActivityForResult(captureIntent, REQUEST_CODE_SCREEN_CAPTURE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_SCREEN_CAPTURE && resultCode == Activity.RESULT_OK) {
startSusService(resultCode, data)
}
}
private fun startSusService(resultCode: Int, data: Intent?) {
val serviceIntent = Intent(this, SusService::class.java).apply {
putExtra("resultCode", resultCode)
putExtra("data", data)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent)
} else {
startService(serviceIntent)
}
}
private fun initView() {
binding.chSourceLanguage.text = MyApp.getSourceLanguage()
binding.chTargetLanguage.text = MyApp.getTargetLanguage()
}
private fun initSet() {
lcm = LocalBroadcastManager.getInstance(this)
// 监听EditText的文本变化
binding.etText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
// 根据EditText的内容显示或隐藏粘贴按钮
if (s.isNullOrEmpty()) {
binding.tvMainTrans.visibility = View.GONE
} else {
binding.tvMainTrans.visibility = View.VISIBLE
}
}
})
}
@ -38,20 +136,29 @@ class MainActivity : AppCompatActivity() {
Intent(this, StillImageActivity::class.java)
)
}
binding.tvMainVoice.setOnClickListener {
voiceToText()
toTextTransResult()
}
binding.tvMainPaste.setOnClickListener {
pasteFromClipboard(binding.etText)
toTextTransResult()
}
binding.tvMainTrans.setOnClickListener {
startActivity(Intent(this, TextResultActivity::class.java))
toTextTransResult()
}
binding.ivMainSetting.setOnClickListener {
startActivity(
Intent(this, SettingsActivity::class.java)
)
}
binding.sourceLanguage2.setOnClickListener {
binding.chSourceLanguage.setOnClickListener {
startActivity(
Intent(this, LanguageChangeActivity::class.java)
)
}
binding.targetLanguage2.setOnClickListener {
binding.chTargetLanguage.setOnClickListener {
startActivity(
Intent(this, LanguageChangeActivity::class.java)
)
@ -67,9 +174,95 @@ class MainActivity : AppCompatActivity() {
)
}
binding.ivQuickStart.setOnClickListener {
startActivity(
Intent(this, QuickSetActivity::class.java)
mediaProjectionManager =
getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
startScreenCapture()
val intent = Intent(this, SusService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
}
}
private fun toTextTransResult() {
if (binding.etText.text.isEmpty()) {
return
}
val intent = Intent(this, TextResultActivity::class.java)
// 将字符串数据添加到Intent中
intent.putExtra("source_text", binding.etText.text.toString())
startActivity(intent)
binding.etText.text = null
}
// 语音转文本
private fun voiceToText() {
val speechIntent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
speechIntent.putExtra(
RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS,
5000
) // 设置5秒的静默时间
speechIntent.putExtra(
RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS,
5000
) // 设置5秒的可能完全静默时间
speechIntent.putExtra(
"android.speech.extra.LANGUAGE_MODEL",
MyApp.getSourceLanguage()
)
speechIntent.putExtra(
"android.speech.extra.LANGUAGE",
MyApp.getSourceLanguageCode()
)
speechIntent.putExtra(
"android.speech.extra.LANGUAGE_PREFERENCE",
MyApp.getSourceLanguage()
)
try {
launcher?.launch(speechIntent)
} catch (ea: ActivityNotFoundException) {
Widget.makeToast(this, "Something went wrong.")
}
}
// 粘贴文本
private fun pasteFromClipboard(etText: EditText) {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
if (clipboard.hasPrimaryClip() && clipboard.primaryClipDescription!!.hasMimeType(
ClipDescription.MIMETYPE_TEXT_PLAIN
)
) {
val item = clipboard.primaryClip!!.getItemAt(0)
val text = item.text.toString()
if (text.isNotEmpty()) {
// 在EditText中显示粘贴的文本
etText.setText(text)
etText.requestFocus() // 获取焦点
}
}
}
override fun onResume() {
super.onResume()
initView()
}
override fun onDestroy() {
super.onDestroy()
if (null != launcher) {
launcher!!.unregister()
launcher = null
}
}
}

View File

@ -1,9 +1,11 @@
package com.assimilate.alltrans.viewui
import android.Manifest
import android.app.Activity
import android.content.ContentValues
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.graphics.Bitmap
import android.net.Uri
@ -22,6 +24,8 @@ import android.widget.PopupMenu
import android.widget.Spinner
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.BitmapUtils
import com.assimilate.alltrans.common.TextRecognitionProcessor
@ -53,9 +57,25 @@ class StillImageActivity : AppCompatActivity() {
private var imageMaxHeight = 0
private var imageProcessor: VisionImageProcessor? = null
private val REQUEST_CAMERA_PERMISSION = 100
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_still_image)
// 检查并请求相机权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA),
REQUEST_CAMERA_PERMISSION
)
}
findViewById<View>(R.id.select_image_button).setOnClickListener { view: View ->
// Menu for selecting either: a) take new photo b) select from existing
val popup = PopupMenu(this@StillImageActivity, view)
@ -109,6 +129,32 @@ class StillImageActivity : AppCompatActivity() {
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_CAMERA_PERMISSION -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// Permission is granted, proceed with camera
startCameraIntentForResult()
} else {
// Permission denied, show a message to the user
Toast.makeText(
this,
"Camera permission is required to use the camera",
Toast.LENGTH_SHORT
).show()
}
return
}
}
}
public override fun onResume() {
super.onResume()
Log.d(TAG, "onResume")
@ -200,7 +246,21 @@ class StillImageActivity : AppCompatActivity() {
outState.putString(KEY_SELECTED_SIZE, selectedSize)
}
private fun startCameraIntentForResult() { // Clean up last time's image
private fun startCameraIntentForResult() {
// Ensure permission is still granted before starting camera intent
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.CAMERA
) != PackageManager.PERMISSION_GRANTED
) {
Toast.makeText(
this,
"Camera permission is required to use the camera",
Toast.LENGTH_SHORT
).show()
return
}
imageUri = null
preview!!.setImageBitmap(null)
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

View File

@ -1,17 +1,32 @@
package com.assimilate.alltrans.viewui
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.speech.tts.TextToSpeech
import android.text.TextUtils
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.Logger
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityTextResultBinding
import com.assimilate.alltrans.http.GoogleTranslator
import com.assimilate.alltrans.http.Translator
import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations
import java.util.Locale
class TextResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityTextResultBinding
private lateinit var tts: TextToSpeech
private var translating = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -24,14 +39,133 @@ class TextResultActivity : AppCompatActivity() {
insets
}
initSet()
initClick()
}
private fun initClick() {
binding.ivReToPhoto.setOnClickListener {
startActivity(
Intent(this, StillImageActivity::class.java)
private fun initSet() {
// 获取Intent
val intent = intent
val receivedString = intent.getStringExtra("source_text")
binding.tvTrSource.text = receivedString
translate(binding.tvTrSource.text.toString())
tts = TextToSpeech(this) { status ->
if (TextToSpeech.SUCCESS == status) tts.setLanguage(
Locale.getDefault()
)
}
}
private fun initClick() {
binding.ivTrBack.setOnClickListener { onBackPressed() }
binding.tvTrNewTrans.setOnClickListener { onBackPressed() }
binding.ivReToPhoto.setOnClickListener {
startActivity(Intent(this, StillImageActivity::class.java))
}
binding.ivTrCopy.setOnClickListener { copyToClipboard() }
binding.ivSourceClear.setOnClickListener { onBackPressed() }
binding.ivSourceTts.setOnClickListener { readText(binding.tvTrSource.text.toString()) }
binding.ivTargetTts.setOnClickListener { readText(binding.tvTrTarget.text.toString()) }
binding.ivTrTargetShare.setOnClickListener { shareText(binding.tvTrTarget.text.toString()) }
binding.ivTrCollect.setOnClickListener { addCollect() }
}
private fun translate(text: String) {
if (text.isEmpty() || translating) {
Logger.d("log", "translating(not post data)...")
return
}
translating = true
val param = HashMap<String, String>().apply {
put("sourceLanguage", MyApp.getSourceLanguageCode())
put("translationLanguage", MyApp.getTargetLanguageCode())
put("text", text)
}
binding.tvTrTarget.text = "translating..."
val translator: Translator<GoogleTranslator.GoogleTranslateCallback> = GoogleTranslator()
translator.translate(param,
GoogleTranslator.GoogleTranslateCallback { result ->
translating = false
if (!TextUtils.isEmpty(result)) {
runOnUiThread {
binding.tvTrTarget.text = result
}
addHistory(result)
}
})
}
private fun addHistory(transResult: String) {
val dbTranslation = DbTranslation(this)
val translations = Translations(
MyApp.getSourceLanguage(),
binding.tvTrSource.text.toString(),
MyApp.getTargetLanguage(),
transResult
)
dbTranslation.addTranslation(translations)
}
private fun addCollect() {
if (translating) return
val dbTranslation = DbTranslation(this)
dbTranslation.collectJust(true)
binding.ivTrCollect.setImageResource(R.drawable.ic_like_yes)
}
private fun shareText(text: String) {
val share: String = text.trim()
if (!TextUtils.isEmpty(share)) {
val intent = Intent(Intent.ACTION_SEND)
intent.setType("text/plain")
intent.putExtra(Intent.EXTRA_TEXT, share)
startActivity(Intent.createChooser(intent, "Share " + getString(R.string.app_name)))
}
}
private fun readText(text: String) {
val speech: String = text.trim()
if (!TextUtils.isEmpty(speech)) {
if (TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(Locale.getDefault())
) {
tts.speak(speech, 0, null, null)
}
}
}
// 复制到粘贴板
private fun copyToClipboard() {
val tip = "Copied to clipboard!"
val tipNull = "text is null!"
val share = binding.tvTrTarget.text.toString().trim()
if (!TextUtils.isEmpty(share)) {
val clipboardManager =
getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("targetValue", share)
clipboardManager.setPrimaryClip(clipData)
Widget.makeToast(this, tip)
} else {
Widget.makeToast(this, tipNull)
}
}
override fun onStop() {
super.onStop()
tts.stop()
}
override fun onDestroy() {
super.onDestroy()
tts.shutdown()
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/ic_his_choose_yes"/>
<item android:drawable="@drawable/ic_his_choose_def"/>
</selector>

View File

@ -5,7 +5,7 @@
<shape android:shape="line">
<stroke
android:width="2dp"
android:color="#FF4B4B4B"
android:color="#887F7F"
android:dashWidth="8dp"
android:dashGap="4dp" />
</shape>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<group>
<path
android:pathData="M2.5 10C2.5 10.9849 2.69399 11.9602 3.0709 12.8701C3.44781 13.7801 4.00026 14.6069 4.6967 15.3033C5.39314 15.9997 6.21993 16.5522 7.12987 16.9291C8.03982 17.306 9.01509 17.5 10 17.5C10.9849 17.5 11.9602 17.306 12.8701 16.9291C13.7801 16.5522 14.6069 15.9997 15.3033 15.3033C15.9997 14.6069 16.5522 13.7801 16.9291 12.8701C17.306 11.9602 17.5 10.9849 17.5 10C17.5 9.01509 17.306 8.03982 16.9291 7.12987C16.5522 6.21993 15.9997 5.39314 15.3033 4.6967C14.6069 4.00026 13.7801 3.44781 12.8701 3.0709C11.9602 2.69399 10.9849 2.5 10 2.5C9.01509 2.5 8.03982 2.69399 7.12987 3.0709C6.21993 3.44781 5.39314 4.00026 4.6967 4.6967C4.00026 5.39314 3.44781 6.21993 3.0709 7.12987C2.69399 8.03982 2.5 9.01509 2.5 10Z"
android:strokeWidth="1.25"
android:strokeColor="#C4E6FF" />
</group>
</vector>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<group>
<path
android:pathData="M14.1667 2.78259C15.4236 3.50831 16.4691 4.5497 17.1999 5.80368C17.9306 7.05765 18.3212 8.48074 18.3329 9.93204C18.3446 11.3833 17.9771 12.8126 17.2667 14.0782C16.5563 15.3438 15.5277 16.4019 14.2827 17.1479C13.0377 17.8938 11.6195 18.3016 10.1684 18.331C8.71738 18.3603 7.28381 18.0102 6.00965 17.3153C4.73549 16.6204 3.66491 15.6047 2.90391 14.3689C2.14291 13.133 1.71786 11.7199 1.67085 10.2693L1.66669 9.99926L1.67085 9.72926C1.71752 8.29008 2.13631 6.88756 2.88639 5.65842C3.63646 4.42928 4.69223 3.41547 5.95076 2.71583C7.2093 2.01619 8.62764 1.65459 10.0675 1.66629C11.5074 1.67799 12.9197 2.06259 14.1667 2.78259ZM13.0892 7.74343C12.9457 7.59995 12.7548 7.51375 12.5523 7.50102C12.3497 7.48828 12.1495 7.54988 11.9892 7.67426L11.9109 7.74343L9.16669 10.4868L8.08919 9.41009L8.01085 9.34093C7.85051 9.21664 7.65033 9.15511 7.44786 9.16789C7.24539 9.18066 7.05453 9.26686 6.91107 9.41031C6.76762 9.55377 6.68142 9.74462 6.66865 9.9471C6.65587 10.1496 6.7174 10.3497 6.84169 10.5101L6.91085 10.5884L8.57752 12.2551L8.65585 12.3243C8.802 12.4376 8.98171 12.4992 9.16669 12.4992C9.35166 12.4992 9.53138 12.4376 9.67752 12.3243L9.75585 12.2551L13.0892 8.92176L13.1584 8.84343C13.2827 8.68309 13.3443 8.48288 13.3316 8.28036C13.3189 8.07784 13.2327 7.88692 13.0892 7.74343Z"
android:fillColor="#0E8CE8"/>
</group>
</vector>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<path
android:fillColor="#F12222"
android:pathData="M4.77976,7.28638C5.6143,7.07569 6.48603,7.04863 7.33069,7.20719C8.17534,7.36575 8.97139,7.70588 9.66014,8.20252L9.69809,8.23005L9.72827,8.19958C10.2976,7.62765 10.9857,7.17907 11.7468,6.88377C12.5079,6.58847 13.3244,6.45323 14.1418,6.48707L14.3798,6.50056C15.4138,6.58497 16.4033,6.93845 17.2436,7.52358C18.0839,8.10871 18.7438,8.9037 19.1533,9.82437C19.5628,10.745 19.7067,11.7571 19.5698,12.7534C19.4328,13.7497 19.0202,14.6931 18.3755,15.4838L18.2178,15.6694L18.1751,15.7112L11.5325,22.0244C11.3813,22.1955 11.1715,22.3082 10.9418,22.3416C10.7121,22.375 10.4782,22.3268 10.2834,22.2059L10.1871,22.1376L2.53805,16.9875C1.71893,16.3372 1.10309,15.4793 0.758747,14.5087C0.414399,13.5381 0.354979,12.4927 0.587068,11.4884C0.819156,10.484 1.3337,9.55979 2.0737,8.81814C2.81371,8.0765 3.7503,7.54634 4.77976,7.28638Z"/>
<path
android:fillColor="#F12222"
android:pathData="M17.4,4.19961A0.6,0.6 0 1,1 16.8,4.19961A0.6,0.6 0 1,1 17.4,4.19961Z"/>
<path
android:fillColor="#F12222"
android:pathData="M20.4,6.00078A1.2,1.2 0 1,1 19.2,6.00078A1.2,1.2 0 1,1 20.4,6.00078Z"/>
</group>
</vector>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<group>
<path
android:pathData="M3.33337 5.83398H16.6667"
android:strokeColor="#FF5F5F"
android:strokeWidth="1.66667" />
<path
android:pathData="M8.33337 9.16602V14.166"
android:strokeColor="#FF5F5F"
android:strokeWidth="1.66667"
/>
<path
android:pathData="M11.6666 9.16602V14.166"
android:strokeColor="#FF5F5F"
android:strokeWidth="1.66667"
/>
<path
android:pathData="M4.16663 5.83398L4.99996 15.834C4.99996 16.276 5.17555 16.6999 5.48811 17.0125C5.80068 17.3251 6.2246 17.5007 6.66663 17.5007H13.3333C13.7753 17.5007 14.1992 17.3251 14.5118 17.0125C14.8244 16.6999 15 16.276 15 15.834L15.8333 5.83398"
android:strokeColor="#FF5F5F"
android:strokeWidth="1.66667"
/>
<path
android:pathData="M7.5 5.83333V3.33333C7.5 3.11232 7.5878 2.90036 7.74408 2.74408C7.90036 2.5878 8.11232 2.5 8.33333 2.5H11.6667C11.8877 2.5 12.0996 2.5878 12.2559 2.74408C12.4122 2.90036 12.5 3.11232 12.5 3.33333V5.83333"
android:strokeColor="#FF5F5F"
android:strokeWidth="1.66667"
/>
</group>
</vector>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="@color/main_bg_ffe2efff"
android:startColor="@color/main_bg_fff9f9f9"
android:type="linear" />
</shape>

View File

@ -2,6 +2,7 @@
<FrameLayout 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/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/main_text_ffffffff"
@ -26,7 +27,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginEnd="76dp"
android:src="@mipmap/ic_launcher"
android:src="@drawable/ic_close"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -46,16 +47,20 @@
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHeight_percent="0.82"
app:layout_constraintHeight_percent="0.9"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
<TextView
android:id="@+id/remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="18dp"
android:drawableStart="@drawable/ic_remove"
android:drawablePadding="6dp"
android:padding="12dp"
android:src="@mipmap/ic_launcher"
android:textColor="#FFFF5F5F"
android:text="@string/his_delete"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

View File

@ -5,6 +5,7 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFF9F9F9"
android:paddingTop="16dp"
tools:context=".viewui.LanguageChangeActivity">
@ -23,7 +24,7 @@
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/source_language2"
android:id="@+id/tv_change_source"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
@ -52,7 +53,7 @@
android:src="@drawable/ic_exchage" />
<TextView
android:id="@+id/target_language2"
android:id="@+id/tv_change_target"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
@ -85,34 +86,44 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/button_r10_gray_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/change_language"
app:queryBackground="@drawable/button_r10_gray_bg"
app:queryHint="Search" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/tr_common" />
android:text="@string/tr_common"
android:textColor="@color/bg_ff605c62"
android:textSize="12sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:minHeight="130dp" />
android:background="@drawable/button_r10_gray_bg"
android:minHeight="210dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/tr_other" />
android:text="@string/tr_other"
android:textColor="@color/bg_ff605c62"
android:textSize="12sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/languages"
android:id="@+id/list_languages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp" />
android:layout_marginTop="16dp"
android:background="@drawable/button_r10_gray_bg" />
</LinearLayout>

View File

@ -5,7 +5,7 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/main_bg_fff9f9f9"
android:background="@drawable/main_bg"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
@ -67,7 +67,7 @@
app:layout_constraintTop_toBottomOf="@id/tv_main_title">
<TextView
android:id="@+id/source_language2"
android:id="@+id/ch_source_language"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
@ -96,7 +96,7 @@
android:src="@drawable/ic_exchage" />
<TextView
android:id="@+id/target_language2"
android:id="@+id/ch_target_language"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
@ -128,6 +128,7 @@
app:layout_constraintTop_toBottomOf="@id/change_language">
<EditText
android:id="@+id/et_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
@ -135,6 +136,7 @@
android:hint="@string/main_text_enter"
android:maxLines="5"
android:minHeight="140dp"
android:selectAllOnFocus="true"
android:textColor="@color/main_text_ff1f1724"
android:textSize="16sp"
android:textStyle="bold" />
@ -191,6 +193,7 @@
android:paddingBottom="9dp"
android:text="@string/main_try_text"
android:textColor="@color/main_bg_fff9f9f9"
android:visibility="gone"
app:drawableEndCompat="@drawable/ic_arrow_try" />
</RelativeLayout>

View File

@ -42,6 +42,7 @@
android:orientation="horizontal">
<TextView
android:id="@+id/tv_tr_source"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@ -54,6 +55,7 @@
android:textStyle="bold" />
<ImageView
android:id="@+id/iv_source_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -62,6 +64,7 @@
</LinearLayout>
<ImageView
android:id="@+id/iv_source_tts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
@ -74,6 +77,7 @@
android:background="@drawable/ic_dashed_line" />
<TextView
android:id="@+id/tv_tr_target"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
@ -92,6 +96,7 @@
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_target_tts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -99,7 +104,7 @@
android:src="@drawable/ic_voice" />
<ImageView
android:id="@+id/tv_main_paste"
android:id="@+id/iv_tr_copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -107,7 +112,7 @@
android:src="@drawable/ic_copy" />
<ImageView
android:id="@+id/tv_main_voice"
android:id="@+id/iv_tr_target_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -120,6 +125,7 @@
android:layout_weight="1" />
<ImageView
android:id="@+id/iv_tr_collect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -163,6 +169,7 @@
android:layout_weight="1" />
<TextView
android:id="@+id/tv_tr_new_trans"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"

View File

@ -10,6 +10,7 @@
android:layout_height="32dp"
android:layout_marginStart="12dp"
android:scaleType="fitCenter"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -18,12 +19,15 @@
android:id="@+id/language"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="24dp"
android:ellipsize="end"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:singleLine="true"
android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/language_flag"

View File

@ -18,9 +18,11 @@
android:layout_gravity="center_vertical"
android:layout_margin="8dp"
android:layout_weight="1"
android:maxLines="7"
android:gravity="center_vertical"
android:textColor="@color/black"
android:textSize="18sp" />
android:textSize="16sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/speak_target"
@ -28,7 +30,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="16dp"
android:src="@mipmap/ic_launcher" />
android:src="@mipmap/ic_launcher"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
@ -46,8 +49,9 @@
android:layout_marginEnd="18dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:textColor="@color/black"
android:textSize="18sp" />
android:maxLines="7"
android:textColor="@color/text_ffa5a5a5"
android:textSize="12sp" />
<CheckBox
android:id="@+id/checkbox_current"
@ -56,6 +60,6 @@
android:layout_gravity="center_vertical"
android:layout_marginVertical="12dp"
android:layout_marginEnd="18dp"
android:button="@drawable/ic_add" />
android:button="@drawable/checkbox_selector" />
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
<com.assimilate.alltrans.curview.GraphicOverlay
android:id="@+id/sus_graphic_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:id="@+id/preview"
android:layout_width="150dp"
android:layout_height="150dp"
android:adjustViewBounds="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:padding="20dp"
android:src="@drawable/ic_close" />
</FrameLayout>

View File

@ -2,14 +2,14 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="180dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_r20_black_bg"
android:orientation="vertical">
<!-- 第一行 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="20dp"
@ -18,32 +18,35 @@
android:orientation="horizontal">
<TextView
android:id="@+id/tv_sus_global"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:drawableTop="@drawable/sus_trans_all"
android:drawablePadding="16dp"
android:gravity="center"
android:text="@string/global_translation"
android:textColor="#FFFFFF"
android:textSize="12sp"
app:drawableTopCompat="@drawable/sus_trans_all" />
android:textSize="12sp" />
<TextView
android:id="@+id/tv_sus_copy"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="19dp"
android:layout_weight="1"
android:drawableTop="@drawable/sus_trans_copy"
android:drawablePadding="16dp"
android:gravity="center"
android:text="@string/copy_text"
android:textColor="#FFFFFF"
android:textSize="12sp"
app:drawableTopCompat="@drawable/sus_trans_copy" />
android:textSize="12sp" />
</LinearLayout>
<!-- 第二行 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="20dp"
@ -51,6 +54,8 @@
android:orientation="horizontal">
<TextView
android:id="@+id/tv_sus_photo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -63,6 +68,8 @@
android:textSize="12sp" />
<TextView
android:id="@+id/tv_sus_district"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -77,16 +84,15 @@
</LinearLayout>
<!-- 分隔线 -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="32dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="32dp"
android:layout_width="110dp"
android:layout_height="5dp"
android:layout_gravity="center"
android:layout_marginTop="16dp"
android:layout_marginBottom="15dp"
android:background="@drawable/ic_dashed_line_4b4b4b4" />
<!-- 第三行 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="20dp"
@ -96,6 +102,8 @@
<ImageView
android:id="@+id/iv_sus_home"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
@ -104,6 +112,7 @@
android:src="@drawable/sus_trans_home" />
<ImageView
android:id="@+id/iv_sus_move"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"

View File

@ -5,6 +5,7 @@
<!--main_page-->
<color name="main_bg_fff9f9f9">#FFF9F9F9</color>
<color name="main_bg_ffe2efff">#FFE2EFFF</color>
<color name="main_text_ff1f1724">#FF1F1724</color>
<color name="main_text_ff0e8ce8">#FF0E8CE8</color>
<color name="main_text_ffffffff">#FFFFFFFF</color>
@ -15,6 +16,10 @@
<color name="bg_fff6f6f6">#FFF6F6F6</color>
<!-- sus_view-->
<color name="bg_ff2f2f2f">#FF2F2F2F</color>
<!-- change_language-->
<color name="bg_ff605c62">#FF605C62</color>
<!-- his_page-->
<color name="text_ffa5a5a5">#FFA5A5A5</color>
</resources>

View File

@ -10,7 +10,7 @@
<string name="select_image" translatable="false">Select image</string>
<!--main_page-->
<string name="menu_item_settings" translatable="false">Settings</string>
<string name="text_main_title">translator</string>
<string name="text_main_title">translate</string>
<string name="text_source_language">Chinese</string>
<string name="text_target_language">English</string>
<string name="main_text_enter">enter text</string>
@ -42,6 +42,8 @@
<string name="copy_text">Copy Text</string>
<string name="photo_translation">Photo Translation</string>
<string name="district_translation">District Translation</string>
<!-- his_page-->
<string name="his_delete">Delete</string>
</resources>