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
/release

View File

@ -1,6 +1,3 @@
import java.text.SimpleDateFormat
import java.util.Date
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
@ -18,8 +15,8 @@ android {
applicationId = "com.assimilate.alltrans"
minSdk = 23
targetSdk = 34
versionCode = 2
versionName = "1.0.2"
versionCode = 3
versionName = "1.0.3"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@ -27,18 +24,19 @@ android {
buildFeatures {
buildConfig = true
viewBinding = true
buildConfig = true
}
buildTypes {
debug {
isShrinkResources = true
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
// debug {
// isShrinkResources = true
// isMinifyEnabled = true
// proguardFiles(
// getDefaultProguardFile("proguard-android-optimize.txt"),
// "proguard-rules.pro"
// )
// }
release {
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 {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
@ -73,6 +60,20 @@ android {
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
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
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-config")
// To recognize Latin script
@ -94,7 +96,6 @@ dependencies {
implementation("com.google.mlkit:text-recognition-korean:16.0.0")
// CameraX core library
implementation(libs.androidx.camera.core)
// 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
# 保留com.assimilate.alltrans.keepmodel包及其子包的所有类
-keep class com.assimilate.alltrans.keepmodel.** { *; }
-keep class com.assimilate.alltrans.model.** { *; }
# 保留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:theme="@style/Theme.Alltrans"
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
android:name=".viewui.MainActivity"
android:exported="false"

View File

@ -1,18 +1,76 @@
package com.assimilate.alltrans
import android.app.Activity
import android.app.ActivityManager
import android.app.Application
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.webkit.WebView
import com.assimilate.alltrans.keepmodel.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.common.AppStore
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() {
init {
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() {
// 检查是否是第一次进入应用
if (PreferenceLanguageUtils.isFirstTime()) {
@ -28,22 +86,29 @@ class MyApp : Application() {
// 设置已经不是第一次进入应用了
PreferenceLanguageUtils.setNotFirstTime()
}
}
// 用于记录上次广告展示的时间
val lastAdDisplayTime: AtomicLong = AtomicLong(0)
val isAdShowing: AtomicBoolean = AtomicBoolean(false)
companion object {
private var instance: MyApp? = null
fun applicationContext(): Context {
return instance!!.applicationContext
}
val app: MyApp
get() = instance!!
}
override fun onCreate() {
super.onCreate()
instance = this
// ScreenUtils.init(this)
registerActivityLifecycle()
initAd()
setSystemLanguage()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
@ -65,9 +130,27 @@ class MyApp : Application() {
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
const val launchPv = "launch_pv"
@ -89,24 +172,459 @@ class MyApp : Application() {
const val hoverButtonClick = "hover_button_click"
const val hoverLimitAgree = "hover_limit_agree"
const val hoverButtonCancel = "hover_button_cancel"
const val hover_button_agree = "hover_button_agree"
const val hover_screen_click = "hover_screen_click"
const val hover_screen_imp = "hover_screen_imp"
const val hover_screen_global = "hover_screen_global"
const val hover_global_result = "hover_global_result"
const val hover_screen_district = "hover_screen_district"
const val hover_district_result = "hover_district_result"
const val hoverButtonAgree = "hover_button_agree"
const val hoverScreenClick = "hover_screen_click"
const val hoverScreenImp = "hover_screen_imp"
const val hoverScreenGlobal = "hover_screen_global"
const val hoverGlobalResult = "hover_global_result"
const val hoverScreenDistrict = "hover_screen_district"
const val hoverDistrictResult = "hover_district_result"
const val image_click = "image_click"
const val image_trans_camera = "image_trans_camera"
const val image_camera_result = "image_camera_result"
const val image_trans_photo = "image_trans_photo"
const val image_photo_result = "image_photo_result"
const val imageClick = "image_click"
const val imageTransCamera = "image_trans_camera"
const val imageCameraResult = "image_camera_result"
const val imageTransPhoto = "image_trans_photo"
const val imagePhotoResult = "image_photo_result"
const val history_click = "history_click"
const val history_delete = "history_delete"
const val historyClick = "history_click"
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 com.assimilate.alltrans.R;
import com.assimilate.alltrans.keepmodel.Language;
import com.assimilate.alltrans.model.Language;
import com.assimilate.alltrans.databinding.LanguageItemLayoutBinding;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;

View File

@ -14,6 +14,7 @@ import android.os.Looper
import android.util.Log
import androidx.core.app.NotificationCompat
import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.ScreenCaptureManager
import com.assimilate.alltrans.curview.ControlView
import com.assimilate.alltrans.curview.CopyTextView
@ -79,6 +80,7 @@ class SusService : Service() {
override fun onClick() {
Log.d("SusService_f", "FloatingView clicked")
addControlView()
FirebaseAnalyticsHelper.hoverScreenClickEvent()
}
})
}
@ -92,6 +94,8 @@ class SusService : Service() {
Handler(Looper.getMainLooper()).postDelayed({
globalView.addGlobalView(screenCaptureManager.getImageReader())
}, 333)
FirebaseAnalyticsHelper.hoverScreenGlobalEvent()
}
override fun onCopyClick() {
@ -102,6 +106,7 @@ class SusService : Service() {
override fun onDistrictClick() {
selectionView = SelectionView(this@SusService)
selectionView.addSelectionView(screenCaptureManager.getImageReader())
FirebaseAnalyticsHelper.hoverScreenDistrictEvent()
}
override fun onChangeLan() {
@ -161,4 +166,5 @@ class SusService : Service() {
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
import android.os.Bundle
import android.text.TextUtils
import com.assimilate.alltrans.MyApp
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import org.json.JSONObject
object FirebaseAnalyticsHelper {
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) {
val params = when (from) {
"cap" -> mapOf("cap" to 1)
"create" -> mapOf("cap" to 1)
else -> {
null
}
}
fun homePvEvent(from: String, value: String) {
val params = mapOf(from to value)
logCusEvent(MyApp.Config.homePv, params)
}
fun textTransSwitchEvent(from: String) {
val params = when (from) {
"cap" -> mapOf("cap" to 1)
"create" -> mapOf("cap" to 1)
else -> {
null
}
fun textTransSwitchEvent(from: String, value: String) {
val params = mapOf(from to value)
logCusEvent(MyApp.Config.textTransSwitch, params)
}
}
fun languageChooseEvent(from: String) {
val params = mapOf(from to 1)
fun languageChooseEvent(from: String,value: String) {
val params = mapOf(from to value)
logCusEvent(MyApp.Config.languageChoose, params)
}
fun languageFromEvent(clickFrom: String,value: String) {
val params = mapOf(clickFrom to value)
logCusEvent(MyApp.Config.languageFrom, params)
}
fun textTransClickEvent() {
logCusEvent(MyApp.Config.textTransClick, null)
}
fun textTransResultEvent(result: String) {
val params = mapOf(result to 1)
fun textTransResultEvent(result: String,value: String) {
val params = mapOf(result to value)
logCusEvent(MyApp.Config.textTransResult, params)
}
@ -85,8 +77,8 @@ object FirebaseAnalyticsHelper {
}
fun textVoiceResultEvent(failReason: String) {
val params = mapOf(failReason to 1)
fun textVoiceResultEvent(failReason: String,value: String) {
val params = mapOf(failReason to value)
logCusEvent(MyApp.Config.textVoiceResult, params)
}
@ -113,10 +105,106 @@ object FirebaseAnalyticsHelper {
logCusEvent(MyApp.Config.hoverButtonClick, null)
}
fun hoverLimitAgreeEvent() {
logCusEvent(MyApp.Config.hoverLimitAgree, null)
}
fun hoverButtonCancelEvent() {
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 showConfidence: Boolean,
private val textShow: Boolean,
private val needTrans: Boolean
private val needTrans: Boolean,
private val fbFrom:String
) : GraphicOverlay.Graphic(overlay) {
private val textPaint: TextPaint = TextPaint().apply {
@ -41,7 +42,7 @@ class TextGraphic(
isVisible = textShow
if (needTrans) {
TranslationManager(text) { translatedTextPairs ->
TranslationManager(text,fbFrom) { translatedTextPairs ->
translatedTextBlocks = translatedTextPairs.map { it.first }
// 可以同时打印原Text和翻译后的结果
translatedTextPairs.forEach { (translated, original) ->

View File

@ -4,8 +4,8 @@ import android.content.Context
import android.util.Log
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.curview.GraphicOverlay
import com.assimilate.alltrans.keepmodel.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.google.android.gms.tasks.Task
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.text.Text
@ -19,6 +19,7 @@ class TextRecognitionProcessor(
textRecognizerOptions: TextRecognizerOptionsInterface,
private val textShow:Boolean,
private val needTrans: Boolean,
private val fbFrom:String,
private val callback: TextRecognitionCallback? = null // 添加回调
) : VisionProcessorBase<Text>(context) {
@ -54,7 +55,8 @@ class TextRecognitionProcessor(
showLanguageTag,
showConfidence,
textShow,
needTrans
needTrans,
fbFrom
)
)

View File

@ -2,18 +2,17 @@ package com.assimilate.alltrans.common
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.http.GoogleTranslator
import com.assimilate.alltrans.http.Translator
import com.assimilate.alltrans.keepmodel.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.google.mlkit.vision.text.Text
import java.util.concurrent.Executors
class TranslationManager(
private val text: Text,
private val fbFrom: String,
private val callback: (List<Pair<String, String>>) -> Unit // 修改callback的参数类型
) {
private val handler = Handler(Looper.getMainLooper())
@ -49,7 +48,8 @@ class TranslationManager(
translatedTextBlocks.add(Pair(index, textBlock.text))
if (translatedTextBlocks.size == text.textBlocks.size) {
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 {
@ -69,7 +69,8 @@ class TranslationManager(
if (translatedTextBlocks.size == text.textBlocks.size) {
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, ""))
if (translatedTextBlocks.size == text.textBlocks.size) {
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 com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.databinding.SusControlViewBinding
import com.assimilate.alltrans.viewui.MainActivity
import com.assimilate.alltrans.viewui.PhotoImageActivity
import com.assimilate.alltrans.viewui.WelActivity
@ -77,6 +78,7 @@ class ControlView(private val context: Context) {
layoutParams.y = 100
windowManager.addView(controlView, layoutParams)
FirebaseAnalyticsHelper.hoverScreenImpEvent()
isAdded = true
initControlClick()
@ -115,6 +117,7 @@ class ControlView(private val context: Context) {
binding.tvSusPhoto.setOnClickListener {
val intent = Intent(context, PhotoImageActivity::class.java)
intent.putExtra("key_start_ph", "hover")
val pendingIntent = PendingIntent.getActivity(
context,
0,
@ -133,7 +136,7 @@ class ControlView(private val context: Context) {
binding.ivSusHome.setOnClickListener {
Log.d("ControlViewManager", "Home clicked")
val intent = Intent(context, WelActivity::class.java)
val intent = Intent(context, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
context,
0,

View File

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

View File

@ -8,7 +8,6 @@ import android.media.ImageReader
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import android.view.Gravity
import android.view.LayoutInflater
@ -18,12 +17,13 @@ import android.view.ViewGroup
import android.view.WindowManager
import com.assimilate.alltrans.MyApp
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.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.databinding.LayoutSusDistrictBinding
import com.assimilate.alltrans.http.GoogleTranslator
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.text.TextRecognition
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
@ -131,12 +131,14 @@ class DistrictView(
bindingSusDistrict.ivSourceClear.setOnClickListener {
bindingSusDistrict.tvTrSource.text = ""
bindingSusDistrict.tvTrTarget.text = ""
removeDistrictView()
}
}
fun removeDistrictView() {
windowManager.removeView(districtView)
windowManager.removeView(overlayView)
}
private fun takeDistrictScreenshot(image: Bitmap, rect: Rect) {
@ -199,37 +201,27 @@ class DistrictView(
val translator: Translator<GoogleTranslator.GoogleTranslateCallback> = GoogleTranslator()
translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback {
override fun onResponse(result: String?, errorMessage: String?) {
if (!TextUtils.isEmpty(result)) {
bindingSusDistrict.tvTrTarget.text
} else {
// 处理错误信息
if (!TextUtils.isEmpty(errorMessage)) {
// 显示错误信息或记录日志
if (errorMessage != null) {
Handler(Looper.getMainLooper()).post {
if (!result.isNullOrEmpty()) {
bindingSusDistrict.tvTrTarget.text = result
} else if (!errorMessage.isNullOrEmpty()) {
Log.e("TranslationError", errorMessage)
bindingSusDistrict.tvTrTarget.text = "Translation error: $errorMessage"
}
}
bindingSusDistrict.tvTrTarget.text = "Translation failed: $errorMessage"
}
}
override fun onFailure(errorMessage: String?) {
// 显示失败信息或记录日志
if (!TextUtils.isEmpty(errorMessage)) {
if (errorMessage != null) {
Log.e("TranslationFailure", errorMessage)
}
Handler(Looper.getMainLooper()).post {
FirebaseAnalyticsHelper.hoverDistrictResultEvent(
MyApp.Config.FAIL_REASON,
"district" + errorMessage.toString()
)
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.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.WindowManager
import android.widget.ImageView
import com.assimilate.alltrans.R
@ -56,11 +57,10 @@ class FloatingView(
// 初始化语言识别
imageProcessor = TextRecognitionProcessor(
context,
ChineseTextRecognizerOptions.Builder().build(), false, true
ChineseTextRecognizerOptions.Builder().build(), false, true, "float"
)
graphicOverlay = GraphicOverlay(context, null)
}
interface OnMovePointListener {
@ -123,11 +123,15 @@ class FloatingView(
private var initialTouchX = 0f
private var initialTouchY = 0f
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 {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
isClick = true
downTime = System.currentTimeMillis()
initialX = params.x
initialY = params.y
initialTouchX = event.rawX
@ -139,21 +143,25 @@ class FloatingView(
}
MotionEvent.ACTION_UP -> {
val upTime = System.currentTimeMillis()
val duration = upTime - downTime
handler.postDelayed(fadeRunnable, 3000)
imageView.setImageResource(originalImageResId)
stickToEdge()
if (isClick) {
if (isClick && duration < maxClickDuration) {
onClickListener?.onClick()
} else {
hasCapturedScreenshot = false
}
try {
windowManager.removeView(graphicOverlay)
hasCapturedScreenshot = false
windowManager.updateViewLayout(imageView, params)
} catch (e: IllegalArgumentException) {
Log.e("FloatingView", "View not attached to window manager", e)
}
}
return true
}
@ -162,14 +170,15 @@ class FloatingView(
val dx = event.rawX - initialTouchX
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
}
if (!isClick) {
// 将图片的位置设置为手指触摸点的上方
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()
imageView.setImageResource(moveImageResId)
@ -177,9 +186,8 @@ class FloatingView(
lastX = params.x + imageView.width / 2
lastY = params.y + imageView.height / 2
updateGraphicOverlay(lastX, lastY)
try {
updateGraphicOverlay(lastX, lastY)
windowManager.updateViewLayout(imageView, params)
} catch (e: IllegalArgumentException) {
Log.e("FloatingView", "View not attached to window manager", e)
@ -188,7 +196,6 @@ class FloatingView(
return true
}
}
return false
}
@ -247,6 +254,7 @@ class FloatingView(
BitmapFactory.decodeResource(context.resources, originalImageResId).width
val edgeImageWidth =
BitmapFactory.decodeResource(context.resources, edgeImageResId).width
val isLeftEdge = params.x + originalImageWidth / 2 < screenWidth / 2
params.x = if (isLeftEdge) {
0
@ -268,10 +276,21 @@ class FloatingView(
val bitmap = BitmapFactory.decodeResource(context.resources, edgeImageResId)
if (isLeftEdge) {
imageView.setImageBitmap(flipBitmapHorizontally(bitmap))
imageView.setPadding(0, 20, 30, 20)
imageView.setPadding(0, 30, 50, 30)
} else {
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() {
Log.e("FloatingView", "View not attached to window manager")
if (isAttachedToWindow) {
try {
windowManager.removeView(imageView)
@ -339,7 +356,6 @@ class FloatingView(
}
fun setImageReader(reader: ImageReader) {
this.imageReader = reader
if (!hasCapturedScreenshot) {
hasCapturedScreenshot = true
@ -347,8 +363,5 @@ class FloatingView(
windowManager.addView(graphicOverlay, fullScreenParams)
}
}
}

View File

@ -32,7 +32,7 @@ class GlobalView(private val context: Context) {
// 这里还需要调整
imageProcessor = TextRecognitionProcessor(
context,
ChineseTextRecognizerOptions.Builder().build(),true,true
ChineseTextRecognizerOptions.Builder().build(), true, true, "global"
)
bindingSubGlobal = LayoutSusGlobalBinding.inflate(LayoutInflater.from(context))
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 androidx.core.content.ContextCompat.getColor
import androidx.recyclerview.widget.LinearLayoutManager
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.LanguageAdapter
import com.assimilate.alltrans.keepmodel.Language
import com.assimilate.alltrans.keepmodel.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.model.Language
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.databinding.LayoutSusChangelanBinding
class LanguageSelectorView(private val context: Context) {
@ -141,10 +143,11 @@ class LanguageSelectorView(private val context: Context) {
// 更新界面显示
binding?.tvChangeSource?.text = currentTargetLanguage
binding?.tvChangeTarget?.text = currentSourceLanguage
FirebaseAnalyticsHelper.textTransSwitchEvent(MyApp.Config.CLICK_FROM, "hover")
removeFloatingView()
}
}
private fun initAllList() {
@ -153,9 +156,17 @@ class LanguageSelectorView(private val context: Context) {
val adapter = LanguageAdapter(context, languages) { _, language ->
Log.d("LanguageChange", language.language)
if (lastTranslateLanguage) {
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
"hover_target"
)
PreferenceLanguageUtils.putString("language_target", language.language)
removeFloatingView()
} else {
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
"hover_source"
)
PreferenceLanguageUtils.putString("language_source", language.language)
removeFloatingView()
}
@ -170,11 +181,13 @@ class LanguageSelectorView(private val context: Context) {
}
}
fun removeFloatingView() {
private fun removeFloatingView() {
binding?.root?.let {
windowManager.removeView(it)
windowManager.removeView(fullScreenView)
}
binding = null
}
}

View File

@ -12,8 +12,12 @@ import android.view.ViewGroup
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.Toast
import com.assimilate.alltrans.MyApp
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.lol.apex.ok.google.adlibrary.base.listener.LolShowError
class SelectionView(private val context: Context) {
private lateinit var binding: LayoutSusSelectBinding
@ -132,4 +136,6 @@ class SelectionView(private val context: Context) {
invalidate()
}
}
}

View File

@ -1,4 +1,4 @@
package com.assimilate.alltrans.keepmodel;
package com.assimilate.alltrans.model;
import android.os.Parcel;
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.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.SharedPreferences

View File

@ -4,18 +4,24 @@ import android.content.Context
import android.os.Bundle
import android.speech.tts.TextToSpeech
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.TranslationAdapter
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.databinding.ActivityHistoryBinding
import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import java.util.Locale
class HistoryActivity : AppCompatActivity() {
@ -123,6 +129,7 @@ class HistoryActivity : AppCompatActivity() {
private fun remove(id: Long, index: Int) {
ids!!.remove(id)
items!!.remove(index)
FirebaseAnalyticsHelper.historyDeleteEvent()
}
private fun updateBtn() {
@ -175,12 +182,71 @@ class HistoryActivity : AppCompatActivity() {
binding!!.histories.layoutManager = layoutManager
binding!!.histories.adapter = adapter
}
adLoad(MyApp.Config.history_int_auto)
backPressedCall()
}
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 {
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.adapters.LanguageAdapter
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.model.Language
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@ -41,32 +41,20 @@ class LanguageChangeActivity : AppCompatActivity() {
}
initView()
initSearch() // 添加这一行
initSearch()
lifecycleScope.launch {
withContext(Dispatchers.IO) {
// 耗时操作
initAllList()
}
}
initClick()
}
private fun initSearch() {
binding.chSearch.apply {
// 获取关闭按钮的ImageView
val closeButton = findViewById<ImageView>(androidx.appcompat.R.id.search_close_btn)
// 设置关闭按钮一直可见
closeButton.visibility = View.VISIBLE
// 确保 SearchView 处于可点击状态
isFocusable = true
isIconified = false
// 延迟请求焦点以避免弹出软件盘
post {
clearFocus()
}
post { clearFocus() }
setOnQueryTextListener(object :
androidx.appcompat.widget.SearchView.OnQueryTextListener {
@ -80,14 +68,9 @@ class LanguageChangeActivity : AppCompatActivity() {
}
})
// 设置点击关闭按钮的行为
closeButton.setOnClickListener {
// 清空搜索框
setQuery("", false)
// 清除焦点
clearFocus()
// 隐藏软件盘
val imm =
context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(windowToken, 0)
@ -96,7 +79,6 @@ class LanguageChangeActivity : AppCompatActivity() {
}
private fun initView() {
val intentT = intent
if (intentT.getBooleanExtra("choose_t", false)) {
lastTranslateLanguage = true
@ -108,39 +90,60 @@ class LanguageChangeActivity : AppCompatActivity() {
binding.tvChangeTarget.setTextColor(getColor(R.color.main_text_ff1f1724))
}
binding.tvChangeSource.text = PreferenceLanguageUtils.getString("language_source")
binding.tvChangeTarget.text = PreferenceLanguageUtils.getString("language_target")
updateRecentLanguages()
}
private fun updateRecentLanguages() {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
val recentLanguages = PreferenceLanguageUtils.getRecentLanguages()
withContext(Dispatchers.Main) {
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)
if (lastTranslateLanguage) {
PreferenceLanguageUtils.putString("language_target", language.language)
onBackPressed()
} else {
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)
binding.tvChangeSource.text = PreferenceLanguageUtils.getString("language_source")
binding.tvChangeTarget.text = PreferenceLanguageUtils.getString("language_target")
updateRecentLanguages()
}
binding.listLanCommon5.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.listLanCommon5.adapter = recentAdapter
}
finish()
}
private fun initClick() {
binding.ivChBack.setOnClickListener { onBackPressed() }
binding.ivChBack.setOnClickListener { finish() }
binding.tvChangeSource.setOnClickListener {
lastTranslateLanguage = false
binding.tvChangeSource.setTextColor(getColor(R.color.main_text_ff0e8ce8))
@ -155,41 +158,35 @@ class LanguageChangeActivity : AppCompatActivity() {
binding.tvExchange.setOnClickListener {
val currentSourceLanguage = PreferenceLanguageUtils.getString("language_source")
val currentTargetLanguage = PreferenceLanguageUtils.getString("language_target")
// 交换源语言和目标语言
PreferenceLanguageUtils.putString("language_source", currentTargetLanguage)
PreferenceLanguageUtils.putString("language_target", currentSourceLanguage)
// 更新界面显示
binding.tvChangeSource.text = currentTargetLanguage
binding.tvChangeTarget.text = currentSourceLanguage
onBackPressed()
FirebaseAnalyticsHelper.textTransSwitchEvent(MyApp.Config.CLICK_FROM, "home")
finish()
}
}
}
private fun initAllList() {
val languages: ArrayList<Language> = LanguagesConstants.getInstance().getList(this)
private suspend fun initAllList() {
withContext(Dispatchers.IO) {
val languages: ArrayList<Language> =
LanguagesConstants.getInstance().getList(this@LanguageChangeActivity)
withContext(Dispatchers.Main) {
if (languages.isNotEmpty()) {
val adapter = LanguageAdapter(this, languages) { _, language ->
Log.d("LanguageChange", language.language)
if (lastTranslateLanguage) {
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()
val adapter =
LanguageAdapter(this@LanguageChangeActivity, languages) { _, language ->
handleLanguageSelection(language)
}
binding.listLanguages.layoutManager =
LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
LinearLayoutManager(
this@LanguageChangeActivity,
LinearLayoutManager.VERTICAL,
false
)
binding.listLanguages.adapter = adapter
}
}
}
}
}

View File

@ -2,7 +2,6 @@ package com.assimilate.alltrans.viewui
import android.app.ActivityManager
import android.content.ActivityNotFoundException
import android.content.ClipDescription
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
@ -18,7 +17,6 @@ import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge
@ -26,13 +24,16 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.allservice.SusService
import com.assimilate.alltrans.common.AppStore
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityMainBinding
import com.assimilate.alltrans.keepmodel.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
class MainActivity : AppCompatActivity() {
@ -50,7 +51,10 @@ class MainActivity : AppCompatActivity() {
if (speech != null) {
binding.etText.setText(speech)
} 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)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(26, systemBars.top + 26, 26, systemBars.bottom)
@ -98,7 +104,7 @@ class MainActivity : AppCompatActivity() {
if (resultCode == RESULT_OK) {
serverIsStart = true
binding.ivQuickStart.setImageResource(R.drawable.main_setting_quick)
FirebaseAnalyticsHelper.hoverButtonClickEvent()
// 权限授予,启动截图
val serviceIntent = Intent(this, SusService::class.java).apply {
@ -110,23 +116,33 @@ class MainActivity : AppCompatActivity() {
} else {
startService(serviceIntent)
}
FirebaseAnalyticsHelper.hoverButtonAgreeEvent()
} else {
Widget.makeToast(
this,
"Please allow access to screen information to identify the content that needs translation."
)
FirebaseAnalyticsHelper.hoverButtonCancelEvent()
}
}
}
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.chTargetLanguage.text = PreferenceLanguageUtils.getString("language_target")
}
private fun initSet() {
FirebaseAnalyticsHelper.homePvEvent("create")
loadNative()
val isRunning = isServiceRunning(this, SusService::class.java)
if (isRunning) {
@ -142,17 +158,18 @@ class MainActivity : AppCompatActivity() {
// 初始化截屏
mediaProjectionManager =
getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
FirebaseAnalyticsHelper.homePvEvent(MyApp.Config.CLICK_FROM, "create")
}
private fun initClick() {
binding.tvMainDic.setOnClickListener {
// startActivity(Intent(this,DicActivity::class.java))
}
binding.tvMainPhotoTrans.setOnClickListener {
startActivity(
Intent(this, PhotoImageActivity::class.java)
Intent(this, PhotoImageActivity::class.java).putExtra("key_start_ph", "camera")
)
}
binding.tvMainVoice.setOnClickListener {
@ -189,11 +206,12 @@ class MainActivity : AppCompatActivity() {
startActivity(
intent
)
FirebaseAnalyticsHelper.historyClickEvent()
}
binding.llQuickSet.setOnClickListener {
startActivity(
Intent(this, QuickSetActivity::class.java)
)
// startActivity(
// Intent(this, QuickSetActivity::class.java)
// )
}
binding.ivQuickStart.setOnClickListener {
if (!serverIsStart) {
@ -205,6 +223,7 @@ class MainActivity : AppCompatActivity() {
)
startActivityForResult(intent, REQUEST_CODE_OVERLAY)
} else {
FirebaseAnalyticsHelper.hoverLimitAgreeEvent()
checkAndRequestMediaProjectionPermission()
}
} else {
@ -212,9 +231,9 @@ class MainActivity : AppCompatActivity() {
serverIsStart = false
binding.ivQuickStart.setImageResource(R.drawable.main_setting_quick_def)
FirebaseAnalyticsHelper.hoverButtonCancelEvent()
}
}
FirebaseAnalyticsHelper.hoverButtonClickEvent()
}
@ -270,7 +289,6 @@ class MainActivity : AppCompatActivity() {
}
private fun checkAndRequestMediaProjectionPermission() {
// 启动截图
startActivityForResult(
@ -321,7 +339,10 @@ class MainActivity : AppCompatActivity() {
try {
launcher.launch(speechIntent)
} 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))
}
@ -374,7 +395,7 @@ class MainActivity : AppCompatActivity() {
override fun onRestart() {
super.onRestart()
FirebaseAnalyticsHelper.homePvEvent("cap")
FirebaseAnalyticsHelper.homePvEvent(MyApp.Config.CLICK_FROM, "cap")
}
override fun onDestroy() {
@ -403,5 +424,14 @@ class MainActivity : AppCompatActivity() {
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.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
@ -30,12 +31,15 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.adapters.LanguageAdapter
import com.assimilate.alltrans.common.BitmapUtils
import com.assimilate.alltrans.keepmodel.Language
import com.assimilate.alltrans.keepmodel.LanguagesConstants
import com.assimilate.alltrans.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper
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.VisionImageProcessor
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.korean.KoreanTextRecognizerOptions
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.IOException
import java.text.SimpleDateFormat
@ -69,6 +75,7 @@ class PhotoImageActivity : AppCompatActivity() {
private lateinit var outputDirectory: File
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
private var isFlashOn = false
private var fbFrom = "photo"
private val REQUEST_CAMERA_PERMISSION = 100
private lateinit var bottomSheetDialog: BottomSheetDialog
@ -85,6 +92,7 @@ class PhotoImageActivity : AppCompatActivity() {
v.setPadding(0, systemBars.top + 26, 0, systemBars.bottom)
insets
}
firebaseEvent()
Widget.makeSnackbar(this, "Photographing text for translation")
@ -113,9 +121,20 @@ class PhotoImageActivity : AppCompatActivity() {
// 检查并启动相机
checkCameraPermission()
initView()
adLoad(MyApp.Config.image_camera_int_auto)
backPressedCall()
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() {
if (ContextCompat.checkSelfPermission(
this, Manifest.permission.CAMERA
@ -131,6 +150,7 @@ class PhotoImageActivity : AppCompatActivity() {
}
}
private fun initView() {
binding.photoPreview.visibility = View.VISIBLE
@ -201,9 +221,18 @@ class PhotoImageActivity : AppCompatActivity() {
PreferenceLanguageUtils.putString("language_source", language.language)
selectedMode = PreferenceLanguageUtils.getString("language_source")
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
"photo_source"
)
tryReloadAndDetectInImage()
bottomSheetDialog.dismiss()
} else {
FirebaseAnalyticsHelper.languageFromEvent(
MyApp.Config.CLICK_FROM,
"photo_target"
)
PreferenceLanguageUtils.putString("language_target", language.language)
tryReloadAndDetectInImage()
@ -222,25 +251,28 @@ class PhotoImageActivity : AppCompatActivity() {
}
}
private fun initClick() {
binding.ivStillPic.setOnClickListener {
binding.photoPreview.visibility = View.INVISIBLE
startChooseImageIntentForResult()
FirebaseAnalyticsHelper.imageTransPhotoEvent()
}
binding.ivStillTake.setOnClickListener {
binding.photoPreview.visibility = View.VISIBLE
takePhoto()
FirebaseAnalyticsHelper.imageTransCameraEvent()
}
binding.ivStillBack.setOnClickListener {
showInstAdFromCache(MyApp.Config.image_camera_int_auto)
finish()
}
binding.ivStillBack.setOnClickListener { onBackPressed() }
binding.ivStillBuling.setOnClickListener {
toggleFlash()
updateFlashButtonUI()
}
binding.stillSourceLanguage.setOnClickListener {
chooseLanguage = false
bottomSheetDialog.show()
}
binding.stillTargetLanguage.setOnClickListener {
@ -257,6 +289,8 @@ class PhotoImageActivity : AppCompatActivity() {
// 更新界面显示
binding.stillSourceLanguage.text = currentTargetLanguage
binding.stillTargetLanguage.text = currentSourceLanguage
FirebaseAnalyticsHelper.textTransSwitchEvent(MyApp.Config.CLICK_FROM, "photo")
}
}
@ -293,6 +327,7 @@ class PhotoImageActivity : AppCompatActivity() {
}
private fun takePhoto() {
fbFrom = "photo"
val photoFile = File(
outputDirectory,
SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(System.currentTimeMillis()) + ".jpg"
@ -378,30 +413,31 @@ class PhotoImageActivity : AppCompatActivity() {
private fun createImageProcessor() {
imageProcessor?.stop()
try {
imageProcessor = when (selectedMode) {
TEXT_RECOGNITION_CHINESE -> TextRecognitionProcessor(
this,
ChineseTextRecognizerOptions.Builder().build(), true, true
ChineseTextRecognizerOptions.Builder().build(), true, true, fbFrom
)
"Hindi", "Marathi", "Nepali", "Sanskrit" -> TextRecognitionProcessor(
this,
DevanagariTextRecognizerOptions.Builder().build(), true, true
DevanagariTextRecognizerOptions.Builder().build(), true, true, fbFrom
)
TEXT_RECOGNITION_JAPANESE -> TextRecognitionProcessor(
this,
JapaneseTextRecognizerOptions.Builder().build(), true, true
JapaneseTextRecognizerOptions.Builder().build(), true, true, fbFrom
)
TEXT_RECOGNITION_KOREAN -> TextRecognitionProcessor(
this,
KoreanTextRecognizerOptions.Builder().build(), true, true
KoreanTextRecognizerOptions.Builder().build(), true, true, fbFrom
)
else -> TextRecognitionProcessor(
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 {
private const val TAG = "StillImageActivity"
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 REQUEST_CHOOSE_IMAGE = 1001
}
}

View File

@ -1,12 +1,15 @@
package com.assimilate.alltrans.viewui
import android.os.Bundle
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.R
import com.assimilate.alltrans.databinding.ActivityQuickSetBinding
import com.google.android.material.slider.Slider
class QuickSetActivity : AppCompatActivity() {
@ -22,5 +25,25 @@ class QuickSetActivity : AppCompatActivity() {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
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
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.widget.RatingBar
import android.widget.TextView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivitySettingsBinding
import com.google.android.material.bottomsheet.BottomSheetDialog
@ -18,6 +20,7 @@ class SettingsActivity
: AppCompatActivity() {
private lateinit var binding: ActivitySettingsBinding
private lateinit var bottomSheetDialog: BottomSheetDialog
private var userChoose = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -30,25 +33,18 @@ class SettingsActivity
insets
}
initView()
initClick()
}
private fun initView() {
// 设置 BottomSheetDialog
bottomSheetDialog = BottomSheetDialog(this)
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()
}
setBottomSheet()
setVersion()
}
private fun initClick() {
binding.ivSetBack.setOnClickListener { onBackPressed() }
binding.ivSetBack.setOnClickListener { finish() }
binding.llRate.setOnClickListener {
bottomSheetDialog.show()
@ -66,6 +62,87 @@ class SettingsActivity
intent.data = Uri.parse(url)
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.util.Log
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
@ -17,15 +18,18 @@ import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
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.keepmodel.PreferenceLanguageUtils
import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityTextResultBinding
import com.assimilate.alltrans.http.GoogleTranslator
import com.assimilate.alltrans.http.Translator
import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import java.util.Locale
@ -50,6 +54,10 @@ class TextResultActivity : AppCompatActivity() {
}
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
val intent = intent
val receivedString = intent.getStringExtra("source_text")
@ -62,21 +70,36 @@ class TextResultActivity : AppCompatActivity() {
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() {
binding.ivTrBack.setOnClickListener { onBackPressed() }
binding.tvTrNewTrans.setOnClickListener { onBackPressed() }
binding.ivTrBack.setOnClickListener {
showInstAdFromCache(MyApp.Config.text_trans_int_auto)
finish()
}
binding.tvTrNewTrans.setOnClickListener {
showInstAdFromCache(MyApp.Config.text_new_int_auto)
finish()
}
binding.ivReToPhoto.setOnClickListener {
startActivity(Intent(this, PhotoImageActivity::class.java))
showInstAdFromCache(MyApp.Config.text_camera_int_auto)
}
binding.ivTrCopy.setOnClickListener {
copyToClipboard()
FirebaseAnalyticsHelper.textTransCopyEvent()
}
binding.ivSourceClear.setOnClickListener { onBackPressed() }
binding.ivSourceClear.setOnClickListener { finish() }
binding.ivSourceTts.setOnClickListener {
readText(
binding.tvTrSource.text.toString(),
@ -111,7 +134,6 @@ class TextResultActivity : AppCompatActivity() {
}
// 更新图标状态的方法
private fun updateCollectIcon(isCollected: Boolean) {
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) {
if (text.isEmpty() || translating) {
Logger.d("log", "translating(not post data)...")
@ -176,7 +190,10 @@ class TextResultActivity : AppCompatActivity() {
override fun onFailure(errorMessage: String?) {
translating = false
FirebaseAnalyticsHelper.textTransResultEvent("Translation failed: $errorMessage")
FirebaseAnalyticsHelper.textTransResultEvent(
MyApp.Config.FAIL_REASON,
"failed: $errorMessage"
)
runOnUiThread {
// 显示失败信息或记录日志
if (!TextUtils.isEmpty(errorMessage)) {
@ -265,4 +282,74 @@ class TextResultActivity : AppCompatActivity() {
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.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.ViewGroup
import android.widget.Button
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
@ -14,9 +12,12 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper
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
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
@ -25,7 +26,6 @@ class WelActivity : AppCompatActivity() {
setContentView(binding.root)
//debugFirebase()
ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
@ -52,20 +52,17 @@ class WelActivity : AppCompatActivity() {
private fun initSet() {
backPressedCall()
Handler(Looper.getMainLooper()).postDelayed({
startActivity(
Intent(this, MainActivity::class.java)
)
}, 2444)
if (MyApp.app.isFirstLaunch) {
adSplash(MyApp.Config.start_cold_int_auto)
} else {
adSplashHot(MyApp.Config.start_hot_int_auto)
}
}
private fun backPressedCall() {
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
}
}
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" />
<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
android:id="@+id/change_language"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="23dp"
android:elevation="2dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_main_title">
android:orientation="horizontal">
<TextView
android:id="@+id/ch_source_language"
@ -117,10 +126,7 @@
android:paddingStart="12dp"
android:paddingTop="16dp"
android:paddingEnd="12dp"
android:paddingBottom="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/change_language">
android:paddingBottom="16dp">
<EditText
android:id="@+id/et_text"
@ -195,6 +201,14 @@
</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
android:id="@+id/ll_main_quick"
android:layout_width="match_parent"
@ -202,10 +216,7 @@
android:layout_marginTop="16dp"
android:background="@drawable/button_r20_white_bg"
android:orientation="vertical"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_main_enter_text">
android:padding="16dp">
<LinearLayout
android:id="@+id/ll_quick_set"
@ -257,12 +268,10 @@
</LinearLayout>
<LinearLayout
android:id="@+id/ll_ph"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/ll_main_quick">
android:layout_marginTop="12dp">
<TextView
android:id="@+id/tv_main_photo_trans"
@ -303,4 +312,7 @@
app:drawableTopCompat="@drawable/main_dic" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

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

View File

@ -108,8 +108,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="@drawable/button_r20_white_bg"
android:orientation="vertical"
android:visibility="gone">
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_rate"
@ -248,6 +247,7 @@
app:drawableStartCompat="@drawable/ic_version_update" />
<TextView
android:id="@+id/tv_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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:textSize="16sp" />
<androidx.appcompat.widget.AppCompatRatingBar
android:id="@+id/rate1"
<RatingBar
android:id="@+id/ratingBar"
style="@style/MyRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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
android:id="@+id/tv_rate_commit"

View File

@ -3,21 +3,30 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/button_r20_white_bg_tlr"
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
android:id="@+id/ph_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
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"
android:baselineAligned="false"
app:queryBackground="@android:color/transparent"
android:background="@android:color/transparent"
app:queryHint="Search" />
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_languages"

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<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_height="wrap_content"
android:background="@drawable/button_r10_gray_bg"
android:background="@drawable/button_r20_white_bg_tlr"
android:orientation="vertical">
<LinearLayout
@ -22,7 +21,8 @@
android:layout_width="0dp"
android:layout_height="match_parent"
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:ellipsize="end"
android:gravity="center"
@ -31,8 +31,7 @@
android:paddingEnd="12dp"
android:textColor="@color/main_text_ff0e8ce8"
android:textSize="16sp"
android:textStyle="bold"
app:drawableEndCompat="@drawable/ic_down_choose" />
android:textStyle="bold" />
<ImageView
android:id="@+id/tv_exchange"
@ -53,7 +52,8 @@
android:layout_width="0dp"
android:layout_height="match_parent"
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:ellipsize="end"
android:gravity="center"
@ -62,8 +62,7 @@
android:paddingEnd="12dp"
android:textColor="@color/main_text_ff1f1724"
android:textSize="16sp"
android:textStyle="bold"
app:drawableEndCompat="@drawable/ic_down_choose" />
android:textStyle="bold" />
</LinearLayout>
<androidx.core.widget.NestedScrollView

View File

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

View File

@ -25,6 +25,7 @@
android:layout_marginTop="6dp"
android:layout_marginEnd="16dp"
android:src="@drawable/more_options_icon"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -76,9 +77,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:visibility="invisible"
android:layout_marginBottom="10dp"
android:src="@drawable/ic_voice" />
android:src="@drawable/ic_voice"
android:visibility="invisible" />
<View
@ -100,11 +101,11 @@
android:textStyle="bold" />
<LinearLayout
android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
android:orientation="horizontal"
android:visibility="invisible">
<ImageView
android:id="@+id/iv_target_tts"

View File

@ -1,5 +1,6 @@
<resources>
<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_group_recognized_text_in_blocks" translatable="false">grtib</string>
@ -83,4 +84,5 @@
<string name="quick_set_kj_double">双击悬浮球</string>
</resources>

View File

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

View File

@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- 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. -->
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
</style>
@ -8,10 +8,7 @@
<style name="Theme.Alltrans" parent="Base.Theme.Alltrans" />
<style name="CustomBottomSheetDialogTheme" parent="Theme.Material3.Light.BottomSheetDialog">
<!-- 自定义颜色属性 -->
<item name="colorPrimary">@color/white</item> <!-- 替换为你想要的颜色 -->
<item name="colorPrimaryDark">@color/white</item> <!-- 替换为你想要的颜色 -->
<item name="colorAccent">@color/white</item> <!-- 替换为你想要的颜色 -->
<item name="backgroundTint">@color/white</item>
</style>
</resources>

View File

@ -7,15 +7,35 @@ pluginManagement {
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
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 {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
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")
}
}
}