diff --git a/README.md b/README.md
index 409fed20..13be0335 100644
--- a/README.md
+++ b/README.md
@@ -197,6 +197,66 @@ return (
📃 Reference
+## AdManager
+AdManager allows you to configure your ads globally when the app starts
+
+### setRequestConfiguration(config)
+Configure your Ad Requests during App Startup. You need to pass a single object as an argument with atleast one of the following properties
+
+| Name | Type | Required |
+| --------- | -------- | -------- |
+| testDeviceIds | `Array` | no |
+| maxAdContentRating | AdManager.MAX_AD_CONTENT_RATING | no |
+| tagForChildDirectedTreatment | AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT | no |
+| tagForUnderAgeConsent | AdManager.TAG_FOR_UNDER_AGE_CONSENT | no |
+
+```js
+
+const config = {
+ testDeviceIds:["YOUR_TEST_DEVICE_ID"],
+ maxAdContetRating:AdManager.MAX_AD_CONTENT_RATING.MA,
+ tagForChildDirectedTreatment:AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT.FALSE,
+ tagForUnderAgeConsent:AdManager.TAG_FOR_UNDER_AGE_CONSENT.FALSE
+}
+
+AdManager.setRequestConfiguration(config);
+
+```
+
+### isTestDevice()
+Check if the current device is registered as a test device to show test ads.
+
+```js
+ AdManager.isTestDevice().then(result => console.log(result))
+```
+return: `boolean`
+
+### AdManager.MAX_AD_CONTENT_RATING
+
+| Name | Description |
+| --------- | -------- |
+| G | "General audiences." Content suitable for all audiences, including families and children. |
+| MA | "Mature audiences." Content suitable only for mature audiences; includes topics such as alcohol, gambling, sexual content, and weapons. |
+| PG | "Parental guidance." Content suitable for most audiences with parental guidance, including topics like non-realistic, cartoonish violence. |
+| T | "Teen." Content suitable for teen and older audiences, including topics such as general health, social networks, scary imagery, and fight sports. |
+| UNSPECIFIED | Set default value to ""|
+
+### AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT
+
+| Name | Description |
+| --------- | -------- |
+| TRUE | Enabled |
+| FALSE | Disabled |
+
+### AdManager.TAG_FOR_UNDER_AGE_CONSENT
+
+| Name | Description |
+| --------- | -------- |
+| TRUE | Enabled |
+| FALSE | Disabled |
+
+#
+
## NativeAdView
NativeAdView will wrap all your views related to the ad and provides a context through which all the Views get their respective information and load it automatically. It has the following properties to it.
@@ -238,7 +298,7 @@ Set Ad Unit ID for Native Advanced Ads that you created on your AdMob account.
| -------- | -------- | -------- |
| `string` | Yes | All |
-#
+#
#### `testDevices`
@@ -248,7 +308,7 @@ Set testDevices during testing ads or during development.
| --------------- | -------- | -------- |
| `Array` | no | All |
-#
+#
#### `enableTestMode`
@@ -258,7 +318,7 @@ Setting this to true will load a placeholder ad (Not from Admob server) incase y
| --------- | -------- | -------- |
| `boolean` | no | All |
-#
+#
#### `delayAdloading`
@@ -269,7 +329,7 @@ Delay ad loading and rendering by the specified time in milliseconds. This is a
| `number` | no | 0 ms | All |
-#
+#
#### `refreshInterval`
@@ -279,7 +339,7 @@ Time in ms after which a new ad should be requested from the server.
| -------- | -------- | ------------------- | -------- |
| `number` | no | 60000 ms (1 minute) | All |
-#
+#
### Events
diff --git a/android/build.gradle b/android/build.gradle
index c6593848..4ed492ed 100755
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -22,7 +22,8 @@ android {
dependencies {
implementation 'com.facebook.react:react-native:+'
- implementation 'com.google.android.gms:play-services-ads:+'
+ implementation 'com.google.android.gms:play-services-ads:19.2.0'
implementation 'com.android.support:support-annotations:28.0.0'
+ implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}
diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativePackage.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativePackage.java
index 0c66e14d..0ec8c739 100755
--- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativePackage.java
+++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativePackage.java
@@ -14,7 +14,9 @@ public class RNAdMobNativePackage implements ReactPackage {
@Override
public List createNativeModules(ReactApplicationContext reactContext) {
- return Arrays.asList();
+ return Arrays.asList(
+ new RNAdmobNativeAdsManager(reactContext)
+ );
}
public List> createJSModules() {
diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativeViewManager.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativeViewManager.java
index 68240c96..37b01c58 100755
--- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativeViewManager.java
+++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNAdMobNativeViewManager.java
@@ -46,6 +46,8 @@ public class RNAdMobNativeViewManager extends ViewGroupManager list = nativeArray.toArrayList();
+ List testDeviceIds = Arrays.asList(list.toArray(new String[list.size()]));
+ configuration.setTestDeviceIds(testDeviceIds);
+ }
+
+ MobileAds.setRequestConfiguration(configuration.build());
+ MobileAds.initialize(reactContext);
+
+ }
+
+
+
+ @ReactMethod
+ public void isTestDevice(Promise promise) {
+
+ AdRequest builder = new AdRequest.Builder().build();
+ if (builder != null) {
+ promise.resolve(builder.isTestDevice(reactContext));
+ }
+ }
+}
diff --git a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java
index 18d05ec6..f6562723 100644
--- a/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java
+++ b/android/src/main/java/com/ammarahmed/rnadmob/nativeads/RNNativeAdWrapper.java
@@ -1,6 +1,7 @@
package com.ammarahmed.rnadmob.nativeads;
import android.content.Context;
+import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
@@ -13,6 +14,7 @@
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.RCTEventEmitter;
+import com.google.ads.mediation.admob.AdMobAdapter;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdLoader;
import com.google.android.gms.ads.AdRequest;
@@ -36,6 +38,11 @@ public void run() {
Context mContext;
UnifiedNativeAdView nativeAdView;
UnifiedNativeAd unifiedNativeAd;
+
+ private int adChoicesPlacement = 1;
+ private boolean requestNonPersonalizedAdsOnly = false;
+
+
AdListener adListener = new AdListener() {
@Override
public void onAdFailedToLoad(int i) {
@@ -136,9 +143,7 @@ public void addMediaView(int id) {
if (adMediaView != null) {
nativeAdView.setMediaView(adMediaView);
adMediaView.requestLayout();
- if (unifiedNativeAd != null && unifiedNativeAd.getMediaContent().hasVideoContent()) {
- unifiedNativeAd.getMediaContent().getVideoController().play();
- }
+
}
} catch (Exception e) {
@@ -162,18 +167,51 @@ private void setNativeAdToJS(UnifiedNativeAd nativeAd) {
if (nativeAd.getStarRating() != null) {
args.putInt("rating", nativeAd.getStarRating().intValue());
}
- args.putString("aspectRatio", String.valueOf(nativeAd.getMediaContent().getAspectRatio()));
+
+ float aspectRatio = 1.0f;
+
+
+ if (nativeAd.getResponseInfo().getMediationAdapterClassName().equals("com.google.ads.mediation.admob.AdMobAdapter")) {
+ if (nativeAd.getMediaContent() != null) {
+ aspectRatio = nativeAd.getMediaContent().getAspectRatio();
+
+ if (aspectRatio > 0) {
+ args.putString("aspectRatio", String.valueOf(aspectRatio));
+ } else {
+ args.putString("aspectRatio", String.valueOf(1.0f));
+ }
+
+ }
+ } else {
+ args.putString("aspectRatio", String.valueOf(1.0f));
+ }
+
+
WritableArray images = Arguments.createArray();
- for (int i = 0; i < nativeAd.getImages().size(); i++) {
- WritableMap map = Arguments.createMap();
- map.putString("url", nativeAd.getImages().get(i).getUri().toString());
- map.putInt("width", nativeAd.getImages().get(i).getWidth());
- map.putInt("height", nativeAd.getImages().get(i).getHeight());
- images.pushMap(map);
+ if (nativeAd.getImages() != null && nativeAd.getImages().size() > 0) {
+
+ for (int i = 0; i < nativeAd.getImages().size(); i++) {
+ WritableMap map = Arguments.createMap();
+ map.putString("url", nativeAd.getImages().get(i).getUri().toString());
+ map.putInt("width", nativeAd.getImages().get(i).getWidth());
+ map.putInt("height", nativeAd.getImages().get(i).getHeight());
+ images.pushMap(map);
+ }
+ }
+
+ if (images != null) {
+ args.putArray("images", images);
+ } else {
+ args.putArray("images", null);
+ }
+
+ if (nativeAd.getIcon() != null || nativeAd.getIcon().getUri() != null) {
+ args.putString("icon", nativeAd.getIcon().getUri().toString());
+ } else {
+ args.putString("icon", "empty");
}
- args.putArray("images", images);
- args.putString("icon", nativeAd.getIcon().getUri().toString());
+
sendEvent(RNAdMobNativeViewManager.EVENT_UNIFIED_NATIVE_AD_LOADED, args);
} catch (Exception e) {
@@ -212,29 +250,39 @@ private void sendEvent(String name, @Nullable WritableMap event) {
private void loadAd() {
- try {
- AdLoader.Builder builder = new AdLoader.Builder(mContext, admobAdUnitId);
- builder.forUnifiedNativeAd(onUnifiedNativeAdLoadedListener);
- VideoOptions videoOptions = new VideoOptions.Builder()
- .setStartMuted(true)
- .build();
+ try {
+ AdLoader.Builder builder = new AdLoader.Builder(mContext, admobAdUnitId);
+ builder.forUnifiedNativeAd(onUnifiedNativeAdLoadedListener);
+
+ VideoOptions videoOptions = new VideoOptions.Builder()
+ .setStartMuted(true)
+ .build();
- NativeAdOptions adOptions = new NativeAdOptions.Builder()
- .setVideoOptions(videoOptions)
- .setAdChoicesPlacement(NativeAdOptions.ADCHOICES_TOP_RIGHT)
- .build();
- builder.withNativeAdOptions(adOptions);
+ NativeAdOptions adOptions = new NativeAdOptions.Builder()
+ .setVideoOptions(videoOptions)
+ .setAdChoicesPlacement(adChoicesPlacement)
+ .build();
+ builder.withNativeAdOptions(adOptions);
- AdLoader adLoader = builder.withAdListener(adListener)
- .build();
- adLoader.loadAd(new AdRequest.Builder().build());
+ AdLoader adLoader = builder.withAdListener(adListener)
+ .build();
- } catch (Exception e) {
- }
+ AdRequest adRequest;
+ if (requestNonPersonalizedAdsOnly) {
+ Bundle extras = new Bundle();
+ extras.putString("npa", "1");
+ adRequest = new AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter.class, extras).build();
+ } else {
+ adRequest = new AdRequest.Builder().build();
+ }
+
+ adLoader.loadAd(adRequest);
+ } catch (Exception e) {
+ }
}
public void setLoadWithDelay(int delay) {
@@ -268,6 +316,14 @@ public void setAdUnitId(String id) {
loadAd();
}
+ public void setAdChoicesPlacement(int location) {
+ adChoicesPlacement = location;
+ }
+
+ public void setRequestNonPersonalizedAdsOnly(boolean npa) {
+ requestNonPersonalizedAdsOnly = npa;
+ }
+
@Override
public void requestLayout() {
super.requestLayout();
diff --git a/example/App.js b/example/App.js
index 15aa9374..65488543 100644
--- a/example/App.js
+++ b/example/App.js
@@ -8,6 +8,7 @@ import NativeAdView, {
AdvertiserView,
MediaView,
} from 'react-native-admob-native-ads';
+import { AdManager } from 'react-native-admob-native-ads';
const NATIVE_AD_ID =
Platform.OS === 'ios'
@@ -26,6 +27,7 @@ const App = () => {
};
const _onAdLoaded = () => {
+
console.log('Ad has loaded');
};
@@ -48,13 +50,12 @@ const App = () => {
alignSelf: 'center',
height: 900,
}}
- adUnitID={NATIVE_AD_VIDEO_ID} // REPLACE WITH NATIVE_AD_VIDEO_ID for video ads.
+ adUnitID={NATIVE_AD_ID} // REPLACE WITH NATIVE_AD_VIDEO_ID for video ads.
>
App);
diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock
index 66fd7c0b..4612613c 100644
--- a/example/ios/Podfile.lock
+++ b/example/ios/Podfile.lock
@@ -19,35 +19,37 @@ PODS:
- DoubleConversion
- glog
- glog (0.3.5)
- - Google-Mobile-Ads-SDK (7.56.0):
+ - Google-Mobile-Ads-SDK (7.61.0):
- GoogleAppMeasurement (~> 6.0)
- - GoogleAppMeasurement (6.3.1):
+ - GoogleAppMeasurement (6.6.1):
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
- GoogleUtilities/MethodSwizzler (~> 6.0)
- GoogleUtilities/Network (~> 6.0)
- "GoogleUtilities/NSData+zlib (~> 6.0)"
- - nanopb (= 0.3.9011)
- - GoogleUtilities/AppDelegateSwizzler (6.5.2):
+ - nanopb (~> 1.30905.0)
+ - GoogleUtilities/AppDelegateSwizzler (6.6.0):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- - GoogleUtilities/Environment (6.5.2)
- - GoogleUtilities/Logger (6.5.2):
+ - GoogleUtilities/Environment (6.6.0):
+ - PromisesObjC (~> 1.2)
+ - GoogleUtilities/Logger (6.6.0):
- GoogleUtilities/Environment
- - GoogleUtilities/MethodSwizzler (6.5.2):
+ - GoogleUtilities/MethodSwizzler (6.6.0):
- GoogleUtilities/Logger
- - GoogleUtilities/Network (6.5.2):
+ - GoogleUtilities/Network (6.6.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- - "GoogleUtilities/NSData+zlib (6.5.2)"
- - GoogleUtilities/Reachability (6.5.2):
+ - "GoogleUtilities/NSData+zlib (6.6.0)"
+ - GoogleUtilities/Reachability (6.6.0):
- GoogleUtilities/Logger
- - nanopb (0.3.9011):
- - nanopb/decode (= 0.3.9011)
- - nanopb/encode (= 0.3.9011)
- - nanopb/decode (0.3.9011)
- - nanopb/encode (0.3.9011)
+ - nanopb (1.30905.0):
+ - nanopb/decode (= 1.30905.0)
+ - nanopb/encode (= 1.30905.0)
+ - nanopb/decode (1.30905.0)
+ - nanopb/encode (1.30905.0)
+ - PromisesObjC (1.2.9)
- RCTRequired (0.61.5)
- RCTTypeSafety (0.61.5):
- FBLazyVector (= 0.61.5)
@@ -211,7 +213,7 @@ PODS:
- React-cxxreact (= 0.61.5)
- React-jsi (= 0.61.5)
- React-jsinspector (0.61.5)
- - react-native-admob-native-ads (0.1.1):
+ - react-native-admob-native-ads (0.2.9):
- React
- React-RCTActionSheet (0.61.5):
- React-Core/RCTActionSheetHeaders (= 0.61.5)
@@ -292,6 +294,7 @@ SPEC REPOS:
- GoogleAppMeasurement
- GoogleUtilities
- nanopb
+ - PromisesObjC
EXTERNAL SOURCES:
DoubleConversion:
@@ -356,10 +359,11 @@ SPEC CHECKSUMS:
FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
- Google-Mobile-Ads-SDK: 65e335fadc97c5a91a9d4546214bfd3a2fb11047
- GoogleAppMeasurement: c29d405ff76e18551b5d158eaba6753fda8c7542
- GoogleUtilities: ad0f3b691c67909d03a3327cc205222ab8f42e0e
- nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd
+ Google-Mobile-Ads-SDK: 4c3b24b04293b4bb370b2cb392cdd3ee97c87752
+ GoogleAppMeasurement: 2fd5c5a56c069db635c8e7b92d4809a9591d0a69
+ GoogleUtilities: 39530bc0ad980530298e9c4af8549e991fd033b1
+ nanopb: c43f40fadfe79e8b8db116583945847910cbabc9
+ PromisesObjC: b48e0338dbbac2207e611750777895f7a5811b75
RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1
RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320
React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78
@@ -369,7 +373,7 @@ SPEC CHECKSUMS:
React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7
React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386
React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0
- react-native-admob-native-ads: d81f8f3232ef42aab90e7de4031fa7241d768b11
+ react-native-admob-native-ads: 37849d7d88dd3348a713d441d012ab23e7ddcd3e
React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76
React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360
React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72
diff --git a/index.d.ts b/index.d.ts
index f83a8b5e..9b3e4ba9 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -18,6 +18,8 @@ type Image = {
}
+
+
type NativeAd = {
/**
* Title of the native ad.
@@ -69,6 +71,40 @@ type NativeAd = {
video: boolean;
};
+type options = {
+ adChoicesPlacement: {
+ TOP_LEFT:number,
+ TOP_RIGHT:number,
+ BOTTOM_RIGHT:number,
+ BOTTOM_LEFT: number
+ }
+}
+
+type MAX_AD_CONTENT_RATING = {
+ G: string,
+ MA:string,
+ PG: string,
+ T: string,
+ UNSPECIFIED:string,
+}
+type TAG_FOR_CHILD_DIRECTED_TREATMENT = {
+ TRUE:number,
+ FALSE:number
+}
+
+type TAG_FOR_UNDER_AGE_CONSENT = {
+ TRUE:number,
+ FALSE:number
+}
+
+type config = {
+ maxAdContentRating:MAX_AD_CONTENT_RATING,
+ tagForChildDirectedTreatment:TAG_FOR_CHILD_DIRECTED_TREATMENT,
+ tagForUnderAgeConsent:TAG_FOR_UNDER_AGE_CONSENT,
+ testDeviceIds:Array
+}
+
+
type NativeAdViewProps = {
/**
* When you are designing your ad, placeholders
@@ -106,7 +142,35 @@ type NativeAdViewProps = {
delayAdLoading?: number;
/**
- * Set testdevices for the ad.
+ * Placement of AdChoicesView in any of the 4 corners of the ad
+ *
+ * import AdOptions then pass the value from there. AdOptions.adChoicesPlacement
+ */
+
+ adChoicesPlacement?: {
+ TOP_LEFT:number,
+ TOP_RIGHT:number,
+ BOTTOM_RIGHT:number,
+ BOTTOM_LEFT: number
+ }
+
+ /**
+ * Under the Google EU User Consent Policy, you must make certain disclosures
+ * to your users in the European Economic Area (EEA) and obtain their consent
+ * to use cookies or other local storage, where legally required, and to use
+ * personal data (such as AdID) to serve ads. This policy reflects the requirements
+ * of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR).
+ *
+ * You can use library such as: https://github.com/birgernass/react-native-ad-consent
+ * to obtain the consent or if you are using rn-firebase you can obtain the consent from
+ * there and then pass the consent to this library. If user has selected
+ * non-personalized-ads then pass `true` and non-personalized ads will be shown to the user.
+ *
+ */
+ requestNonPersonalizedAdsOnly:boolean;
+
+ /**
+ * Set testdevices for the ad. (DEPRECATED)
*/
testDevices?: Array;
onAdOpened?: Function;
@@ -130,7 +194,11 @@ type NestedTextProps = {
allowFontScaling?: boolean;
};
+
+
declare module "react-native-admob-native-ads" {
+
+
/**
*
* Wrapper for the UnifiedNativeAdView from Google Ads SDK. All your views should be
@@ -142,7 +210,97 @@ declare module "react-native-admob-native-ads" {
props: NativeAdViewProps
): React.FunctionComponent;
+
+ const MAX_AD_CONTENT_RATING:MAX_AD_CONTENT_RATING;
+ const TAG_FOR_CHILD_DIRECTED_TREATMENT:TAG_FOR_CHILD_DIRECTED_TREATMENT;
+ const TAG_FOR_UNDER_AGE_CONSENT:TAG_FOR_UNDER_AGE_CONSENT;
+
+
/**
+ * AdManager can be used to configure your ads on App Startup such as setting test devices.
+ *
+ */
+
+ export const AdManager = {
+
+ /**
+ * Configure your Ad Requests during App Startup. You need to pass a single object as an argument with atleast one of the following properties
+
+ | Name | Type | Required |
+ | --------- | -------- | -------- |
+ | testDeviceIds | `Array` | no |
+ | maxAdContentRating | AdManager.MAX_AD_CONTENT_RATING | no |
+ | tagForChildDirectedTreatment | AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT | no |
+ | tagForUnderAgeConsent | AdManager.TAG_FOR_UNDER_AGE_CONSENT | no |
+
+ Example:
+
+ ```js
+
+ const config = {
+ testDeviceIds:["YOUR_TEST_DEVICE_ID"],
+ maxAdContetRating:AdManager.MAX_AD_CONTENT_RATING.MA,
+ tagForChildDirectedTreatment:AdManager.TAG_FOR_CHILD_DIRECTED_TREATMENT.FALSE,
+ tagForUnderAgeConsent:AdManager.TAG_FOR_UNDER_AGE_CONSENT.FALSE
+ }
+
+ AdManager.setRequestConfiguration(config);
+
+ ```
+ *
+ */
+
+ setRequestConfiguration: (config:config) => {},
+
+ /**
+ * Check if the current device is registered as a test device to show test ads.
+
+```js
+ AdManager.isTestDevice().then(result => console.log(result))
+```
+return: `boolean`
+ */
+ isTestDevice:async () => {},
+
+
+ /**
+ * | Name | Description |
+| --------- | -------- |
+| G | "General audiences." Content suitable for all audiences, including families and children. |
+| MA | "Mature audiences." Content suitable only for mature audiences; includes topics such as alcohol, gambling, sexual content, and weapons. |
+| PG | "Parental guidance." Content suitable for most audiences with parental guidance, including topics like non-realistic, cartoonish violence. |
+| T | "Teen." Content suitable for teen and older audiences, including topics such as general health, social networks, scary imagery, and fight sports. |
+| UNSPECIFIED | Set default value to ""|
+ */
+
+ MAX_AD_CONTENT_RATING:MAX_AD_CONTENT_RATING,
+
+
+ /**
+ * | Name | Description |
+| --------- | -------- |
+| TRUE | Enabled |
+| FALSE | Disabled |
+ */
+
+ TAG_FOR_CHILD_DIRECTED_TREATMENT:TAG_FOR_CHILD_DIRECTED_TREATMENT,
+
+ /**
+ * | Name | Description |
+| --------- | -------- |
+| TRUE | Enabled |
+| FALSE | Disabled |
+ */
+
+
+ TAG_FOR_UNDER_AGE_CONSENT:TAG_FOR_UNDER_AGE_CONSENT
+}
+
+
+ export const AdOptions:options;
+
+
+ /**
* Ad Badge shows the {ad} badge on top of the ad telling the user that this is an AD.
*
*/
diff --git a/index.js b/index.js
index 75cc59b6..f0eef755 100755
--- a/index.js
+++ b/index.js
@@ -10,6 +10,8 @@ import StarRatingView from './src/StarRatingView'
import PriceView from "./src/PriceView";
import AdBadge from "./src/AdBadge";
import NativeAdView from './src';
+import {AdOptions} from "./src/utils"
+import AdManager from "./src/AdManager"
export default NativeAdView;
export {
@@ -24,6 +26,8 @@ export {
StarRatingView,
PriceView,
AdBadge,
+ AdOptions,
+ AdManager
}
diff --git a/ios/RNAdmobNativeAdsManager.h b/ios/RNAdmobNativeAdsManager.h
new file mode 100644
index 00000000..f1238ba7
--- /dev/null
+++ b/ios/RNAdmobNativeAdsManager.h
@@ -0,0 +1,8 @@
+// CalendarManager.h
+#import
+
+
+@interface RNAdmobNativeAdsManager : NSObject
+
+@end
+
diff --git a/ios/RNAdmobNativeAdsManager.m b/ios/RNAdmobNativeAdsManager.m
new file mode 100644
index 00000000..8908ae83
--- /dev/null
+++ b/ios/RNAdmobNativeAdsManager.m
@@ -0,0 +1,77 @@
+#import "RNAdmobNativeAdsManager.h"
+
+@import GoogleMobileAds;
+
+@implementation RNAdmobNativeAdsManager
+
+RCT_EXPORT_MODULE();
+
+
+
+RCT_EXPORT_METHOD(setRequestConfiguration:(NSDictionary *)config)
+{
+
+ if ([[config allKeys] containsObject:@"maxAdContentRating"]) {
+
+ NSString *rating = [config valueForKey:@"maxAdContentRating"];
+
+ if ([rating isEqualToString:@"G"]) {
+ [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:GADMaxAdContentRatingGeneral];
+
+ } else if ([rating isEqualToString:@"PG"]) {
+
+ [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:GADMaxAdContentRatingParentalGuidance];
+ } else if ([rating isEqualToString:@"MA"]) {
+
+ [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:GADMaxAdContentRatingMatureAudience];
+ } else if ([rating isEqualToString:@"T"]) {
+ [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:GADMaxAdContentRatingTeen];
+ } else if ([rating isEqualToString:@""]) {
+ [[[GADMobileAds sharedInstance] requestConfiguration] setMaxAdContentRating:NULL];
+
+ }
+
+ };
+
+ if ([[config allKeys] containsObject:@"tagForChildDirectedTreatment"]) {
+ NSNumber *tag = [config valueForKey:@"tagForChildDirectedTreatment"];
+
+ if (tag.intValue == 0) {
+ [[[GADMobileAds sharedInstance] requestConfiguration] tagForChildDirectedTreatment:false];
+
+ } else {
+ [[[GADMobileAds sharedInstance] requestConfiguration] tagForChildDirectedTreatment:true];
+
+ }
+ };
+
+ if ([[config allKeys] containsObject:@"tagForUnderAgeConsent"]) {
+ NSNumber *tagC = [config valueForKey:@"tagForUnderAgeConsent"];
+
+ if (tagC.intValue == 0) {
+ [[[GADMobileAds sharedInstance] requestConfiguration] tagForUnderAgeOfConsent:false];
+ } else {
+ [[[GADMobileAds sharedInstance] requestConfiguration] tagForUnderAgeOfConsent:true];
+ }
+ };
+
+ if ([[config allKeys] containsObject:@"testDeviceIds"]) {
+ NSArray *testDevices = [config valueForKey:@"testDeviceIds"];
+
+ [[[GADMobileAds sharedInstance] requestConfiguration] setTestDeviceIdentifiers:testDevices];
+ };
+
+
+}
+
+RCT_EXPORT_METHOD(isTestDevice:(RCTPromiseResolveBlock)resolve
+rejecter:(RCTPromiseRejectBlock)reject) {
+
+ resolve(@TRUE);
+}
+
+
+
+
+
+@end
diff --git a/ios/RNGADNativeView.h b/ios/RNGADNativeView.h
index 32125463..12920217 100755
--- a/ios/RNGADNativeView.h
+++ b/ios/RNGADNativeView.h
@@ -23,6 +23,8 @@
@property (nonatomic, copy) NSNumber *mediaview;
@property (nonatomic, copy) NSNumber *starrating;
@property (nonatomic, copy) NSNumber *callToAction;
+@property (nonatomic, copy) NSNumber *adChoicesPlacement;
+@property (nonatomic) BOOL *requestNonPersonalizedAdsOnly;
- (instancetype)initWithBridge:(RCTBridge *)bridge;
diff --git a/ios/RNGADNativeView.m b/ios/RNGADNativeView.m
index 12e4800b..174cd078 100755
--- a/ios/RNGADNativeView.m
+++ b/ios/RNGADNativeView.m
@@ -21,6 +21,9 @@ @implementation RNGADNativeView : GADUnifiedNativeAdView
NSString *adUnitId;
NSNumber *refreshingInterval;
NSNumber *delay;
+NSNumber *adChoicesPlace;
+BOOL *nonPersonalizedAds;
+
- (instancetype)initWithBridge:(RCTBridge *)_bridge
@@ -33,6 +36,16 @@ - (instancetype)initWithBridge:(RCTBridge *)_bridge
return self;
}
+- (void)setAdChoicesPlacement:(NSNumber *)adChoicesPlacement {
+
+ adChoicesPlace = adChoicesPlacement;
+}
+
+- (void)setRequestNonPersonalizedAdsOnly:(BOOL *)requestNonPersonalizedAdsOnly {
+
+ nonPersonalizedAds = requestNonPersonalizedAdsOnly;
+}
+
- (void)setDelayAdLoad:(NSNumber *)delayAdLoad
{
delay = delayAdLoad;
@@ -164,10 +177,6 @@ - (void)setPrice:(NSNumber *)price
}];
});
-
-
-
-
}
- (void)setStore:(NSNumber *)store
@@ -184,10 +193,6 @@ - (void)setStore:(NSNumber *)store
}
}];
});
-
-
-
-
}
- (void)setStarrating:(NSNumber *)starrating
@@ -235,7 +240,22 @@ - (void)loadAd:(NSString *)adUnitId
GADNativeAdViewAdOptions *adViewOptions = [GADNativeAdViewAdOptions new];
- adViewOptions.preferredAdChoicesPosition = GADAdChoicesPositionTopRightCorner;
+
+ if ([adChoicesPlace isEqualToNumber:@0]) {
+ [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionTopLeftCorner];
+ } else if ([adChoicesPlace isEqualToNumber:@1]) {
+ [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionTopRightCorner];
+ } else if ([adChoicesPlace isEqualToNumber:@2]) {
+ [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionBottomRightCorner];
+ } else if ([adChoicesPlace isEqualToNumber:@3]) {
+ [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionBottomLeftCorner];
+ } else {
+ [adViewOptions setPreferredAdChoicesPosition:GADAdChoicesPositionTopRightCorner];
+
+ }
+
+
+
self.adLoader = [[GADAdLoader alloc]
@@ -244,8 +264,16 @@ - (void)loadAd:(NSString *)adUnitId
adTypes:@[ kGADAdLoaderAdTypeUnifiedNative ]
options:@[adViewOptions]];
+
self.adLoader.delegate = self;
GADRequest *request = [GADRequest request];
+
+ if (nonPersonalizedAds) {
+ GADExtras *extras = [[GADExtras alloc] init];
+ extras.additionalParameters = @{@"npa": @"1"};
+ [request registerAdNetworkExtras:extras];
+ }
+
GADMobileAds.sharedInstance.requestConfiguration.testDeviceIdentifiers = _testDevices;
[self.adLoader loadRequest:request];
}
@@ -299,7 +327,7 @@ - (void)adLoader:(GADAdLoader *)adLoader didReceiveUnifiedNativeAd:(GADUnifiedNa
NSInteger val2 = @(image.image.size.height).integerValue;
[imageDic setValue: [NSNumber numberWithInteger:val2] forKey:@"height"];
[images addObject:imageDic];
-
+
}
diff --git a/ios/RNGADNativeViewManager.m b/ios/RNGADNativeViewManager.m
index cd65dc83..8db61bd1 100755
--- a/ios/RNGADNativeViewManager.m
+++ b/ios/RNGADNativeViewManager.m
@@ -44,8 +44,8 @@ -(UIView *)view
RCT_EXPORT_VIEW_PROPERTY(price, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(starrating, NSNumber)
RCT_EXPORT_VIEW_PROPERTY(callToAction, NSNumber)
-
-
+RCT_EXPORT_VIEW_PROPERTY(requestNonPersonalizedAdsOnly, BOOL)
+RCT_EXPORT_VIEW_PROPERTY(adChoicesPlacement, NSNumber)
//RCT_EXPORT_VIEW_PROPERTY(ratingStarsColor, NSString)
diff --git a/package.json b/package.json
index 7f1e1199..dac017cd 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-admob-native-ads",
- "version": "0.2.9",
+ "version": "0.3.0",
"description": "A simple and robust library for creating & displaying Admob Native Ads in your React Native App using Native Views",
"author": "Ammar Ahmed ",
"main": "index.js",
diff --git a/src/AdManager.js b/src/AdManager.js
new file mode 100644
index 00000000..c02e5b19
--- /dev/null
+++ b/src/AdManager.js
@@ -0,0 +1,38 @@
+import {NativeModules} from 'react-native';
+
+const RNAdmobNativeAdsManager = NativeModules.RNAdmobNativeAdsManager;
+
+const MAX_AD_CONTENT_RATING = {
+ G: "G",
+ MA:"MA",
+ PG: "PG",
+ T: "T",
+ UNSPECIFIED: "",
+}
+const TAG_FOR_CHILD_DIRECTED_TREATMENT = {
+ TRUE:1,
+ FALSE:0
+}
+
+const TAG_FOR_UNDER_AGE_CONSENT = {
+ TRUE:1,
+ FALSE:0
+}
+
+function setRequestConfiguration(config) {
+
+ RNAdmobNativeAdsManager.setRequestConfiguration(config);
+}
+
+async function isTestDevice() {
+
+ return await RNAdmobNativeAdsManager.isTestDevice();
+}
+
+export default {
+ setRequestConfiguration,
+ isTestDevice,
+ MAX_AD_CONTENT_RATING,
+ TAG_FOR_CHILD_DIRECTED_TREATMENT,
+ TAG_FOR_UNDER_AGE_CONSENT
+}
\ No newline at end of file
diff --git a/src/IconView.js b/src/IconView.js
index 758b9221..2060c008 100644
--- a/src/IconView.js
+++ b/src/IconView.js
@@ -20,7 +20,7 @@ const IconView = (props) => {
_onLayout();
}, [nativeAd, nativeAdView]);
- return nativeAd && nativeAd.icon ? (
+ return nativeAd && nativeAd.icon && nativeAd.icon !== "empty" ? (
{
onLayout={_onLayout}
source={{ uri: nativeAd.icon }}
/>
- ) : null;
+ ) : (
+
+ );
};
export default IconView;
diff --git a/src/ImageView.js b/src/ImageView.js
index 5a148797..958133ed 100644
--- a/src/ImageView.js
+++ b/src/ImageView.js
@@ -19,7 +19,7 @@ const ImageView = (props) => {
_onLayout();
}, [nativeAd, nativeAdView]);
- return nativeAd && nativeAd.images[0] ? (
+ return nativeAd && nativeAd.images && nativeAd.images[0] ? (
{
- return Platform.OS === "android" ? (
-
- ) : (
-
- );
+
+ return
};
-const AdWrapperView =
- Platform.OS === "android"
- ? requireNativeComponent("RNAdComponentWrapper", Wrapper)
- : null;
export default Wrapper;
diff --git a/src/index.js b/src/index.js
index aa176fbe..36465bc3 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from "react";
import { Platform, requireNativeComponent } from "react-native";
import { NativeAdContext } from "./context";
+import Wrapper from "./Wrapper";
const testNativeAd = {
headline: "Test Ad: Lorem ipsum dolor ",
@@ -15,6 +16,8 @@ const testNativeAd = {
images: ["https://dummyimage.com/qvga"],
};
+
+
const waitAsync = (ms) =>
new Promise((resolve, reject) => {
setTimeout(() => {
@@ -66,8 +69,6 @@ const NativeAdView = (props) => {
updateAd(event.nativeEvent);
setTimeout(() => {
setForceRefresh(!forceRefresh);
- setForceRefresh(!forceRefresh);
- setForceRefresh(!forceRefresh);
}, 0);
if (props.onUnifiedNativeAdLoaded) {
@@ -105,11 +106,13 @@ const NativeAdView = (props) => {
value={{ nativeAd, nativeAdView, setNativeAdView, setNativeAd }}
>
{
nativeAdRef = ref;
setNativeAdView(nativeAdRef);
return nativeAdRef;
}}
+ adUnitID={props.adUnitID}
onAdLoaded={_onAdLoaded}
onAdFailedToLoad={_onAdFailedToLoad}
onAdClicked={_onAdClicked}
@@ -121,9 +124,12 @@ const NativeAdView = (props) => {
onUnifiedNativeAdLoaded={_onUnifiedNativeAdLoaded}
refreshInterval={props.refreshInterval? props.refreshInterval : 60000}
testDevices={props.testDevices? props.testDevices : []}
- adUnitID={props.adUnitID}
+ requestNonPersonalizedAdsOnly={props.requestNonPersonalizedAdsOnly? true : false}
+ adChoicesPlacement={props.adChoicesPlacement > -1? props.adChoicesPlacement : 1}
>
+
{props.children}
+
);
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 00000000..5ba3c375
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,10 @@
+
+
+export const AdOptions = Object.freeze({
+ adChoicesPlacement: {
+ TOP_LEFT:0,
+ TOP_RIGHT:1,
+ BOTTOM_RIGHT:2,
+ BOTTOM_LEFT: 3
+ }
+})
\ No newline at end of file