2626import android .widget .RatingBar ;
2727import android .widget .TextView ;
2828import android .widget .Toast ;
29+
2930import com .google .android .gms .ads .AdListener ;
3031import com .google .android .gms .ads .AdLoader ;
32+ import com .google .android .gms .ads .VideoController ;
33+ import com .google .android .gms .ads .VideoOptions ;
3134import com .google .android .gms .ads .doubleclick .PublisherAdRequest ;
35+ import com .google .android .gms .ads .formats .MediaView ;
3236import com .google .android .gms .ads .formats .NativeAd ;
37+ import com .google .android .gms .ads .formats .NativeAdOptions ;
3338import com .google .android .gms .ads .formats .NativeAppInstallAd ;
3439import com .google .android .gms .ads .formats .NativeAppInstallAdView ;
3540import com .google .android .gms .ads .formats .NativeContentAd ;
3641import com .google .android .gms .ads .formats .NativeContentAdView ;
3742import com .google .android .gms .ads .formats .NativeCustomTemplateAd ;
38- import java .util .List ;
43+
44+ import java .util .Locale ;
3945
4046/**
4147 * A simple activity class that displays native ad formats.
4248 */
4349public class MainActivity extends ActionBarActivity {
4450
4551 private static final String DFP_AD_UNIT_ID = "/6499/example/native" ;
46- private static final String SIMPLE_TEMPLATE_ID = "10063170 " ;
52+ private static final String SIMPLE_TEMPLATE_ID = "10104090 " ;
4753
4854 private Button mRefresh ;
4955 private CheckBox mRequestAppInstallAds ;
5056 private CheckBox mRequestContentAds ;
5157 private CheckBox mRequestCustomTemplateAds ;
58+ private CheckBox mStartVideoAdsMuted ;
59+ private TextView mVideoStatus ;
5260
5361 @ Override
5462 protected void onCreate (Bundle savedInstanceState ) {
@@ -59,6 +67,8 @@ protected void onCreate(Bundle savedInstanceState) {
5967 mRequestAppInstallAds = (CheckBox ) findViewById (R .id .cb_appinstall );
6068 mRequestContentAds = (CheckBox ) findViewById (R .id .cb_content );
6169 mRequestCustomTemplateAds = (CheckBox ) findViewById (R .id .cb_customtemplate );
70+ mStartVideoAdsMuted = (CheckBox ) findViewById (R .id .cb_start_muted );
71+ mVideoStatus = (TextView ) findViewById (R .id .tv_video_status );
6272
6373 mRefresh .setOnClickListener (new View .OnClickListener () {
6474 @ Override
@@ -82,13 +92,15 @@ public void onClick(View v) {
8292 private void populateAppInstallAdView (NativeAppInstallAd nativeAppInstallAd ,
8393 NativeAppInstallAdView adView ) {
8494 adView .setHeadlineView (adView .findViewById (R .id .appinstall_headline ));
85- adView .setImageView (adView .findViewById (R .id .appinstall_image ));
8695 adView .setBodyView (adView .findViewById (R .id .appinstall_body ));
8796 adView .setCallToActionView (adView .findViewById (R .id .appinstall_call_to_action ));
8897 adView .setIconView (adView .findViewById (R .id .appinstall_app_icon ));
8998 adView .setPriceView (adView .findViewById (R .id .appinstall_price ));
9099 adView .setStarRatingView (adView .findViewById (R .id .appinstall_stars ));
91100 adView .setStoreView (adView .findViewById (R .id .appinstall_store ));
101+ // The MediaView will display a video asset if one is present in the ad, and the first image
102+ // asset otherwise.
103+ adView .setMediaView ((MediaView ) adView .findViewById (R .id .appinstall_media ));
92104
93105 // Some assets are guaranteed to be in every NativeAppInstallAd.
94106 ((TextView ) adView .getHeadlineView ()).setText (nativeAppInstallAd .getHeadline ());
@@ -97,13 +109,36 @@ private void populateAppInstallAdView(NativeAppInstallAd nativeAppInstallAd,
97109 ((ImageView ) adView .getIconView ()).setImageDrawable (nativeAppInstallAd .getIcon ()
98110 .getDrawable ());
99111
100- List <NativeAd .Image > images = nativeAppInstallAd .getImages ();
101-
102- if (images .size () > 0 ) {
103- ((ImageView ) adView .getImageView ()).setImageDrawable (images .get (0 ).getDrawable ());
112+ // Get the video controller for the ad. One will always be provided, even if the ad doesn't
113+ // have a video asset.
114+ VideoController vc = nativeAppInstallAd .getVideoController ();
115+
116+ // Apps can check the VideoController's hasVideoContent property to determine if the
117+ // NativeAppInstallAd has a video asset.
118+ if (vc .hasVideoContent ()) {
119+ mVideoStatus .setText (String .format (Locale .getDefault (),
120+ "Video status: Ad contains a %.2f:1 video asset." ,
121+ vc .getAspectRatio ()));
122+
123+ // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
124+ // VideoController will call methods on this object when events occur in the video
125+ // lifecycle.
126+ vc .setVideoLifecycleCallbacks (new VideoController .VideoLifecycleCallbacks () {
127+ public void onVideoEnd () {
128+ // Publishers should allow native ads to complete video playback before
129+ // refreshing or replacing them with another ad in the same UI location.
130+ mRefresh .setEnabled (true );
131+ mVideoStatus .setText ("Video status: Video playback has ended." );
132+ super .onVideoEnd ();
133+ }
134+ });
135+ } else {
136+ mRefresh .setEnabled (true );
137+ mVideoStatus .setText ("Video status: Ad does not contain a video asset." );
104138 }
105139
106- // Some aren't guaranteed, however, and should be checked.
140+ // These assets aren't guaranteed to be in every NativeAppInstallAd, so it's important to
141+ // check before trying to display them.
107142 if (nativeAppInstallAd .getPrice () == null ) {
108143 adView .getPriceView ().setVisibility (View .INVISIBLE );
109144 } else {
@@ -141,25 +176,50 @@ private void populateAppInstallAdView(NativeAppInstallAd nativeAppInstallAd,
141176 private void populateContentAdView (NativeContentAd nativeContentAd ,
142177 NativeContentAdView adView ) {
143178 adView .setHeadlineView (adView .findViewById (R .id .contentad_headline ));
144- adView .setImageView (adView .findViewById (R .id .contentad_image ));
145179 adView .setBodyView (adView .findViewById (R .id .contentad_body ));
146180 adView .setCallToActionView (adView .findViewById (R .id .contentad_call_to_action ));
147181 adView .setLogoView (adView .findViewById (R .id .contentad_logo ));
148182 adView .setAdvertiserView (adView .findViewById (R .id .contentad_advertiser ));
183+ // The MediaView will display a video asset if one is present in the ad, and the first image
184+ // asset otherwise.
185+ adView .setMediaView ((MediaView ) adView .findViewById (R .id .contentad_media ));
149186
150187 // Some assets are guaranteed to be in every NativeContentAd.
151188 ((TextView ) adView .getHeadlineView ()).setText (nativeContentAd .getHeadline ());
152189 ((TextView ) adView .getBodyView ()).setText (nativeContentAd .getBody ());
153190 ((TextView ) adView .getCallToActionView ()).setText (nativeContentAd .getCallToAction ());
154191 ((TextView ) adView .getAdvertiserView ()).setText (nativeContentAd .getAdvertiser ());
155192
156- List <NativeAd .Image > images = nativeContentAd .getImages ();
157-
158- if (images .size () > 0 ) {
159- ((ImageView ) adView .getImageView ()).setImageDrawable (images .get (0 ).getDrawable ());
193+ // Get the video controller for the ad. One will always be provided, even if the ad doesn't
194+ // have a video asset.
195+ VideoController vc = nativeContentAd .getVideoController ();
196+
197+ // Apps can check the VideoController's hasVideoContent property to determine if the
198+ // NativeContentAd has a video asset.
199+ if (vc .hasVideoContent ()) {
200+ mVideoStatus .setText (String .format (Locale .getDefault (),
201+ "Video status: Ad contains a %.2f:1 video asset." ,
202+ vc .getAspectRatio ()));
203+
204+ // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
205+ // VideoController will call methods on this object when events occur in the video
206+ // lifecycle.
207+ vc .setVideoLifecycleCallbacks (new VideoController .VideoLifecycleCallbacks () {
208+ public void onVideoEnd () {
209+ // Publishers should allow native ads to complete video playback before
210+ // refreshing or replacing them with another ad in the same UI location.
211+ mRefresh .setEnabled (true );
212+ mVideoStatus .setText ("Video status: Video playback has ended." );
213+ super .onVideoEnd ();
214+ }
215+ });
216+ } else {
217+ mRefresh .setEnabled (true );
218+ mVideoStatus .setText ("Video status: Ad does not contain a video asset." );
160219 }
161220
162- // Some aren't guaranteed, however, and should be checked.
221+ // These assets aren't guaranteed to be in every NativeContentAd, so it's important to
222+ // check before trying to display them.
163223 NativeAd .Image logoImage = nativeContentAd .getLogo ();
164224
165225 if (logoImage == null ) {
@@ -182,22 +242,54 @@ private void populateContentAdView(NativeContentAd nativeContentAd,
182242 */
183243 private void populateSimpleTemplateAdView (final NativeCustomTemplateAd nativeCustomTemplateAd ,
184244 View adView ) {
185- ImageView mainImage = (ImageView ) adView .findViewById (R .id .simplecustom_image );
186245 TextView headline = (TextView ) adView .findViewById (R .id .simplecustom_headline );
187246 TextView caption = (TextView ) adView .findViewById (R .id .simplecustom_caption );
188247
189248 headline .setText (nativeCustomTemplateAd .getText ("Headline" ));
190249 caption .setText (nativeCustomTemplateAd .getText ("Caption" ));
191250
192- mainImage .setImageDrawable (
193- nativeCustomTemplateAd .getImage ("MainImage" ).getDrawable ());
251+ FrameLayout mediaPlaceholder =
252+ (FrameLayout ) adView .findViewById (R .id .simplecustom_media_placeholder );
253+
254+ // Get the video controller for the ad. One will always be provided, even if the ad doesn't
255+ // have a video asset.
256+ VideoController vc = nativeCustomTemplateAd .getVideoController ();
257+
258+ // Apps can check the VideoController's hasVideoContent property to determine if the
259+ // NativeCustomTemplateAd has a video asset.
260+ if (vc .hasVideoContent ()) {
261+ mediaPlaceholder .addView (nativeCustomTemplateAd .getVideoMediaView ());
262+ mVideoStatus .setText (String .format (Locale .getDefault (),
263+ "Video status: Ad contains a %.2f:1 video asset." ,
264+ vc .getAspectRatio ()));
265+
266+ // Create a new VideoLifecycleCallbacks object and pass it to the VideoController. The
267+ // VideoController will call methods on this object when events occur in the video
268+ // lifecycle.
269+ vc .setVideoLifecycleCallbacks (new VideoController .VideoLifecycleCallbacks () {
270+ public void onVideoEnd () {
271+ // Publishers should allow native ads to complete video playback before
272+ // refreshing or replacing them with another ad in the same UI location.
273+ mRefresh .setEnabled (true );
274+ mVideoStatus .setText ("Video status: Video playback has ended." );
275+ super .onVideoEnd ();
276+ }
277+ });
278+ } else {
279+ ImageView mainImage = new ImageView (this );
280+ mainImage .setAdjustViewBounds (true );
281+ mainImage .setImageDrawable (nativeCustomTemplateAd .getImage ("MainImage" ).getDrawable ());
194282
195- mainImage .setOnClickListener (new View .OnClickListener () {
196- @ Override
197- public void onClick (View v ) {
198- nativeCustomTemplateAd .performClick ("MainImage" );
199- }
200- });
283+ mainImage .setOnClickListener (new View .OnClickListener () {
284+ @ Override
285+ public void onClick (View v ) {
286+ nativeCustomTemplateAd .performClick ("MainImage" );
287+ }
288+ });
289+ mediaPlaceholder .addView (mainImage );
290+ mRefresh .setEnabled (true );
291+ mVideoStatus .setText ("Video status: Ad does not contain a video asset." );
292+ }
201293 }
202294
203295 /**
@@ -216,6 +308,8 @@ private void refreshAd(boolean requestAppInstallAds, boolean requestContentAds,
216308 return ;
217309 }
218310
311+ mRefresh .setEnabled (false );
312+
219313 AdLoader .Builder builder = new AdLoader .Builder (this , DFP_AD_UNIT_ID );
220314
221315 if (requestAppInstallAds ) {
@@ -272,14 +366,27 @@ public void onCustomClick(NativeCustomTemplateAd ad, String s) {
272366 });
273367 }
274368
369+ VideoOptions videoOptions = new VideoOptions .Builder ()
370+ .setStartMuted (mStartVideoAdsMuted .isChecked ())
371+ .build ();
372+
373+ NativeAdOptions adOptions = new NativeAdOptions .Builder ()
374+ .setVideoOptions (videoOptions )
375+ .build ();
376+
377+ builder .withNativeAdOptions (adOptions );
378+
275379 AdLoader adLoader = builder .withAdListener (new AdListener () {
276380 @ Override
277381 public void onAdFailedToLoad (int errorCode ) {
382+ mRefresh .setEnabled (true );
278383 Toast .makeText (MainActivity .this , "Failed to load native ad: "
279384 + errorCode , Toast .LENGTH_SHORT ).show ();
280385 }
281386 }).build ();
282387
283388 adLoader .loadAd (new PublisherAdRequest .Builder ().build ());
389+
390+ mVideoStatus .setText ("" );
284391 }
285392}
0 commit comments