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