添加参数上传,添加admob广告封装。
This commit is contained in:
parent
135ec734db
commit
e714a1ef63
@ -84,6 +84,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(files("libs/UpLoadLibrary_11_24_18_30-release.aar"))
|
||||||
implementation(libs.androidx.fragment.ktx)
|
implementation(libs.androidx.fragment.ktx)
|
||||||
implementation(libs.androidx.appcompat)
|
implementation(libs.androidx.appcompat)
|
||||||
implementation(libs.androidx.core.ktx)
|
implementation(libs.androidx.core.ktx)
|
||||||
@ -112,4 +113,11 @@ dependencies {
|
|||||||
implementation(platform("com.google.firebase:firebase-bom:34.6.0"))
|
implementation(platform("com.google.firebase:firebase-bom:34.6.0"))
|
||||||
implementation("com.google.firebase:firebase-crashlytics-ndk")
|
implementation("com.google.firebase:firebase-crashlytics-ndk")
|
||||||
implementation("com.google.firebase:firebase-analytics")
|
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:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
|
android:networkSecurityConfig="@xml/net"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.PDFReaderPro">
|
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
|
<meta-data
|
||||||
android:name="android.max_aspect"
|
android:name="android.max_aspect"
|
||||||
android:value="2.4" />
|
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.room.repository.PdfRepository
|
||||||
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
|
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
|
||||||
import com.all.pdfreader.pdf.reader.util.FileChangeObserver
|
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.tom_roush.pdfbox.android.PDFBoxResourceLoader
|
||||||
|
import com.up.uploadlibrary.UpLoadManager
|
||||||
|
|
||||||
class PRApp : Application() {
|
class PRApp : Application() {
|
||||||
|
|
||||||
@ -39,10 +42,20 @@ class PRApp : Application() {
|
|||||||
PdfRepository.initialize(this)
|
PdfRepository.initialize(this)
|
||||||
// 初始化pdfbox
|
// 初始化pdfbox
|
||||||
PDFBoxResourceLoader.init(this)
|
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() {
|
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 android.os.Bundle
|
||||||
import com.all.pdfreader.pdf.reader.BuildConfig
|
import com.all.pdfreader.pdf.reader.BuildConfig
|
||||||
|
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil
|
||||||
import com.google.firebase.Firebase
|
import com.google.firebase.Firebase
|
||||||
import com.google.firebase.analytics.FirebaseAnalytics
|
import com.google.firebase.analytics.FirebaseAnalytics
|
||||||
import com.google.firebase.analytics.analytics
|
import com.google.firebase.analytics.analytics
|
||||||
@ -97,8 +98,35 @@ object AnalyticsUtils {
|
|||||||
const val KEEP_SCREEN_CLOSE = "keep_screen_close" // 点击关闭(keep_screen_close)
|
const val KEEP_SCREEN_CLOSE = "keep_screen_close" // 点击关闭(keep_screen_close)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** param 常量 */
|
/** param 常量(可扩展) */
|
||||||
object 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 {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
google {
|
google {
|
||||||
@ -7,6 +9,7 @@ pluginManagement {
|
|||||||
includeGroupByRegex("androidx.*")
|
includeGroupByRegex("androidx.*")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
@ -17,6 +20,9 @@ dependencyResolutionManagement {
|
|||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
|
flatDir {
|
||||||
|
dirs("libs")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user