Tip:
Highlight text to annotate it
X
ERIC LEICHTENSCHLAG: Hello, everybody.
My name is Eric Leichtenschlag, from the AdMob
SDK developer relations team here at Google, and I'm here
today to talk to you about AdMob Mediation, and more
specifically, custom events and their use cases and how
you can use them.
So first off, you guys might be wondering,
what are custom events?
A custom event is a mechanism used to execute some custom
code in your app that can serve a view into the ad space
instead of just showing an ad from a normal ad network.
This could be an ad from a network that's not supported
by Mediation or any other custom view that you put in.
So why would you use it?
If you want to incorporate an ad network that doesn't have
an AdMob Mediation adapter, then you could write your own
custom event to serve that network, and you can also show
some custom view instead of an ad.
So let's walk through how you can set up this custom event
and write your own code to serve this custom view.
So the first thing you want to do is, in your AdMob settings
in your Mediation placement, you'll want to
add a custom event.
And the custom event has three properties--
a label, a class name, and a parameter.
The label is just a name for your custom event, so in this
example, we called it AdMobCustomEvent.
The class name is your fully qualified class path to the
custom class you're going to write.
In this case it could be your.package.CustomAd.
And the parameter is just some parameter that you will need
in your app to make the request or to get this ad or
this custom view that you want to show.
We'll walk through some examples later of how you
would use this.
And then in your app you would create this class-- that
your.package.CustomAd class--
and that class would implement the custom
event banner interface.
This interface has two methods--
request banner ad and destroy method.
The main one is request banner ad, and in this method, you
will take in a banner listener, an activity, your
label and serverParameter defined on the server, the
AdSize for the request, some AdRequest parameters, and this
extra object that you can pass to your custom event from
within your app.
The main things to note here are the custom event banner
listener, you will use this to send back notifications from
the custom event to the Mediation layer to let you
know to tell Mediation that you've got an ad or you
didn't get an ad.
So in addition to that request banner ad method, you will
also implement CustomEventBannerListener, and
you'll take that banner listener, and you'll send
these messages back, depending on how your
custom event operates.
If you receive an ad or you want to show a custom view
into your ad space, you'll call back with onReceivedAd
and pass the view that you want to show.
Again, this could be an ad from another network or custom
view of your own.
And if you don't want to return an ad, you just call
onFailedToReceiveAd, and AdMob Mediation will just go to the
next network and try to fetch an ad from the next network in
your Mediation placement.
You can also invoke onClick when your ad is clicked.
This'll track clicks in the AdMob Mediation reporting.
You also might want to call onPresentScreen or
onDismissScreen if your ad or custom view launches another
screen and the app is no longer in control.
So that's it from planning custom events.
Now we're going to walk through some sample custom
events that you can implement.
So the first example is Percentage House Ads.
This example will allow you to request AdMob House Ads a
percentage of the time.
This is a little bit different than the AdMob House Ads
network that you can implement with Mediation.
A couple key differences are when putting custom ads into
your Mediation placement in the back end, if you define
your configuration with ECPM, you might have house ads at
the very back of the flow, and if you have other networks
that are filling every request, you won't
show any house ads.
And if you put house ads as a percentage and do percentage
allocation, then you might get house ads a percentage of the
time, but then you cannot configure other
networks via ECPM.
Maybe you have one network that pays more per click, and
you want to serve them every time that you're not doing
your house ads, but because you're doing percentage
placement, you don't really have that much control.
In addition, AdMob caches the configuration from the server
for 300 seconds.
So if you get house ads first from your percentage order,
then you're going to serve house ads for 300 seconds.
And depending on what your refresh is, you make it five
or six house ads in a row, and you might not want that.
So this percentage house ads custom event gives you a lot
of flexibility.
You can put it first in your Mediation stack with ECPM, and
the app can control how often it would show that house ad or
decide to fail, and I'll show you how that happens.
So the label for this custom event example is just
Percentage House Ads.
The class I'm going to implement is com.google.examp
le.ads.customeve nts.impl.PercentageHouseAds.
And I'm passing in two parameters here.
Since the parameter is going to be a string, I'm actually
passing in some JSON, and I'm going to have the app kind of
decode that JSON and get these values.
It's going to be the publisher ID, which is trafficked to
house ads, and you can also set this up in the AdMob UI,
and as well as a percentage for how often you want to
serve this house ad.
And below this, we have the sample ECPM values for
trafficking these ads.
So in this example I have, I'm going to have house ads valued
higher than the AdMob network.
So what's going to happen is, I'm going to try House Ads
first, and if that fails, I'm going to go
to the AdMob network.
So now let's walk through how you might implement this.
So our custom class is going to implement the request
BannerAd method, and we're going to store the
bannerListener for callbacks later.
And the first thing we're going to do is
extract these values.
I said we passed in JSON to that server parameter, and so
we're going to create a new JSON object here and try to
get the string publisher ID and the
percentage from this JSON.
If we entered bad JSON, or for whatever reason we can't parse
it, it will just log a message and quit, so this fails
gracefully.
If this happens, then we just won't ever serve a house ad,
and we'll just go on to the AdMob network.
So at this point, we'll have our publisher ID as well as
our percentage, and we'll construct a random number.
And if this random number is higher than the percentage, we
won't return the house ad, and if it's less, we will return
the house ad.
So let's pick a random number and say it's 53.
Since 53 is greater than 50, we're just not going to show
the house ad.
But if it's less than 50, then we will show the house ad.
So similarly, if you wanted to do house ads 5% of the time,
then if the random number was greater than five, you just
wouldn't show the house ad, but if it was less
than five, we would.
And creating the house ad is very simple-- we just creating
a new AdView, pass it the activity and the ad size and
that publisher ID from the server.
We set the AdListener so we can listen for when the house
ad comes back, and we can send that event back
to mediation layer.
And then we'll just load an ad with the new AdRequest.
And then in the callbacks, when we get the house ad from
AdMob, we'll set the bannedListener and call
onReceivedAd and pass in the ad view.
So this tells AdMob Mediation, hey, I have this ad view with
my house ad, please show it.
If for some reason the request to get the house ad fails,
we'll just tell Mediation that we failed to get that ad, and
it'll move on to the next network.
And if we click that ad we'll call the onClick methods so
that it gets logged in mediation reporting, and we'll
also call onPresentScreen to let the user know that we
launched a view on top.
These callbacks are important because you'll, as the user,
get them when implementing your app.
So this is custom event code is separate from your normal
AdMob declaration, but when you declare your AdMob AdView,
you might want to know when the user clicks on an ad and
presents a new screen, just so you can maybe pause your game.
So by having your custom events send this
onPresentScreen message, Mediation will then tell you
in your main app code that hey, we're presenting
something on the screen, and you can listen for that and
pause your game or something you need to.
So I'm going to run a little bit of a demo here.
So I have a couple examples on this app and the first one
here is percentage house ads.
So in this example, here is this Mediation ID that I have
set up already on the server.
And in this example, I'm actually overriding what the
server has with this own percentage, so that I can just
demonstrate it for you.
Say I put in 50% here and request ad.
We're noticing that the random number was 47, and it was less
than 50, so we're going to get this percentage house ad.
But if I try it again, 87 this time, is going to be greater
than 50, so we're going to skip the house ad and based on
the configuration I mentioned before, we go to AdMob for an
ad, and look, we're getting back an AdMob ad.
So this is a great way for every refresh to just check,
hey, should I get a custom events or not?
And if I change this number to something like five, maybe you
only want to show house ads 5% of the time,
then there you go.
92 is greater than 5, so we'll skip house ad.
So this is a great way to show house ads a certain percentage
of the time.
As you notice, on every single request, we're making this
check again.
So you're not going to get house ads five or six times in
a row like you would if you set up house ads just via the
AdMob house ads network already
available within Mediation.
You could get a different ad every time.
And you could set this percentage however you want.
When you do implement this yourself, you probably will
not have a percentage input.
Again, you'll get the number for the server.
And this Mediation ID you'll also have set up, and so
you're app won't need to have these inputs.
So the next example is just the demo again.
We request an ad, so sometimes we'll get percentage house
ads, the next time we'll get just an AdMob ad.
So the next demon I have is for birthday ads.
So this is just a simple example that says, hey, if
it's your birthday, I'll just show you this birthday image
instead of showing you an ad.
Maybe if your app gets user information and knows what the
user's birthday is, you might kind of as a happy birthday
thing say, I'm not going to show you ads today.
So we're going to just go through an
example of how that works.
So this label is just Birthday Image, and our class name is
going to be BirthdayAds.
And in this case, we don't need a server parameter, just
for how the implementation works.
So I just passed in unused here.
The apps not actually going to use this parameter.
And then for the ad network set up, again I have the
birthday image event set at a higher ECPM than the AdMob
network so that we'll try to serve the
birthday image first.
So let's now walk through the implementation
for birthday ads.
So one thing you want to do for this example that's a
little bit different than the previous example was we're
going to have to tell the custom event what the user's
birthday is.
So in your main app code, when you're creating your main ad
request, you're going to want to pass in an extra value, and
this can be done through the custom event extras class.
And we're going to pass in the user's birthday.
So in this case, we're going to get the birthday from a
user input, and get the year, month, and day and pass that
birthday into the network extras.
Something important to note here is this extra.addExtra
line with the custom event label.
So when creating custom event extras, it's just key value
pairs, but the key has to be the label
of your custom event.
So going back to this birthday image--
Birthday space Image--
that's going to have to be the key to this custom event
extras that you add.
And so I have it here defined as a constant in my class, and
the value is just going to be the birthday.
And we're going to set the network
lectures on that request.
So what this'll do is when a custom then comes in for
Birthday Image, that birthday will get passed and as the
custom event extra, and we'll go through
that in the next slide.
So in our requestBannerAd method, the last parameter, if
you remember from before, is the object customEventExtra.
And so, in this case, our class is going to check the
customEventExtra and try to cast it as the calendar that
we passed in.
If we, for whatever reason, can't cast as a calendar or
couldn't pass the birthday or couldn't find it, we're just
going to fail to receive an ad, and again we're just going
to the next ad network and request AdMob.
But if we can parse the birthday, then we're going to
continue on.
And again if there's some kind of exception,
it will just fail.
So once we have this birthday.
We can then check if it actually is their
birthday on that day.
So we can just get the current date with just creating a new
Gregorian calendar, and just check if the month and the day
are the same.
And if they are, then it's their birthday, and we'll show
them this custom birthday ad.
So in this case, I have just an image that's static in the
app, it's in my resources.
And just the example I have happened to be an animated
gif, so in this example we'll just create a web view and
load it with this URL from our resources, birthday.gif, and
we'll just call onRecievedAd with that webview.
If it's not your birthday, will just, again, fail to
receive the ad and just move on to the next network.
So this is what the demo looks like.
You can enter your birthday here, and if it is your
birthday then it'll show this happy birthday image.
And it's not clickable, so the user can't accidentally click
it and go to a new screen.
And if it's not their birthday, then we'll move on
the next network and get an AdMob ad.
So we'll try walking through this demo now.
So again, this is the Mediation placement ID I
already set up on the server.
If you want to set up your own, then you
could change this.
And today happens to be April 29th, so if I request ad, I
pass this into the user, and it is their birthday, and so
we get a happy birthday image.
And so maybe in your own implementation you just
wouldn't show an ad at all.
You would say, it's your birthday, I'm not going to
show you any ads, enjoy an ad-free day.
Maybe if we say our birthday is March 29th, which is not
today, then we'll realize that's not your birthday,
we'll go on to the next network, and we'll get the
AdMob ad again.
So that's a cool little example of how to give
somebody a birthday treat and just not show them ads that
day and show them this birthday image, and it's just
a nice touch.
The final example I'm going to show you guys is an in-app
purchase example.
This in-app purchase ad will launch an in-app billing flow,
and so you can actually ask the user to
make an in-app purchase.
Maybe do you want a get rid of ads?
You can upgrade, make an in-app purchase to get
something ad free, and you can show this in a certain amount
of the time.
So I'm going to walk you through how you can do a
custom event to invoke an in-app purchase.
So in this case, our label is just In app purchase, our
class name is going to be the InAppPurchase class, and we're
also not going to need a server parameter for this, so
I called it unused.
For my network configuration, I have in-app purchase turned
on higher, and in this case, I have AdMob turned off, just so
if the in-app purchase doesn't work, then we just
won't get any ads.
So how does this work?
In your requestBannerAd method, the first thing you
want to do is try to find out if the user made a purchase.
In this case, we're using the test purchase of in-app
billing library, just kind of as a proof of concept.
This madeTestPurchase method is checking the shared
preferences.
So in this example, once we make the in-app purchase,
we're just going to store in the shared preferences, hey, I
made the in-app purchase, so I don't need to do this again,
and just don't show ads.
So if we've already made the purchase, we're just going to
fail to receive the ad, and we just won't get any ads.
If we haven't, we're going to start the in-app billing flow.
So this example is largely taken from the trivial drive
example provided with the Google in-app billing library,
version three, and it has all these helper classes, so we're
going to an in-app billing helper, pass in the activity
and our public key.
The public key can be anything if you're just doing the
testPurchase, it doesn't have to be an actual value.
The first thing we're going to do is set it up, start it up,
and when the setup finishes, if this setup succeeds, then
we can move on, otherwise we'll just fail to get the ad.
And after it sets up, we'll want to query the inventory to
see have we made a purchase already.
So sometimes you might have made the purchase, but not
have stored that you actually made it yet, you might not
have consumed it.
So this checks for the case where we actually made the
purchase but didn't consume it yet, while the
madeTestPurchase check at the top checks if we already
consumed it.
So in querying the inventory, if the inventory query fails,
again, we'll fail to return an ad, because we all know if the
user made a test purchase or not.
Otherwise, we check if the purchase is
made, but not consumed.
So once we get this inventory result, we'll check for the
test successful purchase SKU, and we have that
testPurchaseInventory if the testPurchase is not null and
we verified that this is actually a valid purchase.
Again, when you're doing in-app billing yourself,
you're actually going to want to verify that the payload is
valid so that nobody can hack the in-app purchase.
If you've already made this testPurchase, then we're going
to consume it, and once we consume it, we'll just fail to
return an ad, because we've already made the purchase.
Otherwise, we're going to get the ad.
We're going to create the in-app purchase ad and call
onReceivedAd.
So I'm going to walk through how we create it.
So I just want to go back to the point that custom events
only take in a view, it doesn't necessarily
have to be an ad.
So in this case, our ad is just going to be a view.
So just creating a relative layout here with a button on
the right side that says upgrade, and some text that
says, do you want to upgrade?
So here I'm showing how we're going to add the purchase
button, and when it's clicked, we're going to start launching
the purchase flow, iabhelper.launchPurchaseFlow,
with that purchase.
So I didn't show you all the code here, but we'll have a
sample app kind of demonstrating this, and we can
walk through it more, but here's kind of
how the demo works.
Again, we have our Mediation placement ID up top that I set
up, and you can request an ad, and if you haven't made the
in-app purchase yet, you'll get this view at the bottom.
And this is in the same ad space, and it says, you want
to remove ads?
If so, upgrade.
And if you click the upgrade button, you'll
make the sample purchase.
Again, if you wanted to actually do in-app billing,
you're going to want to go to the Android console and set up
your in-app billing SKUs.
But for this sample, we can use the sample SKU.
And if you make this payment, then the next time you request
the ad, you can check, oh, the purchase was already made, we
don't need to show the ad.
And we just won't show an ad.
So I can't give you a demo on the simulator here, because it
doesn't have in-app billing enabled, but I can walk
through some more of the code here.
So here's the full create in-app purchase.
We're actually creating a text view that says do you want to
remove ads?
And that's going to go on the left side, and the button,
upgrade, is going to go on the right side with
this onClick listener.
This is done over here.
Here's our queryInventory finished, we saw this on the
slide as well.
If the result failed, then we're just going to fail to
return an ad.
Otherwise, we check if we made this purchase, and if we have,
we're going to consume it.
Something I didn't put in the slides is once the purchase is
finished and we verified that the purchase is valid, then
we're just going to save the testPurchase, which is just
going to put it in shared preferences, and then we're
going to consume it.
The main reason that we're consuming it is just for the
sample to be able to clear the purchase and be able to
purchase it again.
If you want to make it an infinite thing where you don't
ever consume it, then you can just not consume, and then
your custom event can just query the inventory, and if
it's there it knows it doesn't need to show an ad.
The consuming part was just for the demo purposes.
Finally, when we've consumed it, again, we're going to see
the testPurchase and we're just going to fail to return
an ad, because we just consumed it, we just made the
purchase, we don't need to have an ad anymore.
Again, you're going to want to verify that the payload is
valid when you do it yourself, but in this case, we're just
always assuming it's true.
And here, just a couple wrappers for checking if they
made the test purchase.
Again, we're just checking shared preferences, and saving
the test purchase is also just done with shared preferences.
We're going to put the Boolean and commit it.
Also remember that we need to implement the destroy method
when doing a custom event.
It doesn't really need to do much, in this case, we're just
setting the activity passed to us to null so that we don't
have any memory leaks.
So these are all the demos I have.
Again, custom events are very powerful, you've seen a couple
examples here of what they can do.
You can also integrate--
the standard example would be just to integrate some other
ad network and just return another ad network's view
within that custom event, maybe for network that's not
supported for AdMob directly with an
AdMob Mediation adapter.
Some resources here are the custom event sample project
will be available on our Google code project,
google-mobile-dev.
You can download our SDK from our mobile ads
SDK developer docs.
Google.com/ads/admob is where you can set up your AdMob
Mediation placements.
To learn more about custom events, we actually have a
class on it, and you can learn just more about how customs
events work with the APIs.
We also have our developer docs, our forum, our Google+
page, and our blog, where you can just find a lot more
information about AdMob.
And if you have any questions you can ask us on our
developer forums.
So I hope you guys learned a lot more about custom events
today and have some cool ideas about how you can implement
them in your app.
Thanks for watching.