添加参数上传,添加admob广告封装。
This commit is contained in:
parent
135ec734db
commit
e714a1ef63
@ -84,6 +84,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(files("libs/UpLoadLibrary_11_24_18_30-release.aar"))
|
||||
implementation(libs.androidx.fragment.ktx)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.core.ktx)
|
||||
@ -112,4 +113,11 @@ dependencies {
|
||||
implementation(platform("com.google.firebase:firebase-bom:34.6.0"))
|
||||
implementation("com.google.firebase:firebase-crashlytics-ndk")
|
||||
implementation("com.google.firebase:firebase-analytics")
|
||||
// google ads
|
||||
implementation("com.google.android.gms:play-services-ads:24.7.0")
|
||||
implementation ("com.google.android.gms:play-services-ads-identifier:18.0.1")
|
||||
// okhttp
|
||||
implementation ("com.squareup.okhttp3:okhttp:4.12.0")
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
|
||||
|
||||
}
|
||||
BIN
app/libs/UpLoadLibrary_11_24_18_30-release.aar
Normal file
BIN
app/libs/UpLoadLibrary_11_24_18_30-release.aar
Normal file
Binary file not shown.
@ -35,10 +35,14 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:networkSecurityConfig="@xml/net"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.PDFReaderPro">
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.ads.APPLICATION_ID"
|
||||
android:value="ca-app-pub-3940256099942544~3347511713" />
|
||||
<meta-data
|
||||
android:name="android.max_aspect"
|
||||
android:value="2.4" />
|
||||
|
||||
@ -6,7 +6,10 @@ import androidx.annotation.StringRes
|
||||
import com.all.pdfreader.pdf.reader.room.repository.PdfRepository
|
||||
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
|
||||
import com.all.pdfreader.pdf.reader.util.FileChangeObserver
|
||||
import com.google.android.gms.ads.MobileAds
|
||||
import com.google.android.gms.ads.RequestConfiguration
|
||||
import com.tom_roush.pdfbox.android.PDFBoxResourceLoader
|
||||
import com.up.uploadlibrary.UpLoadManager
|
||||
|
||||
class PRApp : Application() {
|
||||
|
||||
@ -39,10 +42,20 @@ class PRApp : Application() {
|
||||
PdfRepository.initialize(this)
|
||||
// 初始化pdfbox
|
||||
PDFBoxResourceLoader.init(this)
|
||||
// 上传
|
||||
UpLoadManager.init(context = this, tag = "PRApp_upload_task") { _, _ -> }
|
||||
// 广告初始化
|
||||
MobileAds.initialize(this)
|
||||
}
|
||||
|
||||
private fun initMobileAds(){
|
||||
val testDeviceIds = listOf("TEST_DEVICE_ID")
|
||||
val configuration = RequestConfiguration.Builder().setTestDeviceIds(testDeviceIds).build()
|
||||
MobileAds.setRequestConfiguration(configuration)
|
||||
}
|
||||
|
||||
// 在权限授权后调用
|
||||
fun startFileChangeObserving() {
|
||||
fileChangeObserver.startObserving()
|
||||
// fileChangeObserver.startObserving()
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
package com.all.pdfreader.pdf.reader.ad
|
||||
|
||||
import android.app.Activity
|
||||
import android.util.Log
|
||||
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
|
||||
import com.google.android.gms.ads.AdRequest
|
||||
import com.google.android.gms.ads.LoadAdError
|
||||
import com.google.android.gms.ads.interstitial.InterstitialAd
|
||||
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
|
||||
|
||||
class AdInstLoad(
|
||||
private val activity: Activity,
|
||||
private val placement: AdsInsUtil.AdPlacement,
|
||||
private val adLoadListener: LoadListener?
|
||||
) {
|
||||
|
||||
init {
|
||||
loadAd()
|
||||
}
|
||||
|
||||
private fun loadAd() {
|
||||
//多处调用load,也不会重复、不影响缓存广告、展示安全
|
||||
val cachedAd = InstAdCacheManager.instance.getAdCache(placement)
|
||||
if (cachedAd != null) {
|
||||
Log.d("ocean","广告存在缓存,跳过加载,返回成功")
|
||||
//缓存广告有效,跳过加载,返回成功
|
||||
adLoadListener?.loaded(cachedAd)
|
||||
return
|
||||
}
|
||||
|
||||
val adUnitId = AdsInsUtil.adUnitIdMap[placement] ?: run {
|
||||
val errorMsg = "No AdUnitId for $placement"
|
||||
Log.d("ocean","没找到对应的广告ID->$placement")
|
||||
adLoadListener?.loadFailed(errorMsg)
|
||||
AnalyticsUtils.logAdEvent(
|
||||
placement,
|
||||
AnalyticsUtils.AdEvent.LOAD_FAIL,
|
||||
null,
|
||||
errorMsg
|
||||
)
|
||||
return
|
||||
}
|
||||
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.REQ)
|
||||
|
||||
InterstitialAd.load(
|
||||
activity,
|
||||
adUnitId,
|
||||
AdRequest.Builder().build(),
|
||||
object : InterstitialAdLoadCallback() {
|
||||
override fun onAdLoaded(ad: InterstitialAd) {
|
||||
InstAdCacheManager.instance.setAdCache(placement, ad)
|
||||
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.LOADED)
|
||||
adLoadListener?.loaded(ad)
|
||||
}
|
||||
|
||||
override fun onAdFailedToLoad(adError: LoadAdError) {
|
||||
AnalyticsUtils.logAdEvent(
|
||||
placement,
|
||||
AnalyticsUtils.AdEvent.LOAD_FAIL,
|
||||
adError.code,
|
||||
adError.message
|
||||
)
|
||||
adLoadListener?.loadFailed(adError.toString())
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package com.all.pdfreader.pdf.reader.ad
|
||||
|
||||
import android.app.Activity
|
||||
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil.AdPlacement
|
||||
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
|
||||
import com.google.android.gms.ads.AdError
|
||||
import com.google.android.gms.ads.FullScreenContentCallback
|
||||
|
||||
class AdInstShower(
|
||||
private val activity: Activity,
|
||||
private val placement: AdPlacement,
|
||||
private val showListener: ShowListener?
|
||||
) {
|
||||
|
||||
init {
|
||||
showAd()
|
||||
}
|
||||
|
||||
private fun showAd() {
|
||||
val interstitialAd = InstAdCacheManager.instance.getAdCache(placement)
|
||||
?: run {
|
||||
val errorMsg = "InterstitialAd cache is null for place = $placement"
|
||||
AnalyticsUtils.logAdEvent(
|
||||
placement,
|
||||
AnalyticsUtils.AdEvent.SHOW_FAIL,
|
||||
null,
|
||||
errorMsg
|
||||
)
|
||||
showListener?.onAdShowFailed(errorMsg)
|
||||
return
|
||||
}
|
||||
|
||||
interstitialAd.fullScreenContentCallback = object : FullScreenContentCallback() {
|
||||
|
||||
override fun onAdShowedFullScreenContent() {
|
||||
AnalyticsUtils.logAdEvent(placement, AnalyticsUtils.AdEvent.SHOW_SUC)
|
||||
showListener?.onAdShown()
|
||||
}
|
||||
|
||||
override fun onAdDismissedFullScreenContent() {
|
||||
// 用户关闭广告
|
||||
InstAdCacheManager.instance.remove(placement)
|
||||
showListener?.onAdClosed()
|
||||
}
|
||||
|
||||
override fun onAdFailedToShowFullScreenContent(adError: AdError) {
|
||||
AnalyticsUtils.logAdEvent(
|
||||
placement,
|
||||
AnalyticsUtils.AdEvent.SHOW_FAIL,
|
||||
adError.code,
|
||||
adError.message
|
||||
)
|
||||
InstAdCacheManager.instance.remove(placement)
|
||||
showListener?.onAdShowFailed(adError.toString())
|
||||
}
|
||||
|
||||
override fun onAdClicked() {
|
||||
showListener?.onAdClicked()
|
||||
}
|
||||
|
||||
override fun onAdImpression() {
|
||||
// 曝光回调
|
||||
}
|
||||
}
|
||||
|
||||
interstitialAd.show(activity)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package com.all.pdfreader.pdf.reader.ad
|
||||
|
||||
import android.app.Activity
|
||||
|
||||
object AdsInsUtil {
|
||||
/** 广告位定义(可扩展) */
|
||||
enum class AdPlacement(val tag: String) {
|
||||
SPL_AND_INTO_HOME(Placement.SPL_AND_INTO_HOME), INT_AND_TOPDF(Placement.INT_AND_TOPDF), INT_AND_PDFTOHOME(
|
||||
Placement.INT_AND_PDFTOHOME
|
||||
),
|
||||
INT_AND_MERGE(Placement.INT_AND_MERGE), INT_AND_SPLIT(Placement.INT_AND_SPLIT), NATIVE_AND_EXIT(
|
||||
Placement.NATIVE_AND_EXIT
|
||||
),
|
||||
BAN_AND_HOMEPAGE(Placement.BAN_AND_HOMEPAGE)
|
||||
}
|
||||
|
||||
object Placement {
|
||||
/**
|
||||
* 启动页插页
|
||||
*/
|
||||
const val SPL_AND_INTO_HOME = "spl_and_into_home"
|
||||
|
||||
/**
|
||||
* 在首页/最近页/喜欢页-点击文件进入PDF内容页过程中,弹出缓存的插屏广告
|
||||
*/
|
||||
const val INT_AND_TOPDF = "int_and_topdf"
|
||||
|
||||
/**
|
||||
* PDF内容页点击返回到首页/最近页/喜欢页过程中,弹出缓存的插屏广告
|
||||
*/
|
||||
const val INT_AND_PDFTOHOME = "int_and_pdftohome"
|
||||
|
||||
/**
|
||||
* 首页/最近/喜欢-PDF内容页-更多-合并文件(在点击ok后,出现插屏广告,插屏广告结束后到合并成功页面)
|
||||
*/
|
||||
const val INT_AND_MERGE = "int_and_merge"
|
||||
|
||||
/**
|
||||
* 首页/最近/喜欢-PDF内容页-更多-拆分文件(点击ok后,出现插屏广告,插屏广告结束后到拆分成功页面)
|
||||
*/
|
||||
const val INT_AND_SPLIT = "int_and_split"
|
||||
|
||||
/**
|
||||
* 退出提示对话框原生
|
||||
*/
|
||||
const val NATIVE_AND_EXIT = "native_and_exit"
|
||||
|
||||
/**
|
||||
* 首页横幅
|
||||
*/
|
||||
const val BAN_AND_HOMEPAGE = "ban_and_homepage"
|
||||
}
|
||||
|
||||
// 广告位对应的广告ID
|
||||
val adUnitIdMap: Map<AdPlacement, String> = mapOf(
|
||||
AdPlacement.SPL_AND_INTO_HOME to "ca-app-pub-5717753826607607/5211991318",
|
||||
AdPlacement.INT_AND_TOPDF to "ca-app-pub-5717753826607607/5308904672",
|
||||
AdPlacement.INT_AND_PDFTOHOME to "ca-app-pub-5717753826607607/7085128570",
|
||||
AdPlacement.INT_AND_MERGE to "ca-app-pub-5717753826607607/8928693282",
|
||||
AdPlacement.INT_AND_SPLIT to "ca-app-pub-5717753826607607/2338415962",
|
||||
AdPlacement.NATIVE_AND_EXIT to "ca-app-pub-5717753826607607/7276700267",
|
||||
AdPlacement.BAN_AND_HOMEPAGE to "ca-app-pub-5717753826607607/5939567861"
|
||||
)
|
||||
|
||||
fun loadAd(
|
||||
act: Activity, adPlacement: AdPlacement
|
||||
): AdInstLoad {
|
||||
return AdInstLoad(act, adPlacement, null)
|
||||
}
|
||||
|
||||
fun loadAd(
|
||||
act: Activity, adPlacement: AdPlacement, loadListener: LoadListener?
|
||||
): AdInstLoad {
|
||||
return AdInstLoad(act, adPlacement, loadListener)
|
||||
}
|
||||
|
||||
fun showAd(
|
||||
act: Activity, adPlacement: AdPlacement, listener: ShowListener?
|
||||
): AdInstShower {
|
||||
return AdInstShower(act, adPlacement, listener)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
package com.all.pdfreader.pdf.reader.ad
|
||||
|
||||
import com.google.android.gms.ads.interstitial.InterstitialAd
|
||||
|
||||
class InstAdCacheManager {
|
||||
private val mAdCacheDict: MutableMap<AdsInsUtil.AdPlacement, CachedAd> = mutableMapOf()
|
||||
|
||||
companion object {
|
||||
val instance: InstAdCacheManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
InstAdCacheManager()
|
||||
}
|
||||
}
|
||||
|
||||
fun setAdCache(place: AdsInsUtil.AdPlacement, adCache: InterstitialAd) {
|
||||
mAdCacheDict[place] = CachedAd(adCache)
|
||||
}
|
||||
|
||||
fun getAdCache(place: AdsInsUtil.AdPlacement): InterstitialAd? {
|
||||
val cached = mAdCacheDict[place]
|
||||
return if (cached != null && cached.isValid()) cached.ad
|
||||
else {
|
||||
mAdCacheDict.remove(place) // 过期广告清理
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun remove(place: AdsInsUtil.AdPlacement) {
|
||||
mAdCacheDict.remove(place)
|
||||
}
|
||||
|
||||
|
||||
data class CachedAd(
|
||||
val ad: InterstitialAd,
|
||||
val loadedAt: Long = System.currentTimeMillis()
|
||||
) {
|
||||
// 广告有效期, 1 小时
|
||||
fun isValid(): Boolean = System.currentTimeMillis() - loadedAt < 3600_000
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.all.pdfreader.pdf.reader.ad
|
||||
|
||||
import com.google.android.gms.ads.interstitial.InterstitialAd
|
||||
|
||||
interface LoadListener {
|
||||
fun loadFailed(string: String) {}
|
||||
fun loaded(ad: InterstitialAd) {}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.all.pdfreader.pdf.reader.ad
|
||||
|
||||
interface ShowListener {
|
||||
fun onAdShown() {}
|
||||
fun onAdShowFailed(string: String) {}
|
||||
fun onAdClosed() {}
|
||||
fun onAdClicked() {}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.all.pdfreader.pdf.reader.util
|
||||
|
||||
import android.os.Bundle
|
||||
import com.all.pdfreader.pdf.reader.BuildConfig
|
||||
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil
|
||||
import com.google.firebase.Firebase
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.google.firebase.analytics.analytics
|
||||
@ -97,8 +98,35 @@ object AnalyticsUtils {
|
||||
const val KEEP_SCREEN_CLOSE = "keep_screen_close" // 点击关闭(keep_screen_close)
|
||||
}
|
||||
|
||||
/** param 常量 */
|
||||
/** param 常量(可扩展) */
|
||||
object Param {
|
||||
|
||||
const val PLACE = "place"
|
||||
const val ERROR_CODE = "error_code"
|
||||
const val ERROR_MSG = "error_msg"
|
||||
}
|
||||
|
||||
/** 广告事件类型 */
|
||||
enum class AdEvent(val suffix: String) {
|
||||
REQ("req_header"),
|
||||
LOADED("loaded_header"),
|
||||
LOAD_FAIL("load_fail_header"),
|
||||
SHOW_SUC("show_suc_header"),
|
||||
SHOW_FAIL("show_fail_header"),
|
||||
}
|
||||
|
||||
/** 统一广告打点 */
|
||||
fun logAdEvent(
|
||||
placement: AdsInsUtil.AdPlacement,
|
||||
event: AdEvent,
|
||||
errorCode: Int? = null,
|
||||
errorMsg: String? = null
|
||||
) {
|
||||
val eventName = "${placement.tag}_${event.suffix}"
|
||||
logEvent(eventName) {
|
||||
put(Param.PLACE, placement.tag)
|
||||
errorCode?.let { put(Param.ERROR_CODE, it) }
|
||||
errorMsg?.let { put(Param.ERROR_MSG, it) }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
6
app/src/main/res/xml/net.xml
Normal file
6
app/src/main/res/xml/net.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config xmlns:tools="http://schemas.android.com/tools">
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain tools:ignore="NetworkSecurityConfig">mobile-server.lux-ad.com</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
@ -1,3 +1,5 @@
|
||||
import org.gradle.kotlin.dsl.flatDir
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
google {
|
||||
@ -7,6 +9,7 @@ pluginManagement {
|
||||
includeGroupByRegex("androidx.*")
|
||||
}
|
||||
}
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
@ -17,6 +20,9 @@ dependencyResolutionManagement {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven("https://jitpack.io")
|
||||
flatDir {
|
||||
dirs("libs")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user