version 1.0.3.1 backup

This commit is contained in:
Simon 2024-08-09 13:40:38 +08:00
parent 508b57593f
commit 50225a3cfe
30 changed files with 674 additions and 226 deletions

View File

@ -94,33 +94,19 @@ dependencies {
implementation("com.google.mlkit:text-recognition-japanese:16.0.0") implementation("com.google.mlkit:text-recognition-japanese:16.0.0")
// To recognize Korean script // To recognize Korean script
implementation("com.google.mlkit:text-recognition-korean:16.0.0") implementation("com.google.mlkit:text-recognition-korean:16.0.0")
// 文本识别
implementation("com.google.mlkit:language-id:17.0.5")
// CameraX core library // CameraX core library
implementation(libs.androidx.camera.core) implementation(libs.androidx.camera.core)
// CameraX Camera2 extensions // CameraX Camera2 extensions
implementation(libs.androidx.camera.camera2) implementation(libs.androidx.camera.camera2)
// CameraX Lifecycle library // CameraX Lifecycle library
implementation(libs.androidx.camera.lifecycle) implementation(libs.androidx.camera.lifecycle)
// CameraX View class // CameraX View class
implementation(libs.androidx.camera.view) implementation(libs.androidx.camera.view)
// 文本识别
// To recognize Latin script
// implementation(libs.play.services.mlkit.text.recognition)
// // To recognize Chinese script
// implementation(libs.play.services.mlkit.text.recognition.chinese)
// // To recognize Devanagari script
// implementation(libs.play.services.mlkit.text.recognition.devanagari)
// // To recognize Japanese script
// implementation(libs.play.services.mlkit.text.recognition.japanese)
// // To recognize Korean script
// implementation(libs.play.services.mlkit.text.recognition.korean)
// other // other
implementation(libs.guava) implementation(libs.guava)
implementation(libs.retrofit) implementation(libs.retrofit)

View File

@ -1,16 +1,18 @@
package com.assimilate.alltrans.common package com.assimilate.alltrans.common
import android.app.Activity import android.app.Activity
import android.util.Log
import android.widget.FrameLayout import android.widget.FrameLayout
import com.assimilate.alltrans.MyApp import com.assimilate.alltrans.MyApp
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.lol.apex.ok.google.adlibrary.base.listener.AdLoadListener import com.lol.apex.ok.google.adlibrary.base.listener.AdLoadListener
import com.lol.apex.ok.google.adlibrary.base.listener.AdShowListener import com.lol.apex.ok.google.adlibrary.base.listener.AdShowListener
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import com.lol.apex.ok.google.adlibrary.bean.AdType
import com.lol.apex.ok.google.adlibrary.inner.LOLAdsInnerDispatcher import com.lol.apex.ok.google.adlibrary.inner.LOLAdsInnerDispatcher
import com.lol.apex.ok.google.adlibrary.inner.base.AdInnerLoadAdapter import com.lol.apex.ok.google.adlibrary.inner.base.AdInnerLoadAdapter
import com.lol.apex.ok.google.adlibrary.inner.base.AdInnerShowAdapter import com.lol.apex.ok.google.adlibrary.inner.base.AdInnerShowAdapter
import com.lol.apex.ok.google.adlibrary.inst.InstAdCache
import com.lol.apex.ok.google.adlibrary.inst.LOLAdsInstDispatcher import com.lol.apex.ok.google.adlibrary.inst.LOLAdsInstDispatcher
import com.lol.apex.ok.google.adlibrary.rewarded.LOLAdsRewardedDispatcher import com.lol.apex.ok.google.adlibrary.rewarded.LOLAdsRewardedDispatcher
@ -36,6 +38,7 @@ class LolAdWrapper {
return LOLAdsInstDispatcher.canShow(placement, false) return LOLAdsInstDispatcher.canShow(placement, false)
} }
fun hasRewardCache(placement: String): Boolean { fun hasRewardCache(placement: String): Boolean {
return LOLAdsRewardedDispatcher.canShow(placement) return LOLAdsRewardedDispatcher.canShow(placement)
} }
@ -167,6 +170,7 @@ class LolAdWrapper {
private fun showAd(act: Activity, placement: String, listener: LolShowListener? = null) { private fun showAd(act: Activity, placement: String, listener: LolShowListener? = null) {
if (act.isFinishing) return if (act.isFinishing) return
LOLAdsInstDispatcher.getShower(act, placement, object : AdShowListener { LOLAdsInstDispatcher.getShower(act, placement, object : AdShowListener {
override fun onAdClicked() { override fun onAdClicked() {
MyApp.app.isAdShowing.set(true) MyApp.app.isAdShowing.set(true)
} }
@ -202,5 +206,6 @@ class LolAdWrapper {
}).showAd() }).showAd()
} }
} }

View File

@ -0,0 +1,113 @@
package com.assimilate.alltrans.common
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import com.assimilate.alltrans.R
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations
import java.util.Locale
object MyTextTools {
private lateinit var tts: TextToSpeech
// 添加历史
fun addToHistory(context: Context, rText: String, transResult: String?) {
val dbTranslation = DbTranslation(context)
val translations = Translations(
PreferenceLanguageUtils.getString("language_source"),
rText,
PreferenceLanguageUtils.getString("language_target"),
transResult
)
dbTranslation.addTranslation(translations)
}
// 分享文本
fun shareText(context: Context, 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)
context.startActivity(Intent.createChooser(intent, "Share " + R.string.app_name))
}
}
// 复制到粘贴板
fun copyToClipboard(context: Context, string: String) {
val tip = "Copied to clipboard!"
val tipNull = "text is null!"
val share = string.trim()
if (!TextUtils.isEmpty(share)) {
val clipboardManager =
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("targetValue", share)
clipboardManager.setPrimaryClip(clipData)
Toast.makeText(context, tip, Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, tipNull, Toast.LENGTH_SHORT).show()
}
}
// 朗读文本
fun ttsReadText(text: String, targetLanguage: String, context: Context) {
Toast.makeText(context, R.string.tr_tts_reading, Toast.LENGTH_SHORT).show()
tts = TextToSpeech(context) { status ->
if (TextToSpeech.SUCCESS == status) tts.setLanguage(
Locale.getDefault()
)
tts.setSpeechRate(0.7f)
val speech: String = text.trim()
if (!TextUtils.isEmpty(speech)) {
// 获取目标语言的语言代码
val languageCode =
LanguagesConstants.getInstance()
.getLanguageCodeByLanguage(targetLanguage, context)
Log.d("LanguageCode", "Language Code for $targetLanguage: $languageCode")
// 创建语言 Locale 对象
val locale = Locale(languageCode)
// 判断语言是否支持
if (TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(locale)) {
tts.language = locale
tts.speak(speech, TextToSpeech.QUEUE_FLUSH, null, null)
} else {
Toast.makeText(context, R.string.tr_tts_error, Toast.LENGTH_SHORT).show()
}
tts.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
override fun onStart(utteranceId: String?) {
}
override fun onDone(utteranceId: String?) {
tts.shutdown()
}
@Deprecated("Deprecated in Java")
override fun onError(utteranceId: String?) {
tts.shutdown()
}
})
}
}
}
}

View File

@ -35,7 +35,8 @@ class TextGraphic(
color = MARKER_COLOR color = MARKER_COLOR
style = Paint.Style.FILL style = Paint.Style.FILL
} }
private var hiddenTextBlocks: MutableList<Boolean> = MutableList(text.textBlocks.size) { !textShow } private var hiddenTextBlocks: MutableList<Boolean> =
MutableList(text.textBlocks.size) { !textShow }
private var isVisible: Boolean private var isVisible: Boolean
init { init {
@ -51,7 +52,6 @@ class TextGraphic(
postInvalidate() postInvalidate()
} }
} }
// Redraw the overlay, as this graphic has been added. // Redraw the overlay, as this graphic has been added.
postInvalidate() postInvalidate()
} }
@ -156,7 +156,8 @@ class TextGraphic(
var textLayout: StaticLayout var textLayout: StaticLayout
while (textSize > 0) { while (textSize > 0) {
textPaintCopy.textSize = textSize textPaintCopy.textSize = textSize
textLayout = StaticLayout.Builder.obtain(text, 0, text.length, textPaintCopy, availableWidth) textLayout =
StaticLayout.Builder.obtain(text, 0, text.length, textPaintCopy, availableWidth)
.setAlignment(Layout.Alignment.ALIGN_NORMAL) .setAlignment(Layout.Alignment.ALIGN_NORMAL)
.setLineSpacing(0.0f, 1.0f) .setLineSpacing(0.0f, 1.0f)
.setIncludePad(false) .setIncludePad(false)
@ -168,7 +169,8 @@ class TextGraphic(
textSize -= 1 textSize -= 1
} }
textLayout = StaticLayout.Builder.obtain(text, 0, text.length, textPaintCopy, availableWidth) textLayout =
StaticLayout.Builder.obtain(text, 0, text.length, textPaintCopy, availableWidth)
.setAlignment(Layout.Alignment.ALIGN_NORMAL) .setAlignment(Layout.Alignment.ALIGN_NORMAL)
.setLineSpacing(0.0f, 1.0f) .setLineSpacing(0.0f, 1.0f)
.setIncludePad(false) .setIncludePad(false)

View File

@ -20,11 +20,12 @@ class TextRecognitionProcessor(
private val textShow:Boolean, private val textShow:Boolean,
private val needTrans: Boolean, private val needTrans: Boolean,
private val fbFrom:String, private val fbFrom:String,
private val callback: TextRecognitionCallback? = null // 添加回调 private val callback: TextRecognitionCallback? = null
) : VisionProcessorBase<Text>(context) { ) : VisionProcessorBase<Text>(context) {
interface TextRecognitionCallback { interface TextRecognitionCallback {
fun onTextRecognized(text: String) fun onTextRecognized(text: Text,graphicOverlay: GraphicOverlay)
fun onTextFailure(e: Exception)
} }
private val textRecognizer: TextRecognizer = TextRecognition.getClient(textRecognizerOptions) private val textRecognizer: TextRecognizer = TextRecognition.getClient(textRecognizerOptions)
@ -43,10 +44,8 @@ class TextRecognitionProcessor(
} }
override fun onSuccess(text: Text, graphicOverlay: GraphicOverlay) { override fun onSuccess(text: Text, graphicOverlay: GraphicOverlay) {
//
PreferenceLanguageUtils.putString("language_source", getMostFrequentLanguage(text)) PreferenceLanguageUtils.putString("language_source", getMostFrequentLanguage(text))
Log.d(TAG, "On-device Text detection successful")
logExtrasForTesting(text)
graphicOverlay.add( graphicOverlay.add(
TextGraphic( TextGraphic(
graphicOverlay, graphicOverlay,
@ -61,10 +60,13 @@ class TextRecognitionProcessor(
) )
// 调用回调 // 调用回调
callback?.onTextRecognized(text.text) callback?.onTextRecognized(text,graphicOverlay)
logExtrasForTesting(text)
} }
override fun onFailure(e: Exception) { override fun onFailure(e: Exception) {
callback?.onTextFailure(e)
Log.w(TAG, "Text detection failed.$e") Log.w(TAG, "Text detection failed.$e")
} }

View File

@ -42,10 +42,11 @@ class TranslationManager(
val translator: Translator<GoogleTranslator.GoogleTranslateCallback> = val translator: Translator<GoogleTranslator.GoogleTranslateCallback> =
GoogleTranslator() GoogleTranslator()
for ((index, textBlock) in text.textBlocks.withIndex()) { //根据indices获取对应的文本块将翻译后的文本对应
// 如果源语言和目标语言相同,直接添加原始文本到 translatedTextBlocks for (index in text.textBlocks.indices) {
// 如果源语言和目标语言相同,直接添加原始文本到 translatedTextBlocks 不请求网络
if (lanSourceCode == lanTargetCode) { if (lanSourceCode == lanTargetCode) {
translatedTextBlocks.add(Pair(index, textBlock.text)) translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
if (translatedTextBlocks.size == text.textBlocks.size) { if (translatedTextBlocks.size == text.textBlocks.size) {
handler.post { handler.post {
callback(translatedTextBlocks.sortedBy { it.first } callback(translatedTextBlocks.sortedBy { it.first }
@ -56,7 +57,7 @@ class TranslationManager(
val param = HashMap<String, String>().apply { val param = HashMap<String, String>().apply {
put("sourceLanguage", lanSourceCode) put("sourceLanguage", lanSourceCode)
put("translationLanguage", lanTargetCode) put("translationLanguage", lanTargetCode)
put("text", textBlock.text) put("text", text.textBlocks[index].text)
} }
translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback { translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback {
@ -64,7 +65,7 @@ class TranslationManager(
if (result != null) { if (result != null) {
translatedTextBlocks.add(Pair(index, result)) translatedTextBlocks.add(Pair(index, result))
} else { } else {
translatedTextBlocks.add(Pair(index, "")) translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
} }
if (translatedTextBlocks.size == text.textBlocks.size) { if (translatedTextBlocks.size == text.textBlocks.size) {
@ -76,7 +77,7 @@ class TranslationManager(
} }
override fun onFailure(errorMessage: String?) { override fun onFailure(errorMessage: String?) {
translatedTextBlocks.add(Pair(index, "")) translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
if (translatedTextBlocks.size == text.textBlocks.size) { if (translatedTextBlocks.size == text.textBlocks.size) {
handler.post { handler.post {
callback(translatedTextBlocks.sortedBy { it.first } callback(translatedTextBlocks.sortedBy { it.first }
@ -84,32 +85,43 @@ class TranslationManager(
} }
} }
when (fbFrom) { transFailEvent(errorMessage)
"global" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"float" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"photo" -> {
FirebaseAnalyticsHelper.imagePhotoResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"image" -> {
FirebaseAnalyticsHelper.imageCameraResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
}
} }
}) })
} }
} }
} }
} }
private fun transFailEvent(errorMessage: String?) {
when (fbFrom) {
"global" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(
MyApp.Config.FAIL_REASON,
fbFrom + "_" + errorMessage
)
}
"float" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(
MyApp.Config.FAIL_REASON,
fbFrom + "_" + errorMessage
)
}
"photo" -> {
FirebaseAnalyticsHelper.imagePhotoResultEvent(
MyApp.Config.FAIL_REASON,
fbFrom + "_" + errorMessage
)
}
"image" -> {
FirebaseAnalyticsHelper.imageCameraResultEvent(
MyApp.Config.FAIL_REASON,
fbFrom + "_" + errorMessage
)
}
}
}
} }

View File

@ -87,10 +87,12 @@ class ControlView(private val context: Context) {
fullScreenView.setOnTouchListener { _, event -> fullScreenView.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) { if (event.action == MotionEvent.ACTION_DOWN) {
removeControlView() removeControlView()
fullScreenView.performClick()
true true
} else { } else {
false false
} }
} }

View File

@ -17,6 +17,7 @@ import android.widget.Toast
import com.assimilate.alltrans.common.TextRecognitionProcessor import com.assimilate.alltrans.common.TextRecognitionProcessor
import com.assimilate.alltrans.common.VisionImageProcessor import com.assimilate.alltrans.common.VisionImageProcessor
import com.assimilate.alltrans.databinding.LayoutSusCopyBinding import com.assimilate.alltrans.databinding.LayoutSusCopyBinding
import com.google.mlkit.vision.text.Text
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
import java.io.IOException import java.io.IOException
@ -135,10 +136,13 @@ class CopyTextView(private val context: Context) :
} }
} }
override fun onTextRecognized(text: String) {
recognizedText = text override fun onTextRecognized(text: Text, graphicOverlay: GraphicOverlay) {
recognizedText = text.text
}
override fun onTextFailure(e: Exception) {
Log.d("copy_", e.toString())
} }
// 复制到粘贴板 // 复制到粘贴板

View File

@ -49,6 +49,7 @@ class DistrictView(
setOnTouchListener { _, event -> setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) { if (event.action == MotionEvent.ACTION_DOWN) {
removeDistrictView() removeDistrictView()
performClick()
} }
true true
} }

View File

@ -127,6 +127,7 @@ class FloatingView(
private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
private val maxClickDuration = 500 // 最大点击时间(毫秒) private val maxClickDuration = 500 // 最大点击时间(毫秒)
override fun onTouch(v: View?, event: MotionEvent): Boolean { override fun onTouch(v: View?, event: MotionEvent): Boolean {
when (event.action) { when (event.action) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {
@ -139,6 +140,7 @@ class FloatingView(
handler.removeCallbacks(fadeRunnable) handler.removeCallbacks(fadeRunnable)
imageView.alpha = 1.0f imageView.alpha = 1.0f
imageView.setImageResource(originalImageResId) imageView.setImageResource(originalImageResId)
return true return true
} }
@ -150,6 +152,7 @@ class FloatingView(
imageView.setImageResource(originalImageResId) imageView.setImageResource(originalImageResId)
stickToEdge() stickToEdge()
imageView.performClick()
if (isClick && duration < maxClickDuration) { if (isClick && duration < maxClickDuration) {
onClickListener?.onClick() onClickListener?.onClick()
} else { } else {
@ -193,10 +196,10 @@ class FloatingView(
Log.e("FloatingView", "View not attached to window manager", e) Log.e("FloatingView", "View not attached to window manager", e)
} }
} }
return true return true
} }
} }
return false return false
} }
}) })

View File

@ -9,7 +9,6 @@ import android.graphics.Canvas;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Paint; import android.graphics.Paint;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@ -57,23 +56,11 @@ public class GraphicOverlay extends View {
*/ */
public abstract static class Graphic { public abstract static class Graphic {
private GraphicOverlay overlay; private GraphicOverlay overlay;
private boolean textVisible = true; // 添加可见性
public Graphic(GraphicOverlay overlay) { public Graphic(GraphicOverlay overlay) {
this.overlay = overlay; this.overlay = overlay;
} }
public boolean isVisible() {
return textVisible;
}
public void setVisible(boolean visible) {
this.textVisible = visible;
overlay.postInvalidate();
}
/** /**
* Draw the graphic on the supplied canvas. Drawing should use the following methods to convert * Draw the graphic on the supplied canvas. Drawing should use the following methods to convert
* to view coordinates for the graphics that are drawn: * to view coordinates for the graphics that are drawn:
@ -89,7 +76,6 @@ public class GraphicOverlay extends View {
*/ */
public abstract void draw(Canvas canvas); public abstract void draw(Canvas canvas);
public abstract boolean contains(float x, float y); public abstract boolean contains(float x, float y);
protected void drawRect( protected void drawRect(

View File

@ -1,6 +1,7 @@
package com.assimilate.alltrans.viewui package com.assimilate.alltrans.viewui
import android.content.Context import android.content.Context
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.speech.tts.TextToSpeech import android.speech.tts.TextToSpeech
import android.view.View import android.view.View
@ -55,7 +56,6 @@ class HistoryActivity : AppCompatActivity() {
) )
} }
initClick() initClick()
} }
@ -72,11 +72,10 @@ class HistoryActivity : AppCompatActivity() {
binding!!.tvFuncTrans.text = getString(R.string.favor_title) binding!!.tvFuncTrans.text = getString(R.string.favor_title)
val list = DbTranslation(this).getTranslations(true) val list = DbTranslation(this).getTranslations(true)
if (list.isEmpty()) { if (list.isEmpty()) {
binding!!.defEmpty.visibility = View.VISIBLE binding!!.llEmptyFav.visibility = View.VISIBLE
binding!!.remove.visibility = View.GONE binding!!.remove.visibility = View.GONE
binding!!.defEmpty.text = getString(R.string.favor_emtpoy)
} else { } else {
binding!!.defEmpty.visibility = View.GONE binding!!.llEmptyFav.visibility = View.GONE
binding!!.remove.visibility = View.GONE binding!!.remove.visibility = View.GONE
} }
if (null != list && list.isNotEmpty()) { if (null != list && list.isNotEmpty()) {
@ -88,11 +87,10 @@ class HistoryActivity : AppCompatActivity() {
val list = DbTranslation(this).getTranslations(false) val list = DbTranslation(this).getTranslations(false)
if (list.isEmpty()) { if (list.isEmpty()) {
binding!!.remove.visibility = View.GONE binding!!.remove.visibility = View.GONE
binding!!.defEmpty.visibility = View.VISIBLE binding!!.llEmptyHis.visibility = View.VISIBLE
binding!!.defEmpty.text = getString(R.string.his_emtpoy)
} else { } else {
binding!!.remove.visibility = View.GONE binding!!.remove.visibility = View.GONE
binding!!.defEmpty.visibility = View.GONE binding!!.llEmptyHis.visibility = View.GONE
} }
if (null != list && list.isNotEmpty()) { if (null != list && list.isNotEmpty()) {
translations.addAll(list) translations.addAll(list)
@ -192,8 +190,13 @@ class HistoryActivity : AppCompatActivity() {
showInstAdFromCache(MyApp.Config.history_int_auto) showInstAdFromCache(MyApp.Config.history_int_auto)
finish() finish()
} }
binding?.emtpoyHisNow?.setOnClickListener {
finish()
}
binding?.emtpoyFavNow?.setOnClickListener {
startActivity(Intent(this, MainActivity::class.java))
}
} }
private fun backPressedCall() { private fun backPressedCall() {
val callback = object : OnBackPressedCallback(true) { val callback = object : OnBackPressedCallback(true) {
@ -213,13 +216,11 @@ class HistoryActivity : AppCompatActivity() {
place, place,
object : LolAdWrapper.LoLLoadListener { object : LolAdWrapper.LoLLoadListener {
override fun loadFailed(error: LolLoadError?) { override fun loadFailed(error: LolLoadError?) {
// Log.d("dsas",error.toString())
} }
override fun loaded() { override fun loaded() {
// 处理加载成功 // 处理加载成功
// Log.d("dsas","backSucc")
} }
}) })
@ -247,7 +248,6 @@ class HistoryActivity : AppCompatActivity() {
}) })
} }
companion object { companion object {
const val COMMAND: String = "remove" const val COMMAND: String = "remove"
const val COMMAND_COLLECTION: String = "remove_collection" const val COMMAND_COLLECTION: String = "remove_collection"

View File

@ -27,13 +27,13 @@ import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.allservice.SusService import com.assimilate.alltrans.allservice.SusService
import com.assimilate.alltrans.common.AppStore
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.common.Widget import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityMainBinding import com.assimilate.alltrans.databinding.ActivityMainBinding
import com.assimilate.alltrans.model.LanguagesConstants import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.google.mlkit.nl.languageid.LanguageIdentification
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@ -127,19 +127,11 @@ class MainActivity : AppCompatActivity() {
} }
} }
private fun initView() {
LolAdWrapper.shared.loadAdShowNativeAd(
this,
"your_native_ad_placement",
binding.homeNative,
R.layout.ad_layout_admob_banner,
R.layout.ad_layout_max_banner
)
private fun initView(){
binding.chSourceLanguage.text = PreferenceLanguageUtils.getString("language_source") binding.chSourceLanguage.text = PreferenceLanguageUtils.getString("language_source")
binding.chTargetLanguage.text = PreferenceLanguageUtils.getString("language_target") binding.chTargetLanguage.text = PreferenceLanguageUtils.getString("language_target")
} }
private fun initSet() { private fun initSet() {
loadNative() loadNative()
@ -283,6 +275,7 @@ class MainActivity : AppCompatActivity() {
// 更新字符计数显示 // 更新字符计数显示
val displayCharCount = if (charCount > 1800) 1800 else charCount val displayCharCount = if (charCount > 1800) 1800 else charCount
binding.tvMainLimitText.text = getString(R.string.main_limit_num, displayCharCount) binding.tvMainLimitText.text = getString(R.string.main_limit_num, displayCharCount)
reconText(binding.etText.text.toString())
} }
}) })
@ -434,4 +427,25 @@ class MainActivity : AppCompatActivity() {
) )
} }
private fun reconText(text:String){
val languageIdentifier = LanguageIdentification.getClient()
languageIdentifier.identifyLanguage(text)
.addOnSuccessListener { languageCode ->
if (languageCode == "und") {
Log.i("dsafdsf", "Can't identify language.")
} else {
Log.i("dsafdsf", "Language: $languageCode")
val lan = LanguagesConstants.getInstance().getLanguageByLanguageCode(languageCode,this)
PreferenceLanguageUtils.putString("language_source",lan.language)
binding.chSourceLanguage.text = PreferenceLanguageUtils.getString("language_source")
}
}
.addOnFailureListener {
// Model couldnt be loaded or other internal error.
// ...
}
}
} }

View File

@ -94,7 +94,7 @@ class PhotoImageActivity : AppCompatActivity() {
} }
firebaseEvent() firebaseEvent()
Widget.makeSnackbar(this, "Photographing text for translation") Widget.makeSnackbar(this, getString(R.string.ph_toast))
isLandScape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE isLandScape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
savedInstanceState?.let { savedInstanceState?.let {

View File

@ -96,7 +96,7 @@ class SettingsActivity
private fun setBottomSheet() { private fun setBottomSheet() {
// 设置 BottomSheetDialog // 设置 BottomSheetDialog
bottomSheetDialog = BottomSheetDialog(this) bottomSheetDialog = BottomSheetDialog(this,R.style.CustomBottomSheetDialogTheme)
bottomSheetDialog.setContentView(R.layout.bottomsheet_rate) bottomSheetDialog.setContentView(R.layout.bottomsheet_rate)
bottomSheetDialog.dismissWithAnimation = true bottomSheetDialog.dismissWithAnimation = true

View File

@ -1,12 +1,7 @@
package com.assimilate.alltrans.viewui package com.assimilate.alltrans.viewui
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.speech.tts.TextToSpeech
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
@ -18,25 +13,23 @@ import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.common.Logger import com.assimilate.alltrans.common.Logger
import com.assimilate.alltrans.common.LolAdWrapper import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.model.PreferenceLanguageUtils import com.assimilate.alltrans.common.MyTextTools
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityTextResultBinding import com.assimilate.alltrans.databinding.ActivityTextResultBinding
import com.assimilate.alltrans.http.GoogleTranslator import com.assimilate.alltrans.http.GoogleTranslator
import com.assimilate.alltrans.http.Translator import com.assimilate.alltrans.http.Translator
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.mydb.DbTranslation import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import java.util.Locale
class TextResultActivity : AppCompatActivity() { class TextResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityTextResultBinding private lateinit var binding: ActivityTextResultBinding
private lateinit var tts: TextToSpeech
private var translating = false private var translating = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -64,12 +57,6 @@ class TextResultActivity : AppCompatActivity() {
binding.tvTrSource.text = receivedString binding.tvTrSource.text = receivedString
translate(binding.tvTrSource.text.toString()) translate(binding.tvTrSource.text.toString())
tts = TextToSpeech(this) { status ->
if (TextToSpeech.SUCCESS == status) tts.setLanguage(
Locale.getDefault()
)
}
} }
private fun backPressedCall() { private fun backPressedCall() {
@ -96,19 +83,19 @@ class TextResultActivity : AppCompatActivity() {
showInstAdFromCache(MyApp.Config.text_camera_int_auto) showInstAdFromCache(MyApp.Config.text_camera_int_auto)
} }
binding.ivTrCopy.setOnClickListener { binding.ivTrCopy.setOnClickListener {
copyToClipboard() MyTextTools.copyToClipboard(this, binding.tvTrTarget.text.toString())
FirebaseAnalyticsHelper.textTransCopyEvent() FirebaseAnalyticsHelper.textTransCopyEvent()
} }
binding.ivSourceClear.setOnClickListener { finish() } binding.ivSourceClear.setOnClickListener { finish() }
binding.ivSourceTts.setOnClickListener { binding.ivSourceTts.setOnClickListener {
readText( MyTextTools.ttsReadText(
binding.tvTrSource.text.toString(), binding.tvTrSource.text.toString(),
PreferenceLanguageUtils.getString("language_source"), PreferenceLanguageUtils.getString("language_source"),
this this
) )
} }
binding.ivTargetTts.setOnClickListener { binding.ivTargetTts.setOnClickListener {
readText( MyTextTools.ttsReadText(
binding.tvTrTarget.text.toString(), binding.tvTrTarget.text.toString(),
PreferenceLanguageUtils.getString("language_target"), PreferenceLanguageUtils.getString("language_target"),
this this
@ -116,7 +103,7 @@ class TextResultActivity : AppCompatActivity() {
FirebaseAnalyticsHelper.textTransPlayEvent() FirebaseAnalyticsHelper.textTransPlayEvent()
} }
binding.ivTrTargetShare.setOnClickListener { binding.ivTrTargetShare.setOnClickListener {
shareText(binding.tvTrTarget.text.toString()) MyTextTools.shareText(this, binding.tvTrTarget.text.toString())
FirebaseAnalyticsHelper.textTransShareEvent() FirebaseAnalyticsHelper.textTransShareEvent()
} }
binding.ivTrCollect.setOnClickListener { binding.ivTrCollect.setOnClickListener {
@ -166,7 +153,7 @@ class TextResultActivity : AppCompatActivity() {
put("text", text) put("text", text)
} }
binding.tvTrTarget.text = "translating..." binding.tvTrTarget.text = getString(R.string.tr_trans_ing)
val translator: Translator<GoogleTranslator.GoogleTranslateCallback> = GoogleTranslator() val translator: Translator<GoogleTranslator.GoogleTranslateCallback> = GoogleTranslator()
translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback { translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback {
override fun onResponse(result: String?, errorMessage: String?) { override fun onResponse(result: String?, errorMessage: String?) {
@ -174,7 +161,11 @@ class TextResultActivity : AppCompatActivity() {
runOnUiThread { runOnUiThread {
if (!TextUtils.isEmpty(result)) { if (!TextUtils.isEmpty(result)) {
binding.tvTrTarget.text = result binding.tvTrTarget.text = result
addHistory(result) MyTextTools.addToHistory(
this@TextResultActivity,
binding.tvTrSource.text.toString(),
result
)
} else { } else {
// 处理错误信息 // 处理错误信息
if (!TextUtils.isEmpty(errorMessage)) { if (!TextUtils.isEmpty(errorMessage)) {
@ -183,7 +174,7 @@ class TextResultActivity : AppCompatActivity() {
Log.e("TranslationError", errorMessage) Log.e("TranslationError", errorMessage)
} }
} }
binding.tvTrTarget.text = "Translation failed: $errorMessage" binding.tvTrTarget.text = getString(R.string.tr_trans_fail)
} }
} }
} }
@ -200,9 +191,9 @@ class TextResultActivity : AppCompatActivity() {
if (errorMessage != null) { if (errorMessage != null) {
Log.e("TranslationFailure", errorMessage) Log.e("TranslationFailure", errorMessage)
} }
binding.tvTrTarget.text = "Translation failed: $errorMessage" binding.tvTrTarget.text = getString(R.string.tr_trans_fail)
} else { } else {
binding.tvTrTarget.text = "Translation failed: Unknown error" binding.tvTrTarget.text = getString(R.string.tr_trans_fail)
} }
} }
} }
@ -210,78 +201,6 @@ class TextResultActivity : AppCompatActivity() {
} }
private fun addHistory(transResult: String?) {
val dbTranslation = DbTranslation(this)
val translations = Translations(
PreferenceLanguageUtils.getString("language_source"),
binding.tvTrSource.text.toString(),
PreferenceLanguageUtils.getString("language_target"),
transResult
)
dbTranslation.addTranslation(translations)
}
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)))
}
}
// readText 方法,整合获取语言代码和朗读文本功能
private fun readText(text: String, targetLanguage: String, context: Context) {
val speech: String = text.trim()
if (!TextUtils.isEmpty(speech)) {
// 获取目标语言的语言代码
val languageCode =
LanguagesConstants.getInstance().getLanguageCodeByLanguage(targetLanguage, context)
Log.d("LanguageCode", "Language Code for $targetLanguage: $languageCode")
// 创建语言 Locale 对象
val locale = Locale(languageCode)
// 判断语言是否支持
if (TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(locale)) {
tts.language = locale
tts.speak(speech, TextToSpeech.QUEUE_FLUSH, null, null)
} else {
Widget.makeToast(this, getString(R.string.tr_tts_error))
}
}
}
// 复制到粘贴板
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()
}
private fun doBack() { private fun doBack() {
finish() finish()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

View File

@ -4,7 +4,6 @@
<corners android:radius="24dp" /> <corners android:radius="24dp" />
<solid android:color="#ffffffff" /> <solid android:color="#ffffffff" />
<gradient <gradient
android:angle="45"
android:endColor="#ff2da5ff" android:endColor="#ff2da5ff"
android:startColor="#ff14cbf9" android:startColor="#ff14cbf9"
android:type="linear" /> android:type="linear" />

View File

@ -0,0 +1,45 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="327dp"
android:height="199dp"
android:viewportWidth="327"
android:viewportHeight="199">
<path
android:pathData="M12,0L315,0A12,12 0,0 1,327 12L327,187A12,12 0,0 1,315 199L12,199A12,12 0,0 1,0 187L0,12A12,12 0,0 1,12 0z"
android:fillColor="#ffffff"/>
<path
android:pathData="M20,20L307,20A4,4 0,0 1,311 24L311,34A4,4 0,0 1,307 38L20,38A4,4 0,0 1,16 34L16,24A4,4 0,0 1,20 20z"
android:fillColor="#D9D9D9"/>
<path
android:pathData="M20,42L307,42A4,4 0,0 1,311 46L311,56A4,4 0,0 1,307 60L20,60A4,4 0,0 1,16 56L16,46A4,4 0,0 1,20 42z"
android:fillColor="#D9D9D9"/>
<path
android:pathData="M20,78L32,78A4,4 0,0 1,36 82L36,94A4,4 0,0 1,32 98L20,98A4,4 0,0 1,16 94L16,82A4,4 0,0 1,20 78z"
android:fillColor="#D9D9D9"/>
<path
android:pathData="M56,78L68,78A4,4 0,0 1,72 82L72,94A4,4 0,0 1,68 98L56,98A4,4 0,0 1,52 94L52,82A4,4 0,0 1,56 78z"
android:fillColor="#D9D9D9"/>
<path
android:pathData="M92,78L104,78A4,4 0,0 1,108 82L108,94A4,4 0,0 1,104 98L92,98A4,4 0,0 1,88 94L88,82A4,4 0,0 1,92 78z"
android:fillColor="#D9D9D9"/>
<group>
<clip-path
android:pathData="M294,76L306,76A6,6 0,0 1,312 82L312,94A6,6 0,0 1,306 100L294,100A6,6 0,0 1,288 94L288,82A6,6 0,0 1,294 76z"/>
<path
android:pathData="M307.29,90.94L300,97L292.71,90.94C292.23,90.47 291.85,89.91 291.6,89.29C291.34,88.67 291.22,88 291.24,87.33C291.26,86.66 291.41,86 291.7,85.39C291.98,84.78 292.39,84.24 292.9,83.8C293.4,83.36 293.99,83.02 294.63,82.82C295.27,82.62 295.95,82.55 296.61,82.62C297.28,82.69 297.93,82.9 298.51,83.24C299.09,83.57 299.6,84.02 300,84.56C300.4,84.02 300.91,83.58 301.49,83.25C302.07,82.92 302.72,82.71 303.38,82.64C304.05,82.57 304.72,82.64 305.36,82.85C306,83.05 306.59,83.38 307.09,83.82C307.59,84.26 308,84.8 308.28,85.41C308.57,86.01 308.73,86.67 308.74,87.34C308.76,88.01 308.64,88.67 308.39,89.29C308.14,89.92 307.77,90.48 307.29,90.95"
android:strokeLineJoin="round"
android:strokeWidth="1.94445"
android:fillColor="#00000000"
android:strokeColor="#C6C6CB"
android:strokeLineCap="round"/>
</group>
<path
android:pathData="M294,76.25L306,76.25A5.75,5.75 0,0 1,311.75 82L311.75,94A5.75,5.75 0,0 1,306 99.75L294,99.75A5.75,5.75 0,0 1,288.25 94L288.25,82A5.75,5.75 0,0 1,294 76.25z"
android:strokeWidth="0.5"
android:fillColor="#00000000"
android:strokeColor="#E72D2D"/>
<path
android:pathData="M300,100V112.74C300,117.15 296.42,120.74 292,120.74H262C257.58,120.74 254,124.32 254,128.74V137"
android:strokeWidth="0.5"
android:fillColor="#00000000"
android:strokeColor="#E62D2D"/>
</vector>

View File

@ -0,0 +1,115 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="315dp"
android:height="315dp"
android:viewportWidth="315"
android:viewportHeight="315">
<path
android:pathData="M157.5,157.5m-156.85,0a156.85,156.85 0,1 1,313.7 0a156.85,156.85 0,1 1,-313.7 0"
android:strokeAlpha="0.02"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-78.85,0a78.85,78.85 0,1 1,157.7 0a78.85,78.85 0,1 1,-157.7 0"
android:strokeAlpha="0.1"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-58.85,0a58.85,58.85 0,1 1,117.7 0a58.85,58.85 0,1 1,-117.7 0"
android:strokeAlpha="0.12"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-48.85,0a48.85,48.85 0,1 1,97.7 0a48.85,48.85 0,1 1,-97.7 0"
android:strokeAlpha="0.13"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-68.85,0a68.85,68.85 0,1 1,137.7 0a68.85,68.85 0,1 1,-137.7 0"
android:strokeAlpha="0.11"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-88.85,0a88.85,88.85 0,1 1,177.7 0a88.85,88.85 0,1 1,-177.7 0"
android:strokeAlpha="0.09"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-98.85,0a98.85,98.85 0,1 1,197.7 0a98.85,98.85 0,1 1,-197.7 0"
android:strokeAlpha="0.08"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-108.85,0a108.85,108.85 0,1 1,217.7 0a108.85,108.85 0,1 1,-217.7 0"
android:strokeAlpha="0.07"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-118.85,0a118.85,118.85 0,1 1,237.7 0a118.85,118.85 0,1 1,-237.7 0"
android:strokeAlpha="0.06"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-128.85,0a128.85,128.85 0,1 1,257.7 0a128.85,128.85 0,1 1,-257.7 0"
android:strokeAlpha="0.05"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-138.85,0a138.85,138.85 0,1 1,277.7 0a138.85,138.85 0,1 1,-277.7 0"
android:strokeAlpha="0.04"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-148.85,0a148.85,148.85 0,1 1,297.7 0a148.85,148.85 0,1 1,-297.7 0"
android:strokeAlpha="0.03"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M158,158m-40,0a40,40 0,1 1,80 0a40,40 0,1 1,-80 0"
android:fillColor="#ffffff"/>
<path
android:pathData="M163.09,154.88H172.46C172.76,154.88 173.07,154.95 173.35,155.06C173.64,155.18 173.9,155.35 174.12,155.57C174.33,155.79 174.51,156.05 174.62,156.33C174.74,156.62 174.8,156.92 174.8,157.23V172.46C174.8,172.76 174.74,173.07 174.62,173.35C174.51,173.64 174.33,173.9 174.12,174.12C173.9,174.33 173.64,174.51 173.35,174.62C173.07,174.74 172.76,174.8 172.46,174.8H157.23C156.92,174.8 156.62,174.74 156.33,174.62C156.05,174.51 155.79,174.33 155.57,174.12C155.35,173.9 155.18,173.64 155.06,173.35C154.95,173.07 154.88,172.76 154.88,172.46V163.09H159.57C160.03,163.09 160.49,163 160.92,162.82C161.34,162.64 161.73,162.38 162.06,162.06C162.38,161.73 162.64,161.34 162.82,160.92C163,160.49 163.09,160.03 163.09,159.57V154.88ZM142,144.34C142,144.04 142.06,143.73 142.18,143.45C142.29,143.16 142.47,142.9 142.68,142.68C142.9,142.47 143.16,142.29 143.45,142.18C143.73,142.06 144.04,142 144.34,142H159.57C159.88,142 160.18,142.06 160.47,142.18C160.75,142.29 161.01,142.47 161.23,142.68C161.45,142.9 161.62,143.16 161.74,143.45C161.85,143.73 161.91,144.04 161.91,144.34V159.57C161.91,159.88 161.85,160.18 161.74,160.47C161.62,160.75 161.45,161.01 161.23,161.23C161.01,161.45 160.75,161.62 160.47,161.74C160.18,161.85 159.88,161.91 159.57,161.91H144.34C144.04,161.91 143.73,161.85 143.45,161.74C143.16,161.62 142.9,161.45 142.68,161.23C142.47,161.01 142.29,160.75 142.18,160.47C142.06,160.18 142,159.88 142,159.57V144.34ZM146.68,154.46H148.4V153.55H150.86V157.88H152.68V153.55H155.2V154.31H157.06V148.57H152.68V147.3C152.67,146.98 152.72,146.65 152.83,146.35C152.85,146.3 152.87,146.25 152.88,146.2C152.88,146.16 152.76,146.13 152.52,146.1H150.81V148.57H146.68V154.46V154.46ZM148.4,149.98H150.86V152.19H148.4V149.98L148.4,149.98ZM155.19,152.19H152.67V149.98H155.19V152.19V152.19ZM162.65,170.06L163.36,168.1H167.03L167.74,170.06H169.76L166.49,160.75H164.12L160.74,170.06H162.65ZM163.86,166.54L165.22,162.56H165.27L166.53,166.54H163.86ZM172.46,151.37H170.12C170.12,150.13 169.62,148.94 168.74,148.06C167.86,147.18 166.67,146.69 165.43,146.69V144.34C166.35,144.34 167.27,144.52 168.12,144.88C168.97,145.23 169.75,145.75 170.4,146.4C171.05,147.05 171.57,147.83 171.92,148.68C172.28,149.54 172.46,150.45 172.46,151.37ZM144.34,165.43H146.68C146.68,166.04 146.81,166.65 147.04,167.22C147.28,167.79 147.62,168.31 148.06,168.74C148.49,169.18 149.01,169.52 149.58,169.76C150.15,169.99 150.76,170.12 151.37,170.12V172.46C149.51,172.46 147.72,171.72 146.4,170.4C145.08,169.08 144.34,167.29 144.34,165.43Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M163.09,154.88H172.46C172.76,154.88 173.07,154.95 173.35,155.06C173.64,155.18 173.9,155.35 174.12,155.57C174.33,155.79 174.51,156.05 174.62,156.33C174.74,156.62 174.8,156.92 174.8,157.23V172.46C174.8,172.76 174.74,173.07 174.62,173.35C174.51,173.64 174.33,173.9 174.12,174.12C173.9,174.33 173.64,174.51 173.35,174.62C173.07,174.74 172.76,174.8 172.46,174.8H157.23C156.92,174.8 156.62,174.74 156.33,174.62C156.05,174.51 155.79,174.33 155.57,174.12C155.35,173.9 155.18,173.64 155.06,173.35C154.95,173.07 154.88,172.76 154.88,172.46V163.09H159.57C160.03,163.09 160.49,163 160.92,162.82C161.34,162.64 161.73,162.38 162.06,162.06C162.38,161.73 162.64,161.34 162.82,160.92C163,160.49 163.09,160.03 163.09,159.57V154.88ZM142,144.34C142,144.04 142.06,143.73 142.18,143.45C142.29,143.16 142.47,142.9 142.68,142.68C142.9,142.47 143.16,142.29 143.45,142.18C143.73,142.06 144.04,142 144.34,142H159.57C159.88,142 160.18,142.06 160.47,142.18C160.75,142.29 161.01,142.47 161.23,142.68C161.45,142.9 161.62,143.16 161.74,143.45C161.85,143.73 161.91,144.04 161.91,144.34V159.57C161.91,159.88 161.85,160.18 161.74,160.47C161.62,160.75 161.45,161.01 161.23,161.23C161.01,161.45 160.75,161.62 160.47,161.74C160.18,161.85 159.88,161.91 159.57,161.91H144.34C144.04,161.91 143.73,161.85 143.45,161.74C143.16,161.62 142.9,161.45 142.68,161.23C142.47,161.01 142.29,160.75 142.18,160.47C142.06,160.18 142,159.88 142,159.57V144.34ZM146.68,154.46H148.4V153.55H150.86V157.88H152.68V153.55H155.2V154.31H157.06V148.57H152.68V147.3C152.67,146.98 152.72,146.65 152.83,146.35C152.85,146.3 152.87,146.25 152.88,146.2C152.88,146.16 152.76,146.13 152.52,146.1H150.81V148.57H146.68V154.46V154.46ZM148.4,149.98H150.86V152.19H148.4V149.98L148.4,149.98ZM155.19,152.19H152.67V149.98H155.19V152.19V152.19ZM162.65,170.06L163.36,168.1H167.03L167.74,170.06H169.76L166.49,160.75H164.12L160.74,170.06H162.65ZM163.86,166.54L165.22,162.56H165.27L166.53,166.54H163.86ZM172.46,151.37H170.12C170.12,150.13 169.62,148.94 168.74,148.06C167.86,147.18 166.67,146.69 165.43,146.69V144.34C166.35,144.34 167.27,144.52 168.12,144.88C168.97,145.23 169.75,145.75 170.4,146.4C171.05,147.05 171.57,147.83 171.92,148.68C172.28,149.54 172.46,150.45 172.46,151.37ZM144.34,165.43H146.68C146.68,166.04 146.81,166.65 147.04,167.22C147.28,167.79 147.62,168.31 148.06,168.74C148.49,169.18 149.01,169.52 149.58,169.76C150.15,169.99 150.76,170.12 151.37,170.12V172.46C149.51,172.46 147.72,171.72 146.4,170.4C145.08,169.08 144.34,167.29 144.34,165.43Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="158.4"
android:startY="142"
android:endX="158.4"
android:endY="174.8"
android:type="linear">
<item android:offset="0" android:color="#FF14CBF9"/>
<item android:offset="0.98" android:color="#FF2CA7FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M158,158m-34.4,0a34.4,34.4 0,1 1,68.8 0a34.4,34.4 0,1 1,-68.8 0"
android:strokeWidth="1.6"
android:fillColor="#00000000">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="158"
android:startY="103.54"
android:endX="158"
android:endY="221.34"
android:type="linear">
<item android:offset="0" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FF16C8FA"/>
</gradient>
</aapt:attr>
</path>
</vector>

View File

@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M2.899,12H20.899"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#1F1724"
android:strokeLineCap="round"/>
<path
android:pathData="M8.899,18L2.899,12L8.899,6"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#1F1724"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,71 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="60dp"
android:height="60dp"
android:viewportWidth="60"
android:viewportHeight="60">
<path
android:pathData="M30,30m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0">
<aapt:attr name="android:fillColor">
<gradient
android:startX="10"
android:startY="10"
android:endX="49"
android:endY="54"
android:type="linear">
<item android:offset="0.009" android:color="#FFDCEAFF"/>
<item android:offset="1" android:color="#FFA6C7F1"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M30,29.998m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0">
<aapt:attr name="android:fillColor">
<gradient
android:startX="15.333"
android:startY="15.331"
android:endX="43.933"
android:endY="47.598"
android:type="linear">
<item android:offset="0.009" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FFFFFFFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M25,22.104C24.653,22.302 24.319,22.52 24,22.756C23.454,23.161 22.951,23.62 22.5,24.125C20.944,25.865 20,28.151 20,30.654C20,36.106 24.477,40.525 30,40.525C35.523,40.525 40,36.106 40,30.654C40,28.151 39.056,25.865 37.5,24.125C37.049,23.62 36.547,23.161 36,22.756C35.681,22.52 35.347,22.302 35,22.104"
android:strokeLineJoin="round"
android:strokeWidth="2.6"
android:fillColor="#00000000"
android:strokeLineCap="round">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="30"
android:startY="22.104"
android:endX="30"
android:endY="40.525"
android:type="linear">
<item android:offset="0" android:color="#FF15CCFA"/>
<item android:offset="1" android:color="#FF2BA9FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M30,19.998V30.525"
android:strokeLineJoin="round"
android:strokeWidth="2.6"
android:fillColor="#00000000"
android:strokeLineCap="round">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="30.5"
android:startY="19.998"
android:endX="30.5"
android:endY="30.525"
android:type="linear">
<item android:offset="0" android:color="#FF15CCFA"/>
<item android:offset="1" android:color="#FF2BA9FF"/>
</gradient>
</aapt:attr>
</path>
</vector>

View File

@ -0,0 +1,66 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="60dp"
android:height="60dp"
android:viewportWidth="60"
android:viewportHeight="60">
<path
android:pathData="M30,30m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0">
<aapt:attr name="android:fillColor">
<gradient
android:startX="10"
android:startY="10"
android:endX="49"
android:endY="54"
android:type="linear">
<item android:offset="0.009" android:color="#7FDCEAFF"/>
<item android:offset="1" android:color="#7FA6C7F1"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M30,29.998m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0"
android:strokeAlpha="0.5"
android:fillAlpha="0.5">
<aapt:attr name="android:fillColor">
<gradient
android:startX="15.333"
android:startY="15.331"
android:endX="43.933"
android:endY="47.598"
android:type="linear">
<item android:offset="0.009" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FFFFFFFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M25,22.104C24.653,22.302 24.319,22.52 24,22.756C23.454,23.161 22.951,23.62 22.5,24.125C20.944,25.865 20,28.151 20,30.654C20,36.106 24.477,40.525 30,40.525C35.523,40.525 40,36.106 40,30.654C40,28.151 39.056,25.865 37.5,24.125C37.049,23.62 36.547,23.161 36,22.756C35.681,22.52 35.347,22.302 35,22.104"
android:strokeAlpha="0.2"
android:strokeLineJoin="round"
android:strokeWidth="2.6"
android:fillColor="#00000000"
android:fillAlpha="0.2"
android:strokeLineCap="round">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="30"
android:startY="22.104"
android:endX="30"
android:endY="40.525"
android:type="linear">
<item android:offset="0" android:color="#FF15CCFA"/>
<item android:offset="1" android:color="#FF2BA9FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M30,19.998V30.525"
android:strokeAlpha="0.2"
android:strokeLineJoin="round"
android:strokeWidth="2.6"
android:fillColor="#00000000"
android:strokeColor="#15CCFA"
android:fillAlpha="0.2"
android:strokeLineCap="round"/>
</vector>

View File

@ -66,16 +66,87 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
<LinearLayout
<TextView android:id="@+id/ll_empty_his"
android:id="@+id/def_empty"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/main_text_ff1f1724" android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/his_emtpoy"
android:textColor="@color/his_empty_text"
android:textSize="16sp" />
<TextView
android:id="@+id/emtpoy_his_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="32dp"
android:background="@drawable/button_r24_blue_bg"
android:paddingStart="56dp"
android:paddingTop="12dp"
android:paddingEnd="56dp"
android:paddingBottom="12dp"
android:text="@string/translate_now"
android:textColor="@color/white"
android:textSize="18sp" android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@id/histories" android:textStyle="bold" />
app:layout_constraintEnd_toEndOf="@id/histories" </LinearLayout>
app:layout_constraintStart_toStartOf="@id/histories"
app:layout_constraintTop_toTopOf="@id/histories" /> <LinearLayout
android:id="@+id/ll_empty_fav"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="110dp"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/favor_emtpoy"
android:textColor="@color/his_empty_text"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:background="@drawable/emp"
android:gravity="bottom|center"
android:text="@string/fav_emp_description"
android:textColor="@color/text_gray"
android:textSize="12sp" />
<TextView
android:id="@+id/emtpoy_fav_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="32dp"
android:background="@drawable/button_r24_blue_bg"
android:paddingStart="56dp"
android:paddingTop="12dp"
android:paddingEnd="56dp"
android:paddingBottom="12dp"
android:text="@string/translate_now"
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:background="@drawable/button_r20_white_bg_tlr"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView

View File

@ -84,11 +84,11 @@
<!-- 分隔线 --> <!-- 分隔线 -->
<View <View
android:id="@+id/sus_view1" android:id="@+id/sus_view1"
android:layout_width="110dp" android:layout_width="140dp"
android:layout_height="5dp" android:layout_height="5dp"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginBottom="15dp" android:layout_marginBottom="5dp"
android:background="@drawable/ic_dashed_line_4b4b4b4" /> android:background="@drawable/ic_dashed_line_4b4b4b4" />
<!-- 第三行 --> <!-- 第三行 -->
<LinearLayout <LinearLayout
@ -97,7 +97,7 @@
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginBottom="20dp" android:layout_marginBottom="30dp"
android:orientation="horizontal"> android:orientation="horizontal">

View File

@ -23,6 +23,7 @@
<color name="bg_ff605c62">#FF605C62</color> <color name="bg_ff605c62">#FF605C62</color>
<!-- his_page--> <!-- his_page-->
<color name="text_ffa5a5a5">#FFA5A5A5</color> <color name="text_ffa5a5a5">#FFA5A5A5</color>
<color name="his_empty_text">#FFB3B3B3</color>
<!-- still-page--> <!-- still-page-->
<color name="bg_53514c">#FF53514C</color> <color name="bg_53514c">#FF53514C</color>

View File

@ -1,7 +1,7 @@
<resources> <resources>
<string name="app_name">Translark</string> <string name="app_name">Translark</string>
<string name="my_admob_app_id">ca-app-pub-9280511366580942~8779388277</string> <string name="my_admob_app_id">ca-app-pub-9280511366580942~8779388277</string>
<!--system-->
<string name="pref_key_info_hide" translatable="false">ih</string> <string name="pref_key_info_hide" translatable="false">ih</string>
<string name="pref_key_group_recognized_text_in_blocks" translatable="false">grtib</string> <string name="pref_key_group_recognized_text_in_blocks" translatable="false">grtib</string>
<string name="pref_key_show_language_tag" translatable="false">slt</string> <string name="pref_key_show_language_tag" translatable="false">slt</string>
@ -9,12 +9,14 @@
<string name="pref_key_pose_detector_prefer_gpu" translatable="false">pdpg</string> <string name="pref_key_pose_detector_prefer_gpu" translatable="false">pdpg</string>
<string name="pref_key_camera_live_viewport" translatable="false">clv</string> <string name="pref_key_camera_live_viewport" translatable="false">clv</string>
<string name="select_image" translatable="false">Select image</string> <string name="select_image" translatable="false">Select image</string>
<!--main_page--> <!--main_page-->
<string name="menu_item_settings" translatable="false">Settings</string> <string name="menu_item_settings" translatable="false">Settings</string>
<string name="text_main_title">translate</string> <string name="text_main_title">translate</string>
<string name="text_source_language">Chinese</string> <string name="text_source_language">Chinese</string>
<string name="text_target_language">English</string> <string name="text_target_language">English</string>
<string name="main_text_enter">Enter text</string> <string name="main_text_enter">Enter text\nSupport for intelligent recognition of language types</string>
<string name="main_paste_text">Paste</string> <string name="main_paste_text">Paste</string>
<string name="main_paste_empty">Clipboard contains empty or invalid data.</string> <string name="main_paste_empty">Clipboard contains empty or invalid data.</string>
<string name="main_voice_to_text">Your device may not support speech-to-text.</string> <string name="main_voice_to_text">Your device may not support speech-to-text.</string>
@ -27,6 +29,8 @@
<string name="main_dictionary">Dictionary</string> <string name="main_dictionary">Dictionary</string>
<string name="main_limit_num">%1$d/1800</string> <string name="main_limit_num">%1$d/1800</string>
<!-- photo-->
<string name="ph_toast">Photographing text for translation</string>
<!-- change_page--> <!-- change_page-->
<string name="ch_title">Languages</string> <string name="ch_title">Languages</string>
@ -35,7 +39,11 @@
<string name="tr_common">Common</string> <string name="tr_common">Common</string>
<string name="tr_other">other</string> <string name="tr_other">other</string>
<string name="tr_tts_error">Speech in this language is temporarily not supported.</string> <string name="tr_tts_error">Speech in this language is temporarily not supported.</string>
<string name="tr_tts_reading">Preparing to read…</string>
<string name="tr_title">Translator</string> <string name="tr_title">Translator</string>
<string name="tr_trans_fail">Translation failed: Please check the network.</string>
<string name="tr_trans_ing"> translating…</string>
<!-- sus_view--> <!-- sus_view-->
<string name="global_translation">Global Translation</string> <string name="global_translation">Global Translation</string>
@ -49,9 +57,11 @@
<!-- his_page--> <!-- his_page-->
<string name="his_delete">Delete</string> <string name="his_delete">Delete</string>
<string name="his_title">History</string> <string name="his_title">History</string>
<string name="his_emtpoy">No translation records</string> <string name="his_emtpoy">Empty no history...</string>
<string name="favor_title">Favorite</string> <string name="favor_title">Favorite</string>
<string name="favor_emtpoy">No collection record</string> <string name="favor_emtpoy">Empty no favorite...</string>
<string name="translate_now">Translate Now</string>
<!--settings_page--> <!--settings_page-->
<string name="settings">Settings</string> <string name="settings">Settings</string>
<string name="languages">App Languages</string> <string name="languages">App Languages</string>
@ -82,7 +92,7 @@
<string name="quick_set_kj_long">长按悬浮球</string> <string name="quick_set_kj_long">长按悬浮球</string>
<string name="quick_set_kj_long_to">打开应用</string> <string name="quick_set_kj_long_to">打开应用</string>
<string name="quick_set_kj_double">双击悬浮球</string> <string name="quick_set_kj_double">双击悬浮球</string>
<string name="fav_emp_description">Click the \"Favorite\" button at the end\nafter translation.\nEasily bookmark sentences.</string>
</resources> </resources>