Commit 16f75fc7 authored by wanglei's avatar wanglei

...ad

parent 8759bdfd
...@@ -81,7 +81,6 @@ dependencies { ...@@ -81,7 +81,6 @@ dependencies {
implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.4") implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.4")
implementation("com.github.angcyo.DslTablayout:TabLayout:3.5.5") implementation("com.github.angcyo.DslTablayout:TabLayout:3.5.5")
implementation("com.github.angcyo.DslTablayout:ViewPager2Delegate:3.5.5") implementation("com.github.angcyo.DslTablayout:ViewPager2Delegate:3.5.5")
// implementation("com.github.lukelorusso:VerticalSeekBar:1.2.5")
//mlkit //mlkit
implementation("com.google.android.gms:play-services-mlkit-document-scanner:16.0.0-beta1") implementation("com.google.android.gms:play-services-mlkit-document-scanner:16.0.0-beta1")
...@@ -96,5 +95,20 @@ dependencies { ...@@ -96,5 +95,20 @@ dependencies {
//Excel库 //Excel库
api(project(":library")) api(project(":library"))
//广告
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")
//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)")
} }
\ No newline at end of file
...@@ -118,6 +118,10 @@ ...@@ -118,6 +118,10 @@
android:name="android.support.FILE_PROVIDER_PATHS" android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" /> android:resource="@xml/file_paths" />
</provider> </provider>
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package com.base.pdfviewerscannerwhite.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
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.pdfviewerscannerwhite.ads.admob
import android.content.Context
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.core.view.children
import com.base.pdfviewerscannerwhite.BuildConfig
import com.base.pdfviewerscannerwhite.helper.ConfigHelper
import com.base.pdfviewerscannerwhite.utils.AppPreferences
import com.base.pdfviewerscannerwhite.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) {
val isShowBanner = AppPreferences.getInstance().getString("isShowBanner", "0").toInt()
if (isShowBanner == 0) {
return
}
if (adView != null) {
adView?.destroy()
}
adView = AdView(context)
adView?.tag = "CollapsibleBannerAd"
// parent.removeAllViews()
val list = parent.children
list.forEach {
if (it.tag != "zhanweitu") {
parent.removeView(it)
}
}
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(parent)
parent.viewTreeObserver.removeOnGlobalLayoutListener(listener)
}
parent.viewTreeObserver.addOnGlobalLayoutListener(listener)
}
private fun loadCollapsibleBanner(parent: ViewGroup) {
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")
val removeList = arrayListOf<View>()
parent.children.forEach {
if (it.tag != "CollapsibleBannerAd") {
removeList.add(it)
}
}
removeList.forEach {
parent.removeView(it)
}
}
}
adView?.loadAd(adRequest)
}
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ads.admob
object AdmobHelper {
//展示广告关闭时赋值
var lastShowedOnHiddenTime = 0L
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ads.admob
import android.app.Activity
import android.app.Dialog
import android.widget.Toast
import com.base.pdfviewerscannerwhite.BuildConfig
import com.base.pdfviewerscannerwhite.ads.AdDisplayUtils
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.clickAd
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.pullAd
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.showAd
import com.base.pdfviewerscannerwhite.ads.admob.AdmobHelper.lastShowedOnHiddenTime
import com.base.pdfviewerscannerwhite.helper.ConfigHelper
import com.base.pdfviewerscannerwhite.helper.EventUtils
import com.base.pdfviewerscannerwhite.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 var dialog: Dialog? = null
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.getInstance().shouldShowAd("interAd")) {
onHidden?.invoke(false)
return
}
val obj1 = JSONObject()
obj1.put("ad_unit", "interAd")
EventUtils.event("ad_prepare_show", ext = obj1)
if (interAd != null) {
if (!activity.isFinishing && !activity.isDestroyed) {
// dialog = activity.showAdPreparingDialog()
}
displayInterstitialAd(activity, onHidden)
} else {
showAdDialogAndLoadInterstitial(activity, isReLoadAd, isShowDialog, onHidden)
}
}
fun loadInterstitialAd(activity: Activity, onLoad: (() -> Unit)? = null) {
if (interAd != null) {
onLoad?.invoke()
return
}
if (!AdDisplayUtils.getInstance().shouldShowAd("interAd")) {
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)
}
})
}
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, onHidden: ((showed: Boolean) -> Unit)? = null) {
val thisInterAd = interAd
interAd = null
thisInterAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdClicked() {
clickAd(thisInterAd?.responseInfo, "interAd")
AdDisplayUtils.getInstance().incrementAdClickCount()
}
override fun onAdDismissedFullScreenContent() {
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.getInstance().incrementAdDisplayCount()
adLastDisplayTime = System.currentTimeMillis() / 1000
}
}
thisInterAd?.show(activity)
}
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ads.admob
import android.app.Activity
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.base.browserwhite.ads.admob.NativeView
import com.base.pdfviewerscannerwhite.BuildConfig
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.ads.AdDisplayUtils
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.clickAd
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.pullAd
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.showAd
import com.base.pdfviewerscannerwhite.helper.ConfigHelper
import com.base.pdfviewerscannerwhite.helper.EventUtils
import com.base.pdfviewerscannerwhite.helper.MyApplication
import com.base.pdfviewerscannerwhite.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
private fun loadNativeAd() {
if (nativeAd != null) {
return
}
if (isLoading) {
return
}
isLoading = true
if (!AdDisplayUtils.getInstance().shouldShowAd("nativeAd")) {
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
LogEx.logDebug(TAG, "nativeAd=${nativeAd.toString()}")
isLoading = false
loadingListener?.invoke()
pullAd(it.responseInfo, "nativeAd", reqId = reqId)
it.setOnPaidEventListener(AdmobEvent.EventOnPaidEventListener(it))
}.withAdListener(object : AdListener() {
override fun onAdLoaded() {
super.onAdLoaded()
onAdLoaded?.invoke()
onAdLoaded = null
}
override fun onAdClicked() {
clickAd(nativeAd?.responseInfo, "nativeAd")
}
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.getInstance().shouldShowAd("nativeAd")) {
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
loadingListener = 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()
}
}
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)
}
}
}
}
\ No newline at end of file
package com.base.pdfviewerscannerwhite.ads.admob
import android.app.Activity
import com.base.pdfviewerscannerwhite.BuildConfig
import com.base.pdfviewerscannerwhite.ads.AdDisplayUtils
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.clickAd
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.pullAd
import com.base.pdfviewerscannerwhite.ads.admob.AdmobEvent.showAd
import com.base.pdfviewerscannerwhite.helper.ConfigHelper
import com.base.pdfviewerscannerwhite.helper.EventUtils
import com.base.pdfviewerscannerwhite.helper.MyApplication
import com.base.pdfviewerscannerwhite.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
fun isOpenAdLoaded() = mOpenAd != null
fun loadAppOpenAd(skip: Boolean = false, onLoad: ((where: Int) -> Unit)? = null) {
if (mOpenAd != null || skip) {
onLoad?.invoke(1)
return
}
if (!AdDisplayUtils.getInstance().shouldShowAd("openAd")) {
onLoad?.invoke(2)
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(3)
pullAd(ad.responseInfo, "openAd", reqId = reqId)
ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
}
override fun onAdFailedToLoad(p0: LoadAdError) {
LogEx.logDebug(TAG, "LoadAdError ${p0.message}")
mOpenAd = null
onLoad?.invoke(4)
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) {
return
}
if (!AdDisplayUtils.getInstance().shouldShowAd("openAd")) {
onHidden?.invoke(false)
return
}
if (System.currentTimeMillis() - openLoadTime > 1000 * 60 * 60) {
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")
}
override fun onAdDismissedFullScreenContent() {
mOpenAd = null
onHidden?.invoke(true)
loadAppOpenAd()
}
override fun onAdFailedToShowFullScreenContent(p0: AdError) {
mOpenAd = null
onHidden?.invoke(false)
loadAppOpenAd()
val obj = JSONObject()
obj.put("reason", p0.message)
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
}
override fun onAdShowedFullScreenContent() {
showBefore?.invoke(true)
showAd(thisMOpenAd?.responseInfo, "openAd", activity)
}
}
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.pdfviewerscannerwhite.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.pdfviewerscannerwhite.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
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.pdfviewerscannerwhite.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
...@@ -4,4 +4,23 @@ object ConfigHelper { ...@@ -4,4 +4,23 @@ object ConfigHelper {
const val privacyPolicy: String = "https://sites.google.com/view/pdf-reader-scan/pdf-reader" const val privacyPolicy: String = "https://sites.google.com/view/pdf-reader-scan/pdf-reader"
const val termService: String = "https://sites.google.com/view/term-of-service-s/term-of-service" const val termService: String = "https://sites.google.com/view/term-of-service-s/term-of-service"
// 正式包名
const val packageName = "com.lol.pdfscanner.libstdc.chovey"
// 域名
const val eventUrl = "https://rp.gamexzonerk.xyz"
const val apiUrl = "https://api.gamexzonerk.xyz"
//admob test id
const val openAdmobIdTest = "ca-app-pub-3940256099942544/9257395921"
const val bannerAdmobIdTest = "ca-app-pub-3940256099942544/9214589741"
const val interAdmobIdTest = "ca-app-pub-3940256099942544/1033173712"
const val nativeAdmobIdTest = "ca-app-pub-3940256099942544/2247696110"
// admob广告id
const val interAdmobId = "ca-app-pub-3940256099942544/1033173111"
const val nativeAdmobId = "ca-app-pub-3940256099942544/2247696111"
const val openAdmobId = "/6499/example/app-open"
const val bannerAdmobId = "ca-app-pub-3940256099942544/9214581111"
} }
\ No newline at end of file
package com.base.pdfviewerscannerwhite.helper
import android.os.Build
import com.base.pdfviewerscannerwhite.BuildConfig
import com.base.pdfviewerscannerwhite.bean.ConstObject.ifAgreePrivacy
import com.base.pdfviewerscannerwhite.helper.ReportUtils.doPost
import com.base.pdfviewerscannerwhite.utils.AppPreferences
import com.base.pdfviewerscannerwhite.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, "report!")
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.pdfviewerscannerwhite.helper package com.base.pdfviewerscannerwhite.helper
import android.app.Activity
import android.app.Application import android.app.Application
import android.text.TextUtils import android.text.TextUtils
import com.base.pdfviewerscannerwhite.utils.AppPreferences import com.base.pdfviewerscannerwhite.utils.AppPreferences
......
package com.base.pdfviewerscannerwhite.helper;
import android.text.TextUtils;
import com.base.pdfviewerscannerwhite.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\":{}}";
}
}
...@@ -7,7 +7,7 @@ object LogEx { ...@@ -7,7 +7,7 @@ object LogEx {
val isOpen = true val isOpen = true
val filterTAG = arrayOf( val filterTAG = arrayOf(
"", "",
"MediaStoreUtils", "",
) )
fun logDebug(tag: String, content: String, isMust: Boolean = false) { fun logDebug(tag: String, content: String, isMust: Boolean = false) {
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F2F2F2" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF8A00" />
<corners android:radius="10dp" />
</shape>
\ No newline at end of file
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/bg_f2f2f2"
android:baselineAligned="false">
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_media"
android:layout_width="91dp"
android:layout_height="91dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="8dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#FF923E"
android:padding="2dp"
android:text="Ad"
android:textColor="@color/white"
android:textSize="12sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="5dp">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
tools:ignore="ContentDescription" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/ad_call_to_action"
android:layout_width="match_parent"
android:layout_height="26dp"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="12dp"
android:background="@drawable/bg_ff8a00_10"
android:gravity="center"
android:textColor="@color/white"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
\ No newline at end of file
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<string name="next" tools:ignore="MissingTranslation">Next</string> <string name="next" tools:ignore="MissingTranslation">Next</string>
<string name="previous" tools:ignore="MissingTranslation">Previous</string> <string name="previous" tools:ignore="MissingTranslation">Previous</string>
<string name="facebook_app_id" tools:ignore="MissingTranslation">421266364258459</string>
<string name="lorem_ipsum" tools:ignore="MissingTranslation"> <string name="lorem_ipsum" tools:ignore="MissingTranslation">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris volutpat, dolor id interdum Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris volutpat, dolor id interdum
ullamcorper, risus dolor egestas lectus, sit amet mattis purus dui nec risus. Maecenas non sodales nisi, vel dictum dolor. ullamcorper, risus dolor egestas lectus, sit amet mattis purus dui nec risus. Maecenas non sodales nisi, vel dictum dolor.
......
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