Commit 73230eef authored by wanglei's avatar wanglei

初始化

parent d53cd9b6
......@@ -59,4 +59,34 @@ dependencies {
//Pdf库
implementation("com.tom-roush:pdfbox-android:2.0.27.0")
api(project(":pdflibrary"))
//广告
implementation("com.google.android.gms:play-services-ads:23.1.0")
implementation("com.google.ads.mediation:applovin:12.4.3.0")
implementation("com.google.ads.mediation:facebook:6.17.0.0")
implementation("com.google.ads.mediation:mintegral:16.7.21.0")
implementation("com.google.ads.mediation:pangle:5.9.0.4.0")
//ump
implementation("com.google.android.ump:user-messaging-platform:3.0.0")
//firebase
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
implementation("com.google.firebase:firebase-messaging")
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.google.firebase:firebase-crashlytics")
//facebook
implementation("com.facebook.android:facebook-android-sdk:[8,9)")
//网络请求和解析
implementation("com.google.code.gson:gson:2.11.0")
// define a BOM and its version
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0"))
// define any required OkHttp artifacts without version
implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:logging-interceptor")
//mintegral
implementation("com.reyun.solar.engine.oversea:solar-engine-core:1.2.8.3")
}
\ No newline at end of file
{
"project_info": {
"project_number": "953792647345",
"project_id": "pdf-test-d0ae7",
"storage_bucket": "pdf-test-d0ae7.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:953792647345:android:c5234e8bfc859f8b20d290",
"android_client_info": {
"package_name": "com.base.pdfreader2"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyBT6B1oPmkojGX0TgBOI9bDkx5pdEFXWoo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
......@@ -18,4 +18,20 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
#-renamesourcefileattribute SourceFile
-keep class com.base.pdfreader2.bean.** {*; }
-keep class com.reyun.** {*; }
-keep class route.**{*;}
-keep interface com.reyun.** {*; }
-keep interface route.**{*;}
-dontwarn com.reyun.**
-dontwarn org.json.**
-keep class org.json.**{*;}
# Google lib库
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient {
com.google.android.gms.ads.identifier.AdvertisingIdClient$Info getAdvertisingIdInfo(android.content.Context);
}
-keep class com.google.android.gms.ads.identifier.AdvertisingIdClient$Info {
java.lang.String getId();
boolean isLimitAdTrackingEnabled();
}
......@@ -13,31 +13,65 @@
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:icon="@mipmap/logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PdfReader2"
tools:targetApi="31">
<activity
android:name=".ui.splash.SplashActivity"
android:exported="false" />
<activity
android:name=".ui.main.MainActivity"
android:exported="true">
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.main.MainActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.pdf.PdfActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity">
</activity>
<!-- <service-->
<!-- android:name=".fcm.MessagingService"-->
<!-- android:exported="false">-->
<!-- <intent-filter>-->
<!-- <action android:name="com.google.firebase.MESSAGING_EVENT" />-->
<!-- </intent-filter>-->
<!-- </service>-->
<!-- <receiver-->
<!-- android:name=".fcm.FcmReceiver"-->
<!-- android:exported="true"-->
<!-- android:permission="com.google.android.c2dm.permission.SEND">-->
<!-- <intent-filter>-->
<!-- <action android:name="com.google.firebase.MESSAGING_EVENT" />-->
<!-- <action android:name="com.google.android.c2dm.intent.RECEIVE" />-->
<!-- <category android:name="com.ttesst.gododo.redause" />-->
<!-- </intent-filter>-->
<!-- </receiver>-->
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
</application>
</manifest>
\ No newline at end of file
package com.base.pdfreader2.ads
import android.animation.ObjectAnimator
import android.animation.ValueAnimator.INFINITE
import android.app.AlertDialog
import android.content.Context
import android.view.LayoutInflater
import android.view.animation.LinearInterpolator
import com.base.pdfreader2.R
import com.base.pdfreader2.databinding.DialogAdPreparingBinding
object AdDialog {
fun Context.showAdPreparingDialog(): AlertDialog {
val binding = DialogAdPreparingBinding.inflate(LayoutInflater.from(this))
val dialog = AlertDialog.Builder(this).create()
dialog.setView(binding.root)
dialog.setCancelable(false)
dialog.setCanceledOnTouchOutside(false)
dialog.show()
val params = dialog.window?.attributes
params?.width = resources.getDimensionPixelOffset(R.dimen.dp_200)
params?.height = resources.getDimensionPixelOffset(R.dimen.dp_146)
dialog.window?.attributes = params
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
// 创建一个旋转动画
val rotateAnimator = ObjectAnimator.ofFloat(binding.iv, "rotation", 0f, -360f)
rotateAnimator.setDuration(1000) // 设置动画持续时间为1000毫秒
rotateAnimator.repeatCount = INFINITE
rotateAnimator.interpolator = LinearInterpolator() // 设置插值器为线性插值
rotateAnimator.start()
return dialog
}
}
\ No newline at end of file
package com.base.pdfreader2.ads
import com.base.pdfreader2.ads.AdmobHelper.inter_limit_click
import com.base.pdfreader2.ads.AdmobHelper.inter_limit_request
import com.base.pdfreader2.ads.AdmobHelper.inter_limit_show
import com.base.pdfreader2.ads.AdmobHelper.native_limit_request
import com.base.pdfreader2.ads.AdmobHelper.native_limit_show
import com.base.pdfreader2.ads.AdmobHelper.open_limit_click
import com.base.pdfreader2.ads.AdmobHelper.open_limit_request
import com.base.pdfreader2.ads.AdmobHelper.open_limit_show
import com.base.pdfreader2.helper.EventUtils
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.LogEx
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
object AdDisplayUtils {
//region open
private val open_max_request = AppPreferences.getInstance().getString(open_limit_request, "15").toInt()
private val open_max_show = AppPreferences.getInstance().getString(open_limit_show, "10").toInt()
private val open_max_click = AppPreferences.getInstance().getString(open_limit_click, "1").toInt()
fun incrementOpenRequestCount() {
currentOpenRequest += 1
}
fun incrementOpenShow() {
currentOpenShow += 1
}
fun incrementClickShow() {
currentOpenClick += 1
}
//当前开屏请求次数
private var currentOpenRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenRequest_${currentDate()}", value, true)
}
//当前开屏展示次数
private var currentOpenShow = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenShow_${currentDate()}", value, true)
}
//当前开屏点击次数
private var currentOpenClick = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenClick_${currentDate()}", value, true)
}
fun shouldShowOpenAd(): Boolean {
if (currentOpenRequest > open_max_request) {
LogEx.logDebug(TAG, "currentOpenRequest=$currentOpenRequest open_max_request=$open_max_request")
EventUtils.event("ad_limit", "currentOpenRequest=$currentOpenRequest open_max_request=$open_max_request")
return false
}
if (currentOpenShow > open_max_show) {
LogEx.logDebug(TAG, "currentOpenShow=$currentOpenShow open_max_show=$open_max_show")
EventUtils.event("ad_limit", "currentOpenShow=$currentOpenShow open_max_show=$open_max_show")
return false
}
if (currentOpenClick > open_max_click) {
LogEx.logDebug(TAG, "currentOpenClick=$currentOpenClick open_max_click=$open_max_click")
EventUtils.event("ad_limit", "currentOpenClick=$currentOpenClick open_max_click=$open_max_click")
return false
}
return true
}
//endregion
//region inter
private val inter_max_request = AppPreferences.getInstance().getString(inter_limit_request, "15").toInt()
private val inter_max_show = AppPreferences.getInstance().getString(inter_limit_show, "10").toInt()
private val inter_max_click = AppPreferences.getInstance().getString(inter_limit_click, "1").toInt()
fun incrementInterRequestCount() {
currentInterRequest += 1
}
fun incrementInterShowCount() {
currentInterShow += 1
}
fun incrementInterClickCount() {
currentInterClick += 1
}
//当前插页请求次数
private var currentInterRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentInterRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterRequest_${currentDate()}", value, true)
}
//当前插页展示次数
private var currentInterShow = 0
get() {
return AppPreferences.getInstance().getInt("currentInterShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterShow_${currentDate()}", value, true)
}
//当前插页点击次数
private var currentInterClick = 0
get() {
return AppPreferences.getInstance().getInt("currentInterClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterClick_${currentDate()}", value, true)
}
fun shouldShowInterAd(): Boolean {
if (currentInterRequest > inter_max_request) {
LogEx.logDebug(TAG, "currentInterRequest=$currentInterRequest inter_max_request=$inter_max_request")
EventUtils.event("ad_limit", "currentInterRequest=$currentInterRequest inter_max_request=$inter_max_request")
return false
}
if (currentInterShow > inter_max_show) {
LogEx.logDebug(TAG, "currentInterShow=$currentInterShow inter_max_show=$inter_max_show")
EventUtils.event("ad_limit", "currentInterShow=$currentInterShow inter_max_show=$inter_max_show")
return false
}
if (currentInterClick > inter_max_click) {
LogEx.logDebug(TAG, "currentInterClick=$currentInterClick inter_max_click=$inter_max_click")
EventUtils.event("ad_limit", "currentInterClick=$currentInterClick inter_max_click=$inter_max_click")
return false
}
return true
}
//endregion
//region native
private val native_max_request = AppPreferences.getInstance().getString(native_limit_request, "15").toInt()
private val native_max_show = AppPreferences.getInstance().getString(native_limit_show, "10").toInt()
private val native_max_click = AppPreferences.getInstance().getString(native_limit_show, "1").toInt()
fun incrementNativeRequestCount() {
currentNativeRequest += 1
}
fun incrementNativeShowCount() {
currentNativeShow += 1
}
fun incrementNativeClickCount() {
currentNativeClick += 1
}
private var currentNativeRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeRequest_${currentDate()}", value, true)
}
private var currentNativeShow = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeShow_${currentDate()}", value, true)
}
private var currentNativeClick = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeClick_${currentDate()}", value, true)
}
fun shouldShowNative(): Boolean {
if (currentNativeRequest > native_max_request) {
LogEx.logDebug(TAG, "currentNativeRequest=$currentNativeRequest native_max_request=$native_max_request")
EventUtils.event("ad_limit", "currentNativeRequest=$currentNativeRequest native_max_request=$native_max_request")
return false
}
if (currentNativeShow > native_max_show) {
LogEx.logDebug(TAG, "currentNativeShow=$currentNativeShow native_max_show=$native_max_show")
EventUtils.event("ad_limit", "currentNativeShow=$currentNativeShow native_max_show=$native_max_show")
return false
}
if (currentNativeClick > native_max_click) {
LogEx.logDebug(TAG, "currentNativeClick=$currentNativeClick native_max_click=$native_max_click")
EventUtils.event("ad_limit", "currentNativeClick=$currentNativeClick native_max_click=$native_max_click")
return false
}
return true
}
//endregion
private val TAG = "AdDisplayUtils"
private fun currentDate(): String {
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val currentDate = Calendar.getInstance().time
return dateFormat.format(currentDate)
}
}
package com.base.pdfreader2.ads
import android.app.Activity
import com.base.pdfreader2.ads.admob.AdmobInterstitialUtils
import com.base.pdfreader2.ads.admob.AdmobNativeUtils
import com.base.pdfreader2.helper.EventUtils
import com.base.pdfreader2.helper.MyApplication
import com.base.pdfreader2.utils.AppPreferences
import com.google.android.gms.ads.MobileAds
import java.util.concurrent.atomic.AtomicBoolean
object AdmobHelper {
//开屏限制
const val open_limit_request = "open_limit_request"
const val open_limit_show = "open_limit_show"
const val open_limit_click = "open_limit_click"
//插页限制
const val inter_limit_request = "inter_limit_request"
const val inter_limit_show = "inter_limit_show"
const val inter_limit_click = "inter_limit_click"
//原生广告限制
const val native_limit_request = "native_limit_request"
const val native_limit_show = "native_limit_show"
const val native_limit_click = "native_limit_click"
//是否展示多语言
val showLanPage = "showLanPage"
//开屏加载ad时间
val open_ad_loading = "open_ad_loading"
//创建pdf加载ad时间
val create_pdf_loading = "create_pdf_loading"
//删除文件
val delete_loading = "delete_loading"
//打开文件
val open_file_loading = "open_file_loading"
//合并pdf
val merge_loading = "merge_loading"
//拆分pdf
val split_loading = "split_loading"
//可请求时间段(由 x 定义)
const val ad_request_period = "ad_request_interval"
//可请求时间段内允许的最大请求数(由 y 定义)
const val ad_period_max_request = "ad_period_max_request"
//可请求时间段间隔时间
const val ad_request_period_interval = "ad_request_period_interval"
var isAdInit = AtomicBoolean(false)
fun initAdmobAd(activity: Activity) {
MobileAds.initialize(MyApplication.context) { initializationStatus ->
isAdInit.set(true)
EventUtils.event("AdmobInit", "AdmobInit")
AdmobNativeUtils.loadNativeAd()
AdmobInterstitialUtils.loadInterstitialAd(activity)
}
}
//上次展示广告时间关闭赋值,通用开屏和插页
var lastShowedOnHiddenTime = 0L
get() {
return AppPreferences.getInstance().getLong("lastShowedOnHiddenTime", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastShowedOnHiddenTime", value, true)
}
/**
* 通用广告条件判断
*/
fun canCommonShowAd(): Boolean {
val interval = AppPreferences.getInstance().getString("ad_interval", "10").toInt()
if (System.currentTimeMillis() - lastShowedOnHiddenTime < interval * 1000L) {
return false
}
return true
}
//上次scan展示ad时间
var lastScanShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastScanShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastScanShowAd", value, true)
}
//是否显示扫描功能ad
fun isShowScanInter(): Boolean {
val interval = AppPreferences.getInstance().getString("scan_ad_interval", "10").toInt()
return System.currentTimeMillis() - lastScanShowAd > interval * 1000L
}
//上次打开文档展示ad时间
var lastOpenDocumentShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastOpenDocumentShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastOpenDocumentShowAd", value, true)
}
//打开文档是否展示广告
fun isShowOpenDocumentInter(): Boolean {
val interval = AppPreferences.getInstance().getString("open_document_ad_interval", "10").toInt()
val openStatus = AppPreferences.getInstance().getString("open_document_ad_status", "1").toInt()
return openStatus == 1 && System.currentTimeMillis() - lastOpenDocumentShowAd > interval * 1000L
}
var lastCloseDocumentShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastCloseDocumentShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastCloseDocumentShowAd", value, true)
}
fun isShowCloseDocumentInter(): Boolean {
val interval = AppPreferences.getInstance().getString("close_document_ad_interval", "10").toInt()
return System.currentTimeMillis() - lastCloseDocumentShowAd > interval * 1000L
}
fun isShowCloseDocument(): Boolean {
val status = AppPreferences.getInstance().getString("close_document_ad_show", "0").toInt()
return status == 1
}
fun isShowRvNativeAd(): Boolean {
val status = AppPreferences.getInstance().getString("rv_native_ad_show", "0").toInt()
return status == 1
}
fun isBackShowAd(): Boolean {
val status = AppPreferences.getInstance().getString("is_back_show_ad", "0").toInt()
return status == 1
}
}
\ No newline at end of file
//package com.base.pdfviewerscannerwhite.ads
//
//import com.base.pdfviewerscannerwhite.utils.AppPreferences
//import com.base.pdfviewerscannerwhite.utils.LogEx
//import com.google.firebase.database.DataSnapshot
//import com.google.firebase.database.DatabaseError
//import com.google.firebase.database.ValueEventListener
//import com.google.firebase.database.ktx.database
//import com.google.firebase.ktx.Firebase
//
////Realtime Database
//object FirebaseDatabase {
//
// private val TAG = "FirebaseDatabase"
//
// // Write a message to the database
// val database = Firebase.database
// var rootRef = database.reference
//
//
//
// fun saveDatabase2Sp() {
//// add(open_limit_request, "15")
//// add(open_limit_show, "10")
//// add(open_limit_click, "1")
////
////
//// add(inter_limit_request, "15")
//// add(inter_limit_show, "10")
//// add(inter_limit_click, "1")
////
//// add(native_limit_request, "15")
//// add(native_limit_show, "10")
//// add(native_limit_click, "1")
////
//// add(popup_count, "0")
//// add(popup_status, "1")
////
//// add(popup_style1_start, "7")
//// add(popup_style1_end, "11")
//// add(popup_style1_count, "0")
//// add(popup_style1_status, "1")
//// add(popup_style1_interval, "120")
////
//// add(popup_style2_start, "12")
//// add(popup_style2_end, "17")
//// add(popup_style2_count, "0")
//// add(popup_style2_status, "1")
//// add(popup_style2_interval, "120")
////
//// add(popup_style3_start, "18")
//// add(popup_style3_end, "24")
//// add(popup_style3_count, "0")
//// add(popup_style3_status, "1")
//// add(popup_style3_interval, "120")
////
//// add(showLanPage, "1")
////
//// add(open_ad_loading, "8000")
//// add(create_pdf_loading, "8000")
//// add(delete_loading, "8000")
//// add(open_file_loading, "8000")
//// add(merge_loading, "8000")
//// add(split_loading, "8000")
////
//// add(ad_request_period, "1")
//// add(ad_period_max_request, "10")
//// add(ad_request_period_interval, "60")
//
//
// rootRef.addListenerForSingleValueEvent(object : ValueEventListener {
// override fun onDataChange(dataSnapshot: DataSnapshot) {
// var i = 0
// for (snapshot in dataSnapshot.getChildren()) {
// val key1 = snapshot.key
// val value1 = snapshot.value
// i++
// LogEx.logDebug("Database", "Key: $key1, Value: $value1 $i")
// AppPreferences.getInstance().put(key1, value1)
// }
// }
//
// override fun onCancelled(databaseError: DatabaseError) {
// LogEx.logDebug("Database", "onCancelled")
// }
// })
//
// }
//
// fun add(ref: String, value: String) {
// database.getReference(ref).setValue(value)
// }
//
//
//}
\ No newline at end of file
//package com.base.pdfviewerscannerwhite.ads
//
//import com.base.pdfviewerscannerwhite.R
//import com.base.pdfviewerscannerwhite.utils.LogEx
//import com.google.firebase.ktx.Firebase
//import com.google.firebase.remoteconfig.ConfigUpdate
//import com.google.firebase.remoteconfig.ConfigUpdateListener
//import com.google.firebase.remoteconfig.FirebaseRemoteConfig
//import com.google.firebase.remoteconfig.FirebaseRemoteConfigException
//import com.google.firebase.remoteconfig.ktx.get
//import com.google.firebase.remoteconfig.ktx.remoteConfig
//import com.google.firebase.remoteconfig.ktx.remoteConfigSettings
//
//
//object RemoteConfigHelper {
// private val TAG = "RemoteConfigHelper"
// fun test() {
// val remoteConfig: FirebaseRemoteConfig = Firebase.remoteConfig
// val configSettings = remoteConfigSettings {
// minimumFetchIntervalInSeconds = 3600
// }
// remoteConfig.setConfigSettingsAsync(configSettings)
//
// remoteConfig.setDefaultsAsync(R.xml.remote_config_defaults)
//
// //提取并激活值
// remoteConfig.fetchAndActivate().addOnCompleteListener { task ->
// if (task.isSuccessful) {
// val aa = remoteConfig["a"].asString()
// LogEx.logDebug(TAG, "fetchAndActivate aa=$aa")
// }
// }
//
// //监听跟新值
// remoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener {
// override fun onUpdate(configUpdate: ConfigUpdate) {
// remoteConfig.activate().addOnCompleteListener {
// val aa2 = remoteConfig["a"].asString()
// LogEx.logDebug(TAG, "onUpdate aa=$aa2")
// }
// }
//
// override fun onError(error: FirebaseRemoteConfigException) {
// }
//
// })
// }
//
//}
\ No newline at end of file
package com.base.pdfreader2.ads.admob
import android.content.Context
import android.os.Bundle
import android.view.ViewGroup
import android.view.ViewTreeObserver
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.helper.ConfigHelper
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.LogEx
import com.google.ads.mediation.admob.AdMobAdapter
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView
import java.util.UUID
object AdmobBannerUtils {
private const val TAG = "AdmobBannerUtils"
private var adView: AdView? = null
private var listener: ViewTreeObserver.OnGlobalLayoutListener? = null
fun showCollapsibleBannerAd(context: Context, parent: ViewGroup, adClose: (() -> Unit)? = null) {
val isShowBanner = AppPreferences.getInstance().getString("isShowBanner", "0").toInt()
if (isShowBanner == 0) {
return
}
parent.removeAllViews()
adView?.destroy()
adView = null
adView = AdView(context)
// adView?.apply {
// onPaidEventListener = AdmobEvent.EventOnPaidEventListener(this)
// }
parent.addView(adView)
listener = ViewTreeObserver.OnGlobalLayoutListener {
val screenPixelDensity = context.resources.displayMetrics.density
val adWidth = (parent.width / screenPixelDensity).toInt()
val adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, adWidth)
adView?.adUnitId = if (BuildConfig.DEBUG) ConfigHelper.bannerAdmobIdTest else ConfigHelper.bannerAdmobId
adView?.setAdSize(adSize)
loadCollapsibleBanner(adClose)
parent.viewTreeObserver.removeOnGlobalLayoutListener(listener)
}
parent.viewTreeObserver.addOnGlobalLayoutListener(listener)
}
private fun loadCollapsibleBanner(adClose: (() -> Unit)?) {
val extras = Bundle()
extras.putString("collapsible", "bottom")
extras.putString("collapsible_request_id", UUID.randomUUID().toString())
val adRequest =
AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter::class.java, extras).build()
adView?.adListener =
object : AdListener() {
override fun onAdLoaded() {
LogEx.logDebug(TAG, "onAdLoaded")
}
override fun onAdOpened() {
LogEx.logDebug(TAG, "onAdOpened")
}
override fun onAdClosed() {
super.onAdClosed()
LogEx.logDebug(TAG, "onAdClosed")
adClose?.invoke()
}
}
adView?.loadAd(adRequest)
}
}
\ No newline at end of file
This diff is collapsed.
package com.base.pdfreader2.ads.admob
import android.app.Activity
import android.app.Dialog
import android.widget.Toast
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.ads.AdDialog.showAdPreparingDialog
import com.base.pdfreader2.ads.AdDisplayUtils
import com.base.pdfreader2.ads.admob.AdmobEvent.clickAd
import com.base.pdfreader2.ads.admob.AdmobEvent.pullAd
import com.base.pdfreader2.ads.admob.AdmobEvent.showAd
import com.base.pdfreader2.ads.AdmobHelper.lastShowedOnHiddenTime
import com.base.pdfreader2.helper.ConfigHelper
import com.base.pdfreader2.helper.EventUtils
import com.base.pdfreader2.helper.MyApplication
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import org.json.JSONObject
import java.util.UUID
object AdmobInterstitialUtils {
private var interAd: InterstitialAd? = null
private var interLoadTime = Long.MAX_VALUE
private var adLastDisplayTime: Long = 0
private val mRequest = AdRequest.Builder().build()
private fun isAdExpired(): Boolean {
return System.currentTimeMillis() - interLoadTime > 1000 * 60 * 60
}
fun showInterstitialAd(
activity: Activity,
isReLoadAd: Boolean = false,
isShowDialog: Boolean = true,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
if (activity.isFinishing || activity.isDestroyed) {
return
}
if (isAdExpired()) {
val obj2 = JSONObject()
obj2.put("ad_unit", "interAd")
EventUtils.event("ad_expire", ext = obj2)
interAd = null
loadInterstitialAd(activity)
onHidden?.invoke(false)
return
}
if (!AdDisplayUtils.shouldShowInterAd()) {
onHidden?.invoke(false)
return
}
val obj1 = JSONObject()
obj1.put("ad_unit", "interAd")
EventUtils.event("ad_prepare_show", ext = obj1)
if (interAd != null) {
var dialog: Dialog? = null
if (!activity.isFinishing && !activity.isDestroyed) {
dialog = activity.showAdPreparingDialog()
}
displayInterstitialAd(activity, dialog, onHidden)
} else {
showAdDialogAndLoadInterstitial(activity, isReLoadAd, isShowDialog, onHidden)
}
}
fun loadInterstitialAd(activity: Activity, onLoad: (() -> Unit)? = null) {
if (interAd != null) {
onLoad?.invoke()
return
}
if (!AdDisplayUtils.shouldShowInterAd()) {
onLoad?.invoke()
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "interAd")
obj.put("from", activity.javaClass.simpleName)
EventUtils.event("ad_pull_start", ext = obj)
InterstitialAd.load(
activity,
if (BuildConfig.DEBUG) ConfigHelper.interAdmobIdTest else ConfigHelper.interAdmobId,
mRequest,
object : InterstitialAdLoadCallback() {
override fun onAdFailedToLoad(p0: LoadAdError) {
interAd = null
onLoad?.invoke()
pullAd(p0.responseInfo, "interAd", p0.message, reqId = reqId)
if (BuildConfig.DEBUG) {
Toast.makeText(
MyApplication.context, "拉取失败" + p0.message, Toast.LENGTH_SHORT
).show()
}
}
override fun onAdLoaded(ad: InterstitialAd) {
interAd = ad
onLoad?.invoke()
interLoadTime = System.currentTimeMillis()
pullAd(ad.responseInfo, "interAd", reqId = reqId)
ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
AdDisplayUtils.incrementInterRequestCount()
}
})
}
private fun showAdDialogAndLoadInterstitial(
activity: Activity,
isReLoadAd: Boolean,
isShowDialog: Boolean,
onHidden: ((showed: Boolean) -> Unit)?
) {
if (!isShowDialog) {
onHidden?.invoke(false)
return
}
var mDialog: Dialog? = null
if (!activity.isFinishing && !activity.isDestroyed) {
mDialog = activity.showAdPreparingDialog()
mDialog.show()
}
loadInterstitialAd(activity) {
mDialog?.dismiss()
if (!isReLoadAd) {
showInterstitialAd(activity, true, false) {
onHidden?.invoke(it)
}
}
}
if (isReLoadAd) {
mDialog?.dismiss()
onHidden?.invoke(false)
}
}
private fun displayInterstitialAd(
activity: Activity,
dialog: Dialog? = null,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
val thisInterAd = interAd
interAd = null
thisInterAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdClicked() {
clickAd(thisInterAd?.responseInfo, "interAd")
AdDisplayUtils.incrementInterClickCount()
}
override fun onAdDismissedFullScreenContent() {
dialog?.dismiss()
interAd = null
onHidden?.invoke(true)
loadInterstitialAd(activity)
lastShowedOnHiddenTime = System.currentTimeMillis()
}
override fun onAdFailedToShowFullScreenContent(p0: AdError) {
dialog?.dismiss()
interAd = null
onHidden?.invoke(false)
loadInterstitialAd(activity)
}
override fun onAdShowedFullScreenContent() {
dialog?.dismiss()
showAd(thisInterAd?.responseInfo, "interAd", activity)
AdDisplayUtils.incrementInterShowCount()
adLastDisplayTime = System.currentTimeMillis() / 1000
}
}
thisInterAd?.show(activity)
}
fun haveReadAd(): Boolean {
return interAd != null
}
}
\ No newline at end of file
package com.base.pdfreader2.ads.admob
import android.app.Activity
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.R
import com.base.pdfreader2.ads.AdDisplayUtils
import com.base.pdfreader2.ads.admob.AdmobEvent.clickAd
import com.base.pdfreader2.ads.admob.AdmobEvent.pullAd
import com.base.pdfreader2.ads.admob.AdmobEvent.showAd
import com.base.pdfreader2.helper.ConfigHelper
import com.base.pdfreader2.helper.EventUtils
import com.base.pdfreader2.helper.MyApplication
import com.base.pdfreader2.utils.LogEx
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdLoader
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.nativead.NativeAd
import org.json.JSONObject
import java.util.UUID
object AdmobNativeUtils {
private const val TAG = "AdmobNativeUtils"
private var nativeAd: NativeAd? = null
private var isLoading = false
private var nativeLoadTime = Long.MAX_VALUE
private var loadingListener: (() -> Unit)? = null
private val mRequest = AdRequest.Builder().build()
var onAdLoaded: (() -> Unit)? = null
fun loadNativeAd() {
if (nativeAd != null) {
return
}
if (isLoading) {
return
}
isLoading = true
if (!AdDisplayUtils.shouldShowNative()) {
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "nativeAd")
val adLoader = AdLoader.Builder(
MyApplication.context,
if (BuildConfig.DEBUG) ConfigHelper.nativeAdmobIdTest else ConfigHelper.nativeAdmobId
).forNativeAd {
nativeLoadTime = System.currentTimeMillis()
nativeAd = it
it.setOnPaidEventListener(AdmobEvent.EventOnPaidEventListener(it))
LogEx.logDebug(TAG, "nativeAd=${nativeAd.toString()}")
isLoading = false
loadingListener?.invoke()
loadingListener = null
pullAd(it.responseInfo, "nativeAd", reqId = reqId)
}.withAdListener(object : AdListener() {
override fun onAdLoaded() {
super.onAdLoaded()
onAdLoaded?.invoke()
onAdLoaded = null
AdDisplayUtils.incrementNativeRequestCount()
}
override fun onAdClicked() {
clickAd(nativeAd?.responseInfo, "nativeAd")
AdDisplayUtils.incrementNativeClickCount()
}
override fun onAdFailedToLoad(p0: LoadAdError) {
LogEx.logDebug(TAG, "onAdFailedToLoad=${p0.message}")
nativeAd = null
isLoading = false
pullAd(p0.responseInfo, "nativeAd", p0.message, reqId = reqId)
// Log.e("MXL", "NativeAdFailedToLoad: " + p0.message)
}
}).build()
adLoader.loadAd(mRequest)
}
fun showNativeAd(activity: Activity?, parent: ViewGroup, layout: Int = R.layout.layout_admob_native_custom) {
val obj = JSONObject()
obj.put("ad_unit", "nativeAd")
EventUtils.event("ad_prepare_show_native", ext = obj)
if (!AdDisplayUtils.shouldShowNative()) {
return
}
loadingListener = {
if (System.currentTimeMillis() - nativeLoadTime <= 1000 * 60 * 60) {
nativeAd?.let {
NativeView(parent.context, layout).run {
parent.removeAllViews()
setNativeAd(it)
parent.addView(this)
parent.isVisible = true
showAd(nativeAd?.responseInfo, "nativeAd", activity)
}
}
}
nativeAd = null
loadNativeAd()
}
if (nativeAd == null) {
loadNativeAd()
val obj2 = JSONObject()
obj2.put("reason", "no_ad")
obj2.put("ad_unit", "nativeAd")
EventUtils.event("ad_show_error", ext = obj2)
} else {
loadingListener?.invoke()
loadingListener = null
}
}
fun showReadyNativeAd(
activity: Activity?,
readyNativeAd: NativeAd?,
parent: ViewGroup,
layout: Int = R.layout.layout_admob_native_custom
) {
readyNativeAd?.let {
NativeView(parent.context, layout).run {
parent.removeAllViews()
setNativeAd(it)
parent.addView(this)
parent.isVisible = true
showAd(nativeAd?.responseInfo, "nativeAd", activity)
}
}
}
fun onDestroy() {
nativeAd?.destroy()
nativeAd = null
}
}
\ No newline at end of file
package com.base.pdfreader2.ads.admob
import android.app.Activity
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.ads.AdDisplayUtils
import com.base.pdfreader2.ads.AdmobHelper.lastShowedOnHiddenTime
import com.base.pdfreader2.ads.admob.AdmobEvent.clickAd
import com.base.pdfreader2.ads.admob.AdmobEvent.pullAd
import com.base.pdfreader2.ads.admob.AdmobEvent.showAd
import com.base.pdfreader2.helper.ConfigHelper
import com.base.pdfreader2.helper.EventUtils
import com.base.pdfreader2.helper.MyApplication
import com.base.pdfreader2.utils.LogEx
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.appopen.AppOpenAd
import org.json.JSONObject
import java.util.UUID
object AdmobOpenUtils {
private const val TAG = "AdmobOpenUtils"
private val mRequest = AdRequest.Builder().build()
private var openLoadTime = Long.MAX_VALUE
private var mOpenAd: AppOpenAd? = null
private fun isAdExpired(): Boolean {
return System.currentTimeMillis() - openLoadTime > 1000 * 60 * 60
}
fun haveReadAd(): Boolean {
return mOpenAd != null
}
fun loadAppOpenAd(onLoad: ((loaded: Boolean) -> Unit)? = null) {
if (mOpenAd != null) {
onLoad?.invoke(true)
return
}
if (!AdDisplayUtils.shouldShowOpenAd()) {
onLoad?.invoke(false)
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "openAd")
EventUtils.event("ad_pull_start", ext = obj)
AppOpenAd.load(
MyApplication.context,
if (BuildConfig.DEBUG) ConfigHelper.openAdmobIdTest else ConfigHelper.openAdmobId,
mRequest,
object : AppOpenAd.AppOpenAdLoadCallback() {
override fun onAdLoaded(ad: AppOpenAd) {
LogEx.logDebug(TAG, "onAdLoaded")
openLoadTime = System.currentTimeMillis()
mOpenAd = ad
onLoad?.invoke(true)
pullAd(ad.responseInfo, "openAd", reqId = reqId)
ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
AdDisplayUtils.incrementOpenRequestCount()
}
override fun onAdFailedToLoad(p0: LoadAdError) {
LogEx.logDebug(TAG, "LoadAdError ${p0.message}")
mOpenAd = null
onLoad?.invoke(false)
pullAd(p0.responseInfo, "openAd", p0.message, reqId = reqId)
}
})
}
fun showAppOpenAd(
activity: Activity,
isRetry: Boolean = false,
showBefore: ((flag: Boolean) -> Unit)? = null,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
if (activity.isFinishing || activity.isDestroyed) {
LogEx.logDebug(TAG, "activity isDestroyed")
return
}
if (!AdDisplayUtils.shouldShowOpenAd()) {
onHidden?.invoke(false)
return
}
if (isAdExpired()) {
LogEx.logDebug(TAG, "openLoadTime out time")
mOpenAd = null
loadAppOpenAd()
onHidden?.invoke(false)
val obj2 = JSONObject()
obj2.put("ad_unit", "openAd")
EventUtils.event("ad_expire", ext = obj2)
return
}
if (!isRetry) {
val obj1 = JSONObject()
obj1.put("ad_unit", "openAd")
EventUtils.event("ad_prepare_show", ext = obj1)
LogEx.logDebug(TAG, "open ad_prepare_show")
}
if (mOpenAd != null) {
LogEx.logDebug(TAG, "mOpenAd!=null")
val thisMOpenAd = mOpenAd
mOpenAd = null
thisMOpenAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdClicked() {
clickAd(thisMOpenAd?.responseInfo, "openAd")
AdDisplayUtils.incrementClickShow()
}
override fun onAdDismissedFullScreenContent() {
mOpenAd = null
onHidden?.invoke(true)
loadAppOpenAd()
lastShowedOnHiddenTime = System.currentTimeMillis()
}
override fun onAdFailedToShowFullScreenContent(p0: AdError) {
mOpenAd = null
onHidden?.invoke(false)
loadAppOpenAd()
val obj = JSONObject()
obj.put("reason", p0.message)
obj.put("code", p0.code)
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
}
override fun onAdShowedFullScreenContent() {
showBefore?.invoke(true)
showAd(thisMOpenAd?.responseInfo, "openAd", activity)
AdDisplayUtils.incrementOpenShow()
}
}
thisMOpenAd?.show(activity)
} else {
LogEx.logDebug(TAG, "mOpenAd=null")
loadAppOpenAd {
if (mOpenAd != null) {
showAppOpenAd(activity, true, showBefore, onHidden)
} else {
val obj = JSONObject()
obj.put("reason", "no_ad")
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
onHidden?.invoke(false)
}
}
}
}
}
\ No newline at end of file
package com.base.pdfreader2.ads.admob
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.nativead.NativeAdView
import com.base.pdfreader2.R
@SuppressLint("ViewConstructor")
class NativeView(context: Context, val layout: Int, attrs: AttributeSet? = null) : FrameLayout(context, attrs) {
init {
layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
fun setNativeAd(nativeAd: NativeAd?) {
nativeAd ?: return
val adView = LayoutInflater.from(context)
.inflate(layout, this, false) as NativeAdView
// runCatching {
// adView.advertiserView = adView.findViewById(R.id.ad_advertiser)
// }
adView.mediaView = adView.findViewById(R.id.ad_media)
adView.headlineView = adView.findViewById(R.id.ad_headline)
adView.bodyView = adView.findViewById(R.id.ad_body)
adView.callToActionView = adView.findViewById(R.id.ad_call_to_action)
adView.iconView = adView.findViewById(R.id.ad_app_icon)
(adView.headlineView as TextView?)?.text = nativeAd.headline
adView.mediaView?.mediaContent = nativeAd.mediaContent
if (nativeAd.body == null) {
adView.bodyView?.visibility = View.INVISIBLE
} else {
adView.bodyView?.visibility = View.VISIBLE
(adView.bodyView as TextView?)?.text = nativeAd.body
}
if (nativeAd.callToAction == null) {
adView.callToActionView?.visibility = View.INVISIBLE
} else {
adView.callToActionView?.visibility = View.VISIBLE
(adView.callToActionView as Button?)?.text = nativeAd.callToAction
}
if (nativeAd.icon == null) {
adView.iconView?.visibility = View.GONE
} else {
(adView.iconView as ImageView?)?.setImageDrawable(
nativeAd.icon?.drawable
)
adView.iconView?.visibility = View.VISIBLE
}
adView.setNativeAd(nativeAd)
removeAllViews()
addView(adView)
}
}
\ No newline at end of file
package com.base.pdfreader2.bean
import android.graphics.drawable.Drawable
class AppBean(
val icon: Drawable, val name: String, val packageName: String
)
\ No newline at end of file
......@@ -24,14 +24,55 @@ object ConstObject {
const val UI_SORT_NAME_A_Z = "ui_sort_name_a_z"
const val UI_SORT_NAME_Z_A = "ui_sort_name_z_a"
const val NOTIFICATION_ACTION_LOG = "notification_action_log"
const val NOTIFICATION_ACTION_DOCUMENT = "notification_action_document"
const val NOTIFICATION_ACTION_BOOKMARK = "notification_action_bookmark"
const val NOTIFICATION_ACTION_NEW_IMAGE_PDF = "notification_action_new_image_pdf"
var haveGuideGesture = false
const val NOTIFICATION_ACTION_READ_PDF = "notification_action_read_pdf"
const val NOTIFICATION_ACTION_READ_DOCUMENTS = "notification_action_read_documents"
const val NOTIFICATION_ACTION_UN_VIEW_FILES = "notification_action_un_view_files"
const val NOTIFICATION_ACTION_IMPORTANT_DOCUMENT = "notification_action_important_document"
const val NOTIFICATION_ACTION_APP_PROCESS = "notification_action_app_process"
const val NOTIFICATION_ACTION_CLEAN_JUNK = "notification_action_clean_junk"
const val NOTIFICATION_ACTION_WEATHER = "notification_action_weather"
const val FUNCTION_SCAM_JUNK = "function_scam_junk"
const val FUNCTION_APP_PROCESS = "function_app_process"
var ifAgreePrivacy = false
get() {
return AppPreferences.getInstance().getBoolean("ifAgreePrivacy", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("ifAgreePrivacy", value, true)
}
//是否第一次启动
var isFirstStart = true
get() {
return AppPreferences.getInstance().getBoolean("isFirstStart", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("isFirstStart", value, true)
}
var haveSelectLanguage = false
get() {
return AppPreferences.getInstance().getBoolean("haveSelectLanguage", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("haveSelectLanguage", value, true)
}
var selectFollowLanguage = false
get() {
return AppPreferences.getInstance().getBoolean("haveGuideGesture", field)
return AppPreferences.getInstance().getBoolean("selectFollowLanguage", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("haveGuideGesture", value, true)
AppPreferences.getInstance().put("selectFollowLanguage", value, true)
}
var haveSaveDemo = false
get() {
......
......@@ -11,7 +11,7 @@ data class DocumentBean(
var uiType: Int = 0//0首页模式 1合并选择模式 2拆分模式 3解锁加锁模式 4搜索模式
var isSelect: Boolean = false
var state: Int = -1//0正常状态 1 锁定
var password: String = ""
var pwd: String = ""
var lastViewTime: Long = 0
var isAd: Boolean = false
......
package com.base.pdfreader2.bean
data class LanguageBean(
val key: String,
val language: String,
val country: String,
) {
var isSelect: Boolean = false
var isFollowSystem: Boolean = false
companion object {
const val English = "English"
const val 简体中文 = "简体中文"
const val português = "português"
const val Español = "Español "
const val Français = "Français"
const val Deutsch = "Deutsch"
const val ไทย = "ไทย"
const val Bahasa_Indonesia = "Bahasa Indonesia"
const val Melayu = "Melayu"
const val Tiếng_Việt = "Tiếng Việt"
const val 日本語 = "日本語"
const val Italiano = "Italiano"
const val 한국인 = "한국인"
const val Nederlands = "Nederlands"
const val 繁體中文 = "繁體中文"
const val Türk = "Türk"
}
}
\ No newline at end of file
package com.base.pdfreader2.bean
import android.animation.ValueAnimator
import android.graphics.drawable.Drawable
data class ParentBean(
val icon: Int = 0,
val tittle: String = "",
val childItem: List<ChildBean> = arrayListOf(),
) {
var playAnimation: Boolean = true
var isExpand: Boolean = true
var isSelect: Boolean = true
var finished: Boolean = false
var rotateValueAnimator: ValueAnimator? = null
}
data class ChildBean(
val icon: Int = 0,
val path: String = "",
) {
var playAnimation: Boolean = true
var apkIcon: Drawable? = null
var isSelect: Boolean = true
}
\ No newline at end of file
package com.base.pdfreader2.bean
data class WeatherBean(val city: String, val list: List<ListBean>)
data class ListBean(
val tempMax: String,
val tempMin: String,
val humidity: String,
val fxDate: String,
val iconDay: String,
val windScaleDay: String,
val pressure: String,
val textDay: String,
val textNight: String,
)
package com.base.pdfreader2.fcm;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import com.base.pdfreader2.helper.EventUtils;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseApp;
import com.google.firebase.messaging.FirebaseMessaging;
public class FCMManager {
public static void initFirebase(Context context) {
FirebaseApp.initializeApp(context);
}
public static void subscribeToTopic(String topic) {
FirebaseMessaging.getInstance().subscribeToTopic(topic)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d("FCMUtil", "suc:" + topic);
EventUtils.INSTANCE.event("FCM_Topic_" + topic, null, null, false);
} else {
Log.d("FCMUtil", "fail");
}
}
});
}
public static void unsubscribeFromTopic(String topic) {
FirebaseMessaging.getInstance().unsubscribeFromTopic(topic)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
} else {
}
}
});
}
}
package com.base.pdfreader2.fcm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.base.pdfreader2.utils.LogEx;
public class FcmReceiver extends BroadcastReceiver {
private String TAG = "FcmReceiver";
@Override
public void onReceive(Context context, Intent intent) {
LogEx.INSTANCE.logDebug(TAG, "onReceive", false);
}
}
package com.base.pdfreader2.fcm;
import android.annotation.SuppressLint;
import androidx.annotation.NonNull;
import com.base.pdfreader2.helper.EventUtils;
import com.base.pdfreader2.utils.LogEx;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
@SuppressLint("MissingFirebaseInstanceTokenRefresh")
public class MessagingService extends FirebaseMessagingService {
private static final String TAG = "MessagingService";
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
LogEx.INSTANCE.logDebug(TAG, "onMessageReceived", false);
EventUtils.INSTANCE.event("FCM_Received", null, null, false);
String action = NotificationUiUtil.INSTANCE.getNextActionId();
NotificationUiUtil.INSTANCE.sendNotificationIfCan(this, action, PopupConstObject.POPUP_WHERE_FCM);
}
}
\ No newline at end of file
package com.base.pdfreader2.fcm
import android.content.Context
import android.os.Handler
import android.os.HandlerThread
import com.base.pdfreader2.helper.MyApplication
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.LogEx
object NotificationHoverUtils {
private val TAG = "NotificationHoverUtils"
private var handlerThread: HandlerThread? = null
private var handler: Handler? = null
/**
* 发送悬停通知
*/
fun sendHoverNotification(context: Context) {
val hoverCount = AppPreferences.getInstance().getString("popup_hover_count", "0").toInt()
val hoverDelay = AppPreferences.getInstance().getString("popup_hover_delay", "0").toLong()
val hoverStatus = AppPreferences.getInstance().getString("popup_hover_status", "0").toInt()
if (hoverStatus == 0) return
if (handlerThread == null) {
handlerThread = HandlerThread("NotificationHandlerThread")
handlerThread?.start()
}
// 创建 Handler
if (handler == null) {
handlerThread?.let {
handler = Handler(it.getLooper())
}
}
for (i in 1..hoverCount) {
val time = i * hoverDelay
handler?.postDelayed(Runnable {
LogEx.logDebug(TAG, "handler ${MyApplication.PAUSED_VALUE}")
if (MyApplication.PAUSED_VALUE == 1) {
handler?.removeCallbacksAndMessages(null)
return@Runnable
}
if (MyApplication.PAUSED_VALUE != 1) {
LogEx.logDebug(TAG, "handler send notification")
NotificationUiUtil.setActionNotification(context, NotificationUiUtil.hoverActionId)
}
}, time)
}
}
fun stopNotificationHandler() {
// 停止 HandlerThread
if (handler != null) {
handler?.removeCallbacksAndMessages(null)
}
if (handlerThread != null) {
handlerThread?.quit()
handlerThread = null
}
handler = null
}
}
\ No newline at end of file
package com.base.pdfreader2.fcm
import com.base.pdfreader2.utils.AppPreferences
object PopupConstObject {
const val POPUP_WHERE_TIMBER = "Timer"
const val POPUP_WHERE_LOCK = "Lock"
const val POPUP_WHERE_FCM = "fcm"
const val POPUP_WHERE_MEDIA_CHANGE = "media_change"
const val POPUP_WHERE_HOVER_HANDLE = "hover_handle"//悬停调用
//推送总开关 0 关 1开
val popup_status = "popup_status"
//推送总数量现在
val popup_count = "popup_count"//所有常规推送的当日推送次数限制,0 为不限制
val popup_start = "popup_start"
val popup_end = "popup_end"
val popup_interval = "popup_interval"
val popup_timer_interval = "popup_timber_interval"
val popup_lock_interval = "popup_lock_interval"
val popup_fcm_interval = "popup_fcm_interval"
var topic_number = ""
get() {
return AppPreferences.getInstance().getString("topic_number", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("topic_number", value, true)
}
//推送样式一配置
val popup_style1_start = "popup_style1_start"
val popup_style1_end = "popup_style1_end"
val popup_style1_status = "popup_style1_status"
val popup_style1_count = "popup_style1_count"
val popup_style1_interval = "popup_style1_interval"
//推送样式二配置
val popup_style2_start = "popup_style2_start"
val popup_style2_end = "popup_style2_end"
val popup_style2_status = "popup_style2_status"
val popup_style2_count = "popup_style2_count"
val popup_style2_interval = "popup_style2_interval"
//推送样式三配置
val popup_style3_start = "popup_style3_start"
val popup_style3_end = "popup_style3_end"
val popup_style3_status = "popup_style3_status"
val popup_style3_count = "popup_style3_count"
val popup_style3_interval = "popup_style3_interval"
}
\ No newline at end of file
package com.base.pdfreader2.fcm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import com.base.pdfreader2.utils.AppPreferences;
import java.util.Objects;
public class ScreenStatusReceiver extends BroadcastReceiver {
private static boolean isDeviceInteractive = true;
private static boolean isSecureLockActive = false;
public static void setupScreenStatusListener(Context context) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_USER_PRESENT);
final Context applicationContext = context.getApplicationContext();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
applicationContext.registerReceiver(new ScreenStatusReceiver(), intentFilter, Context.RECEIVER_EXPORTED);
} else {
applicationContext.registerReceiver(new ScreenStatusReceiver(), intentFilter);
}
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (Objects.requireNonNull(action)) {
case Intent.ACTION_SCREEN_ON:
setDeviceInteractive(true);
break;
case Intent.ACTION_SCREEN_OFF:
setDeviceInteractive(false);
setSecureLockActive(true);
break;
case Intent.ACTION_USER_PRESENT:
setSecureLockActive(false);
if (isDeviceInteractive() && !isSecureLockActive()) {
int secureSetting = Integer.parseInt(AppPreferences.getInstance().getString("lockS", "1"));
if (secureSetting == 1) {
String actionId = NotificationUiUtil.INSTANCE.getNextActionId();
NotificationUiUtil.INSTANCE.sendNotificationIfCan(context, actionId, PopupConstObject.POPUP_WHERE_LOCK);
}
}
break;
}
}
private void setDeviceInteractive(boolean interactive) {
isDeviceInteractive = interactive;
}
public static boolean isDeviceInteractive() {
return isDeviceInteractive;
}
private void setSecureLockActive(boolean active) {
isSecureLockActive = active;
}
public static boolean isSecureLockActive() {
return isSecureLockActive;
}
}
\ No newline at end of file
package com.base.pdfreader2.fcm;
import android.util.Log;
import com.base.pdfreader2.helper.MyApplication;
import java.util.Timer;
import java.util.TimerTask;
public class TimerManager {
private static TimerManager instance;
private Timer taskTimer;
private boolean isTimerActive;
private TimerManager() {
// 私有构造方法
}
public static synchronized TimerManager getInstance() {
if (instance == null) {
instance = new TimerManager();
}
return instance;
}
public void scheduleTask(long delay, long period) {
synchronized (TimerManager.class) {
ensureTimerIsStopped(); // 确保定时器未运行
taskTimer = new Timer(); // 创建新的 Timer 实例
TimerTask task = new TimerTask() {
@Override
public void run() {
Log.d("glc", "Scheduled task is running");
// 确保设备处于交互状态,未锁定,且应用未暂停
if (ScreenStatusReceiver.isDeviceInteractive() &&
!ScreenStatusReceiver.isSecureLockActive() &&
MyApplication.PAUSED_VALUE != 1) {
Log.d("glc", "Scheduled task conditions are met");
String actionId = NotificationUiUtil.INSTANCE.getNextActionId();
NotificationUiUtil.INSTANCE.sendNotificationIfCan(MyApplication.context, actionId, PopupConstObject.POPUP_WHERE_TIMBER);
}
}
};
taskTimer.schedule(task, delay, period); // 调度任务
isTimerActive = true; // 设置定时器状态为活跃
}
}
private void ensureTimerIsStopped() {
if (isTimerActive) {
if (taskTimer != null) {
taskTimer.cancel();
taskTimer.purge(); // 清除所有取消的任务
}
isTimerActive = false; // 重置定时器状态
}
}
public void stopTaskTimer() {
synchronized (TimerManager.class) {
ensureTimerIsStopped(); // 停止定时器
}
}
public boolean isTaskTimerActive() {
return isTimerActive;
}
}
\ No newline at end of file
package com.base.pdfreader2.helper
import android.util.Base64
import java.security.SecureRandom
import javax.crypto.Cipher
import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec
object AESHelper {
private const val aesKey = "7vwdrlk6bp8rihe4"
private val cipher by lazy {
Cipher.getInstance("AES/GCM/NoPadding")
}
fun encrypt(content: String): String {
try {
val iv = ByteArray(12).apply {
SecureRandom().nextBytes(this)
}
val contentBytes = content.toByteArray(Charsets.UTF_8)
val params = GCMParameterSpec(128, iv)
cipher.init(
Cipher.ENCRYPT_MODE,
secretKey, params
)
val encryptData = cipher.doFinal(contentBytes)
if (encryptData.size != contentBytes.size + 16) {
throw IllegalStateException("Encryption failed")
}
val message = ByteArray(12 + contentBytes.size + 16)
System.arraycopy(iv, 0, message, 0, 12)
System.arraycopy(encryptData, 0, message, 12, encryptData.size)
return String(Base64.encode(message, Base64.NO_WRAP), Charsets.UTF_8)
} catch (_: Exception) {
}
return content
}
@Synchronized
fun decrypt(content: String): String {
try {
val con = content.replace(" ".toRegex(), "+")
val contentByte = Base64.decode(con, Base64.NO_WRAP)
require(contentByte.size >= 12 + 16)
val params = GCMParameterSpec(128, contentByte, 0, 12)
cipher.init(
Cipher.DECRYPT_MODE,
secretKey, params
)
val decryptData = cipher.doFinal(contentByte, 12, contentByte.size - 12)
return String(decryptData, Charsets.UTF_8)
} catch (_: Exception) {
}
return content
}
private val secretKey by lazy {
SecretKeySpec(aesKey.toByteArray(), "AES")
}
}
\ No newline at end of file
......@@ -91,4 +91,12 @@ abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {
return appLanguageSp != changeLanguageSp || activityLanguage != changeLanguageSp
}
/**
* 该页面指定语言显示
*/
fun changeActivityLanguage(languageCountry: String) {
changeAppLanguage(this, languageCountry)
this@BaseActivity.recreate()
}
}
\ No newline at end of file
package com.base.pdfreader2.helper
import android.os.Build
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.bean.ConstObject.ifAgreePrivacy
import com.base.pdfreader2.helper.ReportUtils.doPost
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.LogEx
import org.json.JSONException
import org.json.JSONObject
object EventUtils {
private val TAG = "EventUtils"
fun event(
key: String,
value: String? = null,
ext: JSONObject? = null,
isSingleEvent: Boolean = false
) {
if (!ifAgreePrivacy) {
return
}
if (isSingleEvent) {
val stringSet = AppPreferences.getInstance().getStringSet("singleEvent", setOf())
if (stringSet.contains(key)) {
return
}
}
Thread {
var paramJson: String? = ""
try {
val pkg = ConfigHelper.packageName
val s = JSONObject()
.put("action", key)
.put("value", value)
.put("ext", ext)
val s2 = JSONObject()
.put("${pkg}_3", AppPreferences.getInstance().getString("Equipment", ""))
.put("${pkg}_4", AppPreferences.getInstance().getString("Manufacturer", ""))
.put("${pkg}_5", Build.VERSION.SDK_INT)
.put("${pkg}_9", AppPreferences.getInstance().getString("uuid", ""))
.put("${pkg}_10", AppPreferences.getInstance().getString("gid", ""))
.put("${pkg}_13", "android")
.put("${pkg}_15", "google")
.put("${pkg}_14", BuildConfig.VERSION_CODE)
.put("${pkg}_8", BuildConfig.VERSION_NAME)
.put("${pkg}_24", BuildConfig.BUILD_TYPE)
val data = JSONObject()
.put("data", s)
.put("bp", s2)
.toString()
LogEx.logDebug(TAG, "uuid=${AppPreferences.getInstance().getString("uuid", "")}")
LogEx.logDebug(TAG, "gid=${AppPreferences.getInstance().getString("gid", "")}")
paramJson = AESHelper.encrypt(data)
} catch (e: JSONException) {
paramJson = ""
}
LogEx.logDebug(TAG, "url=$url")
doPost(
url,
HashMap(),
paramJson
)
}.start()
}
private val url by lazy {
val pkg = ConfigHelper.packageName
val url = StringBuilder(
"${ConfigHelper.eventUrl}/${
pkg.filter { it.isLowerCase() }.substring(4, 9)
}sp"
)
url.append("?pkg=$pkg")
url.toString()
}
}
\ No newline at end of file
package com.base.pdfreader2.helper
import com.android.installreferrer.api.InstallReferrerClient
import com.android.installreferrer.api.InstallReferrerStateListener
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.fcm.TimerManager
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.LogEx
import org.json.JSONObject
/**
* call before agree
*/
object InstallHelps {
private val TAG = "InstallHelps"
fun init() {
val referrerClient = InstallReferrerClient.newBuilder(MyApplication.context).build()
referrerClient.startConnection(object : InstallReferrerStateListener {
override fun onInstallReferrerSetupFinished(responseCode: Int) {
try {
when (responseCode) {
InstallReferrerClient.InstallReferrerResponse.OK -> {
val response = referrerClient.installReferrer
val installInfo = response.installReferrer
val obj = JSONObject()
obj.put("referrerUrl", response.installReferrer)
obj.put("referrerClickTime", response.referrerClickTimestampSeconds)
obj.put("appInstallTime", response.installBeginTimestampSeconds)
obj.put("instantExperienceLaunched", installInfo.toString())
EventUtils.event("install_referrer", ext = obj, isSingleEvent = true)
LogEx.logDebug(TAG,"referrerUrl=${response.installReferrer}")
AppPreferences.getInstance().put("referrerUrl", response.installReferrer)
if (listOf(
"gclid",
"facebook",
"instagram"
).all { !installInfo.contains(it, true) }
) {
//自然用户
if (BuildConfig.DEBUG) {
AppPreferences.getInstance().put("install_source", "channel")
} else {
AppPreferences.getInstance().put("install_source", "origin")
}
} else {
//渠道用户
AppPreferences.getInstance().put("install_source", "channel")
}
requestCfg()
}
else -> {
EventUtils.event("install_referrer_error")
requestCfg()
}
}
} catch (_: Exception) {
EventUtils.event("install_referrer_error")
requestCfg()
}
}
override fun onInstallReferrerServiceDisconnected() {
}
})
}
private fun requestCfg() {
NewComUtils.requestCfg {
val timerStatus: Int = AppPreferences.getInstance().getString("timerS", "1").toIntOrNull() ?: 1
if (timerStatus == 0) {
TimerManager.getInstance().stopTaskTimer()
} else {
val timerDelay: Int = AppPreferences.getInstance().getString("timerDelay", "1").toIntOrNull() ?: 1
val timerInterval: Int = AppPreferences.getInstance().getString("timerInterval", "1").toIntOrNull() ?: 1
if (!TimerManager.getInstance().isTaskTimerActive) {
TimerManager.getInstance().scheduleTask(
(timerDelay * 60 * 1000).toLong(),
(timerInterval * 60 * 1000).toLong()
)
}
}
}
}
}
\ No newline at end of file
......@@ -11,8 +11,18 @@ import com.base.pdfreader2.utils.ActivityManagerUtils
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.KotlinExt.toFormatMinute
import com.base.pdfreader2.utils.LogEx
import com.reyun.solar.engine.OnAttributionListener
import com.reyun.solar.engine.OnInitializationCallback
import com.reyun.solar.engine.SolarEngineConfig
import com.reyun.solar.engine.SolarEngineManager
import org.json.JSONObject
import java.util.Locale
import java.util.UUID
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.fcm.FCMManager
import com.base.pdfreader2.fcm.ScreenStatusReceiver
import com.base.pdfreader2.helper.WeatherUtils.requestWeatherData
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
class MyApplication : Application() {
......@@ -23,17 +33,17 @@ class MyApplication : Application() {
lateinit var context: MyApplication
var splashLanguage: String = Locale.getDefault().language
var mainLanguage: String = Locale.getDefault().language
var setLanguage: String = Locale.getDefault().language
var feedbackLanguage: String = Locale.getDefault().language
var pptLanguage: String = Locale.getDefault().language
var pdfLanguage: String = Locale.getDefault().language
var pdfLoadingLanguage: String = Locale.getDefault().language
var pdfMergeLanguage: String = Locale.getDefault().language
var pdfSelectLanguage: String = Locale.getDefault().language
var pdfSplitLanguage: String = Locale.getDefault().language
var wordLanguage: String = Locale.getDefault().language
var splashLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var mainLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var setLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var feedbackLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var pptLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var pdfLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var pdfLoadingLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var pdfMergeLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var pdfSelectLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var pdfSplitLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
var wordLanguage: String = Locale.getDefault().language + "_" + Locale.getDefault().country
@JvmField
var PAUSED_VALUE = 0
......@@ -45,13 +55,13 @@ class MyApplication : Application() {
context = this
initUUid()
initApp()
// PDFBoxResourceLoader.init(applicationContext)
// initWeather()
PDFBoxResourceLoader.init(applicationContext)
initWeather()
}
// private fun initWeather() {
// requestWeatherData()
// }
private fun initWeather() {
requestWeatherData()
}
private fun initUUid() {
uuid = AppPreferences.getInstance().getString("uuid", "")
......@@ -74,53 +84,53 @@ class MyApplication : Application() {
}
val topic = ConfigHelper.packageName + "_push_$topicNumber"
LogEx.logDebug(TAG, "topic=${topic}")
// FCMManager.initFirebase(this)
// FCMManager.subscribeToTopic(topic)
// InstallHelps.init()
FCMManager.initFirebase(this)
FCMManager.subscribeToTopic(topic)
InstallHelps.init()
initLifeListener()
// ScreenStatusReceiver.setupScreenStatusListener(this)
ScreenStatusReceiver.setupScreenStatusListener(this)
}
// fun initSolarEngine(gdprDeny: Boolean = false) {
//
// val configBuilder = SolarEngineConfig.Builder()
//
// if (BuildConfig.DEBUG) {
// configBuilder.logEnabled() //开启本地调试日志
// }
// if (gdprDeny) {
// configBuilder.isGDPRArea = true
// configBuilder.adPersonalizationEnabled = true
// configBuilder.adUserDataEnabled = true
// }
// configBuilder.isCoppaEnabled = true
// configBuilder.setKidsAppEnabled(true)
// configBuilder.fbAppID = ""
//
// val config = configBuilder.build()
//
// SolarEngineManager.getInstance().initialize(context, "81a11caa4076cd7c", config,
// OnInitializationCallback { code ->
// if (code == 0) {
// //初始化成功
// config.setOnAttributionListener(object : OnAttributionListener {
// override fun onAttributionSuccess(attribution: JSONObject) {
// //获取归因结果成功时执行的动作
// LogEx.logDebug(TAG, "attribution=$attribution")
// EventUtils.event("install_referrer", attribution.toString())
// }
//
// override fun onAttributionFail(errorCode: Int) {
// //获取归因结果失败时执行的动作
// EventUtils.event("SolarEngineManager onAttributionFail errorCode=$errorCode")
// }
// })
// } else {
// //初始化失败,具体失败原因参考下方code码释义
// EventUtils.event("SolarEngineManager init error code=$code")
// }
// })
// }
fun initSolarEngine(gdprDeny: Boolean = false) {
val configBuilder = SolarEngineConfig.Builder()
if (BuildConfig.DEBUG) {
configBuilder.logEnabled() //开启本地调试日志
}
if (gdprDeny) {
configBuilder.isGDPRArea = true
configBuilder.adPersonalizationEnabled = true
configBuilder.adUserDataEnabled = true
}
configBuilder.isCoppaEnabled = true
configBuilder.setKidsAppEnabled(true)
configBuilder.fbAppID = ""
val config = configBuilder.build()
SolarEngineManager.getInstance().initialize(context, "81a11caa4076cd7c", config,
OnInitializationCallback { code ->
if (code == 0) {
//初始化成功
config.setOnAttributionListener(object : OnAttributionListener {
override fun onAttributionSuccess(attribution: JSONObject) {
//获取归因结果成功时执行的动作
LogEx.logDebug(TAG, "attribution=$attribution")
EventUtils.event("install_referrer", attribution.toString())
}
override fun onAttributionFail(errorCode: Int) {
//获取归因结果失败时执行的动作
EventUtils.event("SolarEngineManager onAttributionFail errorCode=$errorCode")
}
})
} else {
//初始化失败,具体失败原因参考下方code码释义
EventUtils.event("SolarEngineManager init error code=$code")
}
})
}
private var lastTimePause = 0L
......
package com.base.pdfreader2.helper
import android.util.Log
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.LogEx
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
import java.util.Locale
object NewComUtils {
private val TAG = "NewComUtils"
private const val API_URL = ConfigHelper.apiUrl
private const val PACKAGE_NAME_PREFIX = ConfigHelper.packageName
private const val DATA_KEY = "data"
private val url: String by lazy {
val packageName = ConfigHelper.packageName
val appCode = packageName.substringAfter(PACKAGE_NAME_PREFIX).take(5).toLowerCase(Locale.getDefault())
val bRefer = android.util.Base64.encodeToString(
AppPreferences.getInstance().getString("referrerUrl", "").toByteArray(),
android.util.Base64.DEFAULT
)
"$API_URL/${appCode}spk?pkg=$packageName&referrer=${bRefer}&vn=${BuildConfig.VERSION_NAME}&vc=${BuildConfig.VERSION_CODE}&device=${
AppPreferences.getInstance().getString("gid", "")
}&aid=${AppPreferences.getInstance().getString("uuid", "")}"
// &mode=3
}
fun requestCfg(callback: () -> Unit) {
CoroutineScope(Dispatchers.IO).launch {
val response = doGet()
if (response == null) {
withContext(Dispatchers.Main) {
callback()
}
return@launch
}
val data = extractData(response)
if (data == null) {
withContext(Dispatchers.Main) {
callback()
}
return@launch
}
val decryptedData = AESHelper.decrypt(data)
parseConfigBean(decryptedData)
withContext(Dispatchers.Main) {
callback()
}
}
}
private fun doGet(): String? {
val urlPath = url
LogEx.logDebug(TAG, "url=$url")
try {
val conn: HttpURLConnection = URL(urlPath).openConnection() as HttpURLConnection
conn.setRequestMethod("GET")
conn.connectTimeout = 150000
if (200 == conn.getResponseCode()) {
val json = BufferedReader(InputStreamReader(conn.inputStream)).readLine()
LogEx.logDebug(TAG, "json=$json")
return json
}
} catch (e: Exception) {
e.printStackTrace()
Log.d("okhttp", e.toString())
}
return null
}
private fun extractData(response: String): String? {
val regex = Regex("\"$DATA_KEY\":\"(.*?)\"")
val match = regex.find(response)
return match?.groupValues?.get(1)
}
private fun parseConfigBean(json: String) {
val gson = Gson()
val type = object : TypeToken<Map<String, String>>() {}.type
val configMap = gson.fromJson<Map<String, String>>(json, type)
configMap.forEach { t, u ->
// 对于整型值使用parseInt, 长整型使用parseLong
AppPreferences.getInstance().put(t, u)
LogEx.logDebug(TAG, "t=$t u=$u")
}
val jsonObject = JSONObject()
jsonObject.put("ut", AppPreferences.getInstance().getString("ut", ""))
EventUtils.event("user_type", ext = jsonObject)
}
}
package com.base.pdfreader2.helper;
import android.text.TextUtils;
import com.base.pdfreader2.utils.LogEx;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
public class ReportUtils {
private static String TAG = "ReportUtils";
public static String doPost(String urlPath, Map<String, String> paramsMap, String json) {
try {
HttpURLConnection conn = (HttpURLConnection) new URL(urlPath).openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setConnectTimeout(600000);
if (!TextUtils.isEmpty(json)) {
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Content-Length", Integer.toString(json.getBytes().length));
conn.getOutputStream().write(json.getBytes());
}
StringBuilder result = new StringBuilder();
for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
result.append("&").append(entry.getKey()).append("=").append(entry.getValue());
}
if (result.length() > 0) {
conn.getOutputStream().write(result.substring(1).getBytes());
} else {
// conn.getOutputStream().write(result.substring(0).getBytes());
}
if (conn.getResponseCode() == 200) {
String s = new BufferedReader(new InputStreamReader(conn.getInputStream())).readLine();
if (!TextUtils.isEmpty(s)) {
} else {
s = "";
}
LogEx.INSTANCE.logDebug(TAG, "code=200", false);
return s;
} else {
LogEx.INSTANCE.logDebug(TAG, "code!=200", false);
}
} catch (Exception e) {
e.printStackTrace();
}
return "{ \"success\": false,\n \"errorMsg\": \"后台服务器开小差了!\",\n \"result\":{}}";
}
}
package com.base.pdfreader2.helper
import android.text.TextUtils
import com.base.pdfreader2.BuildConfig
import com.base.pdfreader2.bean.WeatherBean
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.LogEx
import com.google.gson.Gson
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.concurrent.TimeUnit
object WeatherUtils {
private val TAG = "WeatherUtils"
fun getWeatherType(param: Int): String {
val sunny_day: IntArray = intArrayOf(100, 101, 102, 103, 150, 151, 152, 153)
val cloudy_day: IntArray = intArrayOf(104)
val rainy_day: IntArray =
intArrayOf(300, 301, 302, 303, 304, 305, 306, 307, 307, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 350, 351, 399)
val snowy_day: IntArray = intArrayOf(400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 456, 457, 499)
val greasy_day: IntArray = intArrayOf(500, 501, 502, 503, 504, 505, 507, 508, 509, 510, 511, 512, 513, 514, 515)
when (param) {
in sunny_day -> return "Sunny day"
in cloudy_day -> return "Cloudy day"
in rainy_day -> return "Rainy day"
in snowy_day -> return "Snowy day"
in greasy_day -> return "Greasy day"
else -> return "Unknown"
}
}
fun hasWeatherDataToday(): Boolean {
return !TextUtils.isEmpty(getWeatherJsonStr())
}
fun getWeatherJsonStr(): String {
val data = AppPreferences.getInstance().getString(getTodayStr() + "_weather", "")
return data
}
fun getWeatherEntity(): WeatherBean? {
val str = getWeatherJsonStr()
LogEx.logDebug(TAG, "getWeatherEntity str=$str")
if (TextUtils.isEmpty(str)) {
} else {
try {
val gson = Gson()
val wBean = gson.fromJson(str, WeatherBean::class.java)
return wBean
} catch (e: Exception) {
e.printStackTrace()
}
}
return null
}
private val url by lazy {
val pkg = ConfigHelper.packageName
val url = StringBuilder(
"${ConfigHelper.apiUrl}/city/${
pkg.filter { it.isLowerCase() }.substring(4, 9)
}tq"
)
url.append("?pkg=$pkg")
val sdf = SimpleDateFormat("yyyyMMdd")
url.append("&date=${sdf.format(Calendar.getInstance().time)}")
url.toString()
}
fun requestWeatherData() {
val client = OkHttpClient.Builder().apply {
if (BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
}
}.build()
val request = Request.Builder()
.url(url)
.get()
.build()
LogEx.logDebug(TAG, "url=$url")
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
response.body?.string()?.let {
val i = Regex("\"data\":\"(.*?)\"").find(it)
if (i.toString() != "null") {
i?.groupValues?.get(1).let { data ->
LogEx.logDebug(TAG, "data=$data")
if (!TextUtils.isEmpty(data)) {
val str = AESHelper.decrypt(data ?: "")
saveWeatherData(str)
}
}
}
}
}
})
}
/**
* 同步
*/
fun getWeatherData() = runCatching {
val client = OkHttpClient.Builder().apply {
if (BuildConfig.DEBUG) {
addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
}
}.connectTimeout(1, TimeUnit.SECONDS)
.readTimeout(1, TimeUnit.SECONDS)
.writeTimeout(1, TimeUnit.SECONDS)
.build()
val request = Request.Builder()
.url(url)
.get()
.build()
val response = client.newCall(request).execute()
response.body?.string()?.let {
val i = Regex("\"data\":\"(.*?)\"").find(it)
if (i.toString() != "null") {
i?.groupValues?.get(1).let {
if (!TextUtils.isEmpty(it)) {
val str = AESHelper.decrypt(it!!)
saveWeatherData(str)
}
}
}
}
}
private fun saveWeatherData(string: String) {
AppPreferences.getInstance().put(getTodayStr() + "_weather", string)
}
private fun getTodayStr(): String {
val calendar = Calendar.getInstance()
val year = calendar[Calendar.YEAR]
val month = calendar[Calendar.MONTH] + 1
val day = calendar[Calendar.DAY_OF_MONTH]
val today =
year.toString() + "-" + String.format("%02d", month) + "-" + String.format("%02d", day)
return today;
}
}
\ No newline at end of file
package com.base.pdfreader2.service
import android.annotation.SuppressLint
import android.content.Context
import android.database.ContentObserver
import android.database.Cursor
import android.net.Uri
import android.provider.MediaStore
import com.base.pdfreader2.bean.ConstObject
import com.base.pdfreader2.fcm.NotificationUiUtil
import com.base.pdfreader2.fcm.PopupConstObject
import com.base.pdfreader2.utils.LogEx
/**
* Observer MediaContent add
*/
class MediaContentObserver(val context: Context) : ContentObserver(null) {
private val TAG = "MediaContentObserver"
override fun onChange(selfChange: Boolean, uri: Uri?) {
super.onChange(selfChange, uri)
LogEx.logDebug(TAG, "uri=${uri.toString()}")
if (uri.toString().contains("images")) {
NotificationUiUtil.sendNotificationIfCan(
context,
ConstObject.NOTIFICATION_ACTION_NEW_IMAGE_PDF,
PopupConstObject.POPUP_WHERE_MEDIA_CHANGE
)
}
// uri?.let { queryNewMediaFiles(it) }
}
@SuppressLint("Range")
private fun queryNewMediaFiles(uri: Uri) = Thread {
// 查询新添加的媒体文件
val projection = arrayOf(
MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.DATA,
MediaStore.MediaColumns.MIME_TYPE,
MediaStore.MediaColumns.SIZE,
)
val cursor: Cursor? = context.contentResolver.query(uri, projection, null, null, null)
if (cursor != null) {
LogEx.logDebug(TAG, "cursor=$cursor")
try {
if (cursor.count > 0) {
while (cursor.moveToNext()) {
val name = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME))
val path = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA))
val mimeType = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE))
val size = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.SIZE))
LogEx.logDebug(TAG, "path=$path")
// 处理新文件路径
}
} else {
LogEx.logDebug(TAG, "count=0 deleted file uri")
}
} catch (e: Exception) {
e.printStackTrace()
LogEx.logDebug(TAG, "Exception=$e")
} finally {
cursor.close()
}
} else {
LogEx.logDebug(TAG, "cursor=$cursor")
}
}.start()
}
package com.base.pdfreader2.service
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.graphics.BitmapFactory
import android.graphics.drawable.Icon
import android.os.Build
import android.os.IBinder
import android.provider.MediaStore
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import androidx.core.graphics.drawable.IconCompat
import com.base.pdfreader2.R
import com.base.pdfreader2.bean.ConstObject
import com.base.pdfreader2.helper.EventUtils
import com.base.pdfreader2.helper.MyApplication
import com.base.pdfreader2.ui.main.MainActivity
import com.base.pdfreader2.ui.splash.SplashActivity
import com.base.pdfreader2.utils.LogEx
import kotlin.random.Random
/**
* 常驻通知栏
*/
class StayNotificationService : Service() {
private val TAG = "StayNotificationService"
companion object {
var isRunning = false
fun Context.startStayNotification() {
if (isRunning) return
val intent = Intent(this, StayNotificationService::class.java)
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU) {
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
}
fun Context.restartStartStayNotification() {
val intent = Intent(this, StayNotificationService::class.java)
stopService(intent)
startStayNotification()
}
fun createPermanentNotification(context: Context): Notification {
val channelName = "PDF Reader Foreground Service Channel"
val channelId = "PDF_Reader_Service_Id"
val contentView = RemoteViews(context.packageName, R.layout.stay_notification_big)
val expendView = RemoteViews(context.packageName, R.layout.stay_notification_big)
val requestCode1 = Random.nextInt(1800)
val intent1 = Intent(context, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.NOTIFICATION_ACTION_LOG)
}
val pendingIntent1 =
PendingIntent.getActivity(
context,
requestCode1,
intent1,
PendingIntent.FLAG_IMMUTABLE
)
contentView.setOnClickPendingIntent(R.id.fl_1, pendingIntent1)
expendView.setOnClickPendingIntent(R.id.fl_1, pendingIntent1)
val requestCode2 = Random.nextInt(1800)
val intent2 = Intent(context, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.NOTIFICATION_ACTION_DOCUMENT)
}
val pendingIntent2 =
PendingIntent.getActivity(
context,
requestCode2,
intent2,
PendingIntent.FLAG_IMMUTABLE
)
contentView.setOnClickPendingIntent(R.id.ll_2, pendingIntent2)
expendView.setOnClickPendingIntent(R.id.ll_2, pendingIntent2)
val requestCode3 = Random.nextInt(1800)
val intent3 = Intent(context, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.NOTIFICATION_ACTION_BOOKMARK)
}
val pendingIntent3 =
PendingIntent.getActivity(
context,
requestCode3,
intent3,
PendingIntent.FLAG_IMMUTABLE
)
contentView.setOnClickPendingIntent(R.id.ll_3, pendingIntent3)
expendView.setOnClickPendingIntent(R.id.ll_3, pendingIntent3)
val requestCode4 = Random.nextInt(1800)
val intent4 = Intent(context, SplashActivity::class.java).apply {
putExtra("actionId", ConstObject.NOTIFICATION_ACTION_NEW_IMAGE_PDF)
}
val pendingIntent4 =
PendingIntent.getActivity(
context,
requestCode4,
intent4,
PendingIntent.FLAG_IMMUTABLE
)
contentView.setOnClickPendingIntent(R.id.ll_4, pendingIntent4)
expendView.setOnClickPendingIntent(R.id.ll_4, pendingIntent4)
val builder = NotificationCompat.Builder(context, channelId)
val smallIcon = IconCompat.createFromIcon(
context, Icon.createWithResource(
MyApplication.context, R.mipmap.logo
)
)
smallIcon?.let {
builder.setSmallIcon(smallIcon) //设置状态栏内的小图标
}
val nfIntent = Intent(context, MainActivity::class.java)
val pendingIntent =
PendingIntent.getActivity(context, 0, nfIntent, PendingIntent.FLAG_IMMUTABLE)
builder.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.logo))
builder.setContentTitle(context.resources.getString(R.string.app_name))
builder.setContentIntent(pendingIntent) //设置PendingIntent
builder.setVisibility(NotificationCompat.VISIBILITY_PRIVATE) //设置通知公开可见
builder.setAutoCancel(false)
builder.setPriority(NotificationCompat.PRIORITY_MAX) //优先级为:重要通知
builder.setWhen(System.currentTimeMillis())
builder.setCustomContentView(contentView)
builder.setCustomBigContentView(expendView)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW)
channel.lockscreenVisibility = 1
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
builder.setChannelId(channelId)
}
return builder.build()
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
LogEx.logDebug(TAG, "onStartCommand intent=$intent")
if (intent == null) {
EventUtils.event("onStartCommand", "Foreground System auto launch intent=null isRunning=$isRunning")
return START_NOT_STICKY
}
if (!isRunning) {
LogEx.logDebug(TAG, "onStartCommand startForeground")
startForeground()
//监听媒体库变化
observerMediaContentObserver()
isRunning = true
}
return START_STICKY
}
private fun startForeground() {
val notification = createPermanentNotification(MyApplication.context)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(100, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
} else {
startForeground(100, notification)
}
isRunning = true
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onDestroy() {
isRunning = false
super.onDestroy()
}
private var mediaContentObserver: MediaContentObserver? = null
private fun observerMediaContentObserver() {
if (mediaContentObserver == null) {
LogEx.logDebug(TAG, "observerMediaContentObserver")
mediaContentObserver = MediaContentObserver(this)
mediaContentObserver?.let {
this.contentResolver.registerContentObserver(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, it
)
}
}
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.appprocess
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.base.pdfreader2.R
import com.base.pdfreader2.bean.AppBean
import com.base.pdfreader2.databinding.ItemAppProcessBinding
import com.base.pdfreader2.utils.XmlEx.inflate
import com.chad.library.adapter4.BaseQuickAdapter
class AppBeanAdapter : BaseQuickAdapter<AppBean, AppBeanAdapter.AppHolder>() {
inner class AppHolder(view: View) : RecyclerView.ViewHolder(view)
var stopAction: ((pkg: String) -> Unit)? = null
override fun onBindViewHolder(holder: AppHolder, position: Int, item: AppBean?) {
if (item == null) return
val binding = ItemAppProcessBinding.bind(holder.itemView)
binding.iv.setImageDrawable(item.icon)
binding.tvName.text = item.name
binding.tvStop.setOnClickListener {
stopAction?.invoke(item.packageName)
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): AppHolder {
return AppHolder(R.layout.item_app_process.inflate(parent))
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.appprocess
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.graphics.Color
import android.net.Uri
import android.provider.Settings
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.view.View
import androidx.activity.addCallback
import com.base.pdfreader2.ads.AdmobHelper
import com.base.pdfreader2.ads.admob.AdmobInterstitialUtils
import com.base.pdfreader2.bean.AppBean
import com.base.pdfreader2.bean.ConstObject
import com.base.pdfreader2.databinding.ActivityAppProcessBinding
import com.base.pdfreader2.helper.BaseActivity
import com.base.pdfreader2.ui.result.ResultActivity
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.BarUtils
import com.base.pdfreader2.utils.KotlinExt.toFormatSize
import com.base.pdfreader2.utils.RamUtils.ramPair
import kotlin.random.Random
class AppProcessActivity : BaseActivity<ActivityAppProcessBinding>() {
private val TAG = "AppProcessActivity"
override val binding: ActivityAppProcessBinding by lazy {
ActivityAppProcessBinding.inflate(layoutInflater)
}
private lateinit var adapter: AppBeanAdapter
@SuppressLint("SetTextI18n")
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
// binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
adapter = AppBeanAdapter()
adapter.stopAction = { pkg ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", pkg, null)
intent.setData(uri)
startActivity(intent)
}
binding.rv.adapter = adapter
val ramPair = ramPair()
val percent = ((ramPair.first.toFloat() / ramPair.second.toFloat()) * 100).toInt()
binding.progressBar.progress = percent
binding.tvPercent.text = percent.toString()
binding.tvRamRate.text = ramPair.first.toFormatSize() + " / " + ramPair.second.toFormatSize()
AppPreferences.getInstance().put("last_process_use_time", System.currentTimeMillis())
initDataUI()
}
private fun initDataUI() {
binding.progressBarLoading.visibility = View.GONE
adapter.submitList(appList)
val text = "$backAppCount/$totalCount"
val spannableString = SpannableString(text)
val start = text.indexOf("$backAppCount")
val end = start + "$backAppCount".length
val colorSpan = ForegroundColorSpan(Color.parseColor("#0672EE"))
spannableString.setSpan(colorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
binding.tvRate.text = spannableString.toString()
}
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback {
if (AdmobHelper.isBackShowAd()) {
AdmobInterstitialUtils.showInterstitialAd(this@AppProcessActivity) {
finishToMain()
}
} else {
finishToMain()
}
}
binding.flFanhui.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
binding.tvBtn.setOnClickListener {
if (AdmobHelper.isBackShowAd()) {
AdmobInterstitialUtils.showInterstitialAd(this) {
startActivity(Intent(this, ResultActivity::class.java).apply {
putExtra("from", ConstObject.FUNCTION_APP_PROCESS)
})
finish()
}
} else {
startActivity(Intent(this, ResultActivity::class.java).apply {
putExtra("from", ConstObject.FUNCTION_APP_PROCESS)
})
finish()
}
}
}
companion object {
fun isLaunchApp(context: Context, app: PackageInfo, filterSystem: Boolean = true): Boolean {
val flagSystem = (app.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) < 1
val flag = if (filterSystem) flagSystem else true
return flag && app.applicationInfo.packageName != context.packageName
}
@SuppressLint("QueryPermissionsNeeded")
fun fastGetAppIcon(context: Context): List<PackageInfo> {
val pm = context.packageManager
val packages = pm.getInstalledPackages(0).filter { isLaunchApp(context, it) }
return packages
}
private var totalCount = 0
private var backAppCount = 0
private val appList = arrayListOf<AppBean>()
@SuppressLint("QueryPermissionsNeeded")
fun initData(
context: Context,
) {
val pm = context.packageManager
val packages = pm.getInstalledPackages(0)
appList.clear()
packages.forEachIndexed { index, packageInfo ->
if (isLaunchApp(context, packageInfo)) {
totalCount++
if (index % 2 == 0 && Random.nextBoolean()) {
val appBean = AppBean(
packageInfo.applicationInfo.loadIcon(pm),
packageInfo.applicationInfo.loadLabel(pm).toString(),
packageInfo.applicationInfo.packageName
)
appList.add(appBean)
backAppCount++
}
}
}
}
}
override fun onDestroy() {
super.onDestroy()
appList.clear()
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.appprocess
import android.animation.ValueAnimator
import android.content.Intent
import android.graphics.Color
import android.view.View
import android.view.animation.LinearInterpolator
import androidx.core.animation.doOnEnd
import androidx.lifecycle.lifecycleScope
import com.base.pdfreader2.ads.admob.AdmobInterstitialUtils
import com.base.pdfreader2.databinding.ActivityAppProcessLoadingBinding
import com.base.pdfreader2.helper.BaseActivity
import com.base.pdfreader2.utils.BarUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
class AppProcessLoadingActivity : BaseActivity<ActivityAppProcessLoadingBinding>() {
override val binding: ActivityAppProcessLoadingBinding by lazy {
ActivityAppProcessLoadingBinding.inflate(layoutInflater)
}
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
// binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
overridePendingTransition(0, 0)
val colors = intArrayOf(
Color.parseColor("#EE5C42"),
Color.parseColor("#F07D34"),
Color.parseColor("#9171E2"),
Color.parseColor("#5C66FB"),
Color.parseColor("#4EA183")
)
startColorAnimation(binding.view, colors, 0, 800)
lifecycleScope.launch(Dispatchers.IO) {
AppProcessActivity.initData(this@AppProcessLoadingActivity)
}
lifecycleScope.launch(Dispatchers.Main) {
var i = 1
while (isActive) {
i++
binding.tvPercent.text = i.toString()
delay(50)
}
}
jumpAction = {
AdmobInterstitialUtils.showInterstitialAd(this) {
startActivity(Intent(this, AppProcessActivity::class.java))
finish()
}
}
}
override fun initListener() {
super.initListener()
binding.flFanhui.setOnClickListener {
jumpAction = null
AdmobInterstitialUtils.showInterstitialAd(this) {
finishToMain()
}
}
}
var jumpAction: (() -> Unit)? = null
private fun startColorAnimation(view: View, colors: IntArray, index: Int, duration: Long) {
if (index == colors.size - 1) {
jumpAction?.invoke()
jumpAction = null
return // 如果索引超出颜色数组范围,则停止动画
}
val nextIndex = (index + 1)
val animator = ValueAnimator.ofArgb(colors[index], colors[nextIndex])
animator.interpolator = LinearInterpolator()
animator.duration = duration
animator.addUpdateListener { animation ->
view.setBackgroundColor(animation.animatedValue as Int)
}
animator.doOnEnd {
// 当前颜色渐变动画结束后,开始下一个颜色渐变动画
startColorAnimation(view, colors, nextIndex, duration)
}
animator.start()
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.cleanjunk
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.view.animation.LinearInterpolator
import android.widget.Toast
import androidx.activity.addCallback
import androidx.core.animation.doOnEnd
import androidx.core.view.updatePadding
import com.base.pdfreader2.ads.admob.AdmobInterstitialUtils
import com.base.pdfreader2.bean.ConstObject.FUNCTION_SCAM_JUNK
import com.base.pdfreader2.databinding.ActivityLayoutCleanupingBinding
import com.base.pdfreader2.helper.BaseActivity
import com.base.pdfreader2.ui.result.ResultActivity
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.BarUtils
import com.base.pdfreader2.utils.updateMediaStore
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import java.io.File
import kotlin.random.Random
/**
* 实际清理页面
*/
class CleaningActivity : BaseActivity<ActivityLayoutCleanupingBinding>() {
override val binding: ActivityLayoutCleanupingBinding by lazy {
ActivityLayoutCleanupingBinding.inflate(layoutInflater)
}
private val intentSize by lazy {
intent.getLongExtra("size", -1)
}
private val listPath by lazy {
intent.getStringArrayExtra("list") ?: arrayOf()
}
override fun initView() {
BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
MainScope().launch(Dispatchers.IO) {
try {
listPath.forEach {
val file = File(it)
runCatching { file.deleteRecursively() }
}
updateMediaStore(listPath)
} catch (_: Exception) {
} finally {
}
}
playAnm()
}
override fun initListener() {
onBackPressedDispatcher.addCallback {
Toast.makeText(this@CleaningActivity, "wait a moment", Toast.LENGTH_SHORT).show()
}
}
private fun playAnm() {
ValueAnimator.ofFloat(0f, 360f).run {
duration = 1000
repeatMode = ValueAnimator.RESTART
repeatCount = ValueAnimator.INFINITE
interpolator = LinearInterpolator()
addUpdateListener {
binding.idYuan.rotation = it.animatedValue as Float
}
start()
}
ValueAnimator.ofInt(0, 100).run {
duration = Random.nextLong(7000, 8000)
interpolator = LinearInterpolator()
addUpdateListener {
binding.idTvJd.text = "${it.animatedValue as Int}"
}
doOnEnd {
val isCleanEndAdSp = AppPreferences.getInstance().getString("isCleanEndAdSp", "1").toInt()
if (isCleanEndAdSp == 1) {
AdmobInterstitialUtils.showInterstitialAd(this@CleaningActivity) {
startActivity(
Intent(this@CleaningActivity, ResultActivity::class.java).apply {
putExtra("from", FUNCTION_SCAM_JUNK)
putExtra("clean_size", intentSize)
}
)
finish()
}
} else {
startActivity(
Intent(this@CleaningActivity, ResultActivity::class.java).apply {
putExtra("from", FUNCTION_SCAM_JUNK)
putExtra("clean_size", intentSize)
}
)
finish()
}
}
start()
}
}
private var animator1: ValueAnimator? = null
private var animator2: ValueAnimator? = null
private var animator3: ValueAnimator? = null
override fun onResume() {
super.onResume()
resumeLottie()
}
@SuppressLint("SetTextI18n")
private fun resumeLottie() {
if (animator1 == null) {
animator1 = ValueAnimator.ofFloat(0f, 360f)
animator1?.run {
duration = 1000
repeatMode = ValueAnimator.RESTART
repeatCount = ValueAnimator.INFINITE
interpolator = LinearInterpolator()
addUpdateListener {
binding.idView1.rotation = it.animatedValue as Float
}
}
}
animator1?.start()
if (animator2 == null) {
animator2 = ValueAnimator.ofFloat(0f, 360f)
animator2?.run {
duration = 1000
repeatMode = ValueAnimator.RESTART
repeatCount = ValueAnimator.INFINITE
interpolator = LinearInterpolator()
addUpdateListener {
binding.idView2.rotation = it.animatedValue as Float
}
}
}
animator2?.start()
if (animator3 == null) {
animator3 = ValueAnimator.ofFloat(0f, 360f)
animator3?.run {
duration = 1000
repeatMode = ValueAnimator.RESTART
repeatCount = ValueAnimator.INFINITE
interpolator = LinearInterpolator()
addUpdateListener {
binding.idView3.rotation = it.animatedValue as Float
}
}
}
animator3?.start()
}
override fun onPause() {
super.onPause()
animator1?.pause()
animator2?.pause()
animator3?.pause()
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.cleanjunk
import android.annotation.SuppressLint
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import com.base.pdfreader2.R
import com.base.pdfreader2.bean.ParentBean
import com.base.pdfreader2.databinding.ItemJunkChildBinding
import com.base.pdfreader2.databinding.ItemJunkParentBinding
import com.base.pdfreader2.utils.KotlinExt.toFormatSize
import com.base.pdfreader2.utils.XmlEx.inflate
import pokercc.android.expandablerecyclerview.ExpandableAdapter
import java.io.File
class JunkExpandAdapter(private val selectAction: (size: Long) -> Unit) : ExpandableAdapter<ExpandableAdapter.ViewHolder>() {
private val beanList = arrayListOf<ParentBean>()
override fun getChildCount(groupPosition: Int): Int {
return beanList[groupPosition].childItem.size
}
override fun getGroupCount(): Int {
return beanList.size
}
override fun onCreateChildViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(R.layout.item_junk_child.inflate(viewGroup))
}
override fun onCreateGroupViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(R.layout.item_junk_parent.inflate(viewGroup))
}
override fun onBindChildViewHolder(holder: ViewHolder, groupPosition: Int, childPosition: Int, payloads: List<Any>) {
val binding = ItemJunkChildBinding.bind(holder.itemView)
val parentBean = beanList[groupPosition]
val childBeanList = parentBean.childItem
val childBean = childBeanList[childPosition]
if (payloads.isEmpty()) {
if (childBean.apkIcon == null) binding.iv.setImageResource(childBean.icon) else binding.iv.setImageDrawable(childBean.apkIcon)
val file = File(childBean.path)
binding.tvName.text = file.name
binding.tvSize.text = file.length().toFormatSize()
binding.ivSelector.isSelected = childBean.isSelect
binding.root.setOnClickListener {
childBean.isSelect = !childBean.isSelect
notifyChildChange(groupPosition, childPosition, "aaa")
val allSelect = childBeanList.all { it.isSelect }
if (parentBean.isSelect != allSelect) {
parentBean.isSelect = allSelect
notifyGroupChange(groupPosition, "aa")
}
selectChange()
}
if (childBean.playAnimation) {
val slideInFromRight = AnimationUtils.loadAnimation(holder.itemView.context, R.anim.slide_in_from_right)
binding.root.startAnimation(slideInFromRight)
childBean.playAnimation = false
}
} else {
binding.ivSelector.isSelected = childBean.isSelect
}
}
@SuppressLint("NotifyDataSetChanged")
override fun onBindGroupViewHolder(holder: ViewHolder, groupPosition: Int, expand: Boolean, payloads: List<Any>) {
val binding = ItemJunkParentBinding.bind(holder.itemView)
val bean = beanList[groupPosition]
bean.isExpand = expand
if (bean.isExpand) {
binding.ivExpand.setImageResource(R.mipmap.zhankai)
} else {
binding.ivExpand.setImageResource(R.mipmap.shouqi)
}
if (payloads.isEmpty()) {
binding.tvName.text = bean.tittle
val size = bean.childItem.sumOf { File(it.path).length() }
binding.tvSize.text = size.toFormatSize()
binding.flExpand.setOnClickListener {
bean.isExpand = !bean.isExpand
notifyGroupChange(groupPosition, "aa")
if (bean.isExpand) {
expandGroup(groupPosition, true)
} else {
collapseGroup(groupPosition, true)
}
}
binding.ivSelector.isSelected = bean.isSelect
binding.flSelector.setOnClickListener {
bean.isSelect = !bean.isSelect
bean.childItem.forEach { it.isSelect = bean.isSelect }
notifyDataSetChanged()
selectChange()
}
if (bean.playAnimation) {
val slideInFromRight = AnimationUtils.loadAnimation(holder.itemView.context, R.anim.slide_in_from_right)
binding.root.startAnimation(slideInFromRight)
bean.playAnimation = false
}
} else {
binding.ivSelector.isSelected = bean.isSelect
}
}
override fun onGroupViewHolderExpandChange(holder: ViewHolder, groupPosition: Int, animDuration: Long, expand: Boolean) {}
@SuppressLint("NotifyDataSetChanged")
fun addData(list: List<ParentBean>, clear: Boolean = true) {
if (clear) {
beanList.clear()
}
beanList.addAll(list)
notifyDataSetChanged()
}
private fun selectChange() {
val size = beanList.flatMap { it.childItem }.filter { it.isSelect }.sumOf { bean -> File(bean.path).length() }
selectAction.invoke(size)
}
fun getChoosePath(): List<String> {
return beanList.flatMap { it.childItem }.filter { it.isSelect }.map { it.path }
}
}
package com.base.pdfreader2.ui.cleanjunk
import android.animation.ValueAnimator
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.view.animation.LinearInterpolator
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.base.pdfreader2.R
import com.base.pdfreader2.bean.ParentBean
import com.base.pdfreader2.databinding.ItemJunkParentScanBinding
import com.base.pdfreader2.utils.XmlEx.inflate
class JunkScanAdapter : RecyclerView.Adapter<JunkScanAdapter.ParentViewHolder>() {
private val beanList = arrayListOf<ParentBean>()
inner class ParentViewHolder(view: View) : RecyclerView.ViewHolder(view)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ParentViewHolder {
return ParentViewHolder(R.layout.item_junk_parent_scan.inflate(parent))
}
override fun getItemCount(): Int {
return beanList.size
}
override fun onBindViewHolder(holder: ParentViewHolder, position: Int) {
val bean = beanList[position]
val context = holder.itemView.context
val binding = ItemJunkParentScanBinding.bind(holder.itemView)
binding.ivIcon.setImageResource(bean.icon)
binding.tvTitle.text = bean.tittle
if (bean.playAnimation) {
val slideInFromRight = AnimationUtils.loadAnimation(holder.itemView.context, R.anim.slide_in_from_right)
binding.ll.startAnimation(slideInFromRight)
bean.playAnimation = false
}
if (bean.finished) {
binding.ivRotate.rotation = 0f
binding.ivRotate.setImageDrawable(ContextCompat.getDrawable(context, R.mipmap.xuan))
bean.rotateValueAnimator?.cancel()
bean.rotateValueAnimator = null
} else {
bean.rotateValueAnimator = ValueAnimator.ofFloat(0f, 360f).apply {
duration = 1000
repeatMode = ValueAnimator.RESTART
repeatCount = ValueAnimator.INFINITE
interpolator = LinearInterpolator()
addUpdateListener {
binding.ivRotate.rotation = it.animatedValue as Float
}
start()
}
}
}
fun addData(bean: ParentBean, position: Int) {
beanList.add(bean)
notifyItemChanged(position)
}
fun setFinishScan(position: Int) {
val bean = beanList[position]
bean.finished = true
notifyItemChanged(position)
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.main
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.base.pdfreader2.ads.AdmobHelper
import com.base.pdfreader2.ads.AdmobHelper.lastOpenDocumentShowAd
import com.base.pdfreader2.ads.admob.AdmobInterstitialUtils
import com.base.pdfreader2.bean.ConstObject
import com.base.pdfreader2.bean.DocumentBean
import com.base.pdfreader2.bean.DocumentBean.Companion.TYPE_EXCEL
......@@ -12,8 +16,10 @@ import com.base.pdfreader2.bean.DocumentBean.Companion.TYPE_PPT
import com.base.pdfreader2.bean.DocumentBean.Companion.TYPE_WORD
import com.base.pdfreader2.databinding.FragmentDocumentBinding
import com.base.pdfreader2.helper.BaseFragment
import com.base.pdfreader2.ui.pdf.PdfActivity
import com.base.pdfreader2.ui.view.DocumentDialog.showDocumentHomeMoreDialog
import com.base.pdfreader2.ui.view.PdfDialog.showPdfHomeMoreDialog
import com.base.pdfreader2.ui.view.PwdDialog.showPdfPwdDialog
import com.base.pdfreader2.utils.PdfBoxUtils.checkPdfEncryption
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
......@@ -51,16 +57,16 @@ class DocumentFragment() : BaseFragment<FragmentDocumentBinding>() {
documentPresenter.saveBookmarkChange(addRemove, path)
}
adapter.itemClick = { item ->
// if (AdmobHelper.isShowOpenDocumentInter()) {
// AdmobInterstitialUtils.showInterstitialAd(requireActivity()) {
// if (it) {
// lastOpenDocumentShowAd = System.currentTimeMillis()
// }
// requireActivity().jumpDocument(item)
// }
// } else {
// requireActivity().jumpDocument(item)
// }
if (AdmobHelper.isShowOpenDocumentInter()) {
AdmobInterstitialUtils.showInterstitialAd(requireActivity()) {
if (it) {
lastOpenDocumentShowAd = System.currentTimeMillis()
}
requireActivity().jumpDocument(item)
}
} else {
requireActivity().jumpDocument(item)
}
}
adapter.moreAction = { item ->
documentMoreAction.invoke(item)
......@@ -68,7 +74,7 @@ class DocumentFragment() : BaseFragment<FragmentDocumentBinding>() {
binding.rv.adapter = adapter
}
var documentMoreAction: (item: DocumentBean) -> Unit = { item ->
var documentMoreAction: (item: DocumentBean) -> Unit = { item ->
val mainActivity = (requireActivity() as MainActivity)
if (item.type == TYPE_PDF) {
requireContext().showPdfHomeMoreDialog(item, this, documentPresenter)
......@@ -184,5 +190,40 @@ class DocumentFragment() : BaseFragment<FragmentDocumentBinding>() {
adapter.notifyDataSetChanged()
}
companion object {
fun Activity.jumpDocument(item: DocumentBean) {
if (item.type == DocumentBean.TYPE_PDF) {
if (item.state == 0) {
startActivity(Intent(this, PdfActivity::class.java).apply {
putExtra("path", item.path)
})
}
if (item.state == 1) {
showPdfPwdDialog(
state = item.state,
path = item.path,
isCheckPwd = true,
verificationAction = { pwd ->
startActivity(Intent(this, PdfActivity::class.java).apply {
putExtra("path", item.path)
putExtra("pwd", pwd)
})
})
}
}
if (item.type == DocumentBean.TYPE_WORD) {
// WordActivity.wordDocumentBean = item
// WordActivity.launchDocViewer(this, 3, item.path, -1, 100)
}
if (item.type == DocumentBean.TYPE_EXCEL) {
// ExcelActivity.excelDocumentBean = item
// ExcelActivity.launchDocViewer(this, 3, item.path, -1, 100)
}
if (item.type == DocumentBean.TYPE_PPT) {
// PptActivity.pptDocumentBean = item
// PptActivity.launchDocViewer(this, 3, item.path, -1, 100)
}
}
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.main
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.view.View
import android.view.inputmethod.EditorInfo
......@@ -19,7 +17,7 @@ import com.base.pdfreader2.bean.ConstObject.RECENT_DATA_TYPE
import com.base.pdfreader2.bean.DocumentBean
import com.base.pdfreader2.databinding.ActivityMainBinding
import com.base.pdfreader2.helper.BaseActivity
import com.base.pdfreader2.ui.pdf.PdfActivity
import com.base.pdfreader2.ui.main.DocumentFragment.Companion.jumpDocument
import com.base.pdfreader2.ui.view.DialogView.showSortDialog
import com.base.pdfreader2.utils.BarUtils
import com.base.pdfreader2.utils.LogEx
......@@ -355,40 +353,5 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
ViewPager2Delegate.install(binding.viewPager2, binding.tabLayoutDocument)
}
companion object {
fun Activity.jumpDocument(item: DocumentBean) {
if (item.type == DocumentBean.TYPE_PDF) {
if (item.state == 0) {
startActivity(Intent(this, PdfActivity::class.java).apply {
putExtra("path", item.path)
})
}
if (item.state == 1) {
// showPdfPwdDialog(
// state = item.state,
// path = item.path,
// isCheckPwd = true,
// verificationAction = { pwd ->
// startActivity(Intent(this, PdfActivity::class.java).apply {
// putExtra("path", item.path)
// putExtra("pwd", pwd)
// })
// })
}
}
if (item.type == DocumentBean.TYPE_WORD) {
// WordActivity.wordDocumentBean = item
// WordActivity.launchDocViewer(this, 3, item.path, -1, 100)
}
if (item.type == DocumentBean.TYPE_EXCEL) {
// ExcelActivity.excelDocumentBean = item
// ExcelActivity.launchDocViewer(this, 3, item.path, -1, 100)
}
if (item.type == DocumentBean.TYPE_PPT) {
// PptActivity.pptDocumentBean = item
// PptActivity.launchDocViewer(this, 3, item.path, -1, 100)
}
}
}
}
\ No newline at end of file
......@@ -41,6 +41,13 @@ import com.artifex.mupdfdemo.Annotation
import com.artifex.mupdfdemo.Hit
import com.artifex.mupdfdemo.MuPDFPageAdapter
import com.artifex.mupdfdemo.MuPDFReaderViewListener
import com.base.pdfreader2.ads.AdmobHelper
import com.base.pdfreader2.ads.AdmobHelper.isShowCloseDocument
import com.base.pdfreader2.ads.admob.AdmobInterstitialUtils
import com.base.pdfreader2.ads.admob.AdmobNativeUtils
import kotlinx.coroutines.cancel
import kotlinx.coroutines.isActive
import kotlin.random.Random
class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
......@@ -55,7 +62,6 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
private var saveMode = ""
private var path: String = ""
private var uri: String? = null
private var assets: String? = null
private var density = 0f
override val binding: ActivityPdfBinding by lazy {
......@@ -77,21 +83,36 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
override fun onDestroy() {
super.onDestroy()
muPDFCore?.onDestroy()
// AdmobNativeUtils.onDestroy()
AdmobNativeUtils.onDestroy()
}
private fun startLoading() {
binding.flLoading.setOnClickListener { }
lifecycleScope.launch(Dispatchers.Main) {
while (isActive) {
binding.progressBar.progress += 2
delay(150)
if (binding.progressBar.progress >= Random.nextInt(30, 40)) {
binding.flLoading.visibility = View.GONE
cancel()
}
}
}
}
override fun initView() {
val needRecreate = checkNeedRecreate(MyApplication.pdfLanguage)
if (needRecreate) return
startLoading()
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
density = metrics.density
path = intent.extras?.getString("path") ?: ""
uri = intent.extras?.getString("uri")
assets = intent.extras?.getString("assets") ?: ""
LogEx.logDebug(TAG, "path=$path")
LogEx.logDebug(TAG, "uri=$uri")
......@@ -136,8 +157,7 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
binding.flGuideGesture.visibility = View.GONE
}
}
// AdmobNativeUtils.showNativeAd(this, binding.flAd, R.layout.layout_admob_document_in)
AdmobNativeUtils.showNativeAd(this, binding.flAd, R.layout.layout_admob_document_in)
}
override fun jumpPage(pageIndex: Int) {
......@@ -187,16 +207,16 @@ class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
return@addCallback
}
// if (AdmobHelper.isShowCloseDocumentInter() && isShowCloseDocument()) {
// AdmobInterstitialUtils.showInterstitialAd(this@PdfActivity) {
// if (it) {
// AdmobHelper.lastCloseDocumentShowAd = System.currentTimeMillis()
// }
binding.root.postDelayed({ finishToMain() }, 500)
// }
// } else {
// binding.root.postDelayed({ finishToMain() }, 500)
// }
if (AdmobHelper.isShowCloseDocumentInter() && isShowCloseDocument()) {
AdmobInterstitialUtils.showInterstitialAd(this@PdfActivity) {
if (it) {
AdmobHelper.lastCloseDocumentShowAd = System.currentTimeMillis()
}
binding.root.postDelayed({ finishToMain() }, 500)
}
} else {
binding.root.postDelayed({ finishToMain() }, 500)
}
}
binding.flFanhui.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
......
package com.base.pdfreader2.ui.permission
import android.annotation.SuppressLint
import android.graphics.Color
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import androidx.activity.addCallback
import androidx.core.content.ContextCompat
import androidx.core.view.updatePadding
import com.base.pdfreader2.R
import com.base.pdfreader2.bean.ConstObject
import com.base.pdfreader2.databinding.ActivityPermissionBinding
import com.base.pdfreader2.helper.BaseActivity
import com.base.pdfreader2.utils.BarUtils
import com.base.pdfreader2.utils.PermissionUtils.requestStoragePermission
import java.util.Locale
class PermissionActivity : BaseActivity<ActivityPermissionBinding>() {
override val binding: ActivityPermissionBinding by lazy {
ActivityPermissionBinding.inflate(layoutInflater)
}
@SuppressLint("SetTextI18n")
override fun initView() {
val englishLanguageCountry = Locale.ENGLISH.language + "_" + Locale.ENGLISH.country
if (ConstObject.appLanguageSp != englishLanguageCountry) {
changeActivityLanguage(englishLanguageCountry)
return
}
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.parseColor("#F4F5FA"))
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
val tipString = getString(R.string.permission_tip_1)
val redString = getString(R.string.permission_tip_2)
val spannableString = SpannableString(redString)
spannableString.setSpan(
ForegroundColorSpan(ContextCompat.getColor(this, R.color.color_f92b39)),
0,
redString.length,
SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE
)
val spannableStringBuilder = SpannableStringBuilder(tipString)
spannableStringBuilder.append(spannableString)
binding.tvTip.text = spannableStringBuilder
}
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback {
finishToMain()
}
binding.tvLater.setOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
binding.tvAllow.setOnClickListener {
requestStoragePermission(launcher) {
onBackPressedDispatcher.onBackPressed()
}
}
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.result
import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import androidx.activity.addCallback
import com.base.pdfreader2.R
import com.base.pdfreader2.ads.admob.AdmobNativeUtils
import com.base.pdfreader2.bean.ConstObject.FUNCTION_APP_PROCESS
import com.base.pdfreader2.bean.ConstObject.FUNCTION_SCAM_JUNK
import com.base.pdfreader2.databinding.ActivityResultBinding
import com.base.pdfreader2.helper.BaseActivity
import com.base.pdfreader2.ui.appprocess.AppProcessLoadingActivity
import com.base.pdfreader2.ui.cleanjunk.ScanJunkActivity
import com.base.pdfreader2.utils.BarUtils
import com.base.pdfreader2.utils.KotlinExt.toFormatSize
class ResultActivity : BaseActivity<ActivityResultBinding>() {
override val binding: ActivityResultBinding by lazy {
ActivityResultBinding.inflate(layoutInflater)
}
var from = ""
@SuppressLint("SetTextI18n")
override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.parseColor("#00B7DD"))
// binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
AdmobNativeUtils.showNativeAd(this, binding.flAd, R.layout.layout_admob_app_exit)
from = intent.extras?.getString("from") ?: ""
when (from) {
FUNCTION_SCAM_JUNK -> {
binding.ivFunction.setImageResource(R.mipmap.process)
binding.tvFunctionDesc.text = getString(R.string.manage_processes_run_in_the_background)
binding.tvFunctionBtn.text = getString(R.string.scan_now)
binding.tvFunctionBtn.setOnClickListener {
startActivity(Intent(this, AppProcessLoadingActivity::class.java))
finish()
}
}
FUNCTION_APP_PROCESS -> {
binding.ivFunction.setImageResource(R.mipmap.clean)
binding.tvFunctionDesc.text = getString(R.string.clean_up_your_phone_storage)
binding.tvFunctionBtn.text = getString(R.string.clean_now)
binding.tvFunctionBtn.setOnClickListener {
startActivity(Intent(this, ScanJunkActivity::class.java))
finish()
}
val s = intent.extras?.getString("clean_size")?.toLong() ?: 0
if (s != 0L) {
binding.tvSize.text = "Cleaned up ${s.toFormatSize(1)}"
}
}
}
}
override fun initListener() {
super.initListener()
onBackPressedDispatcher.addCallback {
finishToMain()
}
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.set
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.base.pdfreader2.R
import com.base.pdfreader2.bean.LanguageBean
import com.base.pdfreader2.databinding.ItemLanguageSetBinding
import com.base.pdfreader2.utils.XmlEx.inflate
import com.chad.library.adapter4.BaseQuickAdapter
class LanguageAdapter : BaseQuickAdapter<LanguageBean, LanguageAdapter.LanguageViewHolder>() {
inner class LanguageViewHolder(view: View) : ViewHolder(view)
@SuppressLint("NotifyDataSetChanged")
override fun onBindViewHolder(holder: LanguageViewHolder, position: Int, item: LanguageBean?) {
item ?: return
val binding = ItemLanguageSetBinding.bind(holder.itemView)
binding.ivSelector.isSelected = item.isSelect
binding.tvLanguage.text = item.key
binding.root.setOnClickListener {
items.find { it.isSelect }?.isSelect = false
item.isSelect = true
notifyDataSetChanged()
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): LanguageViewHolder {
return LanguageViewHolder(R.layout.item_language_set.inflate(parent))
}
}
\ No newline at end of file
package com.base.pdfreader2.ui.splash
import androidx.lifecycle.LifecycleCoroutineScope
import com.base.pdfreader2.ads.AdmobHelper.open_ad_loading
import com.base.pdfreader2.bean.ConstObject
import com.base.pdfreader2.utils.AppPreferences
import com.base.pdfreader2.utils.LogEx
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class SplashPresenter(
val splashView: SplashView
) {
private val TAG = "SplashActivity"
private var jumpJob: Job? = null
var loadingTime = AppPreferences.getInstance().getString(open_ad_loading, "15").toInt()
var startJumpJob: Boolean = false
/**
* 超时跳转
*/
fun startJumpJob(lifecycleCoroutineScope: LifecycleCoroutineScope) {
if (ConstObject.ifAgreePrivacy && startJumpJob) {
if (jumpJob == null) {
val startTime = System.currentTimeMillis()
jumpJob = lifecycleCoroutineScope.launch {
LogEx.logDebug(TAG, "open_ad_loading=$loadingTime")
delay(loadingTime * 1000L)
val endTime = System.currentTimeMillis()
LogEx.logDebug(TAG, "超时跳转 time=${endTime - startTime}")
splashView.jumpNext()
}
}
}
}
/**
* 暂停超时跳转
*/
fun pauseJumpJob() {
jumpJob?.cancel()
jumpJob = null
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
......@@ -41,7 +41,7 @@ object LanguageUtils {
return supportLanguage.contains(getSystemLanguage())
}
fun changeAppLanguage(context: Context,languageCountry:String) {
fun changeAppLanguage(context: Context, languageCountry: String) {
val config = context.resources.configuration
val lc = languageCountry.split("_")
val locale = if (lc.size == 2) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment