adwhale-sdk-react-native 2.7.204 → 2.7.300
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/AdwhaleSdkReactNative.podspec +22 -0
- package/README.md +80 -37
- package/android/proguard-rules.pro +56 -0
- package/android/src/main/java/com/adwhalesdkreactnative/AdWhaleCustomNativeBinderFactory.java +18 -0
- package/android/src/main/java/com/adwhalesdkreactnative/AdwhaleSdkReactNativePackage.java +51 -6
- package/android/src/main/java/com/adwhalesdkreactnative/BinderFactory.java +9 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAdSettingModule.java +148 -49
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAdView.java +46 -27
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationAppOpenAd.java +136 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationCustomNativeAdView.java +37 -46
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationExitPopupAd.java +240 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationInterstitialAd.java +189 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationLoggerModule.java +2 -1
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationNativeAdViewListenerBridge.java +83 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationRewardAd.java +255 -6
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationTemplateNativeAdView.java +191 -70
- package/android/src/main/java/com/adwhalesdkreactnative/RNAdWhaleMediationTransitionPopupAd.java +218 -0
- package/android/src/main/java/com/adwhalesdkreactnative/RNWrapperView.java +137 -0
- package/android/src/main/java/com/adwhalesdkreactnative/SimpleBinderFactory.java +1 -1
- package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodArgConst.java +112 -0
- package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodCallConst.java +113 -0
- package/android/src/main/java/com/adwhalesdkreactnative/common/RNMethodResultConst.java +28 -0
- package/build/generated/ios/ReactAppDependencyProvider.podspec +34 -0
- package/ios/AdWhaleNativeCustomViewFactoryRegistry.swift +56 -0
- package/ios/AdwhaleSdkReactNative.mm +96 -5
- package/ios/AdwhaleSdkReactNativeModule.swift +148 -0
- package/ios/RNAdWhaleMediationAdViewManager.m +38 -0
- package/ios/RNAdWhaleMediationAdViewManager.swift +14 -0
- package/ios/RNAdWhaleMediationAppOpenAd.m +18 -0
- package/ios/RNAdWhaleMediationAppOpenAd.swift +175 -0
- package/ios/RNAdWhaleMediationCustomNativeAdViewManager.m +22 -0
- package/ios/RNAdWhaleMediationCustomNativeAdViewManager.swift +239 -0
- package/ios/RNAdWhaleMediationInterstitialAd.m +18 -0
- package/ios/RNAdWhaleMediationInterstitialAd.swift +161 -0
- package/ios/RNAdWhaleMediationRewardAd.m +18 -0
- package/ios/RNAdWhaleMediationRewardAd.swift +172 -0
- package/ios/WhaleMediationBannerContainer.swift +182 -0
- package/lib/module/AdWhaleAdView.js +58 -3
- package/lib/module/AdWhaleAdView.js.map +1 -1
- package/lib/module/AdWhaleAppOpenAd.js +223 -25
- package/lib/module/AdWhaleAppOpenAd.js.map +1 -1
- package/lib/module/AdWhaleExitPopupAd.js +93 -0
- package/lib/module/AdWhaleExitPopupAd.js.map +1 -0
- package/lib/module/AdWhaleInterstitialAd.js +146 -22
- package/lib/module/AdWhaleInterstitialAd.js.map +1 -1
- package/lib/module/AdWhaleMediationAds.js +75 -4
- package/lib/module/AdWhaleMediationAds.js.map +1 -1
- package/lib/module/AdWhaleNativeCustomView.js +59 -8
- package/lib/module/AdWhaleNativeCustomView.js.map +1 -1
- package/lib/module/AdWhaleNativeTemplateView.js +37 -19
- package/lib/module/AdWhaleNativeTemplateView.js.map +1 -1
- package/lib/module/AdWhaleRewardAd.js +169 -24
- package/lib/module/AdWhaleRewardAd.js.map +1 -1
- package/lib/module/AdWhaleTransitionPopupAd.js +87 -0
- package/lib/module/AdWhaleTransitionPopupAd.js.map +1 -0
- package/lib/module/NativeAdwhaleSdkReactNative.js +16 -1
- package/lib/module/NativeAdwhaleSdkReactNative.js.map +1 -1
- package/lib/module/constants/AdWhaleMethodArgConst.js +53 -0
- package/lib/module/constants/AdWhaleMethodArgConst.js.map +1 -0
- package/lib/module/constants/AdWhaleMethodCallConst.js +56 -0
- package/lib/module/constants/AdWhaleMethodCallConst.js.map +1 -0
- package/lib/module/constants/AdWhaleMethodResultConst.js +16 -0
- package/lib/module/constants/AdWhaleMethodResultConst.js.map +1 -0
- package/lib/module/index.js +10 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/AdWhaleAdView.d.ts +20 -2
- package/lib/typescript/src/AdWhaleAdView.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleAppOpenAd.d.ts +10 -0
- package/lib/typescript/src/AdWhaleAppOpenAd.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleExitPopupAd.d.ts +36 -0
- package/lib/typescript/src/AdWhaleExitPopupAd.d.ts.map +1 -0
- package/lib/typescript/src/AdWhaleInterstitialAd.d.ts +16 -0
- package/lib/typescript/src/AdWhaleInterstitialAd.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleMediationAds.d.ts +13 -5
- package/lib/typescript/src/AdWhaleMediationAds.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleNativeCustomView.d.ts +7 -4
- package/lib/typescript/src/AdWhaleNativeCustomView.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleNativeTemplateView.d.ts +20 -7
- package/lib/typescript/src/AdWhaleNativeTemplateView.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleRewardAd.d.ts +18 -2
- package/lib/typescript/src/AdWhaleRewardAd.d.ts.map +1 -1
- package/lib/typescript/src/AdWhaleTransitionPopupAd.d.ts +33 -0
- package/lib/typescript/src/AdWhaleTransitionPopupAd.d.ts.map +1 -0
- package/lib/typescript/src/NativeAdwhaleSdkReactNative.d.ts +28 -6
- package/lib/typescript/src/NativeAdwhaleSdkReactNative.d.ts.map +1 -1
- package/lib/typescript/src/constants/AdWhaleMethodArgConst.d.ts +51 -0
- package/lib/typescript/src/constants/AdWhaleMethodArgConst.d.ts.map +1 -0
- package/lib/typescript/src/constants/AdWhaleMethodCallConst.d.ts +53 -0
- package/lib/typescript/src/constants/AdWhaleMethodCallConst.d.ts.map +1 -0
- package/lib/typescript/src/constants/AdWhaleMethodResultConst.d.ts +14 -0
- package/lib/typescript/src/constants/AdWhaleMethodResultConst.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +9 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/AdWhaleAdView.tsx +92 -4
- package/src/AdWhaleAppOpenAd.ts +293 -38
- package/src/AdWhaleExitPopupAd.ts +183 -0
- package/src/AdWhaleInterstitialAd.ts +206 -36
- package/src/AdWhaleMediationAds.ts +108 -4
- package/src/AdWhaleNativeCustomView.tsx +85 -23
- package/src/AdWhaleNativeTemplateView.tsx +79 -42
- package/src/AdWhaleRewardAd.ts +245 -43
- package/src/AdWhaleTransitionPopupAd.ts +171 -0
- package/src/NativeAdwhaleSdkReactNative.ts +30 -6
- package/src/constants/AdWhaleMethodArgConst.ts +50 -0
- package/src/constants/AdWhaleMethodCallConst.ts +60 -0
- package/src/constants/AdWhaleMethodResultConst.ts +13 -0
- package/src/index.ts +33 -0
|
@@ -4,6 +4,7 @@ import android.util.Log;
|
|
|
4
4
|
|
|
5
5
|
import androidx.annotation.NonNull;
|
|
6
6
|
|
|
7
|
+
import com.adwhalesdkreactnative.common.RNMethodResultConst;
|
|
7
8
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
9
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
9
10
|
import com.facebook.react.bridge.ReactMethod;
|
|
@@ -43,7 +44,7 @@ public class RNAdWhaleMediationLoggerModule extends ReactContextBaseJavaModule {
|
|
|
43
44
|
promise.resolve(logLevelString);
|
|
44
45
|
} catch (Exception e) {
|
|
45
46
|
Log.e(REACT_CLASS_NAME, "로그 레벨 조회 실패", e);
|
|
46
|
-
promise.reject(
|
|
47
|
+
promise.reject(RNMethodResultConst.GET_LOG_LEVEL_ERROR, "Failed to get log level", e);
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
package com.adwhalesdkreactnative;
|
|
2
|
+
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
import androidx.annotation.Nullable;
|
|
7
|
+
|
|
8
|
+
import com.adwhalesdkreactnative.common.RNMethodArgConst;
|
|
9
|
+
import com.adwhalesdkreactnative.common.RNMethodCallConst;
|
|
10
|
+
import com.facebook.react.bridge.Arguments;
|
|
11
|
+
import com.facebook.react.bridge.WritableMap;
|
|
12
|
+
|
|
13
|
+
import net.adwhale.sdk.mediation.ads.AdWhaleMediationNativeAdViewListener;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* {@link AdWhaleMediationNativeAdViewListener} 단일 구현체.
|
|
17
|
+
* Flutter {@code FlutterNativeTemplateAd} / {@code FlutterNativeBinderAd}와 동일하게
|
|
18
|
+
* 모든 콜백을 동일한 이벤트 이름({@link RNMethodCallConst#ON_NATIVE_AD_*})으로 정규화합니다.
|
|
19
|
+
*/
|
|
20
|
+
public final class RNAdWhaleMediationNativeAdViewListenerBridge implements AdWhaleMediationNativeAdViewListener {
|
|
21
|
+
|
|
22
|
+
/** Flutter {@link net.adwhale.sdk.adwhale_sdk_flutter.nativeads.FlutterNativeBinderAd} 와 동일. */
|
|
23
|
+
public static final int NATIVE_BINDER_CONFIGURATION_ERROR_CODE = 300;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 네이티브 → JS 로 이벤트를 보낼 때 사용. Flutter AdWhaleAdInstanceManager 의 emit 과 대응.
|
|
27
|
+
*/
|
|
28
|
+
public interface Emitter {
|
|
29
|
+
void emit(@NonNull String eventName, @Nullable WritableMap payload);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@NonNull private final String logTag;
|
|
33
|
+
@NonNull private final Emitter emitter;
|
|
34
|
+
|
|
35
|
+
public RNAdWhaleMediationNativeAdViewListenerBridge(
|
|
36
|
+
@NonNull String logTag,
|
|
37
|
+
@NonNull Emitter emitter) {
|
|
38
|
+
this.logTag = logTag;
|
|
39
|
+
this.emitter = emitter;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@NonNull
|
|
43
|
+
public static WritableMap createErrorPayload(int statusCode, @Nullable String message) {
|
|
44
|
+
WritableMap m = Arguments.createMap();
|
|
45
|
+
m.putInt(RNMethodArgConst.SEND_STATUS_CODE, statusCode);
|
|
46
|
+
m.putString(RNMethodArgConst.SEND_MESSAGE, message != null ? message : "");
|
|
47
|
+
return m;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@Override
|
|
51
|
+
public void onNativeAdLoaded() {
|
|
52
|
+
Log.d(logTag, "onNativeAdLoaded");
|
|
53
|
+
emitter.emit(RNMethodCallConst.ON_NATIVE_AD_LOADED, null);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@Override
|
|
57
|
+
public void onNativeAdFailedToLoad(int errorCode, String errorMessage) {
|
|
58
|
+
Log.d(logTag, "onNativeAdFailedToLoad: " + errorCode + ", " + errorMessage);
|
|
59
|
+
emitter.emit(
|
|
60
|
+
RNMethodCallConst.ON_NATIVE_AD_FAILED_TO_LOAD,
|
|
61
|
+
createErrorPayload(errorCode, errorMessage));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@Override
|
|
65
|
+
public void onNativeAdShowFailed(int errorCode, String errorMessage) {
|
|
66
|
+
Log.d(logTag, "onNativeAdShowFailed: " + errorCode + ", " + errorMessage);
|
|
67
|
+
emitter.emit(
|
|
68
|
+
RNMethodCallConst.ON_NATIVE_AD_SHOW_FAILED,
|
|
69
|
+
createErrorPayload(errorCode, errorMessage));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@Override
|
|
73
|
+
public void onNativeAdClicked() {
|
|
74
|
+
Log.d(logTag, "onNativeAdClicked");
|
|
75
|
+
emitter.emit(RNMethodCallConst.ON_NATIVE_AD_CLICKED, null);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@Override
|
|
79
|
+
public void onNativeAdClosed() {
|
|
80
|
+
Log.d(logTag, "onNativeAdClosed");
|
|
81
|
+
emitter.emit(RNMethodCallConst.ON_NATIVE_AD_CLOSED, null);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package com.adwhalesdkreactnative;
|
|
2
2
|
|
|
3
|
+
import android.app.Activity;
|
|
3
4
|
import android.util.Log;
|
|
4
5
|
|
|
5
6
|
import androidx.annotation.NonNull;
|
|
@@ -10,6 +11,8 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
|
|
10
11
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
11
12
|
import com.facebook.react.bridge.ReactMethod;
|
|
12
13
|
import com.facebook.react.bridge.ReadableMap;
|
|
14
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
15
|
+
import com.facebook.react.bridge.ReadableType;
|
|
13
16
|
import com.facebook.react.bridge.UiThreadUtil;
|
|
14
17
|
import com.facebook.react.bridge.WritableMap;
|
|
15
18
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
@@ -30,6 +33,13 @@ import java.util.Map;
|
|
|
30
33
|
public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule implements AdWhaleMediationRewardedAdLoadCallback, AdWhaleMediationFullScreenContentCallback, AdWhaleMediationUserEarnedRewardListener {
|
|
31
34
|
|
|
32
35
|
public static final String REACT_CLASS_NAME = RNAdWhaleMediationRewardAd.class.getSimpleName();
|
|
36
|
+
|
|
37
|
+
// Flutter와 싱크: adId 기반 멀티 인스턴스 지원
|
|
38
|
+
private final Map<Integer, AdWhaleMediationRewardAd> adsById = new HashMap<>();
|
|
39
|
+
/** 멀티 로드 시 콜백마다 올바른 adId로 onAdEvent 를 보내기 위한 리스너 (공유 this + lastActiveAdId 는 경합) */
|
|
40
|
+
private final Map<Integer, PerAdRewardListener> rewardListenersById = new HashMap<>();
|
|
41
|
+
private int lastActiveAdId = 0;
|
|
42
|
+
|
|
33
43
|
private AdWhaleMediationRewardAd adWhaleMediationRewardAd;
|
|
34
44
|
private String placementUid;
|
|
35
45
|
private String placementName;
|
|
@@ -78,6 +88,7 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
78
88
|
@ReactMethod
|
|
79
89
|
public void loadAd(String placementUid) {
|
|
80
90
|
Log.e(REACT_CLASS_NAME, "loadAd()");
|
|
91
|
+
lastActiveAdId = 0;
|
|
81
92
|
this.placementUid = placementUid;
|
|
82
93
|
adWhaleMediationRewardAd = new AdWhaleMediationRewardAd(placementUid);
|
|
83
94
|
adWhaleMediationRewardAd.setAdWhaleMediationFullScreenContentCallback(this);
|
|
@@ -90,6 +101,70 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
90
101
|
});
|
|
91
102
|
}
|
|
92
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Flutter MethodChannel과 동일 네이밍:
|
|
106
|
+
* loadRewardAd({adId, placementUid, region, gcoder:[lt,lng], placementName})
|
|
107
|
+
*/
|
|
108
|
+
@ReactMethod
|
|
109
|
+
public void loadRewardAd(ReadableMap args) {
|
|
110
|
+
if (args == null) {
|
|
111
|
+
Log.e(REACT_CLASS_NAME, "loadRewardAd args is null");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!args.hasKey("adId") || args.getType("adId") != ReadableType.Number) {
|
|
115
|
+
Log.e(REACT_CLASS_NAME, "loadRewardAd missing adId (number)");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (!args.hasKey("placementUid") || args.getType("placementUid") != ReadableType.String) {
|
|
119
|
+
Log.e(REACT_CLASS_NAME, "loadRewardAd missing placementUid (string)");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
final int adId = args.getInt("adId");
|
|
123
|
+
final String placementUid = args.getString("placementUid");
|
|
124
|
+
|
|
125
|
+
final AdWhaleMediationRewardAd rewardAd = new AdWhaleMediationRewardAd(placementUid);
|
|
126
|
+
final PerAdRewardListener perAdListener = new PerAdRewardListener(adId);
|
|
127
|
+
rewardListenersById.put(adId, perAdListener);
|
|
128
|
+
rewardAd.setAdWhaleMediationFullScreenContentCallback(perAdListener);
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
if (args.hasKey("region") && args.getType("region") == ReadableType.String) {
|
|
132
|
+
String r = args.getString("region");
|
|
133
|
+
if (r != null && !r.isEmpty()) rewardAd.setRegion(r);
|
|
134
|
+
}
|
|
135
|
+
} catch (Throwable t) {
|
|
136
|
+
Log.w(REACT_CLASS_NAME, "setRegion failed: " + t.getMessage());
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
if (args.hasKey("placementName") && args.getType("placementName") == ReadableType.String) {
|
|
141
|
+
String pn = args.getString("placementName");
|
|
142
|
+
if (pn != null && !pn.isEmpty()) rewardAd.setPlacementName(pn);
|
|
143
|
+
}
|
|
144
|
+
} catch (Throwable t) {
|
|
145
|
+
Log.w(REACT_CLASS_NAME, "setPlacementName failed: " + t.getMessage());
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
if (args.hasKey("gcoder") && args.getType("gcoder") == ReadableType.Array) {
|
|
150
|
+
ReadableArray arr = args.getArray("gcoder");
|
|
151
|
+
if (arr != null && arr.size() >= 2
|
|
152
|
+
&& arr.getType(0) == ReadableType.Number
|
|
153
|
+
&& arr.getType(1) == ReadableType.Number) {
|
|
154
|
+
double lat = arr.getDouble(0);
|
|
155
|
+
double lng = arr.getDouble(1);
|
|
156
|
+
rewardAd.setGcoder(lat, lng);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} catch (Throwable t) {
|
|
160
|
+
Log.w(REACT_CLASS_NAME, "setGcoder failed: " + t.getMessage());
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
adsById.put(adId, rewardAd);
|
|
164
|
+
|
|
165
|
+
UiThreadUtil.runOnUiThread(() -> rewardAd.loadAd(perAdListener));
|
|
166
|
+
}
|
|
167
|
+
|
|
93
168
|
@ReactMethod
|
|
94
169
|
public void showAd() {
|
|
95
170
|
Log.e(REACT_CLASS_NAME, "showAd()");
|
|
@@ -98,9 +173,63 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
98
173
|
return;
|
|
99
174
|
}
|
|
100
175
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
176
|
+
lastActiveAdId = 0;
|
|
177
|
+
UiThreadUtil.runOnUiThread(() -> showRewardAdOnUi(adWhaleMediationRewardAd, this));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Flutter 네이밍: showAdWithoutView(adId) */
|
|
181
|
+
@ReactMethod
|
|
182
|
+
public void showAdWithoutView(int adId) {
|
|
183
|
+
AdWhaleMediationRewardAd ad = adsById.get(adId);
|
|
184
|
+
if (ad == null) {
|
|
185
|
+
Log.e(REACT_CLASS_NAME, "showAdWithoutView: ad not found. adId=" + adId);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
PerAdRewardListener listener = rewardListenersById.get(adId);
|
|
189
|
+
if (listener == null) {
|
|
190
|
+
Log.e(REACT_CLASS_NAME, "showAdWithoutView: listener not found. adId=" + adId);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
UiThreadUtil.runOnUiThread(() -> showRewardAdOnUi(ad, listener));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* SDK는 Activity 생명주기와 연동해 onAdDismissed / 보상 콜백을 지연·발행합니다.
|
|
198
|
+
* {@code showAd(Listener)}만 쓰면 현재 Activity를 못 잡아 콜백이 누락될 수 있어
|
|
199
|
+
* {@code showAd(Activity, Listener)}를 우선 사용합니다.
|
|
200
|
+
*/
|
|
201
|
+
/**
|
|
202
|
+
* @param listener 전면/로드/보상 콜백을 동일 adId로 보낼 리스턴스 (싱글턴은 {@code this})
|
|
203
|
+
*/
|
|
204
|
+
private void showRewardAdOnUi(
|
|
205
|
+
@NonNull AdWhaleMediationRewardAd ad,
|
|
206
|
+
@NonNull AdWhaleMediationUserEarnedRewardListener listener) {
|
|
207
|
+
Activity activity = getCurrentActivity();
|
|
208
|
+
if (activity != null && !activity.isFinishing()) {
|
|
209
|
+
try {
|
|
210
|
+
ad.showAd(activity, listener);
|
|
211
|
+
return;
|
|
212
|
+
} catch (Throwable t) {
|
|
213
|
+
Log.w(REACT_CLASS_NAME, "showAd(activity, listener) failed, fallback: " + t.getMessage());
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
Log.w(REACT_CLASS_NAME, "showRewardAdOnUi: no valid Activity, using showAd(listener)");
|
|
217
|
+
}
|
|
218
|
+
ad.showAd(listener);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Flutter 네이밍: destroyAd(adId) */
|
|
222
|
+
@ReactMethod
|
|
223
|
+
public void destroyAd(int adId) {
|
|
224
|
+
rewardListenersById.remove(adId);
|
|
225
|
+
AdWhaleMediationRewardAd ad = adsById.remove(adId);
|
|
226
|
+
if (ad != null) {
|
|
227
|
+
try {
|
|
228
|
+
ad.destroy();
|
|
229
|
+
} catch (Throwable t) {
|
|
230
|
+
Log.w(REACT_CLASS_NAME, "destroyAd failed: " + t.getMessage());
|
|
231
|
+
}
|
|
232
|
+
}
|
|
104
233
|
}
|
|
105
234
|
|
|
106
235
|
|
|
@@ -109,12 +238,17 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
109
238
|
public void onAdClicked() {
|
|
110
239
|
Log.i(REACT_CLASS_NAME, "onAdClicked()");
|
|
111
240
|
sendEvnet("onRewardAdClicked", null);
|
|
241
|
+
sendAdEvent(lastActiveAdId, "onRewardAdClicked", null);
|
|
112
242
|
}
|
|
113
243
|
|
|
114
244
|
@Override
|
|
115
245
|
public void onAdDismissed() {
|
|
116
246
|
Log.i(REACT_CLASS_NAME, "onAdDismissed()");
|
|
117
247
|
sendEvnet("onRewardAdDismissed", null);
|
|
248
|
+
sendAdEvent(lastActiveAdId, "onRewardAdDismissed", null);
|
|
249
|
+
if (adsById.containsKey(lastActiveAdId)) {
|
|
250
|
+
destroyAd(lastActiveAdId);
|
|
251
|
+
}
|
|
118
252
|
}
|
|
119
253
|
|
|
120
254
|
@Override
|
|
@@ -123,6 +257,8 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
123
257
|
WritableMap params = Arguments.createMap();
|
|
124
258
|
params.putInt("statusCode", statusCode);
|
|
125
259
|
params.putString("message", message);
|
|
260
|
+
// NOTE: emit() 이후에는 Map 이 consume 될 수 있으므로, payload 복사(sendAdEvent)를 먼저 수행
|
|
261
|
+
sendAdEvent(lastActiveAdId, "onRewardAdFailedToShow", params);
|
|
126
262
|
sendEvnet("onRewardAdFailedToShow", params);
|
|
127
263
|
}
|
|
128
264
|
|
|
@@ -130,6 +266,7 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
130
266
|
public void onAdShowed() {
|
|
131
267
|
Log.i(REACT_CLASS_NAME, "onAdShowed()");
|
|
132
268
|
sendEvnet("onRewardAdShowed", null);
|
|
269
|
+
sendAdEvent(lastActiveAdId, "onRewardAdShowed", null);
|
|
133
270
|
}
|
|
134
271
|
|
|
135
272
|
/// AdWhaleMediationRewardedAdLoadCallback
|
|
@@ -137,6 +274,7 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
137
274
|
public void onAdLoaded(AdWhaleMediationRewardAd adWhaleMediationRewardAd, String message) {
|
|
138
275
|
Log.i(REACT_CLASS_NAME, "onAdLoaded(+ " + message + ")");
|
|
139
276
|
sendEvnet("onRewardAdLoaded", null);
|
|
277
|
+
sendAdEvent(lastActiveAdId, "onRewardAdLoaded", null);
|
|
140
278
|
}
|
|
141
279
|
|
|
142
280
|
@Override
|
|
@@ -145,6 +283,8 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
145
283
|
WritableMap params = Arguments.createMap();
|
|
146
284
|
params.putInt("statusCode", statusCode);
|
|
147
285
|
params.putString("message", message);
|
|
286
|
+
// NOTE: emit() 이후에는 Map 이 consume 될 수 있으므로, payload 복사(sendAdEvent)를 먼저 수행
|
|
287
|
+
sendAdEvent(lastActiveAdId, "onRewardAdFailedToLoad", params);
|
|
148
288
|
sendEvnet("onRewardAdFailedToLoad", params);
|
|
149
289
|
}
|
|
150
290
|
|
|
@@ -154,8 +294,14 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
154
294
|
public void onUserRewarded(AdWhaleMediationRewardItem adWhaleMediationRewardItem) {
|
|
155
295
|
Log.i(REACT_CLASS_NAME, "onUserRewarded(" + adWhaleMediationRewardItem.toString() + ")");
|
|
156
296
|
WritableMap params = Arguments.createMap();
|
|
297
|
+
// Flutter와 동일 키: RewardType / RewardAmount (대소문자 포함)
|
|
298
|
+
params.putString("RewardType", adWhaleMediationRewardItem.getRewardType());
|
|
299
|
+
params.putInt("RewardAmount", adWhaleMediationRewardItem.getRewardAmount());
|
|
300
|
+
// 레거시 호환 키도 유지
|
|
157
301
|
params.putString("type", adWhaleMediationRewardItem.getRewardType());
|
|
158
302
|
params.putInt("amount", adWhaleMediationRewardItem.getRewardAmount());
|
|
303
|
+
// NOTE: emit() 이후에는 Map 이 consume 될 수 있으므로, payload 복사(sendAdEvent)를 먼저 수행
|
|
304
|
+
sendAdEvent(lastActiveAdId, "onUserRewarded", params);
|
|
159
305
|
sendEvnet("onUserRewarded", params);
|
|
160
306
|
}
|
|
161
307
|
|
|
@@ -167,9 +313,36 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
167
313
|
}
|
|
168
314
|
|
|
169
315
|
private void sendEvnet(String eventName, @Nullable WritableMap params) {
|
|
170
|
-
getReactApplicationContext()
|
|
171
|
-
|
|
316
|
+
final ReactApplicationContext ctx = getReactApplicationContext();
|
|
317
|
+
if (ctx == null) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
// SDK 콜백이 메인이 아닌 스레드에서 올 수 있어 RN 브리지는 UI 큐에서 emit
|
|
321
|
+
ctx.runOnUiQueueThread(() -> {
|
|
322
|
+
try {
|
|
323
|
+
ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
172
324
|
.emit(eventName, params);
|
|
325
|
+
} catch (Throwable t) {
|
|
326
|
+
Log.w(REACT_CLASS_NAME, "emit failed: " + eventName + " — " + t.getMessage());
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Flutter `onAdEvent` 스타일: payload에 eventName + adId 포함.
|
|
333
|
+
* payload: { adId, eventName, statusCode?, message?, RewardType?, RewardAmount? }
|
|
334
|
+
*/
|
|
335
|
+
private void sendAdEvent(int adId, @NonNull String eventName, @Nullable WritableMap original) {
|
|
336
|
+
WritableMap payload = Arguments.createMap();
|
|
337
|
+
payload.putInt("adId", adId);
|
|
338
|
+
payload.putString("eventName", eventName);
|
|
339
|
+
if (original != null) {
|
|
340
|
+
if (original.hasKey("statusCode")) payload.putInt("statusCode", original.getInt("statusCode"));
|
|
341
|
+
if (original.hasKey("message")) payload.putString("message", original.getString("message"));
|
|
342
|
+
if (original.hasKey("RewardType")) payload.putString("RewardType", original.getString("RewardType"));
|
|
343
|
+
if (original.hasKey("RewardAmount")) payload.putInt("RewardAmount", original.getInt("RewardAmount"));
|
|
344
|
+
}
|
|
345
|
+
sendEvnet("onAdEvent", payload);
|
|
173
346
|
}
|
|
174
347
|
|
|
175
348
|
@ReactMethod
|
|
@@ -178,7 +351,83 @@ public class RNAdWhaleMediationRewardAd extends ReactContextBaseJavaModule imple
|
|
|
178
351
|
}
|
|
179
352
|
|
|
180
353
|
@ReactMethod
|
|
181
|
-
|
|
354
|
+
public void removeListeners(Integer count) {
|
|
182
355
|
//TODO NOTHING
|
|
183
356
|
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* 멀티 보상형 인스턴스당 1개: 로드/전면/보상 콜백 모두 boundAdId 로 onAdEvent 전달.
|
|
360
|
+
*/
|
|
361
|
+
private final class PerAdRewardListener implements AdWhaleMediationRewardedAdLoadCallback,
|
|
362
|
+
AdWhaleMediationFullScreenContentCallback,
|
|
363
|
+
AdWhaleMediationUserEarnedRewardListener {
|
|
364
|
+
private final int boundAdId;
|
|
365
|
+
|
|
366
|
+
PerAdRewardListener(int boundAdId) {
|
|
367
|
+
this.boundAdId = boundAdId;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
@Override
|
|
371
|
+
public void onAdClicked() {
|
|
372
|
+
Log.i(REACT_CLASS_NAME, "onAdClicked() adId=" + boundAdId);
|
|
373
|
+
sendEvnet("onRewardAdClicked", null);
|
|
374
|
+
sendAdEvent(boundAdId, "onRewardAdClicked", null);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
@Override
|
|
378
|
+
public void onAdDismissed() {
|
|
379
|
+
Log.i(REACT_CLASS_NAME, "onAdDismissed() adId=" + boundAdId);
|
|
380
|
+
sendEvnet("onRewardAdDismissed", null);
|
|
381
|
+
sendAdEvent(boundAdId, "onRewardAdDismissed", null);
|
|
382
|
+
if (adsById.containsKey(boundAdId)) {
|
|
383
|
+
destroyAd(boundAdId);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
@Override
|
|
388
|
+
public void onFailedToShow(int statusCode, String message) {
|
|
389
|
+
Log.i(REACT_CLASS_NAME, "onFailedToShow(" + statusCode + ", " + message + ") adId=" + boundAdId);
|
|
390
|
+
WritableMap params = Arguments.createMap();
|
|
391
|
+
params.putInt("statusCode", statusCode);
|
|
392
|
+
params.putString("message", message);
|
|
393
|
+
sendAdEvent(boundAdId, "onRewardAdFailedToShow", params);
|
|
394
|
+
sendEvnet("onRewardAdFailedToShow", params);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
@Override
|
|
398
|
+
public void onAdShowed() {
|
|
399
|
+
Log.i(REACT_CLASS_NAME, "onAdShowed() adId=" + boundAdId);
|
|
400
|
+
sendEvnet("onRewardAdShowed", null);
|
|
401
|
+
sendAdEvent(boundAdId, "onRewardAdShowed", null);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
@Override
|
|
405
|
+
public void onAdLoaded(AdWhaleMediationRewardAd adWhaleMediationRewardAd, String message) {
|
|
406
|
+
Log.i(REACT_CLASS_NAME, "onAdLoaded(+ " + message + ") adId=" + boundAdId);
|
|
407
|
+
sendEvnet("onRewardAdLoaded", null);
|
|
408
|
+
sendAdEvent(boundAdId, "onRewardAdLoaded", null);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
@Override
|
|
412
|
+
public void onAdFailedToLoad(int statusCode, String message) {
|
|
413
|
+
Log.i(REACT_CLASS_NAME, "onAdFailedToLoad(" + statusCode + ", " + message + ") adId=" + boundAdId);
|
|
414
|
+
WritableMap params = Arguments.createMap();
|
|
415
|
+
params.putInt("statusCode", statusCode);
|
|
416
|
+
params.putString("message", message);
|
|
417
|
+
sendAdEvent(boundAdId, "onRewardAdFailedToLoad", params);
|
|
418
|
+
sendEvnet("onRewardAdFailedToLoad", params);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
@Override
|
|
422
|
+
public void onUserRewarded(AdWhaleMediationRewardItem adWhaleMediationRewardItem) {
|
|
423
|
+
Log.i(REACT_CLASS_NAME, "onUserRewarded(" + adWhaleMediationRewardItem + ") adId=" + boundAdId);
|
|
424
|
+
WritableMap params = Arguments.createMap();
|
|
425
|
+
params.putString("RewardType", adWhaleMediationRewardItem.getRewardType());
|
|
426
|
+
params.putInt("RewardAmount", adWhaleMediationRewardItem.getRewardAmount());
|
|
427
|
+
params.putString("type", adWhaleMediationRewardItem.getRewardType());
|
|
428
|
+
params.putInt("amount", adWhaleMediationRewardItem.getRewardAmount());
|
|
429
|
+
sendAdEvent(boundAdId, "onUserRewarded", params);
|
|
430
|
+
sendEvnet("onUserRewarded", params);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
184
433
|
}
|