version 1.0.3 release

This commit is contained in:
Simon 2024-08-07 18:35:45 +08:00
parent 3825eca205
commit 508b57593f
62 changed files with 3124 additions and 678 deletions

1
app/.gitignore vendored
View File

@ -1 +1,2 @@
/build /build
/release

View File

@ -1,6 +1,3 @@
import java.text.SimpleDateFormat
import java.util.Date
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android) alias(libs.plugins.jetbrains.kotlin.android)
@ -18,8 +15,8 @@ android {
applicationId = "com.assimilate.alltrans" applicationId = "com.assimilate.alltrans"
minSdk = 23 minSdk = 23
targetSdk = 34 targetSdk = 34
versionCode = 2 versionCode = 3
versionName = "1.0.2" versionName = "1.0.3"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }
@ -27,18 +24,19 @@ android {
buildFeatures { buildFeatures {
buildConfig = true buildConfig = true
viewBinding = true viewBinding = true
buildConfig = true
} }
buildTypes { buildTypes {
debug { // debug {
isShrinkResources = true // isShrinkResources = true
isMinifyEnabled = true // isMinifyEnabled = true
proguardFiles( // proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), // getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" // "proguard-rules.pro"
) // )
} // }
release { release {
isShrinkResources = true isShrinkResources = true
@ -51,17 +49,6 @@ android {
} }
// applicationVariants.all {
// outputs.all {
// val appName = "Translark" // 替换为你的应用名称
// val versionName = versionName
// val date = SimpleDateFormat("yyyyMMdd-HHmm").format(Date())
// val newApkName = "${appName}-${date}-${versionName}.apk"
// (this as com.android.build.gradle.internal.api.BaseVariantOutputImpl).outputFileName = newApkName
// }
// }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
@ -73,6 +60,20 @@ android {
dependencies { dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))
//google ads
implementation("com.google.android.gms:play-services-ads:23.1.0")
implementation("com.google.ads.mediation:adcolony:4.8.0.2")
implementation("com.google.ads.mediation:applovin:12.5.0.0")
implementation("com.google.ads.mediation:vungle:6.12.0.0")
implementation("com.google.ads.mediation:facebook:6.17.0.0")
implementation("com.google.ads.mediation:mintegral:16.7.51.0")
implementation("com.google.ads.mediation:pangle:6.0.0.5.0")
implementation("com.unity3d.ads:unity-ads:4.6.1")
implementation("com.google.ads.mediation:unity:4.12.0.0")
// implementation("com.google.ads.mediation:ironsource:8.1.0.0")
// 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"))
@ -80,6 +81,7 @@ dependencies {
// When using the BoM, you don't specify versions in Firebase library dependencies // 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")
// To recognize Latin script // To recognize Latin script
@ -94,7 +96,6 @@ dependencies {
implementation("com.google.mlkit:text-recognition-korean:16.0.0") implementation("com.google.mlkit:text-recognition-korean:16.0.0")
// CameraX core library // CameraX core library
implementation(libs.androidx.camera.core) implementation(libs.androidx.camera.core)
// CameraX Camera2 extensions // CameraX Camera2 extensions

Binary file not shown.

420
app/myadalltrans.json Normal file
View File

@ -0,0 +1,420 @@
{
"AD_SHOW_LIMIT": {
"admob_inst": 100,
"admob_native": 100,
"max_banner": 100,
"max_inst": 100,
"max_native": 100
},
"sounds_inst_show_interval": 25000,
"LOLAds_EXPIRE_HOURS_NEW_USER": 20,
"alltrans_start_cold_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/2491776559": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_start_hot_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/8726012415": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_text_trans_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/8833823620": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_text_new_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/7552531544": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_text_camera_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/3473685732": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_image_camera_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/9094248890": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_history_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/9160460404": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_home_native_auto": {
"data": [
{
"config": [
[
"admob_native",
{
"ca-app-pub-9280511366580942/6663526672": 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": {
"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/8739025670": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
}
}

View File

@ -17,7 +17,7 @@
#-keepattributes SourceFile,LineNumberTable #-keepattributes SourceFile,LineNumberTable
# 保留com.assimilate.alltrans.keepmodel包及其子包的所有类 # 保留com.assimilate.alltrans.keepmodel包及其子包的所有类
-keep class com.assimilate.alltrans.keepmodel.** { *; } -keep class com.assimilate.alltrans.model.** { *; }
# 保留com.assimilate.alltrans.http包及其子包的所有类 # 保留com.assimilate.alltrans.http包及其子包的所有类
-keep class com.assimilate.alltrans.http.** { *; } -keep class com.assimilate.alltrans.http.** { *; }

View File

@ -1,37 +0,0 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.assimilate.alltrans",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 2,
"versionName": "1.0.2",
"outputFile": "app-release.apk"
}
],
"elementType": "File",
"baselineProfiles": [
{
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
"baselineProfiles/1/app-release.dm"
]
},
{
"minApi": 31,
"maxApi": 2147483647,
"baselineProfiles": [
"baselineProfiles/0/app-release.dm"
]
}
],
"minSdkVersionForDexing": 23
}

Binary file not shown.

View File

@ -28,6 +28,25 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.Alltrans" android:theme="@style/Theme.Alltrans"
tools:targetApi="31"> tools:targetApi="31">
<!-- Sample AdMob app ID: ca-app-pub-3940256099942544~3347511713 -->
<!-- <meta-data-->
<!-- android:name="com.google.android.gms.ads.APPLICATION_ID"-->
<!-- android:value="ca-app-pub-3940256099942544~3347511713" />-->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="@string/my_admob_app_id" />
<meta-data
android:name="applovin.sdk.key"
android:value="12324322423" />
<property
android:name="android.adservices.AD_SERVICES_CONFIG"
android:resource="@xml/ga_ad_services_config"
tools:replace="android:resource"/>
<activity <activity
android:name=".viewui.MainActivity" android:name=".viewui.MainActivity"
android:exported="false" android:exported="false"

View File

@ -1,18 +1,76 @@
package com.assimilate.alltrans package com.assimilate.alltrans
import android.app.Activity
import android.app.ActivityManager import android.app.ActivityManager
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle
import android.webkit.WebView import android.webkit.WebView
import com.assimilate.alltrans.keepmodel.LanguagesConstants import com.assimilate.alltrans.common.AppStore
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils import com.assimilate.alltrans.common.CurrentActivityHolder
import com.assimilate.alltrans.common.RemoteConfigManager
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.viewui.WelActivity
import com.lol.apex.ok.google.adlibrary.LoLAds
import com.lol.apex.ok.google.adlibrary.bean.constants.TestMode
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicLong
class MyApp : Application() { class MyApp : Application() {
init { init {
instance = this instance = this
} }
private var activityReferences = 0
private var isActivityChangingConfigurations = false
var isFirstLaunch = true
private fun registerActivityLifecycle() {
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
CurrentActivityHolder.currentActivity = activity
}
override fun onActivityStarted(activity: Activity) {
CurrentActivityHolder.currentActivity = activity
if (++activityReferences == 1 && !isActivityChangingConfigurations) {
if (isFirstLaunch) {
isFirstLaunch = false
} else {
val intent = Intent(activity, WelActivity::class.java)
activity.startActivity(intent)
}
}
}
override fun onActivityResumed(activity: Activity) {
CurrentActivityHolder.currentActivity = activity
}
override fun onActivityPaused(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {
isActivityChangingConfigurations = activity.isChangingConfigurations;
if (--activityReferences == 0 && !isActivityChangingConfigurations) {
// The app goes to the background
}
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {
if (CurrentActivityHolder.currentActivity == activity) {
CurrentActivityHolder.currentActivity = null
}
}
})
}
private fun setSystemLanguage() { private fun setSystemLanguage() {
// 检查是否是第一次进入应用 // 检查是否是第一次进入应用
if (PreferenceLanguageUtils.isFirstTime()) { if (PreferenceLanguageUtils.isFirstTime()) {
@ -28,22 +86,29 @@ class MyApp : Application() {
// 设置已经不是第一次进入应用了 // 设置已经不是第一次进入应用了
PreferenceLanguageUtils.setNotFirstTime() PreferenceLanguageUtils.setNotFirstTime()
} }
} }
// 用于记录上次广告展示的时间
val lastAdDisplayTime: AtomicLong = AtomicLong(0)
val isAdShowing: AtomicBoolean = AtomicBoolean(false)
companion object { companion object {
private var instance: MyApp? = null private var instance: MyApp? = null
fun applicationContext(): Context { fun applicationContext(): Context {
return instance!!.applicationContext return instance!!.applicationContext
} }
val app: MyApp
get() = instance!!
} }
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
instance = this instance = this
// ScreenUtils.init(this) // ScreenUtils.init(this)
registerActivityLifecycle()
initAd()
setSystemLanguage() setSystemLanguage()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
@ -65,9 +130,27 @@ class MyApp : Application() {
return null return null
} }
object Config {
const val openSusViewMode: String = "open_sus_view"
private fun initAd() {
//初始化firebase并获取firebase值
RemoteConfigManager(this)
LoLAds.initialize(this)
LoLAds.setLogEnable(BuildConfig.DEBUG)//是否打开⽇志和遮罩层颜色release要设置成false
LoLAds.setTestEnable(BuildConfig.DEBUG)//false使用 setAdConfig 中的广告配置
LoLAds.setTestMode(TestMode.REMOTE_TEST)//setTestEnable为true时生效LOCAL_TEST: 会使用sdk内的测试广告; REMOTE_TEST: 会将 setAdConfig 添加的配置中的广告id替换成测试id
//服务器端中⼴告json的key⻅⼴告配置json详情
LoLAds.setAdConfigKey(Config.adKey)
//设置自定义广告配置json
val config = AppStore(app).adMessage.takeIf { it.isNotEmpty() } ?: Config.adDefJson
LoLAds.setAdConfig(config)
}
object Config {
// firebase_event_map_key
const val CLICK_FROM = "clickfrom"
const val FAIL_REASON = "failreason"
// firebase_event_key // firebase_event_key
const val launchPv = "launch_pv" const val launchPv = "launch_pv"
@ -89,24 +172,459 @@ class MyApp : Application() {
const val hoverButtonClick = "hover_button_click" const val hoverButtonClick = "hover_button_click"
const val hoverLimitAgree = "hover_limit_agree"
const val hoverButtonCancel = "hover_button_cancel" const val hoverButtonCancel = "hover_button_cancel"
const val hover_button_agree = "hover_button_agree" const val hoverButtonAgree = "hover_button_agree"
const val hover_screen_click = "hover_screen_click" const val hoverScreenClick = "hover_screen_click"
const val hover_screen_imp = "hover_screen_imp" const val hoverScreenImp = "hover_screen_imp"
const val hover_screen_global = "hover_screen_global" const val hoverScreenGlobal = "hover_screen_global"
const val hover_global_result = "hover_global_result" const val hoverGlobalResult = "hover_global_result"
const val hover_screen_district = "hover_screen_district" const val hoverScreenDistrict = "hover_screen_district"
const val hover_district_result = "hover_district_result" const val hoverDistrictResult = "hover_district_result"
const val image_click = "image_click" const val imageClick = "image_click"
const val image_trans_camera = "image_trans_camera" const val imageTransCamera = "image_trans_camera"
const val image_camera_result = "image_camera_result" const val imageCameraResult = "image_camera_result"
const val image_trans_photo = "image_trans_photo" const val imageTransPhoto = "image_trans_photo"
const val image_photo_result = "image_photo_result" const val imagePhotoResult = "image_photo_result"
const val history_click = "history_click" const val historyClick = "history_click"
const val history_delete = "history_delete" const val historyDelete = "history_delete"
// google_ad_place
const val start_cold_int_auto = "start_cold_int_auto"
const val start_hot_int_auto = "start_hot_int_auto"
const val text_trans_int_auto = "text_trans_int_auto"
const val text_new_int_auto = "text_new_int_auto"
const val text_camera_int_auto = "text_camera_int_auto"
const val image_camera_int_auto = "image_camera_int_auto"
const val history_int_auto = "history_int_auto"
const val home_native_auto = "home_native_auto"
const val backup_int_auto = "backup_int_auto"
const val adKey = "alltrans"
const val adDefJson = """
{
"AD_SHOW_LIMIT": {
"admob_inst": 100,
"admob_native": 100,
"max_banner": 100,
"max_inst": 100,
"max_native": 100
},
"sounds_inst_show_interval": 25000,
"LOLAds_EXPIRE_HOURS_NEW_USER": 20,
"alltrans_start_cold_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/2491776559": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_start_hot_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/8726012415": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_text_trans_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/8833823620": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_text_new_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/7552531544": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_text_camera_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/3473685732": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_image_camera_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/9094248890": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_history_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/9160460404": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
},
"alltrans_home_native_auto": {
"data": [
{
"config": [
[
"admob_native",
{
"ca-app-pub-9280511366580942/6663526672": 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": {
"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/8739025670": 100
}
]
],
"limit": {
"admob_inst": 100,
"max_inst": 100
},
"cycle": 0,
"timeout": 15000,
"showIntervalEnable": false
}
]
}
}
"""
} }
} }

View File

@ -12,7 +12,7 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.assimilate.alltrans.R; import com.assimilate.alltrans.R;
import com.assimilate.alltrans.keepmodel.Language; import com.assimilate.alltrans.model.Language;
import com.assimilate.alltrans.databinding.LanguageItemLayoutBinding; import com.assimilate.alltrans.databinding.LanguageItemLayoutBinding;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;

View File

@ -14,6 +14,7 @@ import android.os.Looper
import android.util.Log import android.util.Log
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.ScreenCaptureManager import com.assimilate.alltrans.common.ScreenCaptureManager
import com.assimilate.alltrans.curview.ControlView import com.assimilate.alltrans.curview.ControlView
import com.assimilate.alltrans.curview.CopyTextView import com.assimilate.alltrans.curview.CopyTextView
@ -79,6 +80,7 @@ class SusService : Service() {
override fun onClick() { override fun onClick() {
Log.d("SusService_f", "FloatingView clicked") Log.d("SusService_f", "FloatingView clicked")
addControlView() addControlView()
FirebaseAnalyticsHelper.hoverScreenClickEvent()
} }
}) })
} }
@ -92,6 +94,8 @@ class SusService : Service() {
Handler(Looper.getMainLooper()).postDelayed({ Handler(Looper.getMainLooper()).postDelayed({
globalView.addGlobalView(screenCaptureManager.getImageReader()) globalView.addGlobalView(screenCaptureManager.getImageReader())
}, 333) }, 333)
FirebaseAnalyticsHelper.hoverScreenGlobalEvent()
} }
override fun onCopyClick() { override fun onCopyClick() {
@ -102,6 +106,7 @@ class SusService : Service() {
override fun onDistrictClick() { override fun onDistrictClick() {
selectionView = SelectionView(this@SusService) selectionView = SelectionView(this@SusService)
selectionView.addSelectionView(screenCaptureManager.getImageReader()) selectionView.addSelectionView(screenCaptureManager.getImageReader())
FirebaseAnalyticsHelper.hoverScreenDistrictEvent()
} }
override fun onChangeLan() { override fun onChangeLan() {
@ -161,4 +166,5 @@ class SusService : Service() {
copyTextView.removeView() copyTextView.removeView()
} }
} }
} }

View File

@ -0,0 +1,29 @@
package com.assimilate.alltrans.common
import android.content.Context
import android.content.SharedPreferences
import com.assimilate.alltrans.MyApp
class AppStore(context: Context) {
private val sharedPreferences: SharedPreferences =
context.getSharedPreferences("AppStore", Context.MODE_PRIVATE)
val showAdIntervalTime: Long
get() = sharedPreferences.getLong("showAdIntervalTime", DEFAULT_INTERVAL_TIME)
val adMessage: String
get() = sharedPreferences.getString(MyApp.Config.adKey, DEFAULT_WELCOME_MESSAGE) ?: DEFAULT_WELCOME_MESSAGE
fun saveLong(key: String, value: Long) {
sharedPreferences.edit().putLong(key, value).apply()
}
fun saveString(key: String, value: String) {
sharedPreferences.edit().putString(key, value).apply()
}
companion object {
private const val DEFAULT_INTERVAL_TIME: Long = 5000 // 默认间隔时间,单位毫秒
private const val DEFAULT_WELCOME_MESSAGE: String = "" // 默认欢迎信息
}
}

View File

@ -0,0 +1,7 @@
package com.assimilate.alltrans.common
import android.app.Activity
object CurrentActivityHolder {
var currentActivity: Activity? = null
}

View File

@ -1,10 +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.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 {
@ -23,7 +25,7 @@ object FirebaseAnalyticsHelper {
} }
} }
} }
// firebaseAnalytics.logEvent(eventName, bundle) firebaseAnalytics.logEvent(eventName, bundle)
} }
@ -32,42 +34,32 @@ object FirebaseAnalyticsHelper {
} }
fun homePvEvent(from: String) { fun homePvEvent(from: String, value: String) {
val params = when (from) { val params = mapOf(from to value)
"cap" -> mapOf("cap" to 1)
"create" -> mapOf("cap" to 1)
else -> {
null
}
}
logCusEvent(MyApp.Config.homePv, params) logCusEvent(MyApp.Config.homePv, params)
} }
fun textTransSwitchEvent(from: String) { fun textTransSwitchEvent(from: String, value: String) {
val params = when (from) { val params = mapOf(from to value)
"cap" -> mapOf("cap" to 1) logCusEvent(MyApp.Config.textTransSwitch, params)
"create" -> mapOf("cap" to 1)
else -> {
null
}
} }
} fun languageChooseEvent(from: String,value: String) {
val params = mapOf(from to value)
fun languageChooseEvent(from: String) {
val params = mapOf(from to 1)
logCusEvent(MyApp.Config.languageChoose, params) logCusEvent(MyApp.Config.languageChoose, params)
} }
fun languageFromEvent(clickFrom: String,value: String) {
val params = mapOf(clickFrom to value)
logCusEvent(MyApp.Config.languageFrom, params)
}
fun textTransClickEvent() { fun textTransClickEvent() {
logCusEvent(MyApp.Config.textTransClick, null) logCusEvent(MyApp.Config.textTransClick, null)
} }
fun textTransResultEvent(result: String) { fun textTransResultEvent(result: String,value: String) {
val params = mapOf(result to 1) val params = mapOf(result to value)
logCusEvent(MyApp.Config.textTransResult, params) logCusEvent(MyApp.Config.textTransResult, params)
} }
@ -85,8 +77,8 @@ object FirebaseAnalyticsHelper {
} }
fun textVoiceResultEvent(failReason: String) { fun textVoiceResultEvent(failReason: String,value: String) {
val params = mapOf(failReason to 1) val params = mapOf(failReason to value)
logCusEvent(MyApp.Config.textVoiceResult, params) logCusEvent(MyApp.Config.textVoiceResult, params)
} }
@ -113,10 +105,106 @@ object FirebaseAnalyticsHelper {
logCusEvent(MyApp.Config.hoverButtonClick, null) logCusEvent(MyApp.Config.hoverButtonClick, null)
} }
fun hoverLimitAgreeEvent() {
logCusEvent(MyApp.Config.hoverLimitAgree, null)
}
fun hoverButtonCancelEvent() { fun hoverButtonCancelEvent() {
logCusEvent(MyApp.Config.hoverButtonCancel, null) logCusEvent(MyApp.Config.hoverButtonCancel, null)
} }
fun hoverButtonAgreeEvent() {
logCusEvent(MyApp.Config.hoverButtonAgree, null)
}
fun hoverScreenClickEvent() {
logCusEvent(MyApp.Config.hoverScreenClick, null)
}
fun hoverScreenImpEvent() {
logCusEvent(MyApp.Config.hoverScreenImp, null)
}
fun hoverScreenGlobalEvent() {
logCusEvent(MyApp.Config.hoverScreenGlobal, null)
}
fun hoverScreenDistrictEvent() {
logCusEvent(MyApp.Config.hoverScreenDistrict, null)
}
fun imageClickEvent(clickFrom: String,value: String) {
val params = mapOf(clickFrom to value)
logCusEvent(MyApp.Config.imageClick, params)
}
fun imageTransCameraEvent() {
logCusEvent(MyApp.Config.imageTransCamera, null)
}
fun imageTransPhotoEvent() {
logCusEvent(MyApp.Config.imageTransPhoto, null)
}
fun historyClickEvent() {
logCusEvent(MyApp.Config.historyClick, null)
}
fun historyDeleteEvent() {
logCusEvent(MyApp.Config.historyDelete, null)
}
fun hoverGlobalResultEvent(failReason: String,value: String) {
val params = mapOf(failReason to value)
logCusEvent(MyApp.Config.hoverGlobalResult, params)
}
fun hoverDistrictResultEvent(failReason: String,value: String) {
val params = mapOf(failReason to value)
logCusEvent(MyApp.Config.hoverDistrictResult, params)
}
fun imageCameraResultEvent(failReason: String,value: String) {
val params = mapOf(failReason to value)
logCusEvent(MyApp.Config.imageCameraResult, params)
}
fun imagePhotoResultEvent(failReason: String,value: String) {
val params = mapOf(failReason to value)
logCusEvent(MyApp.Config.imagePhotoResult, params)
}
//
// fun logEvent(eventName: String, myParam: Map<String, String>? = null) {
//
// val jsonObject = JSONObject()
// jsonObject.put("fail", e.toString())
// val map = mutableMapOf(Pair(MyApp.Config.CLICK_FROM, jsonObject.toString()))
// FirebaseAnalyticsHelper.logEvent(AnalysisUtil.APP_FIRST_OPEN_FAIL, map)
//
//
//
// if (myParam != null) {
// val bundle = Bundle()
// try {
// for ((key, value) in myParam) {
// if (!TextUtils.isEmpty(value) && !TextUtils.isEmpty(key)) {
// bundle.putString(key, value)
// }
// }
// firebaseAnalytics.logEvent(eventName, bundle)
// } catch (ignore: Exception) {
// }
// } else {
// try {
// firebaseAnalytics.logEvent(eventName, null)
// } catch (ignore: Exception) {
// }
// }
// }
//
} }

View File

@ -0,0 +1,206 @@
package com.assimilate.alltrans.common
import android.app.Activity
import android.util.Log
import android.widget.FrameLayout
import com.assimilate.alltrans.MyApp
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.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
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.AdInnerShowAdapter
import com.lol.apex.ok.google.adlibrary.inst.LOLAdsInstDispatcher
import com.lol.apex.ok.google.adlibrary.rewarded.LOLAdsRewardedDispatcher
class LolAdWrapper {
companion object {
val shared: LolAdWrapper by lazy { LolAdWrapper() }
}
interface LoLLoadListener {
fun loadFailed(error: LolLoadError?) {}
fun loaded() {}
}
interface LolShowListener {
fun shown() {}
fun showFailed(error: LolShowError?) {}
fun closed() {}
}
fun hasCache(placement: String): Boolean {
return LOLAdsInstDispatcher.canShow(placement, false)
}
fun hasRewardCache(placement: String): Boolean {
return LOLAdsRewardedDispatcher.canShow(placement)
}
private fun loadAd(act: Activity, placement: String, listener: LoLLoadListener? = null) {
if (act.isFinishing) return
LOLAdsInstDispatcher.getLoader(act, placement, object : AdLoadListener {
override fun onAdLoadFailed(error: LolLoadError?) {
//load广告失败打点
// val map = mutableMapOf(Pair(AnalysisUtil.PARAM_VALUE, "${error?.msg}"))
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_LOAD_FAILED, map)
listener?.loadFailed(error)
}
override fun onAdLoaded() {
listener?.loaded()
}
}).loadAd()
}
fun loadRewardAd(act: Activity, placement: String, listener: LoLLoadListener? = null) {
if (act.isFinishing) return
LOLAdsRewardedDispatcher.getLoader(act, placement, object : AdLoadListener {
override fun onAdLoadFailed(error: LolLoadError?) {
// val map = mutableMapOf(Pair(AnalysisUtil.PARAM_VALUE, "${error?.msg}"))
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_LOAD_FAILED, map)
listener?.loadFailed(error)
}
override fun onAdLoaded() {
listener?.loaded()
}
}).loadAd()
}
fun loadAdIfNotCached(act: Activity, placement: String, listener: LoLLoadListener? = null) {
if (act.isFinishing || hasCache(placement)) return
loadAd(act, placement, listener)
}
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)
}
}
fun showAdTiming(act: Activity, placement: String, listener: LolShowListener? = null) {
//当前时间减去旧时间,才展示广告满足间隔时间才show广告
if (System.currentTimeMillis() - MyApp.app.lastAdDisplayTime.get() >= AppStore(MyApp.app).showAdIntervalTime) {
//判断当前广告位是否可以show不能show则判断补位广告是否可以show。
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"))
// AnalysisUtil.placeToLogEvent(placement, AnalysisAdState.AD_SHOW_FAILED, map)
listener?.showFailed(LolShowError("No cache for ads"))
}
} else {
showAd(act, placement, listener)
}
}
}
fun loadAdShowNativeAd(
context: Activity, nativeId: String, frameAd: FrameLayout, admobLayout: Int, maxLayout: Int
) {
val inner = LOLAdsInnerDispatcher(context, object : AdInnerLoadAdapter() {
//设置广告位
override fun getPlace(): String {
return nativeId
}
//设置admob的native广告布局
override fun getAdmobLayoutResId(): Int {
return admobLayout
}
override fun getMaxLayoutResId(): Int {
return maxLayout
}
})
inner.addAdLoadListener(object : AdLoadListener {
override fun onAdLoadFailed(error: LolLoadError?) {
}
override fun onAdLoaded() {
}
})
//广告展示监听回调
inner.addAdShowListener(object : AdShowListener {
override fun onAdClicked() {
}
override fun onAdRewarded() {
}
override fun onAdShowFailed(error: LolShowError?) {
}
override fun onAdShown() {}
override fun onAdClosed() {}
override fun onAfterClickClosed() {}
override fun onDelayClosed() {}
})
inner.loadAd2Show(object : AdInnerShowAdapter() {
override fun getAdContainer(): FrameLayout {
return frameAd
}
})
}
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()
}
}

View File

@ -0,0 +1,61 @@
package com.assimilate.alltrans.common
import android.content.Context
import android.util.Log
import com.assimilate.alltrans.MyApp
import com.google.firebase.ktx.Firebase
import com.google.firebase.remoteconfig.ConfigUpdate
import com.google.firebase.remoteconfig.ConfigUpdateListener
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.firebase.remoteconfig.FirebaseRemoteConfigException
import com.google.firebase.remoteconfig.ktx.remoteConfig
import com.google.firebase.remoteconfig.ktx.remoteConfigSettings
class RemoteConfigManager(private val context: Context) {
private val remoteConfig: FirebaseRemoteConfig = Firebase.remoteConfig
init {
val configSettings = remoteConfigSettings {
minimumFetchIntervalInSeconds = 3600
}
remoteConfig.setConfigSettingsAsync(configSettings)
remoteConfig.fetchAndActivate()
.addOnCompleteListener { task ->
if (task.isSuccessful) {
val updated = task.result
Log.d(TAG, "Config params updated: $updated")
// Toast.makeText(context, "Fetch and activate succeeded", Toast.LENGTH_SHORT).show()
saveConfigValuesToAppStore()
} else {
// Toast.makeText(context, "Fetch failed", Toast.LENGTH_SHORT).show()
}
}
remoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener {
override fun onUpdate(configUpdate: ConfigUpdate) {
Log.d(TAG, "Updated keys: " + configUpdate.updatedKeys)
if (configUpdate.updatedKeys.contains(MyApp.Config.adKey)) {
remoteConfig.activate().addOnCompleteListener {
saveConfigValuesToAppStore()
}
}
}
override fun onError(error: FirebaseRemoteConfigException) {
Log.w(TAG, "Config update error with code: " + error.code, error)
}
})
}
private fun saveConfigValuesToAppStore() {
val appStore = AppStore(context)
val adValue = remoteConfig.getString(MyApp.Config.adKey)
appStore.saveString(MyApp.Config.adKey, adValue)
}
companion object {
private const val TAG = "RemoteConfigManager"
}
}

View File

@ -21,7 +21,8 @@ class TextGraphic(
private val showLanguageTag: Boolean, private val showLanguageTag: Boolean,
private val showConfidence: 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
) : GraphicOverlay.Graphic(overlay) { ) : GraphicOverlay.Graphic(overlay) {
private val textPaint: TextPaint = TextPaint().apply { private val textPaint: TextPaint = TextPaint().apply {
@ -41,7 +42,7 @@ class TextGraphic(
isVisible = textShow isVisible = textShow
if (needTrans) { if (needTrans) {
TranslationManager(text) { translatedTextPairs -> TranslationManager(text,fbFrom) { translatedTextPairs ->
translatedTextBlocks = translatedTextPairs.map { it.first } translatedTextBlocks = translatedTextPairs.map { it.first }
// 可以同时打印原Text和翻译后的结果 // 可以同时打印原Text和翻译后的结果
translatedTextPairs.forEach { (translated, original) -> translatedTextPairs.forEach { (translated, original) ->

View File

@ -4,8 +4,8 @@ import android.content.Context
import android.util.Log import android.util.Log
import com.assimilate.alltrans.MyApp import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.curview.GraphicOverlay import com.assimilate.alltrans.curview.GraphicOverlay
import com.assimilate.alltrans.keepmodel.LanguagesConstants import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.google.android.gms.tasks.Task import com.google.android.gms.tasks.Task
import com.google.mlkit.vision.common.InputImage import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.text.Text import com.google.mlkit.vision.text.Text
@ -19,6 +19,7 @@ class TextRecognitionProcessor(
textRecognizerOptions: TextRecognizerOptionsInterface, textRecognizerOptions: TextRecognizerOptionsInterface,
private val textShow:Boolean, private val textShow:Boolean,
private val needTrans: 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) {
@ -54,7 +55,8 @@ class TextRecognitionProcessor(
showLanguageTag, showLanguageTag,
showConfidence, showConfidence,
textShow, textShow,
needTrans needTrans,
fbFrom
) )
) )

View File

@ -2,18 +2,17 @@ package com.assimilate.alltrans.common
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.text.TextUtils
import android.util.Log
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
import com.assimilate.alltrans.keepmodel.LanguagesConstants import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.google.mlkit.vision.text.Text import com.google.mlkit.vision.text.Text
import java.util.concurrent.Executors import java.util.concurrent.Executors
class TranslationManager( class TranslationManager(
private val text: Text, private val text: Text,
private val fbFrom: String,
private val callback: (List<Pair<String, String>>) -> Unit // 修改callback的参数类型 private val callback: (List<Pair<String, String>>) -> Unit // 修改callback的参数类型
) { ) {
private val handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
@ -49,7 +48,8 @@ class TranslationManager(
translatedTextBlocks.add(Pair(index, textBlock.text)) translatedTextBlocks.add(Pair(index, textBlock.text))
if (translatedTextBlocks.size == text.textBlocks.size) { if (translatedTextBlocks.size == text.textBlocks.size) {
handler.post { handler.post {
callback(translatedTextBlocks.sortedBy { it.first }.map { it.second to text.textBlocks[it.first].text }) callback(translatedTextBlocks.sortedBy { it.first }
.map { it.second to text.textBlocks[it.first].text })
} }
} }
} else { } else {
@ -69,7 +69,8 @@ class TranslationManager(
if (translatedTextBlocks.size == text.textBlocks.size) { if (translatedTextBlocks.size == text.textBlocks.size) {
handler.post { handler.post {
callback(translatedTextBlocks.sortedBy { it.first }.map { it.second to text.textBlocks[it.first].text }) callback(translatedTextBlocks.sortedBy { it.first }
.map { it.second to text.textBlocks[it.first].text })
} }
} }
} }
@ -78,9 +79,33 @@ class TranslationManager(
translatedTextBlocks.add(Pair(index, "")) translatedTextBlocks.add(Pair(index, ""))
if (translatedTextBlocks.size == text.textBlocks.size) { if (translatedTextBlocks.size == text.textBlocks.size) {
handler.post { handler.post {
callback(translatedTextBlocks.sortedBy { it.first }.map { it.second to text.textBlocks[it.first].text }) callback(translatedTextBlocks.sortedBy { it.first }
.map { it.second to text.textBlocks[it.first].text })
} }
} }
when (fbFrom) {
"global" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"float" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"photo" -> {
FirebaseAnalyticsHelper.imagePhotoResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"image" -> {
FirebaseAnalyticsHelper.imageCameraResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
}
} }
}) })
} }

View File

@ -13,6 +13,7 @@ import android.view.View
import android.view.WindowManager import android.view.WindowManager
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.databinding.SusControlViewBinding import com.assimilate.alltrans.databinding.SusControlViewBinding
import com.assimilate.alltrans.viewui.MainActivity
import com.assimilate.alltrans.viewui.PhotoImageActivity import com.assimilate.alltrans.viewui.PhotoImageActivity
import com.assimilate.alltrans.viewui.WelActivity import com.assimilate.alltrans.viewui.WelActivity
@ -77,6 +78,7 @@ class ControlView(private val context: Context) {
layoutParams.y = 100 layoutParams.y = 100
windowManager.addView(controlView, layoutParams) windowManager.addView(controlView, layoutParams)
FirebaseAnalyticsHelper.hoverScreenImpEvent()
isAdded = true isAdded = true
initControlClick() initControlClick()
@ -115,6 +117,7 @@ class ControlView(private val context: Context) {
binding.tvSusPhoto.setOnClickListener { binding.tvSusPhoto.setOnClickListener {
val intent = Intent(context, PhotoImageActivity::class.java) val intent = Intent(context, PhotoImageActivity::class.java)
intent.putExtra("key_start_ph", "hover")
val pendingIntent = PendingIntent.getActivity( val pendingIntent = PendingIntent.getActivity(
context, context,
0, 0,
@ -133,7 +136,7 @@ class ControlView(private val context: Context) {
binding.ivSusHome.setOnClickListener { binding.ivSusHome.setOnClickListener {
Log.d("ControlViewManager", "Home clicked") Log.d("ControlViewManager", "Home clicked")
val intent = Intent(context, WelActivity::class.java) val intent = Intent(context, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity( val pendingIntent = PendingIntent.getActivity(
context, context,
0, 0,

View File

@ -14,10 +14,8 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.WindowManager import android.view.WindowManager
import android.widget.Toast import android.widget.Toast
import androidx.core.content.ContextCompat.getSystemService
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.databinding.LayoutSusCopyBinding import com.assimilate.alltrans.databinding.LayoutSusCopyBinding
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
import java.io.IOException import java.io.IOException
@ -40,7 +38,7 @@ class CopyTextView(private val context: Context) :
// 这里还需要调整 // 这里还需要调整
imageProcessor = TextRecognitionProcessor( imageProcessor = TextRecognitionProcessor(
context, context,
ChineseTextRecognizerOptions.Builder().build(), true, false, this ChineseTextRecognizerOptions.Builder().build(), true, false, "",this
) )
val inflater = LayoutInflater.from(context) val inflater = LayoutInflater.from(context)
@ -72,7 +70,7 @@ class CopyTextView(private val context: Context) :
Log.d("gdsfsfsadf",recognizedText.toString()) Log.d("gdsfsfsadf",recognizedText.toString())
copyToClipboard(recognizedText.toString()) copyToClipboard(recognizedText.toString())
removeView() // removeView()
} }
} }

View File

@ -8,7 +8,6 @@ import android.media.ImageReader
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import android.text.TextUtils
import android.util.Log import android.util.Log
import android.view.Gravity import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
@ -18,12 +17,13 @@ import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import com.assimilate.alltrans.MyApp import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.keepmodel.LanguagesConstants import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.Logger import com.assimilate.alltrans.common.Logger
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils
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
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.google.mlkit.vision.common.InputImage import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.text.TextRecognition import com.google.mlkit.vision.text.TextRecognition
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
@ -131,12 +131,14 @@ class DistrictView(
bindingSusDistrict.ivSourceClear.setOnClickListener { bindingSusDistrict.ivSourceClear.setOnClickListener {
bindingSusDistrict.tvTrSource.text = "" bindingSusDistrict.tvTrSource.text = ""
bindingSusDistrict.tvTrTarget.text = "" bindingSusDistrict.tvTrTarget.text = ""
removeDistrictView()
} }
} }
fun removeDistrictView() { fun removeDistrictView() {
windowManager.removeView(districtView) windowManager.removeView(districtView)
windowManager.removeView(overlayView) windowManager.removeView(overlayView)
} }
private fun takeDistrictScreenshot(image: Bitmap, rect: Rect) { private fun takeDistrictScreenshot(image: Bitmap, rect: Rect) {
@ -199,37 +201,27 @@ class DistrictView(
val translator: Translator<GoogleTranslator.GoogleTranslateCallback> = GoogleTranslator() val translator: Translator<GoogleTranslator.GoogleTranslateCallback> = GoogleTranslator()
translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback { translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback {
override fun onResponse(result: String?, errorMessage: String?) { override fun onResponse(result: String?, errorMessage: String?) {
Handler(Looper.getMainLooper()).post {
if (!TextUtils.isEmpty(result)) { if (!result.isNullOrEmpty()) {
bindingSusDistrict.tvTrTarget.text bindingSusDistrict.tvTrTarget.text = result
} else { } else if (!errorMessage.isNullOrEmpty()) {
// 处理错误信息
if (!TextUtils.isEmpty(errorMessage)) {
// 显示错误信息或记录日志
if (errorMessage != null) {
Log.e("TranslationError", errorMessage) Log.e("TranslationError", errorMessage)
bindingSusDistrict.tvTrTarget.text = "Translation error: $errorMessage"
} }
} }
bindingSusDistrict.tvTrTarget.text = "Translation failed: $errorMessage"
}
} }
override fun onFailure(errorMessage: String?) { override fun onFailure(errorMessage: String?) {
Handler(Looper.getMainLooper()).post {
FirebaseAnalyticsHelper.hoverDistrictResultEvent(
// 显示失败信息或记录日志 MyApp.Config.FAIL_REASON,
if (!TextUtils.isEmpty(errorMessage)) { "district" + errorMessage.toString()
if (errorMessage != null) { )
Log.e("TranslationFailure", errorMessage)
}
bindingSusDistrict.tvTrTarget.text = "Translation failed: $errorMessage" bindingSusDistrict.tvTrTarget.text = "Translation failed: $errorMessage"
} else {
bindingSusDistrict.tvTrTarget.text = "Translation failed: Unknown error"
} }
} }
}) })
} }
} }

View File

@ -1,75 +0,0 @@
package com.assimilate.alltrans.curview
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Rect
import android.view.MotionEvent
import android.view.View
import com.assimilate.alltrans.listeners.OnRegionSelectedListener
class DrawChooseView(context: Context) : View(context) {
private var paintTransparent: Paint = Paint()
private var paintSemiTransparent: Paint = Paint()
private var rect: Rect? = null
private var startX: Float = 0f
private var startY: Float = 0f
init {
paintTransparent.color = Color.TRANSPARENT
paintTransparent.style = Paint.Style.FILL
paintSemiTransparent.color = Color.parseColor("#88000000") // 半透明黑色
paintSemiTransparent.style = Paint.Style.FILL
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
rect?.let {
val left = Math.min(it.left, it.right)
val right = Math.max(it.left, it.right)
val top = Math.min(it.top, it.bottom)
val bottom = Math.max(it.top, it.bottom)
// 绘制框选外的半透明区域
canvas.drawRect(0f, 0f, width.toFloat(), top.toFloat(), paintSemiTransparent)
canvas.drawRect(0f, top.toFloat(), left.toFloat(), bottom.toFloat(), paintSemiTransparent)
canvas.drawRect(right.toFloat(), top.toFloat(), width.toFloat(), bottom.toFloat(), paintSemiTransparent)
canvas.drawRect(0f, bottom.toFloat(), width.toFloat(), height.toFloat(), paintSemiTransparent)
// 绘制框选内的透明区域
canvas.drawRect(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat(), paintTransparent)
}
}
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
startX = event.x
startY = event.y
rect = Rect(startX.toInt(), startY.toInt(), startX.toInt(), startY.toInt())
invalidate()
return true
}
MotionEvent.ACTION_MOVE -> {
rect?.apply {
right = event.x.toInt()
bottom = event.y.toInt()
}
invalidate()
return true
}
MotionEvent.ACTION_UP -> {
rect?.let {
(context as? OnRegionSelectedListener)?.onRegionSelected(it)
}
return true
}
}
return super.onTouchEvent(event)
}
}

View File

@ -14,6 +14,7 @@ import android.util.Log
import android.view.Gravity import android.view.Gravity
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewConfiguration
import android.view.WindowManager import android.view.WindowManager
import android.widget.ImageView import android.widget.ImageView
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
@ -56,11 +57,10 @@ class FloatingView(
// 初始化语言识别 // 初始化语言识别
imageProcessor = TextRecognitionProcessor( imageProcessor = TextRecognitionProcessor(
context, context,
ChineseTextRecognizerOptions.Builder().build(), false, true ChineseTextRecognizerOptions.Builder().build(), false, true, "float"
) )
graphicOverlay = GraphicOverlay(context, null) graphicOverlay = GraphicOverlay(context, null)
} }
interface OnMovePointListener { interface OnMovePointListener {
@ -123,11 +123,15 @@ class FloatingView(
private var initialTouchX = 0f private var initialTouchX = 0f
private var initialTouchY = 0f private var initialTouchY = 0f
private var isClick = true private var isClick = true
private var downTime: Long = 0
private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
private val maxClickDuration = 500 // 最大点击时间(毫秒)
override fun onTouch(v: View?, event: MotionEvent): Boolean { override fun onTouch(v: View?, event: MotionEvent): Boolean {
when (event.action) { when (event.action) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {
isClick = true isClick = true
downTime = System.currentTimeMillis()
initialX = params.x initialX = params.x
initialY = params.y initialY = params.y
initialTouchX = event.rawX initialTouchX = event.rawX
@ -139,21 +143,25 @@ class FloatingView(
} }
MotionEvent.ACTION_UP -> { MotionEvent.ACTION_UP -> {
val upTime = System.currentTimeMillis()
val duration = upTime - downTime
handler.postDelayed(fadeRunnable, 3000) handler.postDelayed(fadeRunnable, 3000)
imageView.setImageResource(originalImageResId) imageView.setImageResource(originalImageResId)
stickToEdge() stickToEdge()
if (isClick) {
if (isClick && duration < maxClickDuration) {
onClickListener?.onClick() onClickListener?.onClick()
} else { } else {
hasCapturedScreenshot = false
}
try { try {
windowManager.removeView(graphicOverlay) windowManager.removeView(graphicOverlay)
hasCapturedScreenshot = false
windowManager.updateViewLayout(imageView, params) 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)
} }
}
return true return true
} }
@ -162,14 +170,15 @@ class FloatingView(
val dx = event.rawX - initialTouchX val dx = event.rawX - initialTouchX
val dy = event.rawY - initialTouchY val dy = event.rawY - initialTouchY
if (dx * dx + dy * dy > imageView.width * imageView.width) { if (Math.abs(dx) > touchSlop || Math.abs(dy) > touchSlop) {
isClick = false isClick = false
} }
if (!isClick) { if (!isClick) {
// 将图片的位置设置为手指触摸点的上方 // 将图片的位置设置为手指触摸点的上方
params.x = initialX + dx.toInt() params.x = initialX + dx.toInt()
params.y = initialY + dy.toInt() - imageView.height / 2 // 调整y坐标使图片位于手指的上方 params.y =
initialY + dy.toInt() - imageView.height / 2 // 调整y坐标使图片位于手指的上方
onMovePointListener?.onMovePoint() onMovePointListener?.onMovePoint()
imageView.setImageResource(moveImageResId) imageView.setImageResource(moveImageResId)
@ -177,9 +186,8 @@ class FloatingView(
lastX = params.x + imageView.width / 2 lastX = params.x + imageView.width / 2
lastY = params.y + imageView.height / 2 lastY = params.y + imageView.height / 2
updateGraphicOverlay(lastX, lastY)
try { try {
updateGraphicOverlay(lastX, lastY)
windowManager.updateViewLayout(imageView, params) 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)
@ -188,7 +196,6 @@ class FloatingView(
return true return true
} }
} }
return false return false
} }
@ -247,6 +254,7 @@ class FloatingView(
BitmapFactory.decodeResource(context.resources, originalImageResId).width BitmapFactory.decodeResource(context.resources, originalImageResId).width
val edgeImageWidth = val edgeImageWidth =
BitmapFactory.decodeResource(context.resources, edgeImageResId).width BitmapFactory.decodeResource(context.resources, edgeImageResId).width
val isLeftEdge = params.x + originalImageWidth / 2 < screenWidth / 2 val isLeftEdge = params.x + originalImageWidth / 2 < screenWidth / 2
params.x = if (isLeftEdge) { params.x = if (isLeftEdge) {
0 0
@ -268,10 +276,21 @@ class FloatingView(
val bitmap = BitmapFactory.decodeResource(context.resources, edgeImageResId) val bitmap = BitmapFactory.decodeResource(context.resources, edgeImageResId)
if (isLeftEdge) { if (isLeftEdge) {
imageView.setImageBitmap(flipBitmapHorizontally(bitmap)) imageView.setImageBitmap(flipBitmapHorizontally(bitmap))
imageView.setPadding(0, 20, 30, 20) imageView.setPadding(0, 30, 50, 30)
} else { } else {
imageView.setImageBitmap(bitmap) imageView.setImageBitmap(bitmap)
imageView.setPadding(30, 20, 0, 20) imageView.setPadding(50, 30, 0, 30)
}
destroyGraphicOverlay()
}
private fun destroyGraphicOverlay() {
try {
if (isAttachedToWindow && graphicOverlay?.parent != null) {
windowManager.removeView(graphicOverlay)
}
} catch (e: IllegalArgumentException) {
Log.e("FloatingView", "View not attached to window manager", e)
} }
} }
@ -289,8 +308,6 @@ class FloatingView(
} }
fun detachFromWindow() { fun detachFromWindow() {
Log.e("FloatingView", "View not attached to window manager")
if (isAttachedToWindow) { if (isAttachedToWindow) {
try { try {
windowManager.removeView(imageView) windowManager.removeView(imageView)
@ -339,7 +356,6 @@ class FloatingView(
} }
fun setImageReader(reader: ImageReader) { fun setImageReader(reader: ImageReader) {
this.imageReader = reader this.imageReader = reader
if (!hasCapturedScreenshot) { if (!hasCapturedScreenshot) {
hasCapturedScreenshot = true hasCapturedScreenshot = true
@ -347,8 +363,5 @@ class FloatingView(
windowManager.addView(graphicOverlay, fullScreenParams) windowManager.addView(graphicOverlay, fullScreenParams)
} }
} }
} }

View File

@ -32,7 +32,7 @@ class GlobalView(private val context: Context) {
// 这里还需要调整 // 这里还需要调整
imageProcessor = TextRecognitionProcessor( imageProcessor = TextRecognitionProcessor(
context, context,
ChineseTextRecognizerOptions.Builder().build(),true,true ChineseTextRecognizerOptions.Builder().build(), true, true, "global"
) )
bindingSubGlobal = LayoutSusGlobalBinding.inflate(LayoutInflater.from(context)) bindingSubGlobal = LayoutSusGlobalBinding.inflate(LayoutInflater.from(context))
globalView = bindingSubGlobal.root globalView = bindingSubGlobal.root
@ -125,4 +125,5 @@ class GlobalView(private val context: Context) {
} }
} }
} }

View File

@ -12,11 +12,13 @@ import android.view.View
import android.view.WindowManager import android.view.WindowManager
import androidx.core.content.ContextCompat.getColor import androidx.core.content.ContextCompat.getColor
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.LanguageAdapter import com.assimilate.alltrans.adapters.LanguageAdapter
import com.assimilate.alltrans.keepmodel.Language import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.keepmodel.LanguagesConstants import com.assimilate.alltrans.model.Language
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.databinding.LayoutSusChangelanBinding import com.assimilate.alltrans.databinding.LayoutSusChangelanBinding
class LanguageSelectorView(private val context: Context) { class LanguageSelectorView(private val context: Context) {
@ -141,10 +143,11 @@ class LanguageSelectorView(private val context: Context) {
// 更新界面显示 // 更新界面显示
binding?.tvChangeSource?.text = currentTargetLanguage binding?.tvChangeSource?.text = currentTargetLanguage
binding?.tvChangeTarget?.text = currentSourceLanguage binding?.tvChangeTarget?.text = currentSourceLanguage
FirebaseAnalyticsHelper.textTransSwitchEvent(MyApp.Config.CLICK_FROM, "hover")
removeFloatingView() removeFloatingView()
} }
} }
private fun initAllList() { private fun initAllList() {
@ -153,9 +156,17 @@ class LanguageSelectorView(private val context: Context) {
val adapter = LanguageAdapter(context, languages) { _, language -> val adapter = LanguageAdapter(context, languages) { _, language ->
Log.d("LanguageChange", language.language) Log.d("LanguageChange", language.language)
if (lastTranslateLanguage) { if (lastTranslateLanguage) {
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
"hover_target"
)
PreferenceLanguageUtils.putString("language_target", language.language) PreferenceLanguageUtils.putString("language_target", language.language)
removeFloatingView() removeFloatingView()
} else { } else {
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
"hover_source"
)
PreferenceLanguageUtils.putString("language_source", language.language) PreferenceLanguageUtils.putString("language_source", language.language)
removeFloatingView() removeFloatingView()
} }
@ -170,11 +181,13 @@ class LanguageSelectorView(private val context: Context) {
} }
} }
private fun removeFloatingView() {
fun removeFloatingView() {
binding?.root?.let { binding?.root?.let {
windowManager.removeView(it) windowManager.removeView(it)
windowManager.removeView(fullScreenView)
} }
binding = null binding = null
} }
} }

View File

@ -12,8 +12,12 @@ 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
@ -132,4 +136,6 @@ class SelectionView(private val context: Context) {
invalidate() invalidate()
} }
} }
} }

View File

@ -1,4 +1,4 @@
package com.assimilate.alltrans.keepmodel; package com.assimilate.alltrans.model;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;

View File

@ -1,4 +1,4 @@
package com.assimilate.alltrans.keepmodel; package com.assimilate.alltrans.model;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;

View File

@ -1,4 +1,4 @@
package com.assimilate.alltrans.keepmodel package com.assimilate.alltrans.model
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences

View File

@ -4,18 +4,24 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.speech.tts.TextToSpeech import android.speech.tts.TextToSpeech
import android.view.View import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.TranslationAdapter import com.assimilate.alltrans.adapters.TranslationAdapter
import com.assimilate.alltrans.adapters.TranslationAdapter.TranslationItemCallback import com.assimilate.alltrans.adapters.TranslationAdapter.TranslationItemCallback
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.common.Widget import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityHistoryBinding import com.assimilate.alltrans.databinding.ActivityHistoryBinding
import com.assimilate.alltrans.mydb.DbTranslation import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations import com.assimilate.alltrans.mydb.Translations
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import java.util.Locale import java.util.Locale
class HistoryActivity : AppCompatActivity() { class HistoryActivity : AppCompatActivity() {
@ -123,6 +129,7 @@ class HistoryActivity : AppCompatActivity() {
private fun remove(id: Long, index: Int) { private fun remove(id: Long, index: Int) {
ids!!.remove(id) ids!!.remove(id)
items!!.remove(index) items!!.remove(index)
FirebaseAnalyticsHelper.historyDeleteEvent()
} }
private fun updateBtn() { private fun updateBtn() {
@ -175,12 +182,71 @@ class HistoryActivity : AppCompatActivity() {
binding!!.histories.layoutManager = layoutManager binding!!.histories.layoutManager = layoutManager
binding!!.histories.adapter = adapter binding!!.histories.adapter = adapter
} adLoad(MyApp.Config.history_int_auto)
backPressedCall()
}
private fun initClick() { private fun initClick() {
binding?.ivHisBack?.setOnClickListener { onBackPressed() } binding?.ivHisBack?.setOnClickListener {
showInstAdFromCache(MyApp.Config.history_int_auto)
finish()
} }
}
private fun backPressedCall() {
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
showInstAdFromCache(MyApp.Config.history_int_auto)
finish()
}
}
onBackPressedDispatcher.addCallback(this, callback)
}
private fun adLoad(place: String) {
// 加载广告
LolAdWrapper.shared.loadAdIfNotCached(
this,
place,
object : LolAdWrapper.LoLLoadListener {
override fun loadFailed(error: LolLoadError?) {
// Log.d("dsas",error.toString())
}
override fun loaded() {
// 处理加载成功
// Log.d("dsas","backSucc")
}
})
}
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()
}
})
}
companion object { companion object {
const val COMMAND: String = "remove" const val COMMAND: String = "remove"

View File

@ -16,10 +16,10 @@ import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.LanguageAdapter import com.assimilate.alltrans.adapters.LanguageAdapter
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.keepmodel.Language
import com.assimilate.alltrans.keepmodel.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.databinding.ActivityLanguageChangeBinding import com.assimilate.alltrans.databinding.ActivityLanguageChangeBinding
import com.assimilate.alltrans.model.Language
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -41,32 +41,20 @@ class LanguageChangeActivity : AppCompatActivity() {
} }
initView() initView()
initSearch() // 添加这一行 initSearch()
lifecycleScope.launch { lifecycleScope.launch {
withContext(Dispatchers.IO) {
// 耗时操作
initAllList() initAllList()
} }
}
initClick() initClick()
} }
private fun initSearch() { private fun initSearch() {
binding.chSearch.apply { binding.chSearch.apply {
// 获取关闭按钮的ImageView
val closeButton = findViewById<ImageView>(androidx.appcompat.R.id.search_close_btn) val closeButton = findViewById<ImageView>(androidx.appcompat.R.id.search_close_btn)
// 设置关闭按钮一直可见
closeButton.visibility = View.VISIBLE closeButton.visibility = View.VISIBLE
// 确保 SearchView 处于可点击状态
isFocusable = true isFocusable = true
isIconified = false isIconified = false
post { clearFocus() }
// 延迟请求焦点以避免弹出软件盘
post {
clearFocus()
}
setOnQueryTextListener(object : setOnQueryTextListener(object :
androidx.appcompat.widget.SearchView.OnQueryTextListener { androidx.appcompat.widget.SearchView.OnQueryTextListener {
@ -80,14 +68,9 @@ class LanguageChangeActivity : AppCompatActivity() {
} }
}) })
// 设置点击关闭按钮的行为
closeButton.setOnClickListener { closeButton.setOnClickListener {
// 清空搜索框
setQuery("", false) setQuery("", false)
// 清除焦点
clearFocus() clearFocus()
// 隐藏软件盘
val imm = val imm =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(windowToken, 0) imm.hideSoftInputFromWindow(windowToken, 0)
@ -96,7 +79,6 @@ class LanguageChangeActivity : AppCompatActivity() {
} }
private fun initView() { private fun initView() {
val intentT = intent val intentT = intent
if (intentT.getBooleanExtra("choose_t", false)) { if (intentT.getBooleanExtra("choose_t", false)) {
lastTranslateLanguage = true lastTranslateLanguage = true
@ -108,39 +90,60 @@ class LanguageChangeActivity : AppCompatActivity() {
binding.tvChangeTarget.setTextColor(getColor(R.color.main_text_ff1f1724)) binding.tvChangeTarget.setTextColor(getColor(R.color.main_text_ff1f1724))
} }
binding.tvChangeSource.text = PreferenceLanguageUtils.getString("language_source") binding.tvChangeSource.text = PreferenceLanguageUtils.getString("language_source")
binding.tvChangeTarget.text = PreferenceLanguageUtils.getString("language_target") binding.tvChangeTarget.text = PreferenceLanguageUtils.getString("language_target")
updateRecentLanguages() updateRecentLanguages()
} }
private fun updateRecentLanguages() { private fun updateRecentLanguages() {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
val recentLanguages = PreferenceLanguageUtils.getRecentLanguages() val recentLanguages = PreferenceLanguageUtils.getRecentLanguages()
withContext(Dispatchers.Main) {
if (recentLanguages.isNotEmpty()) { if (recentLanguages.isNotEmpty()) {
val recentAdapter = LanguageAdapter(this, ArrayList(recentLanguages)) { _, language -> val recentAdapter = LanguageAdapter(
this@LanguageChangeActivity,
ArrayList(recentLanguages)
) { _, language ->
handleLanguageSelection(language)
}
binding.listLanCommon5.layoutManager =
LinearLayoutManager(
this@LanguageChangeActivity,
LinearLayoutManager.VERTICAL,
false
)
binding.listLanCommon5.adapter = recentAdapter
}
}
}
}
}
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)
onBackPressed()
} else { } else {
PreferenceLanguageUtils.putString("language_source", language.language) PreferenceLanguageUtils.putString("language_source", language.language)
onBackPressed()
} }
FirebaseAnalyticsHelper.languageChooseEvent(
MyApp.Config.CLICK_FROM,
if (lastTranslateLanguage) "target_${language.language}" else "source_${language.language}"
)
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
if (lastTranslateLanguage) "home_target" else "home_source"
)
PreferenceLanguageUtils.addRecentLanguage(language) PreferenceLanguageUtils.addRecentLanguage(language)
binding.tvChangeSource.text = PreferenceLanguageUtils.getString("language_source") binding.tvChangeSource.text = PreferenceLanguageUtils.getString("language_source")
binding.tvChangeTarget.text = PreferenceLanguageUtils.getString("language_target") binding.tvChangeTarget.text = PreferenceLanguageUtils.getString("language_target")
updateRecentLanguages() updateRecentLanguages()
} finish()
binding.listLanCommon5.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.listLanCommon5.adapter = recentAdapter
}
} }
private fun initClick() { private fun initClick() {
binding.ivChBack.setOnClickListener { onBackPressed() } binding.ivChBack.setOnClickListener { finish() }
binding.tvChangeSource.setOnClickListener { binding.tvChangeSource.setOnClickListener {
lastTranslateLanguage = false lastTranslateLanguage = false
binding.tvChangeSource.setTextColor(getColor(R.color.main_text_ff0e8ce8)) binding.tvChangeSource.setTextColor(getColor(R.color.main_text_ff0e8ce8))
@ -155,41 +158,35 @@ class LanguageChangeActivity : AppCompatActivity() {
binding.tvExchange.setOnClickListener { binding.tvExchange.setOnClickListener {
val currentSourceLanguage = PreferenceLanguageUtils.getString("language_source") val currentSourceLanguage = PreferenceLanguageUtils.getString("language_source")
val currentTargetLanguage = PreferenceLanguageUtils.getString("language_target") val currentTargetLanguage = PreferenceLanguageUtils.getString("language_target")
// 交换源语言和目标语言
PreferenceLanguageUtils.putString("language_source", currentTargetLanguage) PreferenceLanguageUtils.putString("language_source", currentTargetLanguage)
PreferenceLanguageUtils.putString("language_target", currentSourceLanguage) PreferenceLanguageUtils.putString("language_target", currentSourceLanguage)
// 更新界面显示
binding.tvChangeSource.text = currentTargetLanguage binding.tvChangeSource.text = currentTargetLanguage
binding.tvChangeTarget.text = currentSourceLanguage binding.tvChangeTarget.text = currentSourceLanguage
onBackPressed() FirebaseAnalyticsHelper.textTransSwitchEvent(MyApp.Config.CLICK_FROM, "home")
finish()
}
} }
private suspend fun initAllList() {
} withContext(Dispatchers.IO) {
val languages: ArrayList<Language> =
private fun initAllList() { LanguagesConstants.getInstance().getList(this@LanguageChangeActivity)
val languages: ArrayList<Language> = LanguagesConstants.getInstance().getList(this) withContext(Dispatchers.Main) {
if (languages.isNotEmpty()) { if (languages.isNotEmpty()) {
val adapter = LanguageAdapter(this, languages) { _, language -> val adapter =
Log.d("LanguageChange", language.language) LanguageAdapter(this@LanguageChangeActivity, languages) { _, language ->
if (lastTranslateLanguage) { handleLanguageSelection(language)
PreferenceLanguageUtils.putString("language_target", language.language)
FirebaseAnalyticsHelper.languageChooseEvent("target_" + language.language)
onBackPressed()
} else {
PreferenceLanguageUtils.putString("language_source", language.language)
FirebaseAnalyticsHelper.languageChooseEvent("source_" + language.language)
onBackPressed()
}
PreferenceLanguageUtils.addRecentLanguage(language)
binding.tvChangeSource.text = PreferenceLanguageUtils.getString("language_source")
binding.tvChangeTarget.text = PreferenceLanguageUtils.getString("language_target")
updateRecentLanguages()
} }
binding.listLanguages.layoutManager = binding.listLanguages.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) LinearLayoutManager(
this@LanguageChangeActivity,
LinearLayoutManager.VERTICAL,
false
)
binding.listLanguages.adapter = adapter binding.listLanguages.adapter = adapter
} }
} }
}
}
} }

View File

@ -2,7 +2,6 @@ package com.assimilate.alltrans.viewui
import android.app.ActivityManager import android.app.ActivityManager
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.ClipDescription
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -18,7 +17,6 @@ import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.EditText
import android.widget.Toast import android.widget.Toast
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
@ -26,13 +24,16 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.allservice.SusService import com.assimilate.alltrans.allservice.SusService
import com.assimilate.alltrans.common.AppStore
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.common.Widget import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityMainBinding import com.assimilate.alltrans.databinding.ActivityMainBinding
import com.assimilate.alltrans.keepmodel.LanguagesConstants import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils import com.assimilate.alltrans.model.PreferenceLanguageUtils
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
@ -50,7 +51,10 @@ class MainActivity : AppCompatActivity() {
if (speech != null) { if (speech != null) {
binding.etText.setText(speech) binding.etText.setText(speech)
} else { } else {
FirebaseAnalyticsHelper.textVoiceResultEvent("speech_is_null") FirebaseAnalyticsHelper.textVoiceResultEvent(
MyApp.Config.FAIL_REASON,
"speech_is_null"
)
} }
} }
} }
@ -71,6 +75,8 @@ class MainActivity : AppCompatActivity() {
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(26, systemBars.top + 26, 26, systemBars.bottom) v.setPadding(26, systemBars.top + 26, 26, systemBars.bottom)
@ -98,7 +104,7 @@ class MainActivity : AppCompatActivity() {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK) {
serverIsStart = true serverIsStart = true
binding.ivQuickStart.setImageResource(R.drawable.main_setting_quick) binding.ivQuickStart.setImageResource(R.drawable.main_setting_quick)
FirebaseAnalyticsHelper.hoverButtonClickEvent()
// 权限授予,启动截图 // 权限授予,启动截图
val serviceIntent = Intent(this, SusService::class.java).apply { val serviceIntent = Intent(this, SusService::class.java).apply {
@ -110,23 +116,33 @@ class MainActivity : AppCompatActivity() {
} else { } else {
startService(serviceIntent) startService(serviceIntent)
} }
FirebaseAnalyticsHelper.hoverButtonAgreeEvent()
} else { } else {
Widget.makeToast( Widget.makeToast(
this, this,
"Please allow access to screen information to identify the content that needs translation." "Please allow access to screen information to identify the content that needs translation."
) )
FirebaseAnalyticsHelper.hoverButtonCancelEvent()
} }
} }
} }
private fun initView() { private fun initView() {
LolAdWrapper.shared.loadAdShowNativeAd(
this,
"your_native_ad_placement",
binding.homeNative,
R.layout.ad_layout_admob_banner,
R.layout.ad_layout_max_banner
)
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() {
FirebaseAnalyticsHelper.homePvEvent("create") loadNative()
val isRunning = isServiceRunning(this, SusService::class.java) val isRunning = isServiceRunning(this, SusService::class.java)
if (isRunning) { if (isRunning) {
@ -142,17 +158,18 @@ class MainActivity : AppCompatActivity() {
// 初始化截屏 // 初始化截屏
mediaProjectionManager = mediaProjectionManager =
getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
FirebaseAnalyticsHelper.homePvEvent(MyApp.Config.CLICK_FROM, "create")
} }
private fun initClick() { private fun initClick() {
binding.tvMainDic.setOnClickListener { binding.tvMainDic.setOnClickListener {
// startActivity(Intent(this,DicActivity::class.java)) // startActivity(Intent(this,DicActivity::class.java))
} }
binding.tvMainPhotoTrans.setOnClickListener { binding.tvMainPhotoTrans.setOnClickListener {
startActivity( startActivity(
Intent(this, PhotoImageActivity::class.java) Intent(this, PhotoImageActivity::class.java).putExtra("key_start_ph", "camera")
) )
} }
binding.tvMainVoice.setOnClickListener { binding.tvMainVoice.setOnClickListener {
@ -189,11 +206,12 @@ class MainActivity : AppCompatActivity() {
startActivity( startActivity(
intent intent
) )
FirebaseAnalyticsHelper.historyClickEvent()
} }
binding.llQuickSet.setOnClickListener { binding.llQuickSet.setOnClickListener {
startActivity( // startActivity(
Intent(this, QuickSetActivity::class.java) // Intent(this, QuickSetActivity::class.java)
) // )
} }
binding.ivQuickStart.setOnClickListener { binding.ivQuickStart.setOnClickListener {
if (!serverIsStart) { if (!serverIsStart) {
@ -205,6 +223,7 @@ class MainActivity : AppCompatActivity() {
) )
startActivityForResult(intent, REQUEST_CODE_OVERLAY) startActivityForResult(intent, REQUEST_CODE_OVERLAY)
} else { } else {
FirebaseAnalyticsHelper.hoverLimitAgreeEvent()
checkAndRequestMediaProjectionPermission() checkAndRequestMediaProjectionPermission()
} }
} else { } else {
@ -212,9 +231,9 @@ class MainActivity : AppCompatActivity() {
serverIsStart = false serverIsStart = false
binding.ivQuickStart.setImageResource(R.drawable.main_setting_quick_def) binding.ivQuickStart.setImageResource(R.drawable.main_setting_quick_def)
FirebaseAnalyticsHelper.hoverButtonCancelEvent()
}
}
FirebaseAnalyticsHelper.hoverButtonClickEvent()
} }
@ -270,7 +289,6 @@ class MainActivity : AppCompatActivity() {
} }
private fun checkAndRequestMediaProjectionPermission() { private fun checkAndRequestMediaProjectionPermission() {
// 启动截图 // 启动截图
startActivityForResult( startActivityForResult(
@ -321,7 +339,10 @@ class MainActivity : AppCompatActivity() {
try { try {
launcher.launch(speechIntent) launcher.launch(speechIntent)
} catch (ea: ActivityNotFoundException) { } catch (ea: ActivityNotFoundException) {
FirebaseAnalyticsHelper.textVoiceResultEvent("device_not_support") FirebaseAnalyticsHelper.textVoiceResultEvent(
MyApp.Config.FAIL_REASON,
"device_not_support"
)
Widget.makeToast(this, getString(R.string.main_voice_to_text)) Widget.makeToast(this, getString(R.string.main_voice_to_text))
} }
@ -374,7 +395,7 @@ class MainActivity : AppCompatActivity() {
override fun onRestart() { override fun onRestart() {
super.onRestart() super.onRestart()
FirebaseAnalyticsHelper.homePvEvent("cap") FirebaseAnalyticsHelper.homePvEvent(MyApp.Config.CLICK_FROM, "cap")
} }
override fun onDestroy() { override fun onDestroy() {
@ -403,5 +424,14 @@ class MainActivity : AppCompatActivity() {
onBackPressedDispatcher.addCallback(this, callback) onBackPressedDispatcher.addCallback(this, callback)
} }
private fun loadNative() {
LolAdWrapper.shared.loadAdShowNativeAd(
this,
MyApp.Config.home_native_auto,
binding.homeNative,
R.layout.ad_layout_admob_banner,
R.layout.ad_layout_max_banner
)
}
} }

View File

@ -16,6 +16,7 @@ import android.view.View
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector import androidx.camera.core.CameraSelector
@ -30,12 +31,15 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.LanguageAdapter import com.assimilate.alltrans.adapters.LanguageAdapter
import com.assimilate.alltrans.common.BitmapUtils import com.assimilate.alltrans.common.BitmapUtils
import com.assimilate.alltrans.keepmodel.Language import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.keepmodel.LanguagesConstants import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils import com.assimilate.alltrans.model.Language
import com.assimilate.alltrans.model.LanguagesConstants
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
@ -48,6 +52,8 @@ import com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions
import com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions import com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions
import com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions import com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions
import com.google.mlkit.vision.text.latin.TextRecognizerOptions import com.google.mlkit.vision.text.latin.TextRecognizerOptions
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -69,6 +75,7 @@ class PhotoImageActivity : AppCompatActivity() {
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 val REQUEST_CAMERA_PERMISSION = 100 private val REQUEST_CAMERA_PERMISSION = 100
private lateinit var bottomSheetDialog: BottomSheetDialog private lateinit var bottomSheetDialog: BottomSheetDialog
@ -85,6 +92,7 @@ class PhotoImageActivity : AppCompatActivity() {
v.setPadding(0, systemBars.top + 26, 0, systemBars.bottom) v.setPadding(0, systemBars.top + 26, 0, systemBars.bottom)
insets insets
} }
firebaseEvent()
Widget.makeSnackbar(this, "Photographing text for translation") Widget.makeSnackbar(this, "Photographing text for translation")
@ -113,9 +121,20 @@ class PhotoImageActivity : AppCompatActivity() {
// 检查并启动相机 // 检查并启动相机
checkCameraPermission() checkCameraPermission()
initView() initView()
adLoad(MyApp.Config.image_camera_int_auto)
backPressedCall()
initClick() initClick()
} }
private fun firebaseEvent() {
// 获取意图中的数据
val eventKey = intent.getStringExtra("key_start_ph")
// 记录Firebase Analytics事件
if (eventKey != null) {
FirebaseAnalyticsHelper.imageClickEvent(MyApp.Config.CLICK_FROM, eventKey)
}
}
private fun checkCameraPermission() { private fun checkCameraPermission() {
if (ContextCompat.checkSelfPermission( if (ContextCompat.checkSelfPermission(
this, Manifest.permission.CAMERA this, Manifest.permission.CAMERA
@ -131,6 +150,7 @@ class PhotoImageActivity : AppCompatActivity() {
} }
} }
private fun initView() { private fun initView() {
binding.photoPreview.visibility = View.VISIBLE binding.photoPreview.visibility = View.VISIBLE
@ -201,9 +221,18 @@ class PhotoImageActivity : AppCompatActivity() {
PreferenceLanguageUtils.putString("language_source", language.language) PreferenceLanguageUtils.putString("language_source", language.language)
selectedMode = PreferenceLanguageUtils.getString("language_source") selectedMode = PreferenceLanguageUtils.getString("language_source")
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
"photo_source"
)
tryReloadAndDetectInImage() tryReloadAndDetectInImage()
bottomSheetDialog.dismiss() bottomSheetDialog.dismiss()
} else { } else {
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
"photo_target"
)
PreferenceLanguageUtils.putString("language_target", language.language) PreferenceLanguageUtils.putString("language_target", language.language)
tryReloadAndDetectInImage() tryReloadAndDetectInImage()
@ -222,25 +251,28 @@ class PhotoImageActivity : AppCompatActivity() {
} }
} }
private fun initClick() { private fun initClick() {
binding.ivStillPic.setOnClickListener { binding.ivStillPic.setOnClickListener {
binding.photoPreview.visibility = View.INVISIBLE binding.photoPreview.visibility = View.INVISIBLE
startChooseImageIntentForResult() startChooseImageIntentForResult()
FirebaseAnalyticsHelper.imageTransPhotoEvent()
} }
binding.ivStillTake.setOnClickListener { binding.ivStillTake.setOnClickListener {
binding.photoPreview.visibility = View.VISIBLE binding.photoPreview.visibility = View.VISIBLE
takePhoto() takePhoto()
FirebaseAnalyticsHelper.imageTransCameraEvent()
}
binding.ivStillBack.setOnClickListener {
showInstAdFromCache(MyApp.Config.image_camera_int_auto)
finish()
} }
binding.ivStillBack.setOnClickListener { onBackPressed() }
binding.ivStillBuling.setOnClickListener { binding.ivStillBuling.setOnClickListener {
toggleFlash() toggleFlash()
updateFlashButtonUI() updateFlashButtonUI()
} }
binding.stillSourceLanguage.setOnClickListener { binding.stillSourceLanguage.setOnClickListener {
chooseLanguage = false chooseLanguage = false
bottomSheetDialog.show() bottomSheetDialog.show()
} }
binding.stillTargetLanguage.setOnClickListener { binding.stillTargetLanguage.setOnClickListener {
@ -257,6 +289,8 @@ class PhotoImageActivity : AppCompatActivity() {
// 更新界面显示 // 更新界面显示
binding.stillSourceLanguage.text = currentTargetLanguage binding.stillSourceLanguage.text = currentTargetLanguage
binding.stillTargetLanguage.text = currentSourceLanguage binding.stillTargetLanguage.text = currentSourceLanguage
FirebaseAnalyticsHelper.textTransSwitchEvent(MyApp.Config.CLICK_FROM, "photo")
} }
} }
@ -293,6 +327,7 @@ class PhotoImageActivity : AppCompatActivity() {
} }
private fun takePhoto() { private fun takePhoto() {
fbFrom = "photo"
val photoFile = File( val photoFile = File(
outputDirectory, outputDirectory,
SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(System.currentTimeMillis()) + ".jpg" SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(System.currentTimeMillis()) + ".jpg"
@ -378,30 +413,31 @@ 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 ChineseTextRecognizerOptions.Builder().build(), true, true, fbFrom
) )
"Hindi", "Marathi", "Nepali", "Sanskrit" -> TextRecognitionProcessor( "Hindi", "Marathi", "Nepali", "Sanskrit" -> TextRecognitionProcessor(
this, this,
DevanagariTextRecognizerOptions.Builder().build(), true, true DevanagariTextRecognizerOptions.Builder().build(), true, true, fbFrom
) )
TEXT_RECOGNITION_JAPANESE -> TextRecognitionProcessor( TEXT_RECOGNITION_JAPANESE -> TextRecognitionProcessor(
this, this,
JapaneseTextRecognizerOptions.Builder().build(), true, true JapaneseTextRecognizerOptions.Builder().build(), true, true, fbFrom
) )
TEXT_RECOGNITION_KOREAN -> TextRecognitionProcessor( TEXT_RECOGNITION_KOREAN -> TextRecognitionProcessor(
this, this,
KoreanTextRecognizerOptions.Builder().build(), true, true KoreanTextRecognizerOptions.Builder().build(), true, true, fbFrom
) )
else -> TextRecognitionProcessor( else -> TextRecognitionProcessor(
this, this,
TextRecognizerOptions.Builder().build(), true, true TextRecognizerOptions.Builder().build(), true, true, fbFrom
) )
} }
@ -481,6 +517,59 @@ class PhotoImageActivity : AppCompatActivity() {
} }
} }
private fun backPressedCall() {
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
showInstAdFromCache(MyApp.Config.image_camera_int_auto)
finish()
}
}
onBackPressedDispatcher.addCallback(this, callback)
}
private fun adLoad(place: String) {
// 加载广告
LolAdWrapper.shared.loadAdIfNotCached(
this,
place,
object : LolAdWrapper.LoLLoadListener {
override fun loadFailed(error: LolLoadError?) {
// Log.d("dsas",error.toString())
}
override fun loaded() {
// 处理加载成功
// Log.d("dsas","backSucc")
}
})
}
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()
}
})
}
companion object { companion object {
private const val TAG = "StillImageActivity" private const val TAG = "StillImageActivity"
private const val KEY_IMAGE_URI = "com.google.mlkit.demo.stillImage.KEY_IMAGE_URI" private const val KEY_IMAGE_URI = "com.google.mlkit.demo.stillImage.KEY_IMAGE_URI"
@ -496,5 +585,7 @@ class PhotoImageActivity : AppCompatActivity() {
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS" private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
private const val REQUEST_CHOOSE_IMAGE = 1001 private const val REQUEST_CHOOSE_IMAGE = 1001
} }
} }

View File

@ -1,12 +1,15 @@
package com.assimilate.alltrans.viewui package com.assimilate.alltrans.viewui
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
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.ActivityQuickSetBinding import com.assimilate.alltrans.databinding.ActivityQuickSetBinding
import com.google.android.material.slider.Slider
class QuickSetActivity : AppCompatActivity() { class QuickSetActivity : AppCompatActivity() {
@ -22,5 +25,25 @@ class QuickSetActivity : AppCompatActivity() {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets insets
} }
sliderSet()
initClick()
}
private fun initClick() {
binding.qsBack.setOnClickListener { finish() }
}
private fun sliderSet() {
binding.slider1.setLabelFormatter { value ->
val percentage = ((value / 5) * 100).toInt()
"$percentage%"
}
binding.slider1.addOnChangeListener(Slider.OnChangeListener { _, value, _ ->
val percentage = ((value / 5) * 100).toInt()
Toast.makeText(this, "Value: $percentage", Toast.LENGTH_SHORT).show()
})
} }
} }

View File

@ -1,15 +1,17 @@
package com.assimilate.alltrans.viewui package com.assimilate.alltrans.viewui
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.widget.RatingBar
import android.widget.TextView import android.widget.TextView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
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.common.Widget
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
@ -18,6 +20,7 @@ class SettingsActivity
: AppCompatActivity() { : AppCompatActivity() {
private lateinit var binding: ActivitySettingsBinding private lateinit var binding: ActivitySettingsBinding
private lateinit var bottomSheetDialog: BottomSheetDialog private lateinit var bottomSheetDialog: BottomSheetDialog
private var userChoose = 1
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -30,25 +33,18 @@ class SettingsActivity
insets insets
} }
initView() initView()
initClick() initClick()
} }
private fun initView() { private fun initView() {
// 设置 BottomSheetDialog setBottomSheet()
bottomSheetDialog = BottomSheetDialog(this) setVersion()
bottomSheetDialog.setContentView(R.layout.bottomsheet_rate)
bottomSheetDialog.dismissWithAnimation = true
bottomSheetDialog.findViewById<TextView>(R.id.tv_rate_commit)?.setOnClickListener {
Widget.makeSnackbar(this, getString(R.string.settings_rate_toast))
bottomSheetDialog.dismiss()
}
} }
private fun initClick() { private fun initClick() {
binding.ivSetBack.setOnClickListener { onBackPressed() } binding.ivSetBack.setOnClickListener { finish() }
binding.llRate.setOnClickListener { binding.llRate.setOnClickListener {
bottomSheetDialog.show() bottomSheetDialog.show()
@ -66,6 +62,87 @@ class SettingsActivity
intent.data = Uri.parse(url) intent.data = Uri.parse(url)
startActivity(intent) startActivity(intent)
} }
binding.llShareApp.setOnClickListener {
val textDescription = "choose please."
val intentShare = Intent().setAction(Intent.ACTION_SEND).setType("text/plain")
var sAux = "\n" + getString(R.string.app_name) + "\n\n"
sAux += "https://play.google.com/store/apps/details?id=" + this.packageName
intentShare.putExtra(Intent.EXTRA_TEXT, sAux)
startActivity(Intent.createChooser(intentShare, textDescription))
}
} }
private fun setVersion() {
try {
// 获取 PackageInfo 对象
val packageInfo = packageManager.getPackageInfo(packageName, 0)
val versionName = packageInfo.versionName
val versionCode =
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
packageInfo.longVersionCode
} else {
@Suppress("DEPRECATION")
packageInfo.versionCode.toLong()
}
// 将版本信息设置到 TextView
binding.tvVersion.text = versionName.toString()
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
binding.tvVersion.text = "1.1.1"
}
}
private fun setBottomSheet() {
// 设置 BottomSheetDialog
bottomSheetDialog = BottomSheetDialog(this)
bottomSheetDialog.setContentView(R.layout.bottomsheet_rate)
bottomSheetDialog.dismissWithAnimation = true
bottomSheetDialog.findViewById<TextView>(R.id.tv_rate_commit)?.setOnClickListener {
toGoogleStar()
bottomSheetDialog.dismiss()
}
bottomSheetDialog.findViewById<RatingBar>(R.id.ratingBar)
?.setOnRatingBarChangeListener { _, rating, fromUser ->
if (fromUser) {
userChoose = rating.toInt()
}
}
}
private fun toGoogleStar() {
if (userChoose < 4) {
// 显示感谢消息
Toast.makeText(
this,
"Thank you for your feedback; we will strive to do better.",
Toast.LENGTH_LONG
).show()
bottomSheetDialog.dismiss()
} else {
// 构建 Google Play 评价页面的 URL
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName"))
// 检查是否有能够处理这个 Intent 的应用(如 Google Play 应用)
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
} else {
// 如果 Google Play 应用不可用,则打开浏览器中的 Google Play 页面
val webIntent = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=$packageName")
)
startActivity(webIntent)
}
bottomSheetDialog.dismiss()
}
}
} }

View File

@ -10,6 +10,7 @@ import android.speech.tts.TextToSpeech
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
@ -17,15 +18,18 @@ import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.keepmodel.LanguagesConstants import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.common.Logger import com.assimilate.alltrans.common.Logger
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.common.Widget import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityTextResultBinding import com.assimilate.alltrans.databinding.ActivityTextResultBinding
import com.assimilate.alltrans.http.GoogleTranslator import com.assimilate.alltrans.http.GoogleTranslator
import com.assimilate.alltrans.http.Translator import com.assimilate.alltrans.http.Translator
import com.assimilate.alltrans.mydb.DbTranslation import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations import com.assimilate.alltrans.mydb.Translations
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import java.util.Locale import java.util.Locale
@ -50,6 +54,10 @@ class TextResultActivity : AppCompatActivity() {
} }
private fun initSet() { private fun initSet() {
backPressedCall()
adLoad(MyApp.Config.text_trans_int_auto)
adLoad(MyApp.Config.text_new_int_auto)
adLoad(MyApp.Config.text_camera_int_auto)
// 获取Intent // 获取Intent
val intent = intent val intent = intent
val receivedString = intent.getStringExtra("source_text") val receivedString = intent.getStringExtra("source_text")
@ -62,21 +70,36 @@ class TextResultActivity : AppCompatActivity() {
Locale.getDefault() Locale.getDefault()
) )
} }
// checkLastTranslationCollectedAndSetIcon() }
private fun backPressedCall() {
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
showInstAdFromCache(MyApp.Config.text_trans_int_auto)
finish()
}
}
onBackPressedDispatcher.addCallback(this, callback)
} }
private fun initClick() { private fun initClick() {
binding.ivTrBack.setOnClickListener { onBackPressed() } binding.ivTrBack.setOnClickListener {
binding.tvTrNewTrans.setOnClickListener { onBackPressed() } showInstAdFromCache(MyApp.Config.text_trans_int_auto)
finish()
}
binding.tvTrNewTrans.setOnClickListener {
showInstAdFromCache(MyApp.Config.text_new_int_auto)
finish()
}
binding.ivReToPhoto.setOnClickListener { binding.ivReToPhoto.setOnClickListener {
startActivity(Intent(this, PhotoImageActivity::class.java)) showInstAdFromCache(MyApp.Config.text_camera_int_auto)
} }
binding.ivTrCopy.setOnClickListener { binding.ivTrCopy.setOnClickListener {
copyToClipboard() copyToClipboard()
FirebaseAnalyticsHelper.textTransCopyEvent() FirebaseAnalyticsHelper.textTransCopyEvent()
} }
binding.ivSourceClear.setOnClickListener { onBackPressed() } binding.ivSourceClear.setOnClickListener { finish() }
binding.ivSourceTts.setOnClickListener { binding.ivSourceTts.setOnClickListener {
readText( readText(
binding.tvTrSource.text.toString(), binding.tvTrSource.text.toString(),
@ -111,7 +134,6 @@ class TextResultActivity : AppCompatActivity() {
} }
// 更新图标状态的方法 // 更新图标状态的方法
private fun updateCollectIcon(isCollected: Boolean) { private fun updateCollectIcon(isCollected: Boolean) {
if (isCollected) { if (isCollected) {
@ -121,14 +143,6 @@ class TextResultActivity : AppCompatActivity() {
} }
} }
// 检查最后一个翻译是否被收藏并更新图标
private fun checkLastTranslationCollectedAndSetIcon() {
val dbTranslation = DbTranslation(this)
val lastTranslationCollected = dbTranslation.isLastTranslationCollected
updateCollectIcon(lastTranslationCollected)
}
private fun translate(text: String) { private fun translate(text: String) {
if (text.isEmpty() || translating) { if (text.isEmpty() || translating) {
Logger.d("log", "translating(not post data)...") Logger.d("log", "translating(not post data)...")
@ -176,7 +190,10 @@ class TextResultActivity : AppCompatActivity() {
override fun onFailure(errorMessage: String?) { override fun onFailure(errorMessage: String?) {
translating = false translating = false
FirebaseAnalyticsHelper.textTransResultEvent("Translation failed: $errorMessage") FirebaseAnalyticsHelper.textTransResultEvent(
MyApp.Config.FAIL_REASON,
"failed: $errorMessage"
)
runOnUiThread { runOnUiThread {
// 显示失败信息或记录日志 // 显示失败信息或记录日志
if (!TextUtils.isEmpty(errorMessage)) { if (!TextUtils.isEmpty(errorMessage)) {
@ -265,4 +282,74 @@ class TextResultActivity : AppCompatActivity() {
tts.shutdown() tts.shutdown()
} }
private fun doBack() {
finish()
}
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@TextResultActivity,
place,
object : LolAdWrapper.LolShowListener {
override fun shown() {
// 处理广告展示成功
}
override fun showFailed(error: LolShowError?) {
// 处理广告展示失败
if (place == MyApp.Config.text_camera_int_auto) {
startActivity(
Intent(
this@TextResultActivity,
PhotoImageActivity::class.java
).putExtra(
"key_start_ph",
"text"
)
)
} else {
doBack()
}
}
override fun closed() {
// 处理广告关闭
if (place == MyApp.Config.text_camera_int_auto) {
startActivity(
Intent(
this@TextResultActivity,
PhotoImageActivity::class.java
).putExtra(
"key_start_ph",
"text"
)
)
} else {
doBack()
}
}
})
}
} }

View File

@ -2,11 +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.os.Handler import android.util.Log
import android.os.Looper
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button import android.widget.Button
import android.widget.Toast
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
@ -14,9 +12,12 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.databinding.ActivityWelBinding 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.LolShowError
class WelActivity : AppCompatActivity() { class WelActivity : AppCompatActivity(){
private lateinit var binding: ActivityWelBinding private lateinit var binding: ActivityWelBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() enableEdgeToEdge()
@ -25,7 +26,6 @@ class WelActivity : AppCompatActivity() {
setContentView(binding.root) setContentView(binding.root)
//debugFirebase() //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())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
@ -52,20 +52,17 @@ class WelActivity : AppCompatActivity() {
private fun initSet() { private fun initSet() {
backPressedCall() backPressedCall()
Handler(Looper.getMainLooper()).postDelayed({ if (MyApp.app.isFirstLaunch) {
startActivity( adSplash(MyApp.Config.start_cold_int_auto)
Intent(this, MainActivity::class.java) } else {
) adSplashHot(MyApp.Config.start_hot_int_auto)
}, 2444) }
} }
private fun backPressedCall() { private fun backPressedCall() {
val callback = object : OnBackPressedCallback(true) { val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() { override fun handleOnBackPressed() {
} }
} }
onBackPressedDispatcher.addCallback(this, callback) onBackPressedDispatcher.addCallback(this, callback)
@ -77,4 +74,82 @@ class WelActivity : AppCompatActivity() {
} }
private fun toNextPage() {
startActivity(Intent(this@WelActivity, MainActivity::class.java))
}
private fun adSplash(place: String) {
// 加载广告
LolAdWrapper.shared.loadAdIfNotCached(
this,
place,
object : LolAdWrapper.LoLLoadListener {
override fun loadFailed(error: LolLoadError?) {
// 处理加载失败
toNextPage()
}
override fun loaded() {
// 处理加载成功
// 如果需要立刻展示广告,可以调用展示方法
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,
place,
object : LolAdWrapper.LoLLoadListener {
override fun loadFailed(error: LolLoadError?) {
// 处理加载失败
finish()
}
override fun loaded() {
// 处理加载成功
// 如果需要立刻展示广告,可以调用展示方法
LolAdWrapper.shared.showAdIfCached(
this@WelActivity,
place,
object : LolAdWrapper.LolShowListener {
override fun shown() {
// 处理广告展示成功
}
override fun showFailed(error: LolShowError?) {
// 处理广告展示失败
finish()
}
override fun closed() {
// 处理广告关闭
finish()
}
})
}
})
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

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

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
android:drawable="@drawable/ic_action_dns" /> <!-- 未选中状态 -->
<item android:id="@android:id/secondaryProgress"
android:drawable="@drawable/ic_action_settings" /> <!-- 半选中状态 -->
<item android:id="@android:id/progress"
android:drawable="@drawable/ic_action_settings" /> <!-- 完全选中状态 -->
</layer-list>

View File

@ -44,17 +44,26 @@
app:srcCompat="@drawable/main_setting" /> app:srcCompat="@drawable/main_setting" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="43dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_main_title">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout <LinearLayout
android:id="@+id/change_language" android:id="@+id/change_language"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="23dp"
android:elevation="2dp" android:elevation="2dp"
android:orientation="horizontal" android:orientation="horizontal">
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_main_title">
<TextView <TextView
android:id="@+id/ch_source_language" android:id="@+id/ch_source_language"
@ -117,10 +126,7 @@
android:paddingStart="12dp" android:paddingStart="12dp"
android:paddingTop="16dp" android:paddingTop="16dp"
android:paddingEnd="12dp" android:paddingEnd="12dp"
android:paddingBottom="16dp" android:paddingBottom="16dp">
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/change_language">
<EditText <EditText
android:id="@+id/et_text" android:id="@+id/et_text"
@ -195,6 +201,14 @@
</LinearLayout> </LinearLayout>
<FrameLayout
android:id="@+id/home_native"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/button_r20_white_bg"
android:minHeight="120dp" />
<LinearLayout <LinearLayout
android:id="@+id/ll_main_quick" android:id="@+id/ll_main_quick"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -202,10 +216,7 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:background="@drawable/button_r20_white_bg" android:background="@drawable/button_r20_white_bg"
android:orientation="vertical" android:orientation="vertical"
android:padding="16dp" android:padding="16dp">
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_main_enter_text">
<LinearLayout <LinearLayout
android:id="@+id/ll_quick_set" android:id="@+id/ll_quick_set"
@ -257,12 +268,10 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/ll_ph"
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">
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_main_quick">
<TextView <TextView
android:id="@+id/tv_main_photo_trans" android:id="@+id/tv_main_photo_trans"
@ -303,4 +312,7 @@
app:drawableTopCompat="@drawable/main_dic" /> app:drawableTopCompat="@drawable/main_dic" />
</LinearLayout> </LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -8,7 +8,6 @@
android:orientation="vertical"> android:orientation="vertical">
<RelativeLayout <RelativeLayout
android:visibility="gone"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/white"> android:background="@color/white">

View File

@ -108,8 +108,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:background="@drawable/button_r20_white_bg" android:background="@drawable/button_r20_white_bg"
android:orientation="vertical" android:orientation="vertical">
android:visibility="gone">
<LinearLayout <LinearLayout
android:id="@+id/ll_rate" android:id="@+id/ll_rate"
@ -248,6 +247,7 @@
app:drawableStartCompat="@drawable/ic_version_update" /> app:drawableStartCompat="@drawable/ic_version_update" />
<TextView <TextView
android:id="@+id/tv_version"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:drawablePadding="12dp" android:drawablePadding="12dp"

View File

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_r20_white_bg"
android:gravity="center_horizontal"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:elevation="0dp"
app:cardBackgroundColor="@android:color/transparent"
app:cardCornerRadius="4dp"
app:cardElevation="0dp">
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/mv_event_con"
android:layout_width="120dp"
android:layout_height="120dp" />
</androidx.cardview.widget.CardView>
<ImageView
android:id="@+id/im_event_icon"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginTop="40dp"
android:visibility="gone"
tools:background="@drawable/ic_launcher_background" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingHorizontal="8dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_r10_gray_bg"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:text="AD"
android:textColor="@color/main_text_ff0e8ce8"
android:textSize="12dp" />
<TextView
android:id="@+id/tv_event_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:ellipsize="end"
android:gravity="start"
android:lineSpacingExtra="0dp"
android:maxLines="1"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16dp"
tools:text="dddd dddd dddd ddd " />
</LinearLayout>
<TextView
android:id="@+id/tv_event_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:gravity="start"
android:lineSpacingExtra="0dp"
android:maxLines="2"
android:minHeight="28dp"
android:textColor="@color/black"
android:textSize="12dp"
tools:text="xxxxx xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
<TextView
android:id="@+id/tv_event_bt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:background="@drawable/button_r10_gray_bg"
android:gravity="center"
android:minHeight="32dp"
android:textColor="@color/black"
android:textSize="14dp"
android:textStyle="bold"
tools:text="action now " />
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_r20_white_bg"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="12dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/im_event_icon"
android:layout_width="46dp"
android:layout_height="46dp"
tools:src="@mipmap/ic_launcher" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingBottom="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_r10_gray_bg"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:text="AD"
android:textColor="@color/white"
android:textSize="12dp" />
<TextView
android:id="@+id/tv_event_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:ellipsize="end"
android:fontFamily="@string/Roboto_Medium"
android:lineSpacingExtra="0dp"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16dp"
android:textStyle="bold"
tools:text="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
</LinearLayout>
<TextView
android:id="@+id/tv_event_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="@string/Roboto_Regular"
android:lineSpacingExtra="0dp"
android:maxLines="2"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textColor="@color/black"
android:textSize="12dp"
tools:text="xxxxxxxxxxxxxxxxxxxxx" />
</LinearLayout>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp">
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/mv_event_con"
android:layout_width="match_parent"
android:layout_height="152dp"
tools:background="@color/white" />
</FrameLayout>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/tv_event_bt"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginHorizontal="14dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="12dp"
android:background="@drawable/button_r10_gray_bg"
android:textColor="@color/black"
android:textSize="15dp"
android:textStyle="bold"
tools:text="action now " />
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="122dp"
android:background="@drawable/button_r10_gray_bg"
android:gravity="center_horizontal"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<FrameLayout
android:id="@+id/mv_event_con"
android:layout_width="148dp"
tools:background="#FF1A1A1A"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/im_event_icon"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginTop="40dp"
android:visibility="gone"
tools:background="@drawable/ic_launcher_background" />
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:paddingHorizontal="12dp"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_r10_gray_bg"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:text="AD"
android:textColor="@color/white"
android:textSize="12dp" />
<TextView
android:id="@+id/tv_event_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:layout_marginStart="4dp"
android:lineSpacingExtra="0dp"
android:drawablePadding="4dp"
android:singleLine="true"
android:gravity="start"
android:maxLines="1"
android:textColor="@color/white"
android:textSize="16dp"
tools:text="dddd dddd dddd ddd " />
<LinearLayout
android:id="@+id/ll_ad_options_view"
android:layout_width="24dp"
android:layout_height="24dp"
android:orientation="vertical"
android:layout_marginStart="2dp"
android:visibility="gone"
android:layout_alignParentEnd="true">
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/tv_event_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="28dp"
android:layout_marginTop="4dp"
android:gravity="start"
android:lineSpacingExtra="0dp"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="12dp"
tools:text="xxxxx xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
<TextView
android:id="@+id/tv_advertiser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="@string/Roboto_Regular"
android:layout_marginHorizontal="12dp"
android:textColor="@color/black"
android:textSize="12dp"
android:visibility="gone"
tools:text="xxxxxxxxxxxxxxxxxxxxx" />
<Button
android:id="@+id/tv_event_bt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="36dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="6dp"
android:gravity="center"
android:background="@drawable/button_r10_gray_bg"
android:textColor="@color/black"
android:textSize="14dp"
android:textStyle="bold"
tools:text="action now " />
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_r20_white_bg"
android:orientation="vertical"
tools:ignore="MissingConstraints">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="12dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/im_event_icon"
android:layout_width="46dp"
android:layout_height="46dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingBottom="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_r10_gray_bg"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:text="AD"
android:textColor="@color/white"
android:textSize="12dp" />
<TextView
android:id="@+id/tv_event_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="@string/Roboto_Medium"
android:lineSpacingExtra="0dp"
android:paddingStart="4dp"
android:paddingBottom="4dp"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="16dp"
android:textStyle="bold"
tools:text="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
</LinearLayout>
<TextView
android:id="@+id/tv_advertiser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:fontFamily="@string/Roboto_Regular"
android:textColor="@color/black"
android:textSize="12dp"
android:visibility="visible"
tools:text="xxxxxxxxxxxxxxxxxxxxx" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_ad_options_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginTop="-10dp"
android:orientation="vertical"
android:visibility="visible">
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/tv_event_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginBottom="12dp"
android:ellipsize="end"
android:fontFamily="@string/Roboto_Regular"
android:lineSpacingExtra="0dp"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="12dp"
tools:text="xxxxxxxxxxxxxxxxxxxxx" />
<FrameLayout
android:id="@+id/mv_event_con"
android:layout_width="match_parent"
android:layout_height="152dp"
android:layout_marginHorizontal="12dp"
tools:background="@drawable/button_r10_gray_bg"></FrameLayout>
<Button
android:id="@+id/tv_event_bt"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginHorizontal="14dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="12dp"
android:background="@drawable/button_r10_gray_bg"
android:textColor="@color/white"
android:textSize="15dp"
android:textStyle="bold"
tools:text="action now " />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,169 @@
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="123dp"
android:background="@android:color/transparent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:background="@drawable/button_r20_white_bg"
android:minHeight="50dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_media"
android:layout_width="121dp"
android:layout_height="121dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:minWidth="123dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingTop="3dp"
android:paddingRight="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:adjustViewBounds="true"
android:paddingEnd="5dp"
android:paddingRight="5dp"
android:paddingBottom="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/ad_headline"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:maxLines="1"
android:textColor="#78A642"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:text="Ad"
android:textColor="#FFFFFF" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/ad_advertiser"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="bottom"
android:textSize="14sp"
android:textStyle="bold" />
<RatingBar
android:id="@+id/ad_stars"
style="?android:attr/ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="true"
android:numStars="5"
android:stepSize="0.5" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:maxLines="1"
android:textColor="#4DAF51"
android:textSize="12sp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:orientation="horizontal"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<TextView
android:id="@+id/ad_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="5dp"
android:paddingLeft="5dp"
android:paddingEnd="5dp"
android:paddingRight="5dp"
android:textColor="#4CAE50"
android:textSize="12sp" />
<TextView
android:id="@+id/ad_store"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="5dp"
android:paddingLeft="5dp"
android:paddingEnd="5dp"
android:paddingRight="5dp"
android:textSize="12sp" />
<Button
android:id="@+id/ad_call_to_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/button_r10_gray_bg"
android:gravity="center"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>

View File

@ -22,12 +22,19 @@
android:textColor="@color/main_text_ff1f1724" android:textColor="@color/main_text_ff1f1724"
android:textSize="16sp" /> android:textSize="16sp" />
<androidx.appcompat.widget.AppCompatRatingBar <RatingBar
android:id="@+id/rate1" android:id="@+id/ratingBar"
style="@style/MyRatingBar"
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_marginTop="32dp" /> android:layout_marginTop="15dp"
android:layout_marginBottom="15dp"
android:numStars="5"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:rating="4.5"
android:stepSize="0.5" />
<TextView <TextView
android:id="@+id/tv_rate_commit" android:id="@+id/tv_rate_commit"

View File

@ -3,21 +3,30 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@drawable/button_r20_white_bg_tlr"
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="19dp"
android:layout_marginEnd="16dp"
android:background="@drawable/button_r10_gray_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/change_language">
<androidx.appcompat.widget.SearchView <androidx.appcompat.widget.SearchView
android:id="@+id/ph_search" android:id="@+id/ph_search"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:baselineAligned="false"
android:layout_marginTop="16dp" app:queryBackground="@android:color/transparent"
android:layout_marginEnd="16dp" android:background="@android:color/transparent"
android:background="@drawable/button_r10_gray_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/change_language"
app:queryHint="Search" /> app:queryHint="Search" />
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_languages" android:id="@+id/list_languages"

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/button_r10_gray_bg" android:background="@drawable/button_r20_white_bg_tlr"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout <LinearLayout
@ -22,7 +21,8 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:background="@drawable/button_r20_white_bg" android:background="@drawable/button_r10_gray_bg"
android:drawableEnd="@drawable/ic_down_choose"
android:drawablePadding="25dp" android:drawablePadding="25dp"
android:ellipsize="end" android:ellipsize="end"
android:gravity="center" android:gravity="center"
@ -31,8 +31,7 @@
android:paddingEnd="12dp" android:paddingEnd="12dp"
android:textColor="@color/main_text_ff0e8ce8" android:textColor="@color/main_text_ff0e8ce8"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold" />
app:drawableEndCompat="@drawable/ic_down_choose" />
<ImageView <ImageView
android:id="@+id/tv_exchange" android:id="@+id/tv_exchange"
@ -53,7 +52,8 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:background="@drawable/button_r20_white_bg" android:background="@drawable/button_r10_gray_bg"
android:drawableEnd="@drawable/ic_down_choose"
android:drawablePadding="25dp" android:drawablePadding="25dp"
android:ellipsize="end" android:ellipsize="end"
android:gravity="center" android:gravity="center"
@ -62,8 +62,7 @@
android:paddingEnd="12dp" android:paddingEnd="12dp"
android:textColor="@color/main_text_ff1f1724" android:textColor="@color/main_text_ff1f1724"
android:textSize="16sp" android:textSize="16sp"
android:textStyle="bold" android:textStyle="bold" />
app:drawableEndCompat="@drawable/ic_down_choose" />
</LinearLayout> </LinearLayout>
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView

View File

@ -2,7 +2,7 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/white"> android:background="@drawable/main_bg">
<com.assimilate.alltrans.curview.GraphicOverlay <com.assimilate.alltrans.curview.GraphicOverlay
android:id="@+id/sus_graphic_overlay" android:id="@+id/sus_graphic_overlay"

View File

@ -25,6 +25,7 @@
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:src="@drawable/more_options_icon" android:src="@drawable/more_options_icon"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -76,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:visibility="invisible"
android:layout_marginBottom="10dp" android:layout_marginBottom="10dp"
android:src="@drawable/ic_voice" /> android:src="@drawable/ic_voice"
android:visibility="invisible" />
<View <View
@ -100,11 +101,11 @@
android:textStyle="bold" /> android:textStyle="bold" />
<LinearLayout <LinearLayout
android:visibility="invisible"
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"

View File

@ -1,5 +1,6 @@
<resources> <resources>
<string name="app_name">Translark</string> <string name="app_name">Translark</string>
<string name="my_admob_app_id">ca-app-pub-9280511366580942~8779388277</string>
<string name="pref_key_info_hide" translatable="false">ih</string> <string name="pref_key_info_hide" translatable="false">ih</string>
<string name="pref_key_group_recognized_text_in_blocks" translatable="false">grtib</string> <string name="pref_key_group_recognized_text_in_blocks" translatable="false">grtib</string>
@ -83,4 +84,5 @@
<string name="quick_set_kj_double">双击悬浮球</string> <string name="quick_set_kj_double">双击悬浮球</string>
</resources> </resources>

View File

@ -18,4 +18,8 @@
<item name="trackColorActive">#FF00FF00</item> <!-- 已填充部分颜色 --> <item name="trackColorActive">#FF00FF00</item> <!-- 已填充部分颜色 -->
</style> </style>
<style name="MyRatingBar" parent="Widget.AppCompat.RatingBar">
<item name="android:progressDrawable">@drawable/stars_selector</item>
</style>
</resources> </resources>

View File

@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="Base.Theme.Alltrans" parent="Theme.Material3.DayNight.NoActionBar"> <style name="Base.Theme.Alltrans" parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
<!-- Customize your light theme here. --> <!-- Customize your light theme here. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> --> <!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style> </style>
@ -8,10 +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="colorPrimary">@color/white</item> <!-- 替换为你想要的颜色 -->
<item name="colorPrimaryDark">@color/white</item> <!-- 替换为你想要的颜色 -->
<item name="colorAccent">@color/white</item> <!-- 替换为你想要的颜色 -->
</style> </style>
</resources> </resources>

View File

@ -7,15 +7,35 @@ pluginManagement {
includeGroupByRegex("androidx.*") includeGroupByRegex("androidx.*")
} }
} }
mavenCentral() mavenCentral()
gradlePluginPortal() gradlePluginPortal()
maven { url = uri("https://jitpack.io") }
maven {
url = uri("https://artifact.bytedance.com/repository/pangle/")
} }
maven {
url =
uri("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea")
}
}
} }
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
maven { url = uri("https://jitpack.io") }
maven {
url = uri("https://artifact.bytedance.com/repository/pangle/")
}
maven {
url =
uri("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea")
}
} }
} }