version 1.0.5 release
This commit is contained in:
parent
50225a3cfe
commit
3de6d92a64
@ -15,8 +15,9 @@ android {
|
|||||||
applicationId = "com.assimilate.alltrans"
|
applicationId = "com.assimilate.alltrans"
|
||||||
minSdk = 23
|
minSdk = 23
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 3
|
// 该打 6
|
||||||
versionName = "1.0.3"
|
versionCode = 5
|
||||||
|
versionName = "1.0.5"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
@ -76,14 +77,10 @@ dependencies {
|
|||||||
|
|
||||||
// Import the BoM for the Firebase platform
|
// Import the BoM for the Firebase platform
|
||||||
implementation(platform("com.google.firebase:firebase-bom:33.1.1"))
|
implementation(platform("com.google.firebase:firebase-bom:33.1.1"))
|
||||||
|
|
||||||
// Add the dependencies for the Crashlytics and Analytics libraries
|
|
||||||
// When using the BoM, you don't specify versions in Firebase library dependencies
|
|
||||||
implementation("com.google.firebase:firebase-crashlytics")
|
implementation("com.google.firebase:firebase-crashlytics")
|
||||||
implementation("com.google.firebase:firebase-analytics")
|
implementation("com.google.firebase:firebase-analytics")
|
||||||
implementation("com.google.firebase:firebase-config")
|
implementation("com.google.firebase:firebase-config")
|
||||||
|
|
||||||
|
|
||||||
// To recognize Latin script
|
// To recognize Latin script
|
||||||
implementation("com.google.mlkit:text-recognition:16.0.0")
|
implementation("com.google.mlkit:text-recognition:16.0.0")
|
||||||
// To recognize Chinese script
|
// To recognize Chinese script
|
||||||
|
|||||||
@ -261,7 +261,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"config": [
|
"config": [
|
||||||
|
|
||||||
[
|
[
|
||||||
"admob_inst",
|
"admob_inst",
|
||||||
{
|
{
|
||||||
@ -324,6 +323,51 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"alltrans_directory_int_auto": {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"after_click": {
|
||||||
|
"admob_inst": "keep",
|
||||||
|
"max_inst": "keep"
|
||||||
|
},
|
||||||
|
"block": {
|
||||||
|
"admob_inst": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
},
|
||||||
|
"max_inst": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"close": {
|
||||||
|
"admob_inst": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
},
|
||||||
|
"max_inst": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": [
|
||||||
|
[
|
||||||
|
"admob_inst",
|
||||||
|
{
|
||||||
|
"ca-app-pub-9280511366580942/1975489976": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"limit": {
|
||||||
|
"admob_inst": 100,
|
||||||
|
"max_inst": 100
|
||||||
|
},
|
||||||
|
"cycle": 0,
|
||||||
|
"timeout": 15000,
|
||||||
|
"showIntervalEnable": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"alltrans_home_native_auto": {
|
"alltrans_home_native_auto": {
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
@ -372,6 +416,54 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"alltrans_text_trans_native_auto": {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"config": [
|
||||||
|
[
|
||||||
|
"admob_native",
|
||||||
|
{
|
||||||
|
"ca-app-pub-9280511366580942/6930403378": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"block": {
|
||||||
|
"admob_native": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
},
|
||||||
|
"max_native": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"click": {
|
||||||
|
"admob_native": [
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"max_native": [
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"after_click": {
|
||||||
|
"admob_native": "next",
|
||||||
|
"max_native": "next"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"admob_native": 100,
|
||||||
|
"max_native": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"alltrans_backup_int_auto": {
|
"alltrans_backup_int_auto": {
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_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" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
@ -30,7 +31,7 @@
|
|||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
|
||||||
<!-- Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 -->
|
<!-- Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 -->
|
||||||
<!-- <meta-data-->
|
<!-- <meta-data-->
|
||||||
<!-- android:name="com.google.android.gms.ads.APPLICATION_ID"-->
|
<!-- android:name="com.google.android.gms.ads.APPLICATION_ID"-->
|
||||||
<!-- android:value="ca-app-pub-3940256099942544~3347511713" />-->
|
<!-- android:value="ca-app-pub-3940256099942544~3347511713" />-->
|
||||||
<meta-data
|
<meta-data
|
||||||
@ -45,7 +46,7 @@
|
|||||||
<property
|
<property
|
||||||
android:name="android.adservices.AD_SERVICES_CONFIG"
|
android:name="android.adservices.AD_SERVICES_CONFIG"
|
||||||
android:resource="@xml/ga_ad_services_config"
|
android:resource="@xml/ga_ad_services_config"
|
||||||
tools:replace="android:resource"/>
|
tools:replace="android:resource" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".viewui.MainActivity"
|
android:name=".viewui.MainActivity"
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import android.os.Build
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.webkit.WebView
|
import android.webkit.WebView
|
||||||
import com.assimilate.alltrans.common.AppStore
|
import com.assimilate.alltrans.common.AppStore
|
||||||
import com.assimilate.alltrans.common.CurrentActivityHolder
|
|
||||||
import com.assimilate.alltrans.common.RemoteConfigManager
|
import com.assimilate.alltrans.common.RemoteConfigManager
|
||||||
import com.assimilate.alltrans.model.LanguagesConstants
|
import com.assimilate.alltrans.model.LanguagesConstants
|
||||||
import com.assimilate.alltrans.model.PreferenceLanguageUtils
|
import com.assimilate.alltrans.model.PreferenceLanguageUtils
|
||||||
@ -26,47 +25,46 @@ class MyApp : Application() {
|
|||||||
|
|
||||||
private var activityReferences = 0
|
private var activityReferences = 0
|
||||||
private var isActivityChangingConfigurations = false
|
private var isActivityChangingConfigurations = false
|
||||||
|
|
||||||
var isFirstLaunch = true
|
var isFirstLaunch = true
|
||||||
|
var isFirstPremisiton = false
|
||||||
|
|
||||||
private fun registerActivityLifecycle() {
|
private fun registerActivityLifecycle() {
|
||||||
|
|
||||||
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
|
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
|
||||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||||
CurrentActivityHolder.currentActivity = activity
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityStarted(activity: Activity) {
|
override fun onActivityStarted(activity: Activity) {
|
||||||
CurrentActivityHolder.currentActivity = activity
|
|
||||||
if (++activityReferences == 1 && !isActivityChangingConfigurations) {
|
if (++activityReferences == 1 && !isActivityChangingConfigurations) {
|
||||||
if (isFirstLaunch) {
|
// Log.d("MyApplication", "应用进入前台")
|
||||||
isFirstLaunch = false
|
if (!isFirstLaunch) {
|
||||||
} else {
|
if (isFirstPremisiton) return
|
||||||
val intent = Intent(activity, WelActivity::class.java)
|
val intent = Intent(activity, WelActivity::class.java)
|
||||||
activity.startActivity(intent)
|
activity.startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResumed(activity: Activity) {
|
override fun onActivityResumed(activity: Activity) {}
|
||||||
CurrentActivityHolder.currentActivity = activity
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityPaused(activity: Activity) {}
|
override fun onActivityPaused(activity: Activity) {}
|
||||||
|
|
||||||
override fun onActivityStopped(activity: Activity) {
|
override fun onActivityStopped(activity: Activity) {
|
||||||
|
|
||||||
isActivityChangingConfigurations = activity.isChangingConfigurations;
|
isActivityChangingConfigurations = activity.isChangingConfigurations
|
||||||
if (--activityReferences == 0 && !isActivityChangingConfigurations) {
|
if (--activityReferences == 0 && !isActivityChangingConfigurations) {
|
||||||
// The app goes to the background
|
|
||||||
|
isFirstLaunch = false
|
||||||
|
// Log.d("MyApplication", "应用进入后台")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
||||||
|
|
||||||
override fun onActivityDestroyed(activity: Activity) {
|
override fun onActivityDestroyed(activity: Activity) {
|
||||||
if (CurrentActivityHolder.currentActivity == activity) {
|
|
||||||
CurrentActivityHolder.currentActivity = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -106,7 +104,7 @@ class MyApp : Application() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
instance = this
|
instance = this
|
||||||
// ScreenUtils.init(this)
|
|
||||||
registerActivityLifecycle()
|
registerActivityLifecycle()
|
||||||
initAd()
|
initAd()
|
||||||
setSystemLanguage()
|
setSystemLanguage()
|
||||||
@ -151,6 +149,8 @@ class MyApp : Application() {
|
|||||||
// firebase_event_map_key
|
// firebase_event_map_key
|
||||||
const val CLICK_FROM = "clickfrom"
|
const val CLICK_FROM = "clickfrom"
|
||||||
const val FAIL_REASON = "failreason"
|
const val FAIL_REASON = "failreason"
|
||||||
|
const val LAN_SOURCE = "source"
|
||||||
|
const val LAN_TARGET = "target"
|
||||||
|
|
||||||
// firebase_event_key
|
// firebase_event_key
|
||||||
const val launchPv = "launch_pv"
|
const val launchPv = "launch_pv"
|
||||||
@ -170,7 +170,6 @@ class MyApp : Application() {
|
|||||||
const val textTransShare = "text_trans_share"
|
const val textTransShare = "text_trans_share"
|
||||||
const val textTransLike = "text_trans_like"
|
const val textTransLike = "text_trans_like"
|
||||||
|
|
||||||
|
|
||||||
const val hoverButtonClick = "hover_button_click"
|
const val hoverButtonClick = "hover_button_click"
|
||||||
const val hoverLimitAgree = "hover_limit_agree"
|
const val hoverLimitAgree = "hover_limit_agree"
|
||||||
const val hoverButtonCancel = "hover_button_cancel"
|
const val hoverButtonCancel = "hover_button_cancel"
|
||||||
@ -191,6 +190,10 @@ class MyApp : Application() {
|
|||||||
const val historyClick = "history_click"
|
const val historyClick = "history_click"
|
||||||
const val historyDelete = "history_delete"
|
const val historyDelete = "history_delete"
|
||||||
|
|
||||||
|
const val directoryClick = "directory_click"
|
||||||
|
const val directoryTransClick = "directory_trans_click"
|
||||||
|
const val directoryTransResult = "directory_trans_result"
|
||||||
|
|
||||||
|
|
||||||
// google_ad_place
|
// google_ad_place
|
||||||
const val start_cold_int_auto = "start_cold_int_auto"
|
const val start_cold_int_auto = "start_cold_int_auto"
|
||||||
@ -200,9 +203,12 @@ class MyApp : Application() {
|
|||||||
const val text_camera_int_auto = "text_camera_int_auto"
|
const val text_camera_int_auto = "text_camera_int_auto"
|
||||||
const val image_camera_int_auto = "image_camera_int_auto"
|
const val image_camera_int_auto = "image_camera_int_auto"
|
||||||
const val history_int_auto = "history_int_auto"
|
const val history_int_auto = "history_int_auto"
|
||||||
|
const val directory_int_auto = "directory_int_auto"
|
||||||
const val home_native_auto = "home_native_auto"
|
const val home_native_auto = "home_native_auto"
|
||||||
|
const val text_trans_native_auto = "text_trans_native_auto"
|
||||||
const val backup_int_auto = "backup_int_auto"
|
const val backup_int_auto = "backup_int_auto"
|
||||||
|
|
||||||
|
|
||||||
const val adKey = "alltrans"
|
const val adKey = "alltrans"
|
||||||
const val adDefJson = """
|
const val adDefJson = """
|
||||||
{
|
{
|
||||||
@ -468,7 +474,6 @@ class MyApp : Application() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"config": [
|
"config": [
|
||||||
|
|
||||||
[
|
[
|
||||||
"admob_inst",
|
"admob_inst",
|
||||||
{
|
{
|
||||||
@ -531,6 +536,51 @@ class MyApp : Application() {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"alltrans_directory_int_auto": {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"after_click": {
|
||||||
|
"admob_inst": "keep",
|
||||||
|
"max_inst": "keep"
|
||||||
|
},
|
||||||
|
"block": {
|
||||||
|
"admob_inst": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
},
|
||||||
|
"max_inst": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"close": {
|
||||||
|
"admob_inst": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
},
|
||||||
|
"max_inst": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"config": [
|
||||||
|
[
|
||||||
|
"admob_inst",
|
||||||
|
{
|
||||||
|
"ca-app-pub-9280511366580942/1975489976": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"limit": {
|
||||||
|
"admob_inst": 100,
|
||||||
|
"max_inst": 100
|
||||||
|
},
|
||||||
|
"cycle": 0,
|
||||||
|
"timeout": 15000,
|
||||||
|
"showIntervalEnable": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"alltrans_home_native_auto": {
|
"alltrans_home_native_auto": {
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
@ -579,6 +629,54 @@ class MyApp : Application() {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"alltrans_text_trans_native_auto": {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"config": [
|
||||||
|
[
|
||||||
|
"admob_native",
|
||||||
|
{
|
||||||
|
"ca-app-pub-9280511366580942/6930403378": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"block": {
|
||||||
|
"admob_native": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
},
|
||||||
|
"max_native": {
|
||||||
|
"delay": 0,
|
||||||
|
"rate": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"click": {
|
||||||
|
"admob_native": [
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"max_native": [
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
100
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"after_click": {
|
||||||
|
"admob_native": "next",
|
||||||
|
"max_native": "next"
|
||||||
|
},
|
||||||
|
"limit": {
|
||||||
|
"admob_native": 100,
|
||||||
|
"max_native": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"alltrans_backup_int_auto": {
|
"alltrans_backup_int_auto": {
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -23,7 +23,7 @@ class AppStore(context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val DEFAULT_INTERVAL_TIME: Long = 5000 // 默认间隔时间,单位毫秒
|
private const val DEFAULT_INTERVAL_TIME: Long = 3000 // 默认间隔时间,单位毫秒
|
||||||
private const val DEFAULT_WELCOME_MESSAGE: String = "" // 默认欢迎信息
|
private const val DEFAULT_WELCOME_MESSAGE: String = "" // 默认欢迎信息
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package com.assimilate.alltrans.common
|
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
|
|
||||||
object CurrentActivityHolder {
|
|
||||||
var currentActivity: Activity? = null
|
|
||||||
}
|
|
||||||
@ -1,12 +1,12 @@
|
|||||||
package com.assimilate.alltrans.common
|
package com.assimilate.alltrans.common
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
import com.assimilate.alltrans.BuildConfig
|
||||||
import com.assimilate.alltrans.MyApp
|
import com.assimilate.alltrans.MyApp
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics
|
import com.google.firebase.analytics.FirebaseAnalytics
|
||||||
import com.google.firebase.analytics.ktx.analytics
|
import com.google.firebase.analytics.ktx.analytics
|
||||||
import com.google.firebase.ktx.Firebase
|
import com.google.firebase.ktx.Firebase
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
object FirebaseAnalyticsHelper {
|
object FirebaseAnalyticsHelper {
|
||||||
private val firebaseAnalytics: FirebaseAnalytics by lazy {
|
private val firebaseAnalytics: FirebaseAnalytics by lazy {
|
||||||
@ -14,6 +14,10 @@ object FirebaseAnalyticsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun logCusEvent(eventName: String, params: Map<String, Any?>? = null) {
|
private fun logCusEvent(eventName: String, params: Map<String, Any?>? = null) {
|
||||||
|
// if (BuildConfig.DEBUG) {
|
||||||
|
// // 在调试模式下不上传事件
|
||||||
|
// return
|
||||||
|
// }
|
||||||
val bundle = Bundle().apply {
|
val bundle = Bundle().apply {
|
||||||
params?.forEach { (key, value) ->
|
params?.forEach { (key, value) ->
|
||||||
when (value) {
|
when (value) {
|
||||||
@ -44,12 +48,12 @@ object FirebaseAnalyticsHelper {
|
|||||||
logCusEvent(MyApp.Config.textTransSwitch, params)
|
logCusEvent(MyApp.Config.textTransSwitch, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun languageChooseEvent(from: String,value: String) {
|
fun languageChooseEvent(from: String, value: String) {
|
||||||
val params = mapOf(from to value)
|
val params = mapOf(from to value)
|
||||||
logCusEvent(MyApp.Config.languageChoose, params)
|
logCusEvent(MyApp.Config.languageChoose, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun languageFromEvent(clickFrom: String,value: String) {
|
fun languageFromEvent(clickFrom: String, value: String) {
|
||||||
val params = mapOf(clickFrom to value)
|
val params = mapOf(clickFrom to value)
|
||||||
logCusEvent(MyApp.Config.languageFrom, params)
|
logCusEvent(MyApp.Config.languageFrom, params)
|
||||||
}
|
}
|
||||||
@ -58,7 +62,7 @@ object FirebaseAnalyticsHelper {
|
|||||||
logCusEvent(MyApp.Config.textTransClick, null)
|
logCusEvent(MyApp.Config.textTransClick, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun textTransResultEvent(result: String,value: String) {
|
fun textTransResultEvent(result: String, value: String) {
|
||||||
val params = mapOf(result to value)
|
val params = mapOf(result to value)
|
||||||
logCusEvent(MyApp.Config.textTransResult, params)
|
logCusEvent(MyApp.Config.textTransResult, params)
|
||||||
}
|
}
|
||||||
@ -77,7 +81,7 @@ object FirebaseAnalyticsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun textVoiceResultEvent(failReason: String,value: String) {
|
fun textVoiceResultEvent(failReason: String, value: String) {
|
||||||
val params = mapOf(failReason to value)
|
val params = mapOf(failReason to value)
|
||||||
logCusEvent(MyApp.Config.textVoiceResult, params)
|
logCusEvent(MyApp.Config.textVoiceResult, params)
|
||||||
}
|
}
|
||||||
@ -133,7 +137,7 @@ object FirebaseAnalyticsHelper {
|
|||||||
logCusEvent(MyApp.Config.hoverScreenDistrict, null)
|
logCusEvent(MyApp.Config.hoverScreenDistrict, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun imageClickEvent(clickFrom: String,value: String) {
|
fun imageClickEvent(clickFrom: String, value: String) {
|
||||||
val params = mapOf(clickFrom to value)
|
val params = mapOf(clickFrom to value)
|
||||||
logCusEvent(MyApp.Config.imageClick, params)
|
logCusEvent(MyApp.Config.imageClick, params)
|
||||||
}
|
}
|
||||||
@ -155,30 +159,42 @@ object FirebaseAnalyticsHelper {
|
|||||||
logCusEvent(MyApp.Config.historyDelete, null)
|
logCusEvent(MyApp.Config.historyDelete, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hoverGlobalResultEvent(failReason: String,value: String) {
|
fun directoryClickEvent() {
|
||||||
|
logCusEvent(MyApp.Config.directoryClick, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun directoryTransClickEvent() {
|
||||||
|
logCusEvent(MyApp.Config.directoryTransClick, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun directoryTransResultEvent(failReason: String, value: String) {
|
||||||
|
val params = mapOf(failReason to value)
|
||||||
|
logCusEvent(MyApp.Config.directoryTransResult, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hoverGlobalResultEvent(failReason: String, value: String) {
|
||||||
val params = mapOf(failReason to value)
|
val params = mapOf(failReason to value)
|
||||||
logCusEvent(MyApp.Config.hoverGlobalResult, params)
|
logCusEvent(MyApp.Config.hoverGlobalResult, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun hoverDistrictResultEvent(failReason: String, value: String) {
|
||||||
fun hoverDistrictResultEvent(failReason: String,value: String) {
|
|
||||||
val params = mapOf(failReason to value)
|
val params = mapOf(failReason to value)
|
||||||
logCusEvent(MyApp.Config.hoverDistrictResult, params)
|
logCusEvent(MyApp.Config.hoverDistrictResult, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun imageCameraResultEvent(failReason: String,value: String) {
|
fun imageCameraResultEvent(failReason: String, value: String) {
|
||||||
val params = mapOf(failReason to value)
|
val params = mapOf(failReason to value)
|
||||||
logCusEvent(MyApp.Config.imageCameraResult, params)
|
logCusEvent(MyApp.Config.imageCameraResult, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun imagePhotoResultEvent(failReason: String, value: String) {
|
||||||
fun imagePhotoResultEvent(failReason: String,value: String) {
|
|
||||||
val params = mapOf(failReason to value)
|
val params = mapOf(failReason to value)
|
||||||
logCusEvent(MyApp.Config.imagePhotoResult, params)
|
logCusEvent(MyApp.Config.imagePhotoResult, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
// oeran domo
|
||||||
|
|
||||||
// fun logEvent(eventName: String, myParam: Map<String, String>? = null) {
|
// fun logEvent(eventName: String, myParam: Map<String, String>? = null) {
|
||||||
//
|
//
|
||||||
// val jsonObject = JSONObject()
|
// val jsonObject = JSONObject()
|
||||||
|
|||||||
@ -3,20 +3,16 @@ package com.assimilate.alltrans.common
|
|||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
class LolAdWrapper {
|
class LolAdWrapper {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -34,16 +30,18 @@ class LolAdWrapper {
|
|||||||
fun closed() {}
|
fun closed() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 有插屏缓存
|
||||||
fun hasCache(placement: String): Boolean {
|
fun hasCache(placement: String): Boolean {
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAd(act: Activity, placement: String, listener: LoLLoadListener? = null) {
|
// 无条件加载插屏
|
||||||
|
fun loadAd(act: Activity, placement: String, listener: LoLLoadListener? = null) {
|
||||||
if (act.isFinishing) return
|
if (act.isFinishing) return
|
||||||
LOLAdsInstDispatcher.getLoader(act, placement, object : AdLoadListener {
|
LOLAdsInstDispatcher.getLoader(act, placement, object : AdLoadListener {
|
||||||
override fun onAdLoadFailed(error: LolLoadError?) {
|
override fun onAdLoadFailed(error: LolLoadError?) {
|
||||||
@ -61,6 +59,7 @@ class LolAdWrapper {
|
|||||||
}).loadAd()
|
}).loadAd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//无条件加载激励
|
||||||
fun loadRewardAd(act: Activity, placement: String, listener: LoLLoadListener? = null) {
|
fun loadRewardAd(act: Activity, placement: String, listener: LoLLoadListener? = null) {
|
||||||
if (act.isFinishing) return
|
if (act.isFinishing) return
|
||||||
LOLAdsRewardedDispatcher.getLoader(act, placement, object : AdLoadListener {
|
LOLAdsRewardedDispatcher.getLoader(act, placement, object : AdLoadListener {
|
||||||
@ -77,22 +76,40 @@ class LolAdWrapper {
|
|||||||
}).loadAd()
|
}).loadAd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//无缓存加载插屏
|
||||||
fun loadAdIfNotCached(act: Activity, placement: String, listener: LoLLoadListener? = null) {
|
fun loadAdIfNotCached(act: Activity, placement: String, listener: LoLLoadListener? = null) {
|
||||||
if (act.isFinishing || hasCache(placement)) return
|
if (act.isFinishing || hasCache(placement)) return
|
||||||
|
|
||||||
loadAd(act, placement, listener)
|
loadAd(act, placement, listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//有缓存(包含全局)展示
|
||||||
fun showAdIfCached(act: Activity, placement: String, listener: LolShowListener? = null) {
|
fun showAdIfCached(act: Activity, placement: String, listener: LolShowListener? = null) {
|
||||||
|
// if (act.isFinishing || !hasCache(placement)) {
|
||||||
|
//// val map = mutableMapOf(Pair(AnalysisUtil.PARAM_VALUE, "No cache for ads"))
|
||||||
|
//// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_SHOW_FAILED, map)
|
||||||
|
// listener?.showFailed(LolShowError("No cache for ads"))
|
||||||
|
// } else {
|
||||||
|
// showAd(act, placement, listener)
|
||||||
|
// }
|
||||||
|
|
||||||
|
//判断当前广告位是否可以show,不能show则判断补位广告是否可以show。
|
||||||
if (act.isFinishing || !hasCache(placement)) {
|
if (act.isFinishing || !hasCache(placement)) {
|
||||||
|
if (hasCache(MyApp.Config.backup_int_auto)) {
|
||||||
|
showAd(act, MyApp.Config.backup_int_auto, listener)
|
||||||
|
} else {
|
||||||
// val map = mutableMapOf(Pair(AnalysisUtil.PARAM_VALUE, "No cache for ads"))
|
// val map = mutableMapOf(Pair(AnalysisUtil.PARAM_VALUE, "No cache for ads"))
|
||||||
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_SHOW_FAILED, map)
|
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_SHOW_FAILED, map)
|
||||||
listener?.showFailed(LolShowError("No cache for ads"))
|
listener?.showFailed(LolShowError("No cache for ads"))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
showAd(act, placement, listener)
|
showAd(act, placement, listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 带时间带缓存展示
|
||||||
fun showAdTiming(act: Activity, placement: String, listener: LolShowListener? = null) {
|
fun showAdTiming(act: Activity, placement: String, listener: LolShowListener? = null) {
|
||||||
//当前时间减去旧时间,才展示广告(满足间隔时间才show广告)
|
//当前时间减去旧时间,才展示广告(满足间隔时间才show广告)
|
||||||
if (System.currentTimeMillis() - MyApp.app.lastAdDisplayTime.get() >= AppStore(MyApp.app).showAdIntervalTime) {
|
if (System.currentTimeMillis() - MyApp.app.lastAdDisplayTime.get() >= AppStore(MyApp.app).showAdIntervalTime) {
|
||||||
@ -111,6 +128,47 @@ class LolAdWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 无条件展示
|
||||||
|
private fun showAd(act: Activity, placement: String, listener: LolShowListener? = null) {
|
||||||
|
if (act.isFinishing) return
|
||||||
|
LOLAdsInstDispatcher.getShower(act, placement, object : AdShowListener {
|
||||||
|
|
||||||
|
override fun onAdClicked() {
|
||||||
|
MyApp.app.isAdShowing.set(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdClosed() {
|
||||||
|
MyApp.app.isAdShowing.set(false)
|
||||||
|
listener?.closed()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdRewarded() {}
|
||||||
|
override fun onAdShowFailed(error: LolShowError?) {
|
||||||
|
MyApp.app.isAdShowing.set(false)
|
||||||
|
//广告show失败打点
|
||||||
|
// val map = mutableMapOf(Pair(AnalysisUtil.PARAM_VALUE, "${error?.msg}"))
|
||||||
|
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_SHOW_FAILED, map)
|
||||||
|
listener?.showFailed(error)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdShown() {
|
||||||
|
MyApp.app.isAdShowing.set(true)
|
||||||
|
listener?.shown()
|
||||||
|
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_SHOWN)
|
||||||
|
if (placement != MyApp.Config.start_cold_int_auto) {
|
||||||
|
MyApp.app.lastAdDisplayTime.set(System.currentTimeMillis())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAfterClickClosed() {}
|
||||||
|
|
||||||
|
override fun onDelayClosed() {}
|
||||||
|
|
||||||
|
}).showAd()
|
||||||
|
}
|
||||||
|
|
||||||
|
//加载展示原生
|
||||||
fun loadAdShowNativeAd(
|
fun loadAdShowNativeAd(
|
||||||
context: Activity, nativeId: String, frameAd: FrameLayout, admobLayout: Int, maxLayout: Int
|
context: Activity, nativeId: String, frameAd: FrameLayout, admobLayout: Int, maxLayout: Int
|
||||||
) {
|
) {
|
||||||
@ -167,45 +225,6 @@ class LolAdWrapper {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showAd(act: Activity, placement: String, listener: LolShowListener? = null) {
|
|
||||||
if (act.isFinishing) return
|
|
||||||
LOLAdsInstDispatcher.getShower(act, placement, object : AdShowListener {
|
|
||||||
|
|
||||||
override fun onAdClicked() {
|
|
||||||
MyApp.app.isAdShowing.set(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAdClosed() {
|
|
||||||
MyApp.app.isAdShowing.set(false)
|
|
||||||
listener?.closed()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAdRewarded() {}
|
|
||||||
override fun onAdShowFailed(error: LolShowError?) {
|
|
||||||
MyApp.app.isAdShowing.set(false)
|
|
||||||
//广告show失败打点
|
|
||||||
// val map = mutableMapOf(Pair(AnalysisUtil.PARAM_VALUE, "${error?.msg}"))
|
|
||||||
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_SHOW_FAILED, map)
|
|
||||||
listener?.showFailed(error)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAdShown() {
|
|
||||||
MyApp.app.isAdShowing.set(true)
|
|
||||||
listener?.shown()
|
|
||||||
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_SHOWN)
|
|
||||||
if (placement != MyApp.Config.start_cold_int_auto) {
|
|
||||||
MyApp.app.lastAdDisplayTime.set(System.currentTimeMillis())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAfterClickClosed() {}
|
|
||||||
|
|
||||||
override fun onDelayClosed() {}
|
|
||||||
|
|
||||||
}).showAd()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,10 +4,19 @@ import android.content.ClipData
|
|||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.graphics.Color
|
||||||
import android.speech.tts.TextToSpeech
|
import android.speech.tts.TextToSpeech
|
||||||
import android.speech.tts.UtteranceProgressListener
|
import android.speech.tts.UtteranceProgressListener
|
||||||
|
import android.text.Spannable
|
||||||
|
import android.text.SpannableStringBuilder
|
||||||
|
import android.text.TextPaint
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
|
import android.text.method.LinkMovementMethod
|
||||||
|
import android.text.style.ClickableSpan
|
||||||
|
import android.text.style.UnderlineSpan
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.assimilate.alltrans.R
|
import com.assimilate.alltrans.R
|
||||||
import com.assimilate.alltrans.model.LanguagesConstants
|
import com.assimilate.alltrans.model.LanguagesConstants
|
||||||
@ -21,6 +30,55 @@ object MyTextTools {
|
|||||||
|
|
||||||
private lateinit var tts: TextToSpeech
|
private lateinit var tts: TextToSpeech
|
||||||
|
|
||||||
|
|
||||||
|
// 分割文本,添加下划线并让其可点击
|
||||||
|
fun makeWordsClickableWithUnderline(
|
||||||
|
textView: TextView,
|
||||||
|
text: String,
|
||||||
|
listener: OnWordClickListener?
|
||||||
|
) {
|
||||||
|
val spannableStringBuilder = SpannableStringBuilder(text)
|
||||||
|
|
||||||
|
val words = text.split(" ".toRegex()).dropLastWhile { it.isEmpty() }
|
||||||
|
.toTypedArray()
|
||||||
|
var start = 0
|
||||||
|
|
||||||
|
for (word in words) {
|
||||||
|
val end = start + word.length
|
||||||
|
spannableStringBuilder.setSpan(object : ClickableSpan() {
|
||||||
|
override fun onClick(widget: View) {
|
||||||
|
// Call the listener when the word is clicked
|
||||||
|
listener?.onWordClick(word)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateDrawState(ds: TextPaint) {
|
||||||
|
super.updateDrawState(ds)
|
||||||
|
ds.color = Color.BLUE // Change text color on click
|
||||||
|
ds.isUnderlineText = false // Remove default underline
|
||||||
|
}
|
||||||
|
}, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
|
|
||||||
|
// Apply underline span
|
||||||
|
spannableStringBuilder.setSpan(
|
||||||
|
UnderlineSpan(),
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
|
|
||||||
|
start = end + 1 // Move start position for next word
|
||||||
|
}
|
||||||
|
|
||||||
|
textView.text = spannableStringBuilder
|
||||||
|
textView.movementMethod = LinkMovementMethod.getInstance() // Enable clicks
|
||||||
|
}
|
||||||
|
// Interface for click listener
|
||||||
|
interface OnWordClickListener {
|
||||||
|
fun onWordClick(word: String?)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 添加历史
|
// 添加历史
|
||||||
fun addToHistory(context: Context, rText: String, transResult: String?) {
|
fun addToHistory(context: Context, rText: String, transResult: String?) {
|
||||||
val dbTranslation = DbTranslation(context)
|
val dbTranslation = DbTranslation(context)
|
||||||
|
|||||||
@ -88,7 +88,6 @@ class ScreenCaptureManager(private val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getImageReader(): ImageReader {
|
fun getImageReader(): ImageReader {
|
||||||
|
|
||||||
return imageReader
|
return imageReader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import android.text.Layout
|
|||||||
import android.text.StaticLayout
|
import android.text.StaticLayout
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import com.assimilate.alltrans.MyApp
|
||||||
import com.assimilate.alltrans.curview.GraphicOverlay
|
import com.assimilate.alltrans.curview.GraphicOverlay
|
||||||
import com.google.mlkit.vision.text.Text
|
import com.google.mlkit.vision.text.Text
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
@ -17,14 +18,19 @@ import kotlin.math.min
|
|||||||
class TextGraphic(
|
class TextGraphic(
|
||||||
overlay: GraphicOverlay?,
|
overlay: GraphicOverlay?,
|
||||||
private val text: Text,
|
private val text: Text,
|
||||||
private val shouldGroupTextInBlocks: Boolean,
|
|
||||||
private val showLanguageTag: Boolean,
|
|
||||||
private val showConfidence: Boolean,
|
|
||||||
private val textShow: Boolean,
|
private val textShow: Boolean,
|
||||||
private val needTrans: Boolean,
|
private val needTrans: Boolean,
|
||||||
private val fbFrom: String
|
private val fbFrom: String
|
||||||
) : GraphicOverlay.Graphic(overlay) {
|
) : GraphicOverlay.Graphic(overlay) {
|
||||||
|
|
||||||
|
private val shouldGroupRecognizedTextInBlocks: Boolean =
|
||||||
|
PreferenceUtils.shouldGroupRecognizedTextInBlocks(MyApp.applicationContext())
|
||||||
|
private val showLanguageTag: Boolean =
|
||||||
|
PreferenceUtils.showLanguageTag(MyApp.applicationContext())
|
||||||
|
private val showConfidence: Boolean =
|
||||||
|
PreferenceUtils.shouldShowTextConfidence(MyApp.applicationContext())
|
||||||
|
|
||||||
|
|
||||||
private val textPaint: TextPaint = TextPaint().apply {
|
private val textPaint: TextPaint = TextPaint().apply {
|
||||||
color = TEXT_COLOR
|
color = TEXT_COLOR
|
||||||
textSize = TEXT_SIZE
|
textSize = TEXT_SIZE
|
||||||
@ -39,16 +45,25 @@ class TextGraphic(
|
|||||||
MutableList(text.textBlocks.size) { !textShow }
|
MutableList(text.textBlocks.size) { !textShow }
|
||||||
private var isVisible: Boolean
|
private var isVisible: Boolean
|
||||||
|
|
||||||
|
private var isLoading: Boolean = false
|
||||||
|
|
||||||
|
// 翻译后的文本
|
||||||
|
private var translatedTextBlocks: List<String> = listOf()
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
isVisible = textShow
|
isVisible = textShow
|
||||||
|
|
||||||
if (needTrans) {
|
if (needTrans) {
|
||||||
|
isLoading = true
|
||||||
TranslationManager(text, fbFrom) { translatedTextPairs ->
|
TranslationManager(text, fbFrom) { translatedTextPairs ->
|
||||||
translatedTextBlocks = translatedTextPairs.map { it.first }
|
translatedTextBlocks = translatedTextPairs.map { it.first }
|
||||||
|
isLoading = false
|
||||||
// 可以同时打印原Text和翻译后的结果
|
// 可以同时打印原Text和翻译后的结果
|
||||||
translatedTextPairs.forEach { (translated, original) ->
|
translatedTextPairs.forEach { (translated, original) ->
|
||||||
Log.d("Translation", "Original: $original -> Translated: $translated")
|
Log.d("Translation", "Original: $original -> Translated: $translated")
|
||||||
}
|
}
|
||||||
|
|
||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,7 +71,6 @@ class TextGraphic(
|
|||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var translatedTextBlocks: List<String> = listOf()
|
|
||||||
|
|
||||||
override fun draw(canvas: Canvas) {
|
override fun draw(canvas: Canvas) {
|
||||||
if (!isVisible) return
|
if (!isVisible) return
|
||||||
@ -67,10 +81,26 @@ class TextGraphic(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun drawLoadingIndicator(textBlock: Text.TextBlock, canvas: Canvas) {
|
||||||
|
val rect = RectF(textBlock.boundingBox)
|
||||||
|
val centerX = (rect.left + rect.right) / 2
|
||||||
|
val centerY = (rect.top + rect.bottom) / 2
|
||||||
|
val radius = min(rect.width(), rect.height()) / 4
|
||||||
|
|
||||||
|
val paint = Paint().apply {
|
||||||
|
color = Color.BLUE
|
||||||
|
style = Paint.Style.STROKE
|
||||||
|
strokeWidth = 8f
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.drawCircle(centerX, centerY, radius, paint)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun drawTextBlock(textBlock: Text.TextBlock, canvas: Canvas, index: Int) {
|
private fun drawTextBlock(textBlock: Text.TextBlock, canvas: Canvas, index: Int) {
|
||||||
val translatedBlockText = translatedTextBlocks.getOrNull(index) ?: textBlock.text
|
val translatedBlockText = translatedTextBlocks.getOrNull(index) ?: textBlock.text
|
||||||
|
|
||||||
if (shouldGroupTextInBlocks) {
|
if (shouldGroupRecognizedTextInBlocks) {
|
||||||
val rect = RectF(textBlock.boundingBox)
|
val rect = RectF(textBlock.boundingBox)
|
||||||
drawText(
|
drawText(
|
||||||
getFormattedText(translatedBlockText, textBlock.recognizedLanguage, null),
|
getFormattedText(translatedBlockText, textBlock.recognizedLanguage, null),
|
||||||
@ -79,6 +109,9 @@ class TextGraphic(
|
|||||||
textPaint
|
textPaint
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
// if (isLoading) {
|
||||||
|
// drawLoadingIndicator(textBlock, canvas)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun contains(x: Float, y: Float): Boolean {
|
override fun contains(x: Float, y: Float): Boolean {
|
||||||
|
|||||||
@ -17,9 +17,6 @@ import com.google.mlkit.vision.text.TextRecognizerOptionsInterface
|
|||||||
class TextRecognitionProcessor(
|
class TextRecognitionProcessor(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
textRecognizerOptions: TextRecognizerOptionsInterface,
|
textRecognizerOptions: TextRecognizerOptionsInterface,
|
||||||
private val textShow:Boolean,
|
|
||||||
private val needTrans: Boolean,
|
|
||||||
private val fbFrom:String,
|
|
||||||
private val callback: TextRecognitionCallback? = null
|
private val callback: TextRecognitionCallback? = null
|
||||||
) : VisionProcessorBase<Text>(context) {
|
) : VisionProcessorBase<Text>(context) {
|
||||||
|
|
||||||
@ -29,10 +26,6 @@ class TextRecognitionProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val textRecognizer: TextRecognizer = TextRecognition.getClient(textRecognizerOptions)
|
private val textRecognizer: TextRecognizer = TextRecognition.getClient(textRecognizerOptions)
|
||||||
private val shouldGroupRecognizedTextInBlocks: Boolean =
|
|
||||||
PreferenceUtils.shouldGroupRecognizedTextInBlocks(context)
|
|
||||||
private val showLanguageTag: Boolean = PreferenceUtils.showLanguageTag(context)
|
|
||||||
private val showConfidence: Boolean = PreferenceUtils.shouldShowTextConfidence(context)
|
|
||||||
|
|
||||||
override fun stop() {
|
override fun stop() {
|
||||||
super.stop()
|
super.stop()
|
||||||
@ -44,30 +37,15 @@ 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))
|
||||||
graphicOverlay.add(
|
logExtrasForTesting(text)
|
||||||
TextGraphic(
|
|
||||||
graphicOverlay,
|
|
||||||
text,
|
|
||||||
shouldGroupRecognizedTextInBlocks,
|
|
||||||
showLanguageTag,
|
|
||||||
showConfidence,
|
|
||||||
textShow,
|
|
||||||
needTrans,
|
|
||||||
fbFrom
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
// 调用回调
|
// 调用回调
|
||||||
callback?.onTextRecognized(text,graphicOverlay)
|
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")
|
||||||
|
callback?.onTextFailure(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 推测最可能的语言
|
// 推测最可能的语言
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.assimilate.alltrans.common
|
|||||||
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.widget.Toast
|
||||||
import com.assimilate.alltrans.MyApp
|
import com.assimilate.alltrans.MyApp
|
||||||
import com.assimilate.alltrans.http.GoogleTranslator
|
import com.assimilate.alltrans.http.GoogleTranslator
|
||||||
import com.assimilate.alltrans.http.Translator
|
import com.assimilate.alltrans.http.Translator
|
||||||
@ -18,6 +19,8 @@ class TranslationManager(
|
|||||||
private val handler = Handler(Looper.getMainLooper())
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
private val executor = Executors.newSingleThreadExecutor()
|
private val executor = Executors.newSingleThreadExecutor()
|
||||||
private var translatedTextBlocks: MutableList<Pair<Int, String>> = mutableListOf()
|
private var translatedTextBlocks: MutableList<Pair<Int, String>> = mutableListOf()
|
||||||
|
private var errorShowed = false
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
prepareTranslation()
|
prepareTranslation()
|
||||||
@ -62,30 +65,45 @@ class TranslationManager(
|
|||||||
|
|
||||||
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?) {
|
||||||
|
handler.post {
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
translatedTextBlocks.add(Pair(index, result))
|
translatedTextBlocks.add(Pair(index, result))
|
||||||
} else {
|
} else {
|
||||||
translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
|
translatedTextBlocks.add(
|
||||||
|
Pair(
|
||||||
|
index,
|
||||||
|
text.textBlocks[index].text
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (translatedTextBlocks.size == text.textBlocks.size) {
|
if (translatedTextBlocks.size == text.textBlocks.size) {
|
||||||
handler.post {
|
|
||||||
callback(translatedTextBlocks.sortedBy { it.first }
|
callback(translatedTextBlocks.sortedBy { it.first }
|
||||||
.map { it.second to text.textBlocks[it.first].text })
|
.map { it.second to text.textBlocks[it.first].text })
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(errorMessage: String?) {
|
override fun onFailure(errorMessage: String?) {
|
||||||
|
handler.post {
|
||||||
translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
|
translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
|
||||||
if (translatedTextBlocks.size == text.textBlocks.size) {
|
if (translatedTextBlocks.size == text.textBlocks.size) {
|
||||||
handler.post {
|
|
||||||
callback(translatedTextBlocks.sortedBy { it.first }
|
callback(translatedTextBlocks.sortedBy { it.first }
|
||||||
.map { it.second to text.textBlocks[it.first].text })
|
.map { it.second to text.textBlocks[it.first].text })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!errorShowed) {
|
||||||
|
Toast.makeText(
|
||||||
|
MyApp.applicationContext(),
|
||||||
|
errorMessage,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
transFailEvent(errorMessage)
|
||||||
|
errorShowed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
transFailEvent(errorMessage)
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,7 @@ public class Widget {
|
|||||||
Animation.RELATIVE_TO_SELF, 0.5f, // 以自身中心X轴为缩放中心
|
Animation.RELATIVE_TO_SELF, 0.5f, // 以自身中心X轴为缩放中心
|
||||||
Animation.RELATIVE_TO_SELF, 0.5f // 以自身中心Y轴为缩放中心
|
Animation.RELATIVE_TO_SELF, 0.5f // 以自身中心Y轴为缩放中心
|
||||||
);
|
);
|
||||||
scaleAnimation.setDuration(700); // 动画持续时间,单位为毫秒
|
scaleAnimation.setDuration(900); // 动画持续时间,单位为毫秒
|
||||||
scaleAnimation.setFillAfter(true); // 动画结束后保持放大状态
|
scaleAnimation.setFillAfter(true); // 动画结束后保持放大状态
|
||||||
|
|
||||||
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
|
scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
|
||||||
|
|||||||
@ -117,35 +117,36 @@ class ControlView(private val context: Context) {
|
|||||||
listener?.onCopyClick()
|
listener?.onCopyClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvSusPhoto.setOnClickListener {
|
|
||||||
val intent = Intent(context, PhotoImageActivity::class.java)
|
|
||||||
intent.putExtra("key_start_ph", "hover")
|
|
||||||
val pendingIntent = PendingIntent.getActivity(
|
|
||||||
context,
|
|
||||||
0,
|
|
||||||
intent,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
||||||
)
|
|
||||||
pendingIntent.send()
|
|
||||||
removeControlView()
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.tvSusDistrict.setOnClickListener {
|
binding.tvSusDistrict.setOnClickListener {
|
||||||
binding.susControlRoot.visibility = View.GONE
|
binding.susControlRoot.visibility = View.GONE
|
||||||
Log.d("ControlViewManager", "District translation clicked")
|
Log.d("ControlViewManager", "District translation clicked")
|
||||||
listener?.onDistrictClick()
|
listener?.onDistrictClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.ivSusHome.setOnClickListener {
|
binding.tvSusPhoto.setOnClickListener {
|
||||||
Log.d("ControlViewManager", "Home clicked")
|
val intentPh = Intent(context, PhotoImageActivity::class.java)
|
||||||
val intent = Intent(context, MainActivity::class.java)
|
intentPh.putExtra("sus_ph", "sus_ph")
|
||||||
val pendingIntent = PendingIntent.getActivity(
|
val pendingIntent = PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
0,
|
0,
|
||||||
intent,
|
intentPh,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
pendingIntent.send()
|
pendingIntent.send()
|
||||||
|
removeControlView()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivSusHome.setOnClickListener {
|
||||||
|
val intentHome = Intent(context, MainActivity::class.java)
|
||||||
|
intentHome.putExtra("sus_home","sus_home")
|
||||||
|
val pendingIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
intentHome,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
pendingIntent.send()
|
||||||
|
removeControlView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,22 +1,25 @@
|
|||||||
package com.assimilate.alltrans.curview
|
package com.assimilate.alltrans.curview
|
||||||
|
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.PixelFormat
|
import android.graphics.PixelFormat
|
||||||
import android.media.Image
|
import android.media.Image
|
||||||
import android.media.ImageReader
|
import android.media.ImageReader
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.text.TextUtils
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import com.assimilate.alltrans.R
|
||||||
|
import com.assimilate.alltrans.common.MyTextTools
|
||||||
|
import com.assimilate.alltrans.common.TextGraphic
|
||||||
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.android.material.snackbar.Snackbar
|
||||||
import com.google.mlkit.vision.text.Text
|
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
|
||||||
@ -39,7 +42,7 @@ class CopyTextView(private val context: Context) :
|
|||||||
// 这里还需要调整
|
// 这里还需要调整
|
||||||
imageProcessor = TextRecognitionProcessor(
|
imageProcessor = TextRecognitionProcessor(
|
||||||
context,
|
context,
|
||||||
ChineseTextRecognizerOptions.Builder().build(), true, false, "", this
|
ChineseTextRecognizerOptions.Builder().build(), this
|
||||||
)
|
)
|
||||||
|
|
||||||
val inflater = LayoutInflater.from(context)
|
val inflater = LayoutInflater.from(context)
|
||||||
@ -68,9 +71,8 @@ class CopyTextView(private val context: Context) :
|
|||||||
removeView()
|
removeView()
|
||||||
}
|
}
|
||||||
binding?.btSusCopyAll?.setOnClickListener {
|
binding?.btSusCopyAll?.setOnClickListener {
|
||||||
|
MyTextTools.copyToClipboard(context, recognizedText.toString())
|
||||||
|
|
||||||
Log.d("gdsfsfsadf", recognizedText.toString())
|
|
||||||
copyToClipboard(recognizedText.toString())
|
|
||||||
// removeView()
|
// removeView()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +126,6 @@ class CopyTextView(private val context: Context) :
|
|||||||
|
|
||||||
imageProcessor!!.processBitmap(bitmap, binding?.susGraphicOverlay)
|
imageProcessor!!.processBitmap(bitmap, binding?.susGraphicOverlay)
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.e(
|
Log.e(
|
||||||
"SusService",
|
"SusService",
|
||||||
@ -136,29 +137,19 @@ class CopyTextView(private val context: Context) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onTextRecognized(text: Text, graphicOverlay: GraphicOverlay) {
|
override fun onTextRecognized(text: Text, graphicOverlay: GraphicOverlay) {
|
||||||
recognizedText = text.text
|
recognizedText = text.text
|
||||||
|
graphicOverlay.add(
|
||||||
|
TextGraphic(
|
||||||
|
graphicOverlay,
|
||||||
|
text, true, false, ""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTextFailure(e: Exception) {
|
override fun onTextFailure(e: Exception) {
|
||||||
Log.d("copy_", e.toString())
|
// Log.d("copy_", e.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
// 复制到粘贴板
|
|
||||||
private fun copyToClipboard(text: String?) {
|
|
||||||
val tip = "Copied to clipboard!"
|
|
||||||
val tipNull = "Text is null!"
|
|
||||||
if (!TextUtils.isEmpty(text)) {
|
|
||||||
val clipboardManager =
|
|
||||||
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
|
||||||
val clipData = ClipData.newPlainText("targetValue", text)
|
|
||||||
clipboardManager.setPrimaryClip(clipData)
|
|
||||||
Toast.makeText(context, tip, Toast.LENGTH_SHORT).show()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(context, tipNull, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ 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.common.Logger
|
import com.assimilate.alltrans.common.Logger
|
||||||
|
import com.assimilate.alltrans.common.MyTextTools
|
||||||
import com.assimilate.alltrans.databinding.LayoutSusDistrictBinding
|
import com.assimilate.alltrans.databinding.LayoutSusDistrictBinding
|
||||||
import com.assimilate.alltrans.http.GoogleTranslator
|
import com.assimilate.alltrans.http.GoogleTranslator
|
||||||
import com.assimilate.alltrans.http.Translator
|
import com.assimilate.alltrans.http.Translator
|
||||||
@ -63,7 +64,10 @@ class DistrictView(
|
|||||||
} else {
|
} else {
|
||||||
WindowManager.LayoutParams.TYPE_PHONE
|
WindowManager.LayoutParams.TYPE_PHONE
|
||||||
},
|
},
|
||||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR,
|
||||||
PixelFormat.TRANSLUCENT
|
PixelFormat.TRANSLUCENT
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -128,6 +132,48 @@ class DistrictView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initDistrictClick() {
|
private fun initDistrictClick() {
|
||||||
|
bindingSusDistrict.ivSourceTts.setOnClickListener {
|
||||||
|
val lanSourceCode = LanguagesConstants.getInstance().getLanguageCodeByLanguage(
|
||||||
|
PreferenceLanguageUtils.getString("language_source"),
|
||||||
|
MyApp.applicationContext()
|
||||||
|
)
|
||||||
|
MyTextTools.ttsReadText(
|
||||||
|
bindingSusDistrict.tvTrSource.text.toString(), lanSourceCode, context
|
||||||
|
)
|
||||||
|
}
|
||||||
|
bindingSusDistrict.ivTrCopy.setOnClickListener {
|
||||||
|
MyTextTools.copyToClipboard(context, bindingSusDistrict.tvTrTarget.text.toString())
|
||||||
|
}
|
||||||
|
bindingSusDistrict.ivTrTargetDic.setOnClickListener {
|
||||||
|
if (bindingSusDistrict.tvTrTarget.text.toString().isNotEmpty()) {
|
||||||
|
MyTextTools.makeWordsClickableWithUnderline(
|
||||||
|
bindingSusDistrict.tvTrTarget,
|
||||||
|
bindingSusDistrict.tvTrTarget.text.toString(),
|
||||||
|
object : MyTextTools.OnWordClickListener {
|
||||||
|
override fun onWordClick(word: String?) {
|
||||||
|
Log.d("gvsdacd", "$word is clicked")
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// bindingSusDistrict.ivTrTargetShare.setOnClickListener {
|
||||||
|
// MyTextTools.shareText(
|
||||||
|
// context,
|
||||||
|
// bindingSusDistrict.tvTrTarget.text.toString()
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
bindingSusDistrict.ivTargetTts.setOnClickListener {
|
||||||
|
val lanTargetCode = LanguagesConstants.getInstance().getLanguageCodeByLanguage(
|
||||||
|
PreferenceLanguageUtils.getString("language_target"),
|
||||||
|
MyApp.applicationContext()
|
||||||
|
)
|
||||||
|
|
||||||
|
MyTextTools.ttsReadText(
|
||||||
|
bindingSusDistrict.tvTrTarget.text.toString(), lanTargetCode, context
|
||||||
|
)
|
||||||
|
}
|
||||||
bindingSusDistrict.ivTrCollect.setOnClickListener { addCollect() }
|
bindingSusDistrict.ivTrCollect.setOnClickListener { addCollect() }
|
||||||
bindingSusDistrict.ivSourceClear.setOnClickListener {
|
bindingSusDistrict.ivSourceClear.setOnClickListener {
|
||||||
bindingSusDistrict.tvTrSource.text = ""
|
bindingSusDistrict.tvTrSource.text = ""
|
||||||
@ -205,9 +251,11 @@ class DistrictView(
|
|||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
if (!result.isNullOrEmpty()) {
|
if (!result.isNullOrEmpty()) {
|
||||||
bindingSusDistrict.tvTrTarget.text = result
|
bindingSusDistrict.tvTrTarget.text = result
|
||||||
|
|
||||||
} else if (!errorMessage.isNullOrEmpty()) {
|
} else if (!errorMessage.isNullOrEmpty()) {
|
||||||
Log.e("TranslationError", errorMessage)
|
Log.e("TranslationError", errorMessage)
|
||||||
bindingSusDistrict.tvTrTarget.text = "Translation error: $errorMessage"
|
bindingSusDistrict.tvTrTarget.text = "Translation error: $errorMessage"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,6 +267,7 @@ class DistrictView(
|
|||||||
"district" + errorMessage.toString()
|
"district" + errorMessage.toString()
|
||||||
)
|
)
|
||||||
bindingSusDistrict.tvTrTarget.text = "Translation failed: $errorMessage"
|
bindingSusDistrict.tvTrTarget.text = "Translation failed: $errorMessage"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -21,12 +21,13 @@ import com.assimilate.alltrans.R
|
|||||||
import com.assimilate.alltrans.common.TextGraphic
|
import com.assimilate.alltrans.common.TextGraphic
|
||||||
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.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
|
||||||
|
|
||||||
class FloatingView(
|
class FloatingView(
|
||||||
private val context: Context
|
private val context: Context
|
||||||
) {
|
) : TextRecognitionProcessor.TextRecognitionCallback {
|
||||||
|
|
||||||
private var isAttachedToWindow = false
|
private var isAttachedToWindow = false
|
||||||
private var imageProcessor: VisionImageProcessor? = null
|
private var imageProcessor: VisionImageProcessor? = null
|
||||||
@ -57,7 +58,7 @@ class FloatingView(
|
|||||||
// 初始化语言识别
|
// 初始化语言识别
|
||||||
imageProcessor = TextRecognitionProcessor(
|
imageProcessor = TextRecognitionProcessor(
|
||||||
context,
|
context,
|
||||||
ChineseTextRecognizerOptions.Builder().build(), false, true, "float"
|
ChineseTextRecognizerOptions.Builder().build(), this
|
||||||
)
|
)
|
||||||
|
|
||||||
graphicOverlay = GraphicOverlay(context, null)
|
graphicOverlay = GraphicOverlay(context, null)
|
||||||
@ -159,13 +160,20 @@ class FloatingView(
|
|||||||
hasCapturedScreenshot = false
|
hasCapturedScreenshot = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (graphicOverlay?.isAttachedToWindow == true) {
|
||||||
try {
|
try {
|
||||||
windowManager.removeView(graphicOverlay)
|
windowManager.removeView(graphicOverlay)
|
||||||
windowManager.updateViewLayout(imageView, params)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
Log.e("FloatingView", "View not attached to window manager", e)
|
Log.e("FloatingView", "View not attached to window manager", e)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Log.e(
|
||||||
|
"FloatingView",
|
||||||
|
"Attempted to remove a view that is not attached to the window manager"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
windowManager.updateViewLayout(imageView, params)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,4 +375,17 @@ class FloatingView(
|
|||||||
windowManager.addView(graphicOverlay, fullScreenParams)
|
windowManager.addView(graphicOverlay, fullScreenParams)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onTextRecognized(text: Text, graphicOverlay: GraphicOverlay) {
|
||||||
|
graphicOverlay.add(
|
||||||
|
TextGraphic(
|
||||||
|
graphicOverlay,
|
||||||
|
text,
|
||||||
|
false, true, "float"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextFailure(e: Exception) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,14 +11,16 @@ import android.view.Gravity
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import com.assimilate.alltrans.common.TextGraphic
|
||||||
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.LayoutSusGlobalBinding
|
import com.assimilate.alltrans.databinding.LayoutSusGlobalBinding
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
class GlobalView(private val context: Context) {
|
class GlobalView(private val context: Context) : TextRecognitionProcessor.TextRecognitionCallback {
|
||||||
|
|
||||||
private var imageProcessor: VisionImageProcessor? = null
|
private var imageProcessor: VisionImageProcessor? = null
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ class GlobalView(private val context: Context) {
|
|||||||
// 这里还需要调整
|
// 这里还需要调整
|
||||||
imageProcessor = TextRecognitionProcessor(
|
imageProcessor = TextRecognitionProcessor(
|
||||||
context,
|
context,
|
||||||
ChineseTextRecognizerOptions.Builder().build(), true, true, "global"
|
ChineseTextRecognizerOptions.Builder().build(), this
|
||||||
)
|
)
|
||||||
bindingSubGlobal = LayoutSusGlobalBinding.inflate(LayoutInflater.from(context))
|
bindingSubGlobal = LayoutSusGlobalBinding.inflate(LayoutInflater.from(context))
|
||||||
globalView = bindingSubGlobal.root
|
globalView = bindingSubGlobal.root
|
||||||
@ -125,5 +127,18 @@ class GlobalView(private val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onTextRecognized(text: Text, graphicOverlay: GraphicOverlay) {
|
||||||
|
graphicOverlay.add(
|
||||||
|
TextGraphic(
|
||||||
|
graphicOverlay,
|
||||||
|
text,
|
||||||
|
true, true, "global"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextFailure(e: Exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -297,7 +297,6 @@ public class GraphicOverlay extends View {
|
|||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas) {
|
protected void onDraw(Canvas canvas) {
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
|
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
updateTransformationIfNeeded();
|
updateTransformationIfNeeded();
|
||||||
|
|
||||||
|
|||||||
@ -12,12 +12,8 @@ import android.view.ViewGroup
|
|||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.assimilate.alltrans.MyApp
|
|
||||||
import com.assimilate.alltrans.R
|
import com.assimilate.alltrans.R
|
||||||
import com.assimilate.alltrans.common.CurrentActivityHolder
|
|
||||||
import com.assimilate.alltrans.common.LolAdWrapper
|
|
||||||
import com.assimilate.alltrans.databinding.LayoutSusSelectBinding
|
import com.assimilate.alltrans.databinding.LayoutSusSelectBinding
|
||||||
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
|
|
||||||
|
|
||||||
class SelectionView(private val context: Context) {
|
class SelectionView(private val context: Context) {
|
||||||
private lateinit var binding: LayoutSusSelectBinding
|
private lateinit var binding: LayoutSusSelectBinding
|
||||||
@ -51,7 +47,10 @@ class SelectionView(private val context: Context) {
|
|||||||
} else {
|
} else {
|
||||||
WindowManager.LayoutParams.TYPE_PHONE
|
WindowManager.LayoutParams.TYPE_PHONE
|
||||||
},
|
},
|
||||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR,
|
||||||
PixelFormat.TRANSLUCENT
|
PixelFormat.TRANSLUCENT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ object PreferenceLanguageUtils {
|
|||||||
private const val KEY_RECENT_LANGUAGES = "recent_languages"
|
private const val KEY_RECENT_LANGUAGES = "recent_languages"
|
||||||
private const val MAX_RECENT_LANGUAGES = 5
|
private const val MAX_RECENT_LANGUAGES = 5
|
||||||
private const val PREF_KEY_FIRST_TIME = "first_time"
|
private const val PREF_KEY_FIRST_TIME = "first_time"
|
||||||
|
private const val PREF_KEY_FIRST_ALLOW = "first_allow"
|
||||||
private val LANGUAGE_LIST_TYPE = object : TypeToken<List<Language>>() {}.type
|
private val LANGUAGE_LIST_TYPE = object : TypeToken<List<Language>>() {}.type
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
@ -85,4 +86,19 @@ object PreferenceLanguageUtils {
|
|||||||
fun setNotFirstTime() {
|
fun setNotFirstTime() {
|
||||||
getSharedPreferences().edit().putBoolean(PREF_KEY_FIRST_TIME, false).apply()
|
getSharedPreferences().edit().putBoolean(PREF_KEY_FIRST_TIME, false).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 检查是否是第一次进入应用
|
||||||
|
fun isFirstAllow(): Boolean {
|
||||||
|
return getSharedPreferences().getBoolean(PREF_KEY_FIRST_ALLOW, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置已经不是第一次进入应用了
|
||||||
|
fun setNotFirstAllow() {
|
||||||
|
getSharedPreferences().edit().putBoolean(PREF_KEY_FIRST_ALLOW, false).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,86 +1,310 @@
|
|||||||
package com.assimilate.alltrans.viewui
|
package com.assimilate.alltrans.viewui
|
||||||
|
|
||||||
import android.os.AsyncTask
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Button
|
import android.view.View
|
||||||
import android.widget.EditText
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.TextView
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import android.webkit.WebChromeClient
|
||||||
|
import android.webkit.WebResourceError
|
||||||
|
import android.webkit.WebResourceRequest
|
||||||
|
import android.webkit.WebView
|
||||||
|
import android.webkit.WebViewClient
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.OnBackPressedCallback
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.widget.PopupMenu
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import com.assimilate.alltrans.MyApp
|
||||||
import com.assimilate.alltrans.R
|
import com.assimilate.alltrans.R
|
||||||
import org.json.JSONArray
|
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
|
||||||
import org.json.JSONException
|
import com.assimilate.alltrans.common.LolAdWrapper
|
||||||
import java.io.BufferedReader
|
import com.assimilate.alltrans.databinding.ActivityDicBinding
|
||||||
import java.io.InputStreamReader
|
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
|
||||||
import java.net.HttpURLConnection
|
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
|
||||||
import java.net.URL
|
import java.util.Locale
|
||||||
|
|
||||||
class DicActivity : AppCompatActivity() {
|
class DicActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var editTextWord: EditText
|
private lateinit var binding: ActivityDicBinding
|
||||||
private lateinit var buttonSearch: Button
|
private var isWikiIng = false
|
||||||
private lateinit var textViewDefinition: TextView
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_dic)
|
binding = ActivityDicBinding.inflate(layoutInflater)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(binding.root)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.dic_root)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
|
||||||
editTextWord = findViewById(R.id.editTextWord)
|
// 初始化ProgressBar
|
||||||
buttonSearch = findViewById(R.id.buttonSearch)
|
binding.wikiProgressBar.visibility = View.GONE
|
||||||
textViewDefinition = findViewById(R.id.textViewDefinition)
|
adLoad(MyApp.Config.directory_int_auto)
|
||||||
|
|
||||||
buttonSearch.setOnClickListener {
|
intiClick()
|
||||||
val word = editTextWord.text.toString().trim()
|
backPressedCall()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun intiClick() {
|
||||||
|
binding.ivDicMore.setOnClickListener {
|
||||||
|
// 创建 PopupMenu
|
||||||
|
val popupMenu = PopupMenu(this, it)
|
||||||
|
// 关联菜单资源文件
|
||||||
|
popupMenu.menuInflater.inflate(R.menu.popup_menu, popupMenu.menu)
|
||||||
|
// 设置菜单项点击事件
|
||||||
|
popupMenu.setOnMenuItemClickListener { menuItem ->
|
||||||
|
when (menuItem.itemId) {
|
||||||
|
R.id.action_one -> {
|
||||||
|
|
||||||
|
if (binding.editTextWord.text.toString().isNotEmpty()) {
|
||||||
|
val url = generateWiktionaryUrl(binding.editTextWord.text.toString())
|
||||||
|
// 创建Intent
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||||||
|
data = Uri.parse(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动浏览器
|
||||||
|
startActivity(intent)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.dic_et, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理第一个菜单项的点击事件
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示 PopupMenu
|
||||||
|
popupMenu.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.editTextWord.setOnEditorActionListener { _, actionId, _ ->
|
||||||
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
|
// 隐藏键盘
|
||||||
|
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
imm.hideSoftInputFromWindow(binding.editTextWord.windowToken, 0)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivDicBack.setOnClickListener {
|
||||||
|
showInstAdFromCache(MyApp.Config.directory_int_auto)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
binding.buttonSearch.setOnClickListener {
|
||||||
|
val word = binding.editTextWord.text.toString().trim()
|
||||||
if (word.isNotEmpty()) {
|
if (word.isNotEmpty()) {
|
||||||
FetchDefinitionTask().execute(word)
|
if (!isWikiIng) {
|
||||||
|
getWeb(word)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.dic_wikiing, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.dic_et, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
FirebaseAnalyticsHelper.directoryTransClickEvent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class FetchDefinitionTask : AsyncTask<String, Void, String?>() {
|
|
||||||
override fun doInBackground(vararg params: String): String? {
|
private fun backPressedCall() {
|
||||||
val word = params[0]
|
val callback = object : OnBackPressedCallback(true) {
|
||||||
val apiUrl = "https://api.dictionaryapi.dev/api/v2/entries/en/$word"
|
override fun handleOnBackPressed() {
|
||||||
return try {
|
showInstAdFromCache(MyApp.Config.directory_int_auto)
|
||||||
val url = URL(apiUrl)
|
finish()
|
||||||
val urlConnection = url.openConnection() as HttpURLConnection
|
|
||||||
urlConnection.requestMethod = "GET"
|
|
||||||
val responseCode = urlConnection.responseCode
|
|
||||||
if (responseCode == HttpURLConnection.HTTP_OK) {
|
|
||||||
val inputStream = BufferedReader(InputStreamReader(urlConnection.inputStream))
|
|
||||||
val response = StringBuilder()
|
|
||||||
var inputLine: String?
|
|
||||||
while (inputStream.readLine().also { inputLine = it } != null) {
|
|
||||||
response.append(inputLine)
|
|
||||||
}
|
}
|
||||||
inputStream.close()
|
|
||||||
response.toString()
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
onBackPressedDispatcher.addCallback(this, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getWeb(word: String) {
|
||||||
|
// 显示 ProgressBar
|
||||||
|
binding.wikiProgressBar.visibility = View.VISIBLE
|
||||||
|
isWikiIng = true
|
||||||
|
// 创建 WebView 实例并配置
|
||||||
|
val webView = createConfiguredWebView()
|
||||||
|
|
||||||
|
// 设置 WebView 浏览器客户端
|
||||||
|
webView.webViewClient = object : WebViewClient() {
|
||||||
|
override fun onPageFinished(view: WebView?, url: String?) {
|
||||||
|
super.onPageFinished(view, url)
|
||||||
|
// 注入 JavaScript 隐藏指定区域
|
||||||
|
injectJavaScript(view)
|
||||||
|
// 加载完成后隐藏 ProgressBar
|
||||||
|
binding.wikiProgressBar.visibility = View.GONE
|
||||||
|
isWikiIng = false
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onReceivedError(
|
||||||
|
view: WebView?,
|
||||||
|
request: WebResourceRequest?,
|
||||||
|
error: WebResourceError?
|
||||||
|
) {
|
||||||
|
super.onReceivedError(view, request, error)
|
||||||
|
// 加载失败后隐藏 ProgressBar
|
||||||
|
binding.wikiProgressBar.visibility = View.GONE
|
||||||
|
isWikiIng = false
|
||||||
|
FirebaseAnalyticsHelper.directoryTransResultEvent(
|
||||||
|
MyApp.Config.FAIL_REASON,
|
||||||
|
error.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
webView.webChromeClient = WebChromeClient()
|
||||||
|
|
||||||
|
// 设置 WebView 布局参数并添加到视图中
|
||||||
|
val params = FrameLayout.LayoutParams(
|
||||||
|
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
)
|
||||||
|
webView.layoutParams = params
|
||||||
|
binding.toUrl.addView(webView)
|
||||||
|
// 加载指定的 URL
|
||||||
|
webView.loadUrl(generateWiktionaryUrl(word))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建并配置 WebView
|
||||||
|
private fun createConfiguredWebView(): WebView {
|
||||||
|
val webView = WebView(this)
|
||||||
|
val settings = webView.settings
|
||||||
|
|
||||||
|
settings.loadsImagesAutomatically = true
|
||||||
|
settings.javaScriptEnabled = true
|
||||||
|
settings.domStorageEnabled = true
|
||||||
|
WebView.setWebContentsDebuggingEnabled(false)
|
||||||
|
|
||||||
|
return webView
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注入 JavaScript 脚本隐藏指定区域
|
||||||
|
private fun injectJavaScript(view: WebView?) {
|
||||||
|
view?.loadUrl(
|
||||||
|
"""
|
||||||
|
javascript:(function() {
|
||||||
|
|
||||||
|
var mainTitle = document.getElementById('firstHeading');
|
||||||
|
if (mainTitle) {
|
||||||
|
mainTitle.style.color = 'rgb(16, 171, 251)';
|
||||||
|
mainTitle.style.fontWeight = 'bold';
|
||||||
|
mainTitle.style.fontSize = '43px';
|
||||||
|
}
|
||||||
|
|
||||||
|
var bodyContent = document.getElementById('bodyContent');
|
||||||
|
if (bodyContent) {
|
||||||
|
bodyContent.style.marginBottom = '55px';
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.getElementsByClassName('minerva-header');
|
||||||
|
if (header.length > 0) {
|
||||||
|
header[0].style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
var footer = document.getElementsByClassName('post-content footer-content');
|
||||||
|
if (footer.length > 0) {
|
||||||
|
footer[0].style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
var minerva_footer = document.getElementsByClassName('mw-footer minerva-footer');
|
||||||
|
if (minerva_footer.length > 0) {
|
||||||
|
minerva_footer[0].style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
var last_modified_bar = document.getElementsByClassName('post-content last-modified-bar__content');
|
||||||
|
if (last_modified_bar.length > 0) {
|
||||||
|
last_modified_bar[0].style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
var actionsMenu = document.getElementsByClassName('page-actions-menu');
|
||||||
|
if (actionsMenu.length > 0) {
|
||||||
|
actionsMenu[0].style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
var editSections = document.getElementsByClassName('mw-editsection');
|
||||||
|
for (var i = 0; i < editSections.length; i++) {
|
||||||
|
editSections[i].style.display = 'none';
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateWiktionaryUrl(word: String?): String {
|
||||||
|
// 检查传入的字符串是否为空或null
|
||||||
|
if (word.isNullOrBlank()) {
|
||||||
|
throw IllegalArgumentException("Word cannot be null or blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
val language = try {
|
||||||
|
// 获取本地语言,若获取失败则抛出异常
|
||||||
|
Locale.getDefault().language
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
throw RuntimeException("Unable to retrieve the default language", e)
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPostExecute(result: String?) {
|
val lowerCaseWord = try {
|
||||||
if (result != null) {
|
// 将传入字符串转换为小写,若转换失败则抛出异常
|
||||||
try {
|
word.lowercase(Locale.ROOT)
|
||||||
val jsonArray = JSONArray(result)
|
} catch (e: Exception) {
|
||||||
val jsonObject = jsonArray.getJSONObject(0)
|
throw RuntimeException("Unable to convert word to lowercase", e)
|
||||||
val meanings = jsonObject.getJSONArray("meanings")
|
|
||||||
val meaning = meanings.getJSONObject(0)
|
|
||||||
val definitions = meaning.getJSONArray("definitions")
|
|
||||||
val definition = definitions.getJSONObject(0)
|
|
||||||
val definitionText = definition.getString("definition")
|
|
||||||
textViewDefinition.text = definitionText
|
|
||||||
} catch (e: JSONException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
textViewDefinition.text = "Error parsing definition"
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
textViewDefinition.text = "Definition not found"
|
return "https://$language.m.wiktionary.org/wiki/$lowerCaseWord"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun adLoad(place: String) {
|
||||||
|
// 加载广告
|
||||||
|
LolAdWrapper.shared.loadAdIfNotCached(
|
||||||
|
this,
|
||||||
|
place,
|
||||||
|
object : LolAdWrapper.LoLLoadListener {
|
||||||
|
override fun loadFailed(error: LolLoadError?) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun loaded() {
|
||||||
|
// 处理加载成功
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showInstAdFromCache(place: String) {
|
||||||
|
// 如果需要立刻展示广告,可以调用展示方法
|
||||||
|
LolAdWrapper.shared.showAdIfCached(
|
||||||
|
this,
|
||||||
|
place,
|
||||||
|
object : LolAdWrapper.LolShowListener {
|
||||||
|
override fun shown() {
|
||||||
|
// 处理广告展示成功
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun showFailed(error: LolShowError?) {
|
||||||
|
// 处理广告展示失败
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun closed() {
|
||||||
|
// 处理广告关闭
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,16 +121,22 @@ class LanguageChangeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleLanguageSelection(language: Language) {
|
private fun handleLanguageSelection(language: Language) {
|
||||||
Log.d("LanguageChange", language.language)
|
// Log.d("LanguageChange", language.language)
|
||||||
if (lastTranslateLanguage) {
|
if (lastTranslateLanguage) {
|
||||||
PreferenceLanguageUtils.putString("language_target", language.language)
|
PreferenceLanguageUtils.putString("language_target", language.language)
|
||||||
|
|
||||||
|
FirebaseAnalyticsHelper.languageChooseEvent(
|
||||||
|
MyApp.Config.LAN_TARGET,
|
||||||
|
"target_${language.language}"
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
PreferenceLanguageUtils.putString("language_source", language.language)
|
PreferenceLanguageUtils.putString("language_source", language.language)
|
||||||
}
|
|
||||||
FirebaseAnalyticsHelper.languageChooseEvent(
|
FirebaseAnalyticsHelper.languageChooseEvent(
|
||||||
MyApp.Config.CLICK_FROM,
|
MyApp.Config.LAN_SOURCE,
|
||||||
if (lastTranslateLanguage) "target_${language.language}" else "source_${language.language}"
|
"source_${language.language}"
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
FirebaseAnalyticsHelper.languageFromEvent(
|
FirebaseAnalyticsHelper.languageFromEvent(
|
||||||
MyApp.Config.CLICK_FROM,
|
MyApp.Config.CLICK_FROM,
|
||||||
if (lastTranslateLanguage) "home_target" else "home_source"
|
if (lastTranslateLanguage) "home_target" else "home_source"
|
||||||
|
|||||||
@ -34,6 +34,7 @@ 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
|
import com.google.mlkit.nl.languageid.LanguageIdentification
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@ -100,6 +101,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
Widget.makeToast(this, "To allow floating windows for quick translation.")
|
Widget.makeToast(this, "To allow floating windows for quick translation.")
|
||||||
}
|
}
|
||||||
} else if (requestCode == REQUEST_CODE_MEDIA_PROJECTION) {
|
} else if (requestCode == REQUEST_CODE_MEDIA_PROJECTION) {
|
||||||
|
// 第一次授权后将正常走hot
|
||||||
|
MyApp.app.isFirstPremisiton = false
|
||||||
// 处理mediaProjectionManager权限请求结果
|
// 处理mediaProjectionManager权限请求结果
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
serverIsStart = true
|
serverIsStart = true
|
||||||
@ -128,10 +131,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun initView(){
|
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()
|
||||||
@ -156,7 +160,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun initClick() {
|
private fun initClick() {
|
||||||
binding.tvMainDic.setOnClickListener {
|
binding.tvMainDic.setOnClickListener {
|
||||||
// startActivity(Intent(this,DicActivity::class.java))
|
startActivity(Intent(this, DicActivity::class.java))
|
||||||
|
FirebaseAnalyticsHelper.directoryClickEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvMainPhotoTrans.setOnClickListener {
|
binding.tvMainPhotoTrans.setOnClickListener {
|
||||||
@ -206,6 +211,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
binding.ivQuickStart.setOnClickListener {
|
binding.ivQuickStart.setOnClickListener {
|
||||||
|
|
||||||
if (!serverIsStart) {
|
if (!serverIsStart) {
|
||||||
// 检查并请求悬浮窗权限
|
// 检查并请求悬浮窗权限
|
||||||
if (!Settings.canDrawOverlays(this)) {
|
if (!Settings.canDrawOverlays(this)) {
|
||||||
@ -214,6 +220,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
Uri.parse("package:$packageName")
|
Uri.parse("package:$packageName")
|
||||||
)
|
)
|
||||||
startActivityForResult(intent, REQUEST_CODE_OVERLAY)
|
startActivityForResult(intent, REQUEST_CODE_OVERLAY)
|
||||||
|
MyApp.app.isFirstPremisiton = true
|
||||||
} else {
|
} else {
|
||||||
FirebaseAnalyticsHelper.hoverLimitAgreeEvent()
|
FirebaseAnalyticsHelper.hoverLimitAgreeEvent()
|
||||||
checkAndRequestMediaProjectionPermission()
|
checkAndRequestMediaProjectionPermission()
|
||||||
@ -283,6 +290,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkAndRequestMediaProjectionPermission() {
|
private fun checkAndRequestMediaProjectionPermission() {
|
||||||
|
|
||||||
// 启动截图
|
// 启动截图
|
||||||
startActivityForResult(
|
startActivityForResult(
|
||||||
mediaProjectionManager.createScreenCaptureIntent(),
|
mediaProjectionManager.createScreenCaptureIntent(),
|
||||||
@ -427,7 +435,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reconText(text:String){
|
private fun reconText(text: String) {
|
||||||
val languageIdentifier = LanguageIdentification.getClient()
|
val languageIdentifier = LanguageIdentification.getClient()
|
||||||
languageIdentifier.identifyLanguage(text)
|
languageIdentifier.identifyLanguage(text)
|
||||||
.addOnSuccessListener { languageCode ->
|
.addOnSuccessListener { languageCode ->
|
||||||
@ -436,9 +444,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.i("dsafdsf", "Language: $languageCode")
|
Log.i("dsafdsf", "Language: $languageCode")
|
||||||
val lan = LanguagesConstants.getInstance().getLanguageByLanguageCode(languageCode,this)
|
val lan = LanguagesConstants.getInstance()
|
||||||
PreferenceLanguageUtils.putString("language_source",lan.language)
|
.getLanguageByLanguageCode(languageCode, this)
|
||||||
binding.chSourceLanguage.text = PreferenceLanguageUtils.getString("language_source")
|
PreferenceLanguageUtils.putString("language_source", lan.language)
|
||||||
|
binding.chSourceLanguage.text =
|
||||||
|
PreferenceLanguageUtils.getString("language_source")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.addOnFailureListener {
|
.addOnFailureListener {
|
||||||
|
|||||||
@ -37,16 +37,19 @@ import com.assimilate.alltrans.adapters.LanguageAdapter
|
|||||||
import com.assimilate.alltrans.common.BitmapUtils
|
import com.assimilate.alltrans.common.BitmapUtils
|
||||||
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.TextGraphic
|
||||||
import com.assimilate.alltrans.model.Language
|
import com.assimilate.alltrans.model.Language
|
||||||
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.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.common.Widget
|
import com.assimilate.alltrans.common.Widget
|
||||||
|
import com.assimilate.alltrans.curview.GraphicOverlay
|
||||||
import com.assimilate.alltrans.databinding.ActivityStillImageBinding
|
import com.assimilate.alltrans.databinding.ActivityStillImageBinding
|
||||||
import com.google.android.gms.common.annotation.KeepName
|
import com.google.android.gms.common.annotation.KeepName
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
|
import com.google.mlkit.vision.text.Text
|
||||||
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
|
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
|
||||||
import com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions
|
import com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions
|
||||||
import com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions
|
import com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions
|
||||||
@ -62,7 +65,7 @@ import kotlin.math.max
|
|||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@KeepName
|
@KeepName
|
||||||
class PhotoImageActivity : AppCompatActivity() {
|
class PhotoImageActivity : AppCompatActivity(), TextRecognitionProcessor.TextRecognitionCallback {
|
||||||
|
|
||||||
private var selectedMode = TEXT_RECOGNITION_CHINESE
|
private var selectedMode = TEXT_RECOGNITION_CHINESE
|
||||||
private var selectedSize: String? = SIZE_SCREEN
|
private var selectedSize: String? = SIZE_SCREEN
|
||||||
@ -74,8 +77,10 @@ class PhotoImageActivity : AppCompatActivity() {
|
|||||||
private lateinit var imageCapture: ImageCapture
|
private lateinit var imageCapture: ImageCapture
|
||||||
private lateinit var outputDirectory: File
|
private lateinit var outputDirectory: File
|
||||||
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
|
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
|
||||||
|
|
||||||
private var isFlashOn = false
|
private var isFlashOn = false
|
||||||
private var fbFrom = "photo"
|
private var fbFrom = "photo"
|
||||||
|
private var needReshoot = false
|
||||||
|
|
||||||
private val REQUEST_CAMERA_PERMISSION = 100
|
private val REQUEST_CAMERA_PERMISSION = 100
|
||||||
private lateinit var bottomSheetDialog: BottomSheetDialog
|
private lateinit var bottomSheetDialog: BottomSheetDialog
|
||||||
@ -216,7 +221,7 @@ class PhotoImageActivity : AppCompatActivity() {
|
|||||||
private fun initList() {
|
private fun initList() {
|
||||||
val languages: ArrayList<Language> = LanguagesConstants.getInstance().getList(this)
|
val languages: ArrayList<Language> = LanguagesConstants.getInstance().getList(this)
|
||||||
if (languages.isNotEmpty()) {
|
if (languages.isNotEmpty()) {
|
||||||
val adapter = LanguageAdapter(this, languages) { _, language ->
|
val myAdapter = LanguageAdapter(this, languages) { _, language ->
|
||||||
if (!chooseLanguage) {
|
if (!chooseLanguage) {
|
||||||
|
|
||||||
PreferenceLanguageUtils.putString("language_source", language.language)
|
PreferenceLanguageUtils.putString("language_source", language.language)
|
||||||
@ -245,9 +250,16 @@ class PhotoImageActivity : AppCompatActivity() {
|
|||||||
binding.stillTargetLanguage.text =
|
binding.stillTargetLanguage.text =
|
||||||
PreferenceLanguageUtils.getString("language_target")
|
PreferenceLanguageUtils.getString("language_target")
|
||||||
}
|
}
|
||||||
bottomSheetDialog.findViewById<RecyclerView>(R.id.list_languages)?.layoutManager =
|
bottomSheetDialog.findViewById<RecyclerView>(R.id.list_languages)?.apply {
|
||||||
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
|
layoutManager =
|
||||||
bottomSheetDialog.findViewById<RecyclerView>(R.id.list_languages)?.adapter = adapter
|
LinearLayoutManager(
|
||||||
|
this@PhotoImageActivity,
|
||||||
|
LinearLayoutManager.VERTICAL,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
adapter = myAdapter
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,11 +269,21 @@ class PhotoImageActivity : AppCompatActivity() {
|
|||||||
startChooseImageIntentForResult()
|
startChooseImageIntentForResult()
|
||||||
FirebaseAnalyticsHelper.imageTransPhotoEvent()
|
FirebaseAnalyticsHelper.imageTransPhotoEvent()
|
||||||
}
|
}
|
||||||
binding.ivStillTake.setOnClickListener {
|
binding.ivReshoot.setOnClickListener {
|
||||||
binding.photoPreview.visibility = View.VISIBLE
|
needReshoot = false
|
||||||
|
|
||||||
|
binding.photoPreview.visibility = View.VISIBLE
|
||||||
|
binding.preview.setImageBitmap(null)
|
||||||
|
binding.graphicOverlay.clear()
|
||||||
|
|
||||||
|
}
|
||||||
|
binding.ivStillTake.setOnClickListener {
|
||||||
|
|
||||||
|
if (needReshoot) return@setOnClickListener
|
||||||
|
binding.photoPreview.visibility = View.VISIBLE
|
||||||
takePhoto()
|
takePhoto()
|
||||||
FirebaseAnalyticsHelper.imageTransCameraEvent()
|
FirebaseAnalyticsHelper.imageTransCameraEvent()
|
||||||
|
needReshoot = true
|
||||||
}
|
}
|
||||||
binding.ivStillBack.setOnClickListener {
|
binding.ivStillBack.setOnClickListener {
|
||||||
showInstAdFromCache(MyApp.Config.image_camera_int_auto)
|
showInstAdFromCache(MyApp.Config.image_camera_int_auto)
|
||||||
@ -413,31 +435,30 @@ class PhotoImageActivity : AppCompatActivity() {
|
|||||||
private fun createImageProcessor() {
|
private fun createImageProcessor() {
|
||||||
imageProcessor?.stop()
|
imageProcessor?.stop()
|
||||||
try {
|
try {
|
||||||
|
|
||||||
imageProcessor = when (selectedMode) {
|
imageProcessor = when (selectedMode) {
|
||||||
TEXT_RECOGNITION_CHINESE -> TextRecognitionProcessor(
|
TEXT_RECOGNITION_CHINESE -> TextRecognitionProcessor(
|
||||||
this,
|
this,
|
||||||
ChineseTextRecognizerOptions.Builder().build(), true, true, fbFrom
|
ChineseTextRecognizerOptions.Builder().build(), this
|
||||||
)
|
)
|
||||||
|
|
||||||
"Hindi", "Marathi", "Nepali", "Sanskrit" -> TextRecognitionProcessor(
|
"Hindi", "Marathi", "Nepali", "Sanskrit" -> TextRecognitionProcessor(
|
||||||
this,
|
this,
|
||||||
DevanagariTextRecognizerOptions.Builder().build(), true, true, fbFrom
|
DevanagariTextRecognizerOptions.Builder().build(), this
|
||||||
)
|
)
|
||||||
|
|
||||||
TEXT_RECOGNITION_JAPANESE -> TextRecognitionProcessor(
|
TEXT_RECOGNITION_JAPANESE -> TextRecognitionProcessor(
|
||||||
this,
|
this,
|
||||||
JapaneseTextRecognizerOptions.Builder().build(), true, true, fbFrom
|
JapaneseTextRecognizerOptions.Builder().build(), this
|
||||||
)
|
)
|
||||||
|
|
||||||
TEXT_RECOGNITION_KOREAN -> TextRecognitionProcessor(
|
TEXT_RECOGNITION_KOREAN -> TextRecognitionProcessor(
|
||||||
this,
|
this,
|
||||||
KoreanTextRecognizerOptions.Builder().build(), true, true, fbFrom
|
KoreanTextRecognizerOptions.Builder().build(), this
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> TextRecognitionProcessor(
|
else -> TextRecognitionProcessor(
|
||||||
this,
|
this,
|
||||||
TextRecognizerOptions.Builder().build(), true, true, fbFrom
|
TextRecognizerOptions.Builder().build(), this
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -586,6 +607,22 @@ class PhotoImageActivity : AppCompatActivity() {
|
|||||||
private const val REQUEST_CHOOSE_IMAGE = 1001
|
private const val REQUEST_CHOOSE_IMAGE = 1001
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onTextRecognized(text: Text, graphicOverlay: GraphicOverlay) {
|
||||||
|
graphicOverlay.add(
|
||||||
|
TextGraphic(
|
||||||
|
graphicOverlay,
|
||||||
|
text,
|
||||||
|
true, true,
|
||||||
|
fbFrom
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextFailure(e: Exception) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,6 @@ class QuickSetActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun sliderSet() {
|
private fun sliderSet() {
|
||||||
|
|
||||||
binding.slider1.setLabelFormatter { value ->
|
binding.slider1.setLabelFormatter { value ->
|
||||||
val percentage = ((value / 5) * 100).toInt()
|
val percentage = ((value / 5) * 100).toInt()
|
||||||
"$percentage%"
|
"$percentage%"
|
||||||
|
|||||||
@ -2,18 +2,25 @@ package com.assimilate.alltrans.viewui
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.MenuInflater
|
||||||
|
import android.view.View
|
||||||
import android.widget.RatingBar
|
import android.widget.RatingBar
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import com.assimilate.alltrans.R
|
import com.assimilate.alltrans.R
|
||||||
import com.assimilate.alltrans.databinding.ActivitySettingsBinding
|
import com.assimilate.alltrans.databinding.ActivitySettingsBinding
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
class SettingsActivity
|
class SettingsActivity
|
||||||
@ -22,6 +29,8 @@ class SettingsActivity
|
|||||||
private lateinit var bottomSheetDialog: BottomSheetDialog
|
private lateinit var bottomSheetDialog: BottomSheetDialog
|
||||||
private var userChoose = 1
|
private var userChoose = 1
|
||||||
|
|
||||||
|
private val languageCodes = mutableListOf("en", "zh")
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivitySettingsBinding.inflate(layoutInflater)
|
binding = ActivitySettingsBinding.inflate(layoutInflater)
|
||||||
@ -44,6 +53,9 @@ class SettingsActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initClick() {
|
private fun initClick() {
|
||||||
|
|
||||||
|
// binding.llLanguages.setOnClickListener(this::showLanguagePopup)
|
||||||
|
|
||||||
binding.ivSetBack.setOnClickListener { finish() }
|
binding.ivSetBack.setOnClickListener { finish() }
|
||||||
binding.llRate.setOnClickListener {
|
binding.llRate.setOnClickListener {
|
||||||
bottomSheetDialog.show()
|
bottomSheetDialog.show()
|
||||||
@ -96,7 +108,7 @@ class SettingsActivity
|
|||||||
|
|
||||||
private fun setBottomSheet() {
|
private fun setBottomSheet() {
|
||||||
// 设置 BottomSheetDialog
|
// 设置 BottomSheetDialog
|
||||||
bottomSheetDialog = BottomSheetDialog(this,R.style.CustomBottomSheetDialogTheme)
|
bottomSheetDialog = BottomSheetDialog(this, R.style.CustomBottomSheetDialogTheme)
|
||||||
bottomSheetDialog.setContentView(R.layout.bottomsheet_rate)
|
bottomSheetDialog.setContentView(R.layout.bottomsheet_rate)
|
||||||
bottomSheetDialog.dismissWithAnimation = true
|
bottomSheetDialog.dismissWithAnimation = true
|
||||||
|
|
||||||
@ -145,4 +157,56 @@ class SettingsActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun showLanguagePopup(view: View) {
|
||||||
|
val popupMenu = PopupMenu(this, view, Gravity.END)
|
||||||
|
val inflater: MenuInflater = popupMenu.menuInflater
|
||||||
|
inflater.inflate(R.menu.language_menu, popupMenu.menu)
|
||||||
|
|
||||||
|
popupMenu.setOnMenuItemClickListener { item ->
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.language_english -> {
|
||||||
|
setLocale(languageCodes[0])
|
||||||
|
return@setOnMenuItemClickListener true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.language_chinese -> {
|
||||||
|
setLocale(languageCodes[1])
|
||||||
|
return@setOnMenuItemClickListener true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> return@setOnMenuItemClickListener false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
popupMenu.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setLocale(lang: String) {
|
||||||
|
val locale = Locale(lang)
|
||||||
|
Locale.setDefault(locale)
|
||||||
|
val config = Configuration()
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
config.setLocale(locale)
|
||||||
|
} else {
|
||||||
|
config.locale = locale
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新资源配置
|
||||||
|
resources.updateConfiguration(config, resources.displayMetrics)
|
||||||
|
// 创建新的配置上下文
|
||||||
|
baseContext.createConfigurationContext(config)
|
||||||
|
|
||||||
|
// // 保存用户选择的语言
|
||||||
|
// val editor = getSharedPreferences("Settings", MODE_PRIVATE).edit()
|
||||||
|
// editor.putString("My_Lang", lang)
|
||||||
|
// editor.apply()
|
||||||
|
|
||||||
|
// 重新启动Activity以应用语言更改
|
||||||
|
// val intent = Intent(this, SettingsActivity::class.java)
|
||||||
|
// startActivity(intent)
|
||||||
|
// finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -47,6 +47,7 @@ class TextResultActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initSet() {
|
private fun initSet() {
|
||||||
|
loadNative()
|
||||||
backPressedCall()
|
backPressedCall()
|
||||||
adLoad(MyApp.Config.text_trans_int_auto)
|
adLoad(MyApp.Config.text_trans_int_auto)
|
||||||
adLoad(MyApp.Config.text_new_int_auto)
|
adLoad(MyApp.Config.text_new_int_auto)
|
||||||
@ -59,6 +60,16 @@ class TextResultActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loadNative() {
|
||||||
|
LolAdWrapper.shared.loadAdShowNativeAd(
|
||||||
|
this,
|
||||||
|
MyApp.Config.text_trans_native_auto,
|
||||||
|
binding.textNative,
|
||||||
|
R.layout.ad_layout_admob_banner,
|
||||||
|
R.layout.ad_layout_max_banner
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun backPressedCall() {
|
private fun backPressedCall() {
|
||||||
val callback = object : OnBackPressedCallback(true) {
|
val callback = object : OnBackPressedCallback(true) {
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
@ -70,6 +81,8 @@ class TextResultActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initClick() {
|
private fun initClick() {
|
||||||
|
|
||||||
|
|
||||||
binding.ivTrBack.setOnClickListener {
|
binding.ivTrBack.setOnClickListener {
|
||||||
showInstAdFromCache(MyApp.Config.text_trans_int_auto)
|
showInstAdFromCache(MyApp.Config.text_trans_int_auto)
|
||||||
finish()
|
finish()
|
||||||
@ -86,7 +99,7 @@ class TextResultActivity : AppCompatActivity() {
|
|||||||
MyTextTools.copyToClipboard(this, binding.tvTrTarget.text.toString())
|
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 {
|
||||||
MyTextTools.ttsReadText(
|
MyTextTools.ttsReadText(
|
||||||
binding.tvTrSource.text.toString(),
|
binding.tvTrSource.text.toString(),
|
||||||
@ -201,7 +214,6 @@ class TextResultActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun doBack() {
|
private fun doBack() {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
@ -247,7 +259,6 @@ class TextResultActivity : AppCompatActivity() {
|
|||||||
doBack()
|
doBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun closed() {
|
override fun closed() {
|
||||||
|
|||||||
@ -2,9 +2,9 @@ package com.assimilate.alltrans.viewui
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.os.Handler
|
||||||
import android.view.ViewGroup
|
import android.os.Looper
|
||||||
import android.widget.Button
|
import android.os.Message
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
@ -17,14 +17,80 @@ import com.assimilate.alltrans.databinding.ActivityWelBinding
|
|||||||
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
|
||||||
|
|
||||||
class WelActivity : AppCompatActivity(){
|
class WelActivity : AppCompatActivity() {
|
||||||
|
companion object {
|
||||||
|
private const val MSG_PROGRESS = 0
|
||||||
|
private const val MSG_LOAD_AD_LOADED = 1
|
||||||
|
private const val MSG_LOAD_AD_FAIL = 2
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var binding: ActivityWelBinding
|
private lateinit var binding: ActivityWelBinding
|
||||||
|
|
||||||
|
private val mMaxLoading = 10 * 1000L//最大超时
|
||||||
|
private var progress = 0f
|
||||||
|
private val delayMillis = mMaxLoading / 100
|
||||||
|
private var place: String = MyApp.Config.start_cold_int_auto
|
||||||
|
|
||||||
|
|
||||||
|
private val handler = object : Handler(Looper.getMainLooper()) {
|
||||||
|
override fun handleMessage(msg: Message) {
|
||||||
|
val progressBar = binding.customProgressBar
|
||||||
|
if (!isFinishing && !isDestroyed) {
|
||||||
|
|
||||||
|
when (msg.what) {
|
||||||
|
MSG_PROGRESS -> {
|
||||||
|
if (progress >= 100f) {//超时
|
||||||
|
//超时就是没有广告,就是广告show失败了
|
||||||
|
toNextPage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (adCanShow()) {
|
||||||
|
//能展示走展示,移除进度,结束循环
|
||||||
|
sendEmptyMessageDelayed(MSG_LOAD_AD_LOADED, delayMillis)
|
||||||
|
removeMessages(MSG_PROGRESS)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 继续加载进度,除非上面条件有成立
|
||||||
|
progress += 1
|
||||||
|
progressBar.progress = progress.toInt()
|
||||||
|
sendEmptyMessageDelayed(MSG_PROGRESS, delayMillis)
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG_LOAD_AD_LOADED -> {
|
||||||
|
|
||||||
|
//展示广告,移除加载,移除进度条,结束循环
|
||||||
|
// if (progress >= 100f) {
|
||||||
|
showAd()
|
||||||
|
removeMessages(MSG_LOAD_AD_LOADED)
|
||||||
|
removeMessages(MSG_PROGRESS)
|
||||||
|
return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// progress += 1
|
||||||
|
// progressBar.progress = progress.toInt()
|
||||||
|
// sendEmptyMessageDelayed(MSG_LOAD_AD_LOADED, delayMillis)
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG_LOAD_AD_FAIL -> {
|
||||||
|
if (progress < 77f) {
|
||||||
|
progress = 77f
|
||||||
|
}
|
||||||
|
// 失败走进度条,移除失败
|
||||||
|
sendEmptyMessageDelayed(MSG_PROGRESS, delayMillis)
|
||||||
|
removeMessages(MSG_LOAD_AD_FAIL)
|
||||||
|
// removeMessages(MSG_PROGRESS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityWelBinding.inflate(layoutInflater)
|
binding = ActivityWelBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
//debugFirebase()
|
|
||||||
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
|
ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
|
||||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
@ -35,30 +101,20 @@ class WelActivity : AppCompatActivity(){
|
|||||||
initSet()
|
initSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun debugFirebase() {
|
|
||||||
val crashButton = Button(this)
|
|
||||||
crashButton.text = "Test Crash"
|
|
||||||
crashButton.setOnClickListener {
|
|
||||||
throw RuntimeException("Test Crash") // Force a crash
|
|
||||||
}
|
|
||||||
|
|
||||||
addContentView(
|
|
||||||
crashButton, ViewGroup.LayoutParams(
|
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initSet() {
|
private fun initSet() {
|
||||||
backPressedCall()
|
backPressedCall()
|
||||||
if (MyApp.app.isFirstLaunch) {
|
|
||||||
adSplash(MyApp.Config.start_cold_int_auto)
|
|
||||||
} else {
|
|
||||||
adSplashHot(MyApp.Config.start_hot_int_auto)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 判断走冷启动还是热启动广告
|
||||||
|
place = if (!MyApp.app.isFirstLaunch) {
|
||||||
|
MyApp.Config.start_cold_int_auto
|
||||||
|
} else {
|
||||||
|
MyApp.Config.start_hot_int_auto
|
||||||
|
|
||||||
|
}
|
||||||
|
//请求广告,启动进度条
|
||||||
|
loadAd()
|
||||||
|
handler.sendEmptyMessageDelayed(MSG_PROGRESS, delayMillis)
|
||||||
|
}
|
||||||
|
|
||||||
private fun backPressedCall() {
|
private fun backPressedCall() {
|
||||||
val callback = object : OnBackPressedCallback(true) {
|
val callback = object : OnBackPressedCallback(true) {
|
||||||
@ -73,83 +129,45 @@ class WelActivity : AppCompatActivity(){
|
|||||||
FirebaseAnalyticsHelper.launchPvEvent()
|
FirebaseAnalyticsHelper.launchPvEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun toNextPage() {
|
private fun toNextPage() {
|
||||||
|
// 热启动关闭加载页,冷启动进入主页
|
||||||
|
if (MyApp.app.isFirstLaunch) {
|
||||||
startActivity(Intent(this@WelActivity, MainActivity::class.java))
|
startActivity(Intent(this@WelActivity, MainActivity::class.java))
|
||||||
|
} else {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun adSplash(place: String) {
|
private fun loadAd() {
|
||||||
// 加载广告
|
LolAdWrapper.shared.loadAd(
|
||||||
LolAdWrapper.shared.loadAdIfNotCached(
|
|
||||||
this,
|
this,
|
||||||
place,
|
place,
|
||||||
object : LolAdWrapper.LoLLoadListener {
|
object : LolAdWrapper.LoLLoadListener {
|
||||||
override fun loadFailed(error: LolLoadError?) {
|
override fun loadFailed(error: LolLoadError?) {
|
||||||
// 处理加载失败
|
handler.sendEmptyMessage(MSG_LOAD_AD_FAIL)
|
||||||
toNextPage()
|
}
|
||||||
|
})
|
||||||
|
LolAdWrapper.shared.loadAdIfNotCached(this, MyApp.Config.backup_int_auto)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loaded() {
|
private fun adCanShow(): Boolean {
|
||||||
// 处理加载成功
|
return LolAdWrapper.shared.hasCache(place)
|
||||||
// 如果需要立刻展示广告,可以调用展示方法
|
}
|
||||||
|
|
||||||
|
private fun showAd() {
|
||||||
LolAdWrapper.shared.showAdIfCached(
|
LolAdWrapper.shared.showAdIfCached(
|
||||||
this@WelActivity,
|
|
||||||
place,
|
|
||||||
object : LolAdWrapper.LolShowListener {
|
|
||||||
override fun shown() {
|
|
||||||
// 处理广告展示成功
|
|
||||||
Log.d("fcasc", place)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showFailed(error: LolShowError?) {
|
|
||||||
// 处理广告展示失败
|
|
||||||
toNextPage()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun closed() {
|
|
||||||
// 处理广告关闭
|
|
||||||
toNextPage()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun adSplashHot(place: String) {
|
|
||||||
// 加载广告
|
|
||||||
LolAdWrapper.shared.loadAdIfNotCached(
|
|
||||||
this,
|
this,
|
||||||
place,
|
place,
|
||||||
object : LolAdWrapper.LoLLoadListener {
|
|
||||||
override fun loadFailed(error: LolLoadError?) {
|
|
||||||
// 处理加载失败
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loaded() {
|
|
||||||
// 处理加载成功
|
|
||||||
// 如果需要立刻展示广告,可以调用展示方法
|
|
||||||
LolAdWrapper.shared.showAdIfCached(
|
|
||||||
this@WelActivity,
|
|
||||||
place,
|
|
||||||
object : LolAdWrapper.LolShowListener {
|
object : LolAdWrapper.LolShowListener {
|
||||||
override fun shown() {
|
override fun closed() {
|
||||||
// 处理广告展示成功
|
toNextPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showFailed(error: LolShowError?) {
|
override fun showFailed(error: LolShowError?) {
|
||||||
// 处理广告展示失败
|
toNextPage()
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun closed() {
|
|
||||||
// 处理广告关闭
|
|
||||||
finish()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,10 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
|
|
||||||
<gradient
|
<gradient
|
||||||
|
android:angle="270"
|
||||||
android:endColor="#FF1099FC"
|
android:endColor="#FF1099FC"
|
||||||
android:angle="10"
|
|
||||||
android:startColor="#FF14CBF9"
|
android:startColor="#FF14CBF9"
|
||||||
android:type="linear" />
|
android:type="linear" />
|
||||||
</shape>
|
</shape>
|
||||||
|
|||||||
@ -1,25 +1,114 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/dic_root"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/main_bg_ffe2efff"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp">
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_dic_back"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:src="@drawable/ic_back"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_dic_more"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:src="@drawable/ic_dic_more"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/tv_dic_title"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/tv_dic_title" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_dic_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="19dp"
|
||||||
|
android:text="@string/dic_title"
|
||||||
|
android:textColor="@color/main_text_ff1f1724"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/fl_e"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="30dp"
|
||||||
|
android:background="@drawable/button_r20_white_bg"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/buttonSearch"
|
||||||
|
app:layout_constraintHorizontal_weight="1"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_dic_title">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/editTextWord"
|
android:id="@+id/editTextWord"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="Enter a word" />
|
android:background="@android:color/transparent"
|
||||||
|
android:gravity="center|start"
|
||||||
|
android:hint="@string/dic_et"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="text"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingBottom="8dp" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonSearch"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Search" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textViewDefinition"
|
android:id="@+id/buttonSearch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:background="@drawable/button_r24_blue_bg"
|
||||||
|
android:paddingStart="20dp"
|
||||||
|
android:paddingTop="7dp"
|
||||||
|
android:paddingEnd="20dp"
|
||||||
|
android:paddingBottom="7dp"
|
||||||
|
android:text="@string/dic_search"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/fl_e"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/fl_e"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/fl_e" />
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/to_url"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="16dp" />
|
android:layout_marginTop="30dp"
|
||||||
</LinearLayout>
|
android:layout_marginBottom="40dp"
|
||||||
|
android:minHeight="500dp"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/fl_e">
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<android.widget.ProgressBar
|
||||||
|
android:id="@+id/wiki_progressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/to_url"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/to_url"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/to_url"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/to_url" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@ -206,8 +206,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
android:background="@drawable/button_r20_white_bg"
|
android:background="@drawable/button_r20_white_bg" />
|
||||||
android:minHeight="120dp" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/ll_main_quick"
|
android:id="@+id/ll_main_quick"
|
||||||
@ -254,7 +253,6 @@
|
|||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:drawableEndCompat="@drawable/ic_arrow_right" />
|
app:drawableEndCompat="@drawable/ic_arrow_right" />
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@ -265,6 +263,7 @@
|
|||||||
android:paddingTop="11dp"
|
android:paddingTop="11dp"
|
||||||
android:paddingBottom="11dp"
|
android:paddingBottom="11dp"
|
||||||
android:src="@drawable/main_setting_quick_def" />
|
android:src="@drawable/main_setting_quick_def" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -308,7 +307,6 @@
|
|||||||
android:textColor="@color/main_text_ff1f1724"
|
android:textColor="@color/main_text_ff1f1724"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:visibility="gone"
|
|
||||||
app:drawableTopCompat="@drawable/main_dic" />
|
app:drawableTopCompat="@drawable/main_dic" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@ -61,6 +61,7 @@
|
|||||||
android:paddingEnd="10dp"
|
android:paddingEnd="10dp"
|
||||||
android:src="@drawable/ic_still_pic" />
|
android:src="@drawable/ic_still_pic" />
|
||||||
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/iv_still_take"
|
android:id="@+id/iv_still_take"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@ -69,15 +70,34 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:src="@drawable/ic_still_take" />
|
android:src="@drawable/ic_still_take" />
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/iv_still_buling"
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="top"
|
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_reshoot"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/ic_reshoot"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/change_language"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_still_buling"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="top"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
android:paddingStart="10dp"
|
android:paddingStart="10dp"
|
||||||
android:paddingEnd="10dp"
|
android:paddingEnd="10dp"
|
||||||
android:src="@drawable/ic_still_notbuli" />
|
android:src="@drawable/ic_still_notbuli" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@ -66,13 +66,13 @@
|
|||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<ImageView
|
<!-- <ImageView-->
|
||||||
android:id="@+id/iv_source_clear"
|
<!-- android:id="@+id/iv_source_clear"-->
|
||||||
android:layout_width="wrap_content"
|
<!-- android:layout_width="wrap_content"-->
|
||||||
android:layout_height="wrap_content"
|
<!-- android:layout_height="wrap_content"-->
|
||||||
android:layout_gravity="center"
|
<!-- android:layout_gravity="center"-->
|
||||||
android:padding="12dp"
|
<!-- android:padding="12dp"-->
|
||||||
android:src="@drawable/ic_tr_close" />
|
<!-- android:src="@drawable/ic_tr_close" />-->
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@ -148,6 +148,16 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/text_native"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:background="@drawable/button_r20_white_bg"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/ll_main_enter_text" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
@ -8,6 +8,14 @@
|
|||||||
android:background="@drawable/ic_wel_bg"
|
android:background="@drawable/ic_wel_bg"
|
||||||
tools:context=".viewui.WelActivity">
|
tools:context=".viewui.WelActivity">
|
||||||
|
|
||||||
|
<android.widget.ProgressBar
|
||||||
|
android:id="@+id/custom_progressBar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -28,5 +36,4 @@
|
|||||||
app:lottie_fileName="tran_wel_1.json"
|
app:lottie_fileName="tran_wel_1.json"
|
||||||
app:lottie_loop="true" />
|
app:lottie_loop="true" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@ -77,9 +77,9 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="10dp"
|
||||||
|
android:padding="5dp"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:src="@drawable/ic_voice"
|
android:src="@drawable/ic_voice" />
|
||||||
android:visibility="invisible" />
|
|
||||||
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
@ -92,6 +92,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="10dp"
|
||||||
|
android:autoLink="web"
|
||||||
|
android:linksClickable="true"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:gravity="start|top"
|
android:gravity="start|top"
|
||||||
android:maxLines="5"
|
android:maxLines="5"
|
||||||
@ -104,8 +106,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:visibility="invisible">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/iv_target_tts"
|
android:id="@+id/iv_target_tts"
|
||||||
@ -123,13 +124,13 @@
|
|||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
android:src="@drawable/ic_copy" />
|
android:src="@drawable/ic_copy" />
|
||||||
|
|
||||||
<ImageView
|
<!-- <ImageView-->
|
||||||
android:id="@+id/iv_tr_target_share"
|
<!-- android:id="@+id/iv_tr_target_share"-->
|
||||||
android:layout_width="wrap_content"
|
<!-- android:layout_width="wrap_content"-->
|
||||||
android:layout_height="wrap_content"
|
<!-- android:layout_height="wrap_content"-->
|
||||||
android:layout_gravity="center"
|
<!-- android:layout_gravity="center"-->
|
||||||
android:layout_marginEnd="12dp"
|
<!-- android:layout_marginEnd="12dp"-->
|
||||||
android:src="@drawable/ic_share" />
|
<!-- android:src="@drawable/ic_share" />-->
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/iv_tr_target_dic"
|
android:id="@+id/iv_tr_target_dic"
|
||||||
@ -137,6 +138,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
|
android:visibility="invisible"
|
||||||
android:src="@drawable/ic_dic" />
|
android:src="@drawable/ic_dic" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
@ -57,10 +57,17 @@
|
|||||||
<!-- 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">Empty no history...</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">Empty no favorite...</string>
|
<string name="favor_emtpoy">Empty no favorite…</string>
|
||||||
<string name="translate_now">Translate Now</string>
|
<string name="translate_now">Translate Now</string>
|
||||||
|
<!-- dic_page-->
|
||||||
|
<string name="dic_title">Directory</string>
|
||||||
|
<string name="dic_search">Search</string>
|
||||||
|
<string name="dic_et">Enter a word</string>
|
||||||
|
<string name="dic_wikiing">loading…</string>
|
||||||
|
<string name="dic_open_in">Open in browser</string>
|
||||||
|
|
||||||
|
|
||||||
<!--settings_page-->
|
<!--settings_page-->
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
@ -94,5 +101,9 @@
|
|||||||
<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>
|
<string name="fav_emp_description">Click the \"Favorite\" button at the end\nafter translation.\nEasily bookmark sentences.</string>
|
||||||
|
|
||||||
|
<!-- menu_choose_lan-->
|
||||||
|
<string name="language_english">English</string>
|
||||||
|
<string name="language_chinese">Chinese</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
<style name="Theme.Alltrans" parent="Base.Theme.Alltrans" />
|
<style name="Theme.Alltrans" parent="Base.Theme.Alltrans" />
|
||||||
|
|
||||||
<style name="CustomBottomSheetDialogTheme" parent="Theme.Material3.Light.BottomSheetDialog">
|
<style name="CustomBottomSheetDialogTheme" parent="Theme.Material3.Light.BottomSheetDialog">
|
||||||
<item name="backgroundTint">@color/white</item>
|
<item name="android:background">@android:color/transparent</item>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in New Issue
Block a user