@bigcrunch/react-native-ads 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchAds.kt +434 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchBannerView.kt +484 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchInterstitial.kt +403 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/BigCrunchRewarded.kt +409 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/adapters/GoogleAdsAdapter.kt +592 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/AdOrchestrator.kt +623 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/AnalyticsClient.kt +719 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/BidRequestClient.kt +364 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/ConfigManager.kt +300 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/DeviceContext.kt +385 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/RewardedCallback.kt +42 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/core/SessionManager.kt +330 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/DeviceHelper.kt +60 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/HttpClient.kt +114 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/Logger.kt +71 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/PrivacyStore.kt +125 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/internal/Storage.kt +88 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/BannerAdListener.kt +55 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/InterstitialAdListener.kt +55 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/listeners/RewardedAdListener.kt +58 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/AdEvent.kt +880 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/AppConfig.kt +87 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/DeviceData.kt +18 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/PlacementConfig.kt +70 -0
- package/android/bigcrunch-ads/com/bigcrunch/ads/models/SessionInfo.kt +21 -0
- package/android/build.gradle +22 -10
- package/android/settings.gradle +2 -6
- package/android/src/main/java/com/bigcrunch/ads/react/BigCrunchAdsModule.kt +8 -2
- package/ios/BigCrunchAds/Sources/Adapters/GoogleAdsAdapter.swift +512 -0
- package/ios/BigCrunchAds/Sources/BigCrunchAds.swift +387 -0
- package/ios/BigCrunchAds/Sources/BigCrunchBannerView.swift +448 -0
- package/ios/BigCrunchAds/Sources/BigCrunchInterstitial.swift +412 -0
- package/ios/BigCrunchAds/Sources/BigCrunchRewarded.swift +523 -0
- package/ios/BigCrunchAds/Sources/Core/AdOrchestrator.swift +514 -0
- package/ios/BigCrunchAds/Sources/Core/AnalyticsClient.swift +874 -0
- package/ios/BigCrunchAds/Sources/Core/BidRequestClient.swift +344 -0
- package/ios/BigCrunchAds/Sources/Core/ConfigManager.swift +305 -0
- package/ios/BigCrunchAds/Sources/Core/DeviceContext.swift +284 -0
- package/ios/BigCrunchAds/Sources/Core/SessionManager.swift +392 -0
- package/ios/BigCrunchAds/Sources/Internal/HTTPClient.swift +146 -0
- package/ios/BigCrunchAds/Sources/Internal/Logger.swift +62 -0
- package/ios/BigCrunchAds/Sources/Internal/PrivacyStore.swift +129 -0
- package/ios/BigCrunchAds/Sources/Internal/Storage.swift +73 -0
- package/ios/BigCrunchAds/Sources/Models/AdEvent.swift +784 -0
- package/ios/BigCrunchAds/Sources/Models/AppConfig.swift +97 -0
- package/ios/BigCrunchAds/Sources/Models/DeviceData.swift +68 -0
- package/ios/BigCrunchAds/Sources/Models/PlacementConfig.swift +137 -0
- package/ios/BigCrunchAds/Sources/Models/SessionInfo.swift +48 -0
- package/ios/BigCrunchAdsModule.swift +37 -9
- package/ios/BigCrunchBannerViewManager.swift +0 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -2
- package/package.json +7 -1
- package/react-native-bigcrunch-ads.podspec +0 -1
- package/scripts/inject-version.js +55 -0
- package/src/index.ts +3 -2
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# BigCrunch Mobile Ads SDK for React Native
|
|
2
2
|
|
|
3
|
-
Simplified in-app advertising for React Native apps with
|
|
3
|
+
Simplified in-app advertising for React Native apps with S2S demand and Google Ad Manager integration.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Simple Integration**: One SDK to handle
|
|
7
|
+
- **Simple Integration**: One SDK to handle S2S demand, Google Ad Manager, and Amazon integration
|
|
8
8
|
- **Built-in Analytics**: Automatic tracking of screen views, impressions, clicks, and revenue
|
|
9
|
-
- **Revenue Optimization**: Server-side header bidding via
|
|
9
|
+
- **Revenue Optimization**: Server-side header bidding via BigCrunch S2S
|
|
10
10
|
- **Configuration-Driven**: Manage placements and ad sizes from the BigCrunch dashboard
|
|
11
11
|
- **Cross-Platform**: Supports both iOS and Android
|
|
12
12
|
- **Ad Formats**: Banner, Interstitial, and Rewarded ads
|
|
@@ -137,7 +137,7 @@ function ArticleScreen() {
|
|
|
137
137
|
| Prop | Type | Default | Description |
|
|
138
138
|
|------|------|---------|-------------|
|
|
139
139
|
| `placementId` | `string` | *required* | Placement ID from the BigCrunch dashboard |
|
|
140
|
-
| `size` | `BannerSize \| { width, height }` |
|
|
140
|
+
| `size` | `BannerSize \| { width, height }` | `'BANNER'` | Banner size. Defaults to standard 320x50. |
|
|
141
141
|
| `autoLoad` | `boolean` | `true` | Automatically load ad on mount |
|
|
142
142
|
| `refreshInterval` | `number` | `0` | Auto-refresh interval in seconds (0 = disabled) |
|
|
143
143
|
| `customTargeting` | `Record<string, string>` | — | Custom key-value targeting |
|
|
@@ -316,7 +316,7 @@ console.log('SDK initialized:', isReady);
|
|
|
316
316
|
// Get session information
|
|
317
317
|
const session = await BigCrunchAds.getSessionInfo();
|
|
318
318
|
console.log('Session ID:', session.sessionId);
|
|
319
|
-
console.log('
|
|
319
|
+
console.log('Session depth:', session.sessionDepth);
|
|
320
320
|
|
|
321
321
|
// Enable debug logging during development
|
|
322
322
|
await BigCrunchAds.setDebugMode(true);
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
package com.bigcrunch.ads
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import com.bigcrunch.ads.core.AnalyticsClient
|
|
5
|
+
import com.bigcrunch.ads.core.BidRequestClient
|
|
6
|
+
import com.bigcrunch.ads.core.ConfigManager
|
|
7
|
+
import com.bigcrunch.ads.core.SessionManager
|
|
8
|
+
import com.bigcrunch.ads.internal.BCLogger
|
|
9
|
+
import com.bigcrunch.ads.internal.DeviceHelper
|
|
10
|
+
import com.bigcrunch.ads.internal.HttpClient
|
|
11
|
+
import com.bigcrunch.ads.internal.PrivacyStore
|
|
12
|
+
import com.bigcrunch.ads.internal.SharedPreferencesStore
|
|
13
|
+
import com.bigcrunch.ads.models.AppConfig
|
|
14
|
+
import com.bigcrunch.ads.models.DeviceData
|
|
15
|
+
import com.bigcrunch.ads.models.SessionInfo
|
|
16
|
+
import com.google.android.gms.ads.MobileAds
|
|
17
|
+
import com.google.android.gms.ads.RequestConfiguration
|
|
18
|
+
import com.squareup.moshi.Moshi
|
|
19
|
+
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
|
20
|
+
import kotlinx.coroutines.CoroutineScope
|
|
21
|
+
import kotlinx.coroutines.Dispatchers
|
|
22
|
+
import kotlinx.coroutines.SupervisorJob
|
|
23
|
+
import kotlinx.coroutines.launch
|
|
24
|
+
import kotlinx.coroutines.CompletableDeferred
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* BigCrunch Mobile Ads SDK - Main entry point
|
|
28
|
+
*
|
|
29
|
+
* Initialize the SDK before using any ad components:
|
|
30
|
+
* ```
|
|
31
|
+
* BigCrunchAds.initialize(
|
|
32
|
+
* context = applicationContext,
|
|
33
|
+
* propertyId = "your-property-id"
|
|
34
|
+
* )
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
object BigCrunchAds {
|
|
38
|
+
|
|
39
|
+
private const val TAG = "BigCrunchAds"
|
|
40
|
+
|
|
41
|
+
enum class Environment {
|
|
42
|
+
Prod, Staging
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Safely execute a block of code, catching any exceptions to prevent SDK errors
|
|
47
|
+
* from crashing the host app. Used for public API methods.
|
|
48
|
+
*/
|
|
49
|
+
private inline fun <T> runSafely(default: T, block: () -> T): T {
|
|
50
|
+
return try {
|
|
51
|
+
block()
|
|
52
|
+
} catch (e: Exception) {
|
|
53
|
+
BCLogger.e(TAG, "SDK exception caught - will not propagate to prevent app crash", e)
|
|
54
|
+
default
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Safely execute a Unit-returning block, catching any exceptions.
|
|
60
|
+
*/
|
|
61
|
+
private inline fun runSafely(block: () -> Unit) {
|
|
62
|
+
try {
|
|
63
|
+
block()
|
|
64
|
+
} catch (e: Exception) {
|
|
65
|
+
BCLogger.e(TAG, "SDK exception caught - will not propagate to prevent app crash", e)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private var initialized = false
|
|
70
|
+
private var configReady = false
|
|
71
|
+
private val configDeferred = CompletableDeferred<Boolean>()
|
|
72
|
+
private lateinit var appContext: Context
|
|
73
|
+
private lateinit var configManager: ConfigManager
|
|
74
|
+
private lateinit var analyticsClient: AnalyticsClient
|
|
75
|
+
private val initScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
|
|
76
|
+
private var debugMode = false
|
|
77
|
+
private val testDeviceIds = mutableSetOf<String>()
|
|
78
|
+
internal lateinit var privacyStore: PrivacyStore
|
|
79
|
+
private set
|
|
80
|
+
internal var bidRequestClient: BidRequestClient? = null
|
|
81
|
+
private set
|
|
82
|
+
|
|
83
|
+
internal var propertyId: String = ""
|
|
84
|
+
private set
|
|
85
|
+
internal var environment: Environment = Environment.Prod
|
|
86
|
+
private set
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Callback interface for SDK initialization completion
|
|
90
|
+
*/
|
|
91
|
+
interface InitializationCallback {
|
|
92
|
+
/**
|
|
93
|
+
* Called when SDK initialization is complete and config is ready
|
|
94
|
+
*/
|
|
95
|
+
fun onInitialized()
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Called if SDK initialization fails
|
|
99
|
+
* @param error Error message describing the failure
|
|
100
|
+
*/
|
|
101
|
+
fun onInitializationFailed(error: String)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Initialize the BigCrunch Ads SDK
|
|
106
|
+
*
|
|
107
|
+
* @param context Application context
|
|
108
|
+
* @param propertyId Your BigCrunch property ID
|
|
109
|
+
* @param env Environment (Prod or Staging)
|
|
110
|
+
* @param useMockConfig If true, uses hardcoded mock config for testing (default: false)
|
|
111
|
+
* @param callback Optional callback to be notified when initialization is complete
|
|
112
|
+
*/
|
|
113
|
+
fun initialize(
|
|
114
|
+
context: Context,
|
|
115
|
+
propertyId: String,
|
|
116
|
+
env: Environment = Environment.Prod,
|
|
117
|
+
useMockConfig: Boolean = false,
|
|
118
|
+
callback: InitializationCallback? = null
|
|
119
|
+
) {
|
|
120
|
+
if (initialized) {
|
|
121
|
+
BCLogger.w("BigCrunchAds", "SDK already initialized, ignoring duplicate call")
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
BCLogger.i("BigCrunchAds", "BigCrunch Ads SDK v${com.bigcrunch.ads.core.DeviceContext.SDK_VERSION} initializing...")
|
|
126
|
+
BCLogger.d("BigCrunchAds", "Property ID: $propertyId, Environment: $env")
|
|
127
|
+
|
|
128
|
+
// Store initialization parameters
|
|
129
|
+
this.appContext = context.applicationContext
|
|
130
|
+
this.propertyId = propertyId
|
|
131
|
+
this.environment = env
|
|
132
|
+
|
|
133
|
+
// Initialize Google Mobile Ads SDK
|
|
134
|
+
BCLogger.d("BigCrunchAds", "Initializing Google Mobile Ads SDK...")
|
|
135
|
+
MobileAds.initialize(appContext) { initStatus ->
|
|
136
|
+
BCLogger.d("BigCrunchAds", "Google Mobile Ads initialized: ${initStatus.adapterStatusMap}")
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Initialize device context FIRST - must be done synchronously before anything else
|
|
140
|
+
BCLogger.d("BigCrunchAds", "Initializing device context...")
|
|
141
|
+
com.bigcrunch.ads.core.DeviceContext.initialize(appContext)
|
|
142
|
+
|
|
143
|
+
// Enable verbose logging in staging
|
|
144
|
+
if (env == Environment.Staging) {
|
|
145
|
+
BCLogger.isEnabled = true
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Create internal components
|
|
149
|
+
val httpClient = HttpClient()
|
|
150
|
+
val storage = SharedPreferencesStore(appContext)
|
|
151
|
+
val moshi = Moshi.Builder()
|
|
152
|
+
.add(KotlinJsonAdapterFactory())
|
|
153
|
+
.build()
|
|
154
|
+
|
|
155
|
+
// Initialize session manager
|
|
156
|
+
BCLogger.d("BigCrunchAds", "Initializing session manager...")
|
|
157
|
+
SessionManager.initialize(storage)
|
|
158
|
+
|
|
159
|
+
// Analytics always uses pipeline.bigcrunch.com for both prod and staging
|
|
160
|
+
val baseUrl = "https://pipeline.bigcrunch.com"
|
|
161
|
+
|
|
162
|
+
configManager = ConfigManager(httpClient, storage, moshi)
|
|
163
|
+
analyticsClient = AnalyticsClient(appContext, httpClient, moshi, baseUrl)
|
|
164
|
+
privacyStore = PrivacyStore(appContext)
|
|
165
|
+
|
|
166
|
+
// Mark as initialized (but not config ready yet)
|
|
167
|
+
initialized = true
|
|
168
|
+
|
|
169
|
+
// Kick off async config fetch
|
|
170
|
+
BCLogger.d("BigCrunchAds", "Fetching app configuration...")
|
|
171
|
+
initScope.launch {
|
|
172
|
+
val result = configManager.loadConfig(
|
|
173
|
+
propertyId = propertyId,
|
|
174
|
+
isProd = env == Environment.Prod,
|
|
175
|
+
useMockConfig = useMockConfig
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
when {
|
|
179
|
+
result.isSuccess -> {
|
|
180
|
+
val config = result.getOrNull()
|
|
181
|
+
if (config == null) {
|
|
182
|
+
BCLogger.e(TAG, "Config was null despite success result")
|
|
183
|
+
configDeferred.complete(false)
|
|
184
|
+
callback?.onInitializationFailed("Internal error: config was null")
|
|
185
|
+
return@launch
|
|
186
|
+
}
|
|
187
|
+
BCLogger.d(TAG, "Configuration loaded successfully")
|
|
188
|
+
BCLogger.v(TAG, "Placements: ${config.placements.size}")
|
|
189
|
+
|
|
190
|
+
// Create shared BidRequestClient for S2S demand
|
|
191
|
+
if (config.s2s.enabled) {
|
|
192
|
+
bidRequestClient = BidRequestClient(
|
|
193
|
+
httpClient = httpClient,
|
|
194
|
+
configManager = configManager,
|
|
195
|
+
privacyStore = privacyStore,
|
|
196
|
+
s2sConfig = config.s2s
|
|
197
|
+
)
|
|
198
|
+
BCLogger.d(TAG, "BidRequestClient created: ${config.s2s.serverUrl}")
|
|
199
|
+
} else {
|
|
200
|
+
BCLogger.d(TAG, "S2S is disabled in config")
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Mark config as ready and complete the deferred
|
|
204
|
+
configReady = true
|
|
205
|
+
configDeferred.complete(true)
|
|
206
|
+
|
|
207
|
+
// Notify callback of successful initialization
|
|
208
|
+
callback?.onInitialized()
|
|
209
|
+
}
|
|
210
|
+
result.isFailure -> {
|
|
211
|
+
val error = result.exceptionOrNull()?.message ?: "Unknown error"
|
|
212
|
+
BCLogger.e(TAG, "Failed to load configuration", result.exceptionOrNull())
|
|
213
|
+
// Complete the deferred even on failure so waiters don't hang
|
|
214
|
+
configDeferred.complete(false)
|
|
215
|
+
|
|
216
|
+
// Notify callback of initialization failure
|
|
217
|
+
callback?.onInitializationFailed(error)
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
BCLogger.d("BigCrunchAds", "BigCrunch Ads SDK initialization complete")
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Track screen view for analytics
|
|
227
|
+
*
|
|
228
|
+
* @param screenName Name of the screen being viewed
|
|
229
|
+
*/
|
|
230
|
+
fun trackScreen(screenName: String) = runSafely {
|
|
231
|
+
if (!initialized) {
|
|
232
|
+
BCLogger.w(TAG, "trackScreen called before initialization, ignoring")
|
|
233
|
+
return@runSafely
|
|
234
|
+
}
|
|
235
|
+
analyticsClient.trackScreenView(screenName)
|
|
236
|
+
SessionManager.incrementScreenViewCount()
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Track screen view for analytics (alias for React Native compatibility)
|
|
241
|
+
*
|
|
242
|
+
* @param screenName Name of the screen being viewed
|
|
243
|
+
*/
|
|
244
|
+
fun trackScreenView(screenName: String) = runSafely {
|
|
245
|
+
trackScreen(screenName)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Check if the SDK has been initialized
|
|
250
|
+
*
|
|
251
|
+
* @return true if initialized, false otherwise
|
|
252
|
+
*/
|
|
253
|
+
fun isInitialized(): Boolean = initialized
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Check if configuration has been loaded
|
|
257
|
+
*
|
|
258
|
+
* @return true if configuration has been successfully loaded
|
|
259
|
+
*/
|
|
260
|
+
fun isConfigReady(): Boolean = configReady
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Wait for configuration to be loaded
|
|
264
|
+
*
|
|
265
|
+
* This suspends until the configuration is loaded or fails to load.
|
|
266
|
+
* Returns true if config loaded successfully, false otherwise.
|
|
267
|
+
*
|
|
268
|
+
* @return true if configuration loaded successfully
|
|
269
|
+
*/
|
|
270
|
+
suspend fun waitForConfig(): Boolean {
|
|
271
|
+
return configDeferred.await()
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Get the current app configuration
|
|
276
|
+
*
|
|
277
|
+
* @return The app configuration, or null if not yet loaded
|
|
278
|
+
*/
|
|
279
|
+
fun getAppConfig(): AppConfig? {
|
|
280
|
+
return if (initialized) {
|
|
281
|
+
configManager.getCachedConfig()
|
|
282
|
+
} else {
|
|
283
|
+
null
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Refresh the app configuration from the server
|
|
289
|
+
*/
|
|
290
|
+
suspend fun refreshConfig() {
|
|
291
|
+
if (!initialized) {
|
|
292
|
+
BCLogger.w("BigCrunchAds", "refreshConfig called before initialization")
|
|
293
|
+
return
|
|
294
|
+
}
|
|
295
|
+
configManager.loadConfig(
|
|
296
|
+
propertyId = propertyId,
|
|
297
|
+
isProd = environment == Environment.Prod,
|
|
298
|
+
useMockConfig = false
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Get current session information
|
|
304
|
+
*
|
|
305
|
+
* @return Session info with tracking counts
|
|
306
|
+
*/
|
|
307
|
+
fun getSessionInfo(): SessionInfo {
|
|
308
|
+
return SessionInfo(
|
|
309
|
+
sessionId = SessionManager.getSessionId(),
|
|
310
|
+
startTime = SessionManager.getSessionStartTime(),
|
|
311
|
+
screenViewCount = SessionManager.getScreenViewCount(),
|
|
312
|
+
adRequestCount = SessionManager.getAdRequestCount(),
|
|
313
|
+
adImpressionCount = SessionManager.getAdImpressionCount(),
|
|
314
|
+
totalRevenueMicros = SessionManager.getTotalRevenueMicros()
|
|
315
|
+
)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Start a new session (resets all counters)
|
|
320
|
+
*/
|
|
321
|
+
fun startNewSession() {
|
|
322
|
+
SessionManager.startNewSession()
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Get device data
|
|
327
|
+
*
|
|
328
|
+
* @return Device data with device information
|
|
329
|
+
*/
|
|
330
|
+
fun getDeviceData(): DeviceData? = runSafely(null) {
|
|
331
|
+
requireInitialized()
|
|
332
|
+
DeviceHelper.getDeviceData(appContext)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Set GDPR consent string for privacy compliance
|
|
337
|
+
*
|
|
338
|
+
* @param consent GDPR consent string
|
|
339
|
+
*/
|
|
340
|
+
fun setGdprConsent(consent: String) = runSafely {
|
|
341
|
+
privacyStore.setGdprConsent(consent)
|
|
342
|
+
BCLogger.d(TAG, "GDPR consent set")
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Set CCPA string for privacy compliance
|
|
347
|
+
*
|
|
348
|
+
* @param ccpaString CCPA consent string
|
|
349
|
+
*/
|
|
350
|
+
fun setCcpaString(ccpaString: String) = runSafely {
|
|
351
|
+
privacyStore.setCcpaString(ccpaString)
|
|
352
|
+
BCLogger.d(TAG, "CCPA string set: $ccpaString")
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Set COPPA compliance flag
|
|
357
|
+
*
|
|
358
|
+
* @param isCompliant true if the app should comply with COPPA
|
|
359
|
+
*/
|
|
360
|
+
fun setCoppaCompliant(isCompliant: Boolean) = runSafely {
|
|
361
|
+
privacyStore.setCoppaApplies(isCompliant)
|
|
362
|
+
val config = RequestConfiguration.Builder()
|
|
363
|
+
.setTagForChildDirectedTreatment(
|
|
364
|
+
if (isCompliant) RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_TRUE
|
|
365
|
+
else RequestConfiguration.TAG_FOR_CHILD_DIRECTED_TREATMENT_FALSE
|
|
366
|
+
)
|
|
367
|
+
.build()
|
|
368
|
+
MobileAds.setRequestConfiguration(config)
|
|
369
|
+
BCLogger.d(TAG, "COPPA compliance set to: $isCompliant")
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Enable or disable debug mode
|
|
374
|
+
*
|
|
375
|
+
* @param enabled true to enable debug logging
|
|
376
|
+
*/
|
|
377
|
+
fun setDebugMode(enabled: Boolean) = runSafely {
|
|
378
|
+
debugMode = enabled
|
|
379
|
+
BCLogger.isEnabled = enabled
|
|
380
|
+
BCLogger.d(TAG, "Debug mode set to: $enabled")
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Add a test device ID for Google Ads testing
|
|
385
|
+
*
|
|
386
|
+
* @param deviceId Test device ID from Google Ads logs
|
|
387
|
+
*/
|
|
388
|
+
fun addTestDevice(deviceId: String) = runSafely {
|
|
389
|
+
testDeviceIds.add(deviceId)
|
|
390
|
+
updateTestDeviceConfiguration()
|
|
391
|
+
BCLogger.d(TAG, "Added test device: $deviceId")
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Remove a test device ID
|
|
396
|
+
*
|
|
397
|
+
* @param deviceId Test device ID to remove
|
|
398
|
+
*/
|
|
399
|
+
fun removeTestDevice(deviceId: String) = runSafely {
|
|
400
|
+
testDeviceIds.remove(deviceId)
|
|
401
|
+
updateTestDeviceConfiguration()
|
|
402
|
+
BCLogger.d(TAG, "Removed test device: $deviceId")
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Get list of test device IDs
|
|
407
|
+
*
|
|
408
|
+
* @return List of currently configured test device IDs
|
|
409
|
+
*/
|
|
410
|
+
fun getTestDevices(): List<String> = testDeviceIds.toList()
|
|
411
|
+
|
|
412
|
+
private fun updateTestDeviceConfiguration() {
|
|
413
|
+
val config = RequestConfiguration.Builder()
|
|
414
|
+
.setTestDeviceIds(testDeviceIds.toList())
|
|
415
|
+
.build()
|
|
416
|
+
MobileAds.setRequestConfiguration(config)
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
internal fun requireInitialized() {
|
|
420
|
+
check(initialized) {
|
|
421
|
+
"BigCrunchAds SDK not initialized. Call BigCrunchAds.initialize() first."
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
internal fun getConfigManager(): ConfigManager {
|
|
426
|
+
requireInitialized()
|
|
427
|
+
return configManager
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
internal fun getAnalyticsClient(): AnalyticsClient {
|
|
431
|
+
requireInitialized()
|
|
432
|
+
return analyticsClient
|
|
433
|
+
}
|
|
434
|
+
}
|