For showing interestitial ad in my android app (which i have made using ionic) i have used the following code :
<script type="text/javascript">
function runads(){
document.addEventListener("deviceready", onDeviceReady, false);
}
function initAds() {
if (admob) {
var adPublisherIds = {
ios : {
banner : "###############",
interstitial : "##################"
},
android : {
banner : "#############",
interstitial : "#########################"
}
};
var admobid = (/(android)/i.test(navigator.userAgent)) ? adPublisherIds.android : adPublisherIds.ios;
admob.setOptions({
publisherId: admobid.banner,
interstitialAdId: admobid.interstitial,
tappxIdiOs: "/XXXXXXXXX/Pub-XXXX-iOS-IIII",
tappxIdAndroid: "/XXXXXXXXX/Pub-XXXX-Android-AAAA",
tappxShare: 0.5
});
registerAdEvents();
} else {
alert('AdMobAds plugin not ready');
}
}
function onAdLoaded(e) {
if (e.adType === admob.AD_TYPE.INTERSTITIAL) {
admob.showInterstitialAd();
showNextInterstitial = setTimeout(function() {
admob.requestInterstitialAd();
}, 2 * 60 * 1000); // 2 minutes
}
}
// optional, in case respond to events
function registerAdEvents() {
document.addEventListener(admob.events.onAdLoaded, onAdLoaded);
document.addEventListener(admob.events.onAdFailedToLoad, function (e) {});
document.addEventListener(admob.events.onAdOpened, function (e) {});
document.addEventListener(admob.events.onAdClosed, function (e) {});
document.addEventListener(admob.events.onAdLeftApplication, function (e) {});
document.addEventListener(admob.events.onInAppPurchaseRequested, function (e) {});
}
function onDeviceReady() {
document.removeEventListener('deviceready', onDeviceReady, false);
initAds();
// display a banner at startup
admob.createBannerView();
// request an interstitial
admob.requestInterstitialAd();
}
My interestitial ad is showing perfectly using this code.Then, i have uploaded it in google play store.suddenly i have got a message from google Admob team regarding interestitial ad placing . The message is -
Hello,We are alerting you that your app is currently in violation of the AdMob program policies. Importantly, this will require action on your part to ensure no disruption in ad serving. Please read below for more information on the actions you need to take:
Violation explanation
LAYOUT ENCOURAGES ACCIDENTAL CLICKS - INTERSTITIAL ADS:Publishers are not permitted to encourage users to click AdMob interstitial ads in any way. Please review how you’ve implemented interstitial ads and be mindful of the following non-compliant implementation(s):Interstitial ads that load unexpectedly while a user is viewing the app’s content.For more information about our policies and tips for how to comply please read the following:
Interstitial ads that load unexpectedly while a user is viewing the app’s content.For more information about our policies and tips for how to comply please read the following:AdMob ad placement policyAdMob interstitial ad guidanceAdMob preload instructions for Android and iOSAction required: Please make changes immediately to your app to comply with AdMob program policies.Current account status: ActiveYou do not need to contact us once you've made the necessary changes to your app. Please be aware that if additional violations are accrued, ad serving may be disabled to the app listed above.Note that the app listed above is just one example and the same violation may exist on other apps you own. We suggest that you review all your apps for compliance with the AdMob program policies to reduce the likelihood of future warnings.For more information regarding our policy warning notifications, visit our Help Center.Thank you for your cooperation.Sincerely,The Google AdMob Team
How Can i solve this problem ?
Probably what is going on is that the loading of an interstitial ad takes some time, so you need to plan the loading of an interstitial and ensure the interstitial is available when you need to show it. If not, launching admob.showInterstitialAd() will load the interstital and show it when it is available (as the flag autoShowInterstitial is true by default, see https://github.com/appfeel/admob-google-cordova/wiki/setOptions).
There is a complete example on how to plan the interstitials: https://github.com/appfeel/admob-google-cordova/wiki/showInterstitialAd.
Basically what you do is to request an interstitial and let the app know if the interstitial is available or not. Probably your code for ionic should look like this:
angular.module('myApp', ['admobModule'])
.constant('AdmobConfig', {
bannerId: /(android)/i.test(navigator.userAgent) ? "ca-app-pub-XXXXXXXXXXXXXXXX/ANDROID_BANNER_ID" : "ca-app-pub-XXXXXXXXXXXXXXXX/IOS_BANNER_ID",
interstitialId: /(android)/i.test(navigator.userAgent) ? "ca-app-pub-XXXXXXXXXXXXXXXX/ANDROID_INTERSTITIAL_ID" : "ca-app-pub-XXXXXXXXXXXXXXXX/IOS_INTERSTITIAL_ID",
})
.config(function (admobSvcProvider, AdmobConfig) {
admobSvcProvider.setOptions({
publisherId: AdmobConfig.bannerId,
interstitialAdId: AdmobConfig.interstitialId,
autoShowInterstitial: false,
});
})
.run(function ($rootScope, $ionicPlatform, $timeout, admobSvc) {
admobSvc.requestInterstitialAd();
$rootScope.isInterstitialAvailable = false;
$rootScope.isAppForeground = false;
$rootScope.$on(admobSvc.events.onAdLoaded, function onAdLoaded(evt, e) {
if ($rootScope.isAppForeground) {
if (e.adType === admobSvc.AD_TYPE.INTERSTITIAL) {
$rootScope.isInterstitialAvailable = true;
}
}
});
$rootScope.$on(admobSvc.events.onAdOpened, function onAdOpened(evt, e) {
if ($rootScope.isAppForeground) {
if (e.adType === admobSvc.AD_TYPE.INTERSTITIAL) {
$rootScope.isInterstitialAvailable = false;
$timeout(admobSvc.requestInterstitialAd, 1); // Immediately request next interstitial asap
}
}
});
$ionicPlatform.on('pause', function onPause() {
if ($rootScope.isAppForeground) {
$rootScope.isAppForeground = false;
}
});
$ionicPlatform.on('resume', function onResume() {
if (!$rootScope.isAppForeground) {
$timeout(admobSvc.requestInterstitialAd, 1);
$rootScope.isAppForeground = true;
}
});
})
.controller('YourController', function ($rootScope, admobSvc) {
var vm = this;
vm.pleaseShowInterstitial = function () {
if ($rootScope.isInterstitialAvailable) {
admobSvc.showInterstitialAd();
}
};
});
Also note that there is a management for foreground app. This is important as if not, the user could put the app in background and the interstitial would automatically be shown. In your case it is not so relevant, as you control when the interstitial is shown, but I recommend you to keep this, in case you decide to start auto showing interstitials :)
Related
Recently I implemented consent dialog for users based on https://developers.google.com/admob/ump/android/quick-start
Today I received the next issue in my Admob account:
IAB TCF v2.0 errors detected. We've detected an issue on your IAB TC
string on one or more of your sites or apps. These errors may affect
your ability to serve ads to European users. A detailed report is
available for you on the EU user consent page.
I pressed "GO TO EU USER CONSENT" button and this was shown:
Downloaded csv file, here's content:
iab_tcf_errors_12_3_2020.csv
Mobile App,Ad unit,Error,Error count,Last detected date
com.*.*,7579454036,1.2,140,12/2/2020
com.*.*,3141515571,1.2,140,12/1/2020
Error code 1.2 from https://support.google.com/adsense/answer/9999955:
Consent code in my app (userConsentSDKSetup is called in onCreate of launch activity):
fun userConsentSDKSetup() {
val params = ConsentRequestParameters.Builder().build()
val information = UserMessagingPlatform.getConsentInformation(activity)
information.requestConsentInfoUpdate(
activity,
params,
{
// The consent information state was updated.
// You are now ready to check if a form is available.
if (information.isConsentFormAvailable && information.consentStatus == ConsentInformation.ConsentStatus.REQUIRED) {
activity.lifecycleScope.launchWhenStarted {
loadUserConsentForm(information)
}
}
},
{ Timber.e("userConsentSDK error ${it.message}") }
)
}
private fun loadUserConsentForm(information: ConsentInformation) {
UserMessagingPlatform.loadConsentForm(
activity,
{ consentForm ->
if (information.consentStatus == ConsentInformation.ConsentStatus.REQUIRED) {
activity.lifecycleScope.launchWhenStarted {
consentForm.show(activity) { // Handle dismissal by reloading form.
loadUserConsentForm(information)
}
}
}
}
) { Timber.e("userConsentSDK error loadForm ${it.message}") }
}
So what is wrong here? How can I solve this issue?
I am developing an Android app using Cordova and Ionic framework. I am playing a YouTube video with InAppBrowser using the code below:
window.open('https://www.youtube.com/embed/rAiw2SXPS-4', '_self');
But when I press the home button on the device while playing the video, the video is not paused. Due to this issue, my app is rejected after submitting to Google Play with the reason below:
Your submission has been rejected for enabling background playing of YouTube videos in violation of the YouTube API Terms of Service. If this submission was an update to an existing app, the version published prior to this update is still available in Google Play. Please modify your app and resubmit. Additional details have been sent to your account owner's email address.
I searched for a solution but have no luck. Can anybody help?
I was also struggling to find complete solution to pause(not stop) ongoing video(s) when device locks, but with no success. Eventually I found solution myself by combining several parts together.
Here is the directive that accomplishes YouTube player pause on device lock:
import { Directive, ElementRef, OnInit } from '#angular/core'
import { Platform } from 'ionic-angular'
import * as _ from 'lodash-es'
/* tslint:disable */
(function (apiInit) {
let _registerYouTubeAPIIfNotAlready = function () {
if (!window[ 'onYouTubeIframeAPIReady' ]) {
window[ 'onYouTubeIframeAPIReady' ] = function () {
apiInit.youTubeApiRegistered = true
if ((typeof apiInit.callback !== "undefined") && _.isFunction(apiInit.callback)) {
apiInit.callback()
}
}
} else {
console.error("trying to register YouTube API when it's already registered")
}
}
apiInit.setupYouTubeApiOrDefault = function (callback) {
if ((typeof callback === "undefined") || !_.isFunction(callback)) {
_registerYouTubeAPIIfNotAlready()
return
}
if(apiInit.youTubeApiRegistered){
callback()
return;
}
apiInit.callback = callback
_registerYouTubeAPIIfNotAlready()
}
}(window[ 'youTubeApiInit' ] = window[ 'youTubeApiInit' ] || {}))
#Directive({
selector: "[preventYoutubePlayOnBackground]",
})
export class PreventYouTubePlayOnBackgroundDirective implements OnInit {
public static youTubeIframeAPI = 'https://www.youtube.com/iframe_api'
public static injectYouTubeIframeApi(): void {
let youTubeCheckQuery = "script[src*='" + PreventYouTubePlayOnBackgroundDirective.youTubeIframeAPI + "']"
if (!document.querySelector(youTubeCheckQuery)) {
// from YouTube API documentation
let tag = document.createElement('script')
tag.src = PreventYouTubePlayOnBackgroundDirective.youTubeIframeAPI
let firstScriptTag = document.getElementsByTagName('script')[ 0 ]
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag)
}
}
public iframeId: string
private youTubeIframeElm: any
constructor(
public elm: ElementRef,
private platform: Platform,) {
this.youTubeIframeElm = elm.nativeElement
this.iframeId = this.youTubeIframeElm.getAttribute('id')
}
ngOnInit(): void {
this.platform.ready().then(() => {
PreventYouTubePlayOnBackgroundDirective.injectYouTubeIframeApi()
window[ 'youTubeApiInit' ].setupYouTubeApiOrDefault(() => {
this.setYouTubeApi()
this.platform.pause.subscribe(() => {
let player = new window[ 'YT' ].Player(this.iframeId) // TODO: add youtube API node module
player.a.contentWindow.postMessage('{"event":"command","func":"' + 'pauseVideo' + '","args":""}', '*')
})
})
})
}
private setYouTubeApi(): void {
let url = new URL(this.youTubeIframeElm.src)
if (!url.searchParams.get("enablejsapi")) { // enabling youTube js api to be able to create player
let prefix = (this.youTubeIframeElm.src.indexOf("?") === -1) ? "?" : "&"
this.youTubeIframeElm.src += prefix + "enablejsapi=true"
}
}
}
HTML for embedded YouTube player will be:
<iframe id="onboarding-video"
width="400"
height="300"
[src]="videoUrl"
frameborder="0"
allowfullscreen
preventYoutubePlayOnBackground
iframe-id="onboarding-video">
</iframe>
Note: above code is for ionic 2+, however for ionic 1 you can use:
(function() {
// same kind of logic here as written in above constructor body
$ionicPlatform.on('pause', function(event) {
// pausing player here
});
}())
Also you will need to create Angular 1 style directive instead of TypeScript one written above.
With $ionicPlatform you can use "on" method:
$ionicPlatform.on('pause', function(event) {
// pause video here
});
It is based on Cordova pause event:
document.addEventListener("pause", onPause, false);
function onPause() {
// Handle the pause event
}
See ionic documentation here and cordova documentation here.
You need to set shouldPauseOnSuspend=yes within the options when calling the open method for the inappbrowser. See the documentation here: https://github.com/apache/cordova-plugin-inappbrowser.
Something like this will work:
window.open('http://google.com','_blank', 'shouldPauseOnSuspend=yes');
I am developing an android phonegap application and I want to use in app billing in it. I installed the phonegap billing plugin and it works perfectly. Can you help me make it work correct with a link.
For example, here is the script code:
<script >
function successHandler (result) {
var strResult = "";
if(typeof result === 'object') {
strResult = JSON.stringify(result);
} else {
strResult = result;
}
alert("SUCCESS: \r\n"+strResult );
}
function errorHandler (error) {
alert("ERROR: \r\n"+error );
}
// Click on init button
function init(){
// Initialize the billing plugin
inappbilling.init(successHandler, errorHandler, {showLog:true});
}
// Click on purchase button
function buy(){
// make the purchase
inappbilling.buy(successHandler, errorHandler, "good_id");
}
// Click on ownedProducts button
function ownedProducts(){
// Initialize the billing plugin
inappbilling.getPurchases(successHandler, errorHandler);
}
// Click on Consume purchase button
function consumePurchase(){
inappbilling.consumePurchase(successHandler, errorHandler, "good_id");
}
// Click on subscribe button
function subscribe(){
// make the purchase
inappbilling.subscribe(successHandler, errorHandler,"good_id");
}
// Click on Query Details button
function getDetails(){
// Query the store for the product details
inappbilling.getProductDetails(successHandler, errorHandler, "good_id");
}
// Click on Get Available Products button
function getAvailable(){
// Get the products available for purchase.
inappbilling.getAvailableProducts(successHandler, errorHandler);
}
</script>
And i need it to work with for example -
Good
Thats after clicking on a link first of all i ll be able to pay before linking to a page.
Thanks. Sorry for my bad English.
I'm not sure i understood what you want, your english is worst than mine. But if you just want to launch a purchase when clicking and after redirect, you may use onclick event and window.location.replace :
<a href="good.html" id='good' data-ignore="true" onclick="buy()" >Good</a>
// Click on purchase button
function buy(){
// make the purchase
inappbilling.buy(successHandler, errorHandler, "good_id");
return false;
}
and then add window.location.replace('yourlinkpage'); on your successHandler
But maybe an input submit should be more appropriate?
I have an Android application build with PhoneGap 3.4.
The plugin I am running is: https://github.com/floatinghotpot/cordova-plugin-admob.git
The installation instructions are:
A simplified method (tested on Cordova 3.4.0)
1. Install the Google Play Services plugin:
```cordova plugin add https://github.com/MobileChromeApps/google-play-services.git```
2. Install _this_ plugin:
```cordova plugin add https://github.com/floatinghotpot/cordova-plugin-admob.git```
The directions for displaying the Ads are:
##Using the Plugin:
There are 3 calls needed to get AdMob Ads:
1. `createBannerView`
Takes in a object containing a publisherId and adSize, as well as success
and failure callbacks. An example call is provided below:
window.plugins.AdMob.createBannerView(
{
'publisherId': 'INSERT_YOUR_PUBLISHER_ID_HERE',
'adSize': window.plugins.AdMob.AD_SIZE.BANNER
},
successCallback,
failureCallback
);
2. `requestAd`
Takes in an object containing an optional testing flag, and an optional
list of extras. This method should only be invoked once createBannerView
has invoked successCallback. An example call is provided below:
window.plugins.AdMob.requestAd(
{
'isTesting': false,
'extras': {
'color_bg': 'AAAAFF',
'color_bg_top': 'FFFFFF',
'color_border': 'FFFFFF',
'color_link': '000080',
'color_text': '808080',
'color_url': '008000'
},
},
successCallback,
failureCallback
);
3. `showAd`
Show or hide the Ad.
This method should only be invoked once createBannerView has invoked successCallback.
An example call is provided below:
window.plugins.AdMob.showAd(
true,
successCallback,
failureCallback
);
And here is my attempt:
function onLoad(){
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady() {
if(window.plugins && window.plugins.AdMob) {
var admob_android_key = 'ca-app-pub-xxxxxxxxxxxxxxxxxxxxxxx';
var adId = (navigator.userAgent.indexOf('Android') >=0) ? admob_android_key : admob_ios_key;
var am = window.plugins.Admob;
am.createBannerView(
{
'publisherId': adId,
'adSize': am.AD_SIZE.BANNER,
'bannerAtTop': false
},
function() {
am.requestAd(
{ 'isTesting':false },
function(){
am.showAd( true );
},
function(){ alert('failed to request ad'); }
);
},
function(){ alert('failed to create banner view'); }
);
} else {
alert('AdMob plugin not available/ready.');
}
}
Any idea where I am going wrong with this? Thank you in advance.
what you pasted is too complex
there are several to show ad right.
1.install ,just add this in your phonegap build config
<gap:plugin name="com.admob.plugin" version="1.0.0" source="plugins.cordova.io"/>
2.config admob
admob.showBannerAbsolute(admob.BannerSize.BANNER,0,70);
3.show admob ad when you want.
admob.showBanner(admob.BannerSize.BANNER,admob.Position.TOP_APP);
that is all.
I'm using facebook 3.0.1 titanium module. In Android, the Facebook apprequests dialog always returns as cancelled, even while the actual apprequest is send as can be seen on Facebook. Because of this I cannot store the requestid in my back-end, which makes the apprequest useless.
But in iOS it works fine.
This is my code
var fb = require('facebook');
fb.appid = 'my_app_id';
fb.permissions = ['publish_stream', 'read_stream', 'email']; // Permissions your app needs
fb.forceDialogAuth = true;
fb.addEventListener('login', function(evt) {
if (evt.success) {
fb.dialog("apprequests", {
message:"LeaugeNation",
// max_recipients : "2"
}, function(response) {
alert(JSON.stringify(response));
if(response.result) {
alert("send friend req");
// sendFacebookInvite(e.result);
}
});
} else if (evt.error) {
alert("error");
} else if (evt.cancelled) {
alert("cancelled");
} else {
alert("default");
}
});
fb.authorize();
If i run the code i'm getting the following result
{"cancelled":true,"code":-1,"success":false}
I made the following changes, but did't got the result.
changed the appid won't change result
changed the Key Hash for that Facebook App
Thanks in advance.
Can you please tell me what change, that i want to made to get the correct result in Android.
You must look to facebook setting. did you register Your activity and allow the permission from developers site which you are using here. Also If you are not exporting your app please export properly with proper keystore.