Chapter 15: In App Advertising

Slides:



Advertisements
Similar presentations
2D Graphics Drawing Things. Graphics In your GUI, you might want to draw graphics E.g. draw lines, circles, shapes, draw strings etc The Graphics class.
Advertisements

Android UserInterfaces Nasrullah Niazi. overView All user interface elements in an Android app are built using View and ViewGroup objects. A View is an.
CE881: Mobile and Social Application Programming Simon M. Lucas Layouts.
All About Android Introduction to Android 1. Creating a New App “These aren’t the droids we’re looking for.” Obi-wan Kenobi 1. Bring up Eclipse. 2. Click.
Application Fundamentals. See: developer.android.com/guide/developing/building/index.html.
Filip Debelić What is it? Android is a mobile operating system (OS) based on the Linux kernel and currently developed by Google Android,
Cosc 4730 Android TabActivity and ListView. TabActivity A TabActivity allows for multiple “tabs”. – Each Tab is it’s own activity and the “root” activity.
Android Development (Basics)
Android Application Development 2013 PClassic Chris Murphy 1.
Chien-Chung Shen Manifest and Activity Chien-Chung Shen
Better reference the original webpage :
Mobile Programming Lecture 1 Getting Started. Today's Agenda About the Eclipse IDE Hello, World! Project Android Project Structure Intro to Activities,
Android development the first app. Andoid vs iOS which is better? Short answer: neither Proponents on both sides For an iOS side, see this article on.
CS5103 Software Engineering Lecture 08 Android Development II.
ANDROID UI – FRAGMENTS. Fragment  An activity is a container for views  When you have a larger screen device than a phone –like a tablet it can look.
Favorite Twitter® Searches App Android How to Program © by Pearson Education, Inc. All Rights Reserved.
1 Mobile Computing Monetizing An App Copyright 2014 by Janson Industries.
Tip Calculator App Building an Android App with Java © by Pearson Education, Inc. All Rights Reserved.
Cosc 5/4730 Introduction: Threads, Android Activities, and MVC.
Basic Android Tutorial USF’s Association for Computing Machinery.
Resources and RelativeLayouts. Resources Android Resources We’ve already talked about the different types of Android Resources DirectoryResource Type.
INTRODUCTION TO ANDROID. Slide 2 Application Components An Android application is made of up one or more of the following components Activities We will.
SpotOn Game App Android How to Program © by Pearson Education, Inc. All Rights Reserved.
© 2016 Cengage Learning®. May not be scanned, copied or duplicated, or posted to a publicly accessible website, in whole or in part. Android Boot Camp.
Programming Mobile Applications with Android September, Albacete, Spain Jesus Martínez-Gómez.
Android – Fragments L. Grewe.
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved Introduction to Android (Part.
HW#9 Clues CSCI 571 Fall, HW#9 Prototype
ANDROID LAYOUTS AND WIDGETS. Slide 2 Introduction Parts of the Android screen Sizing widgets and fonts Layouts and their characteristics Buttons, checkboxes.
School of Engineering and Information and Communication Technology KIT305/KIT607 Mobile Application Development Android OS –Permissions (cont.), Fragments,
Java for android Development Nasrullah Khan. Using instanceof in Android Development the classes such as Button, TextView, and CheckBox, which represent.
Chapter 5 Introduction to Defining Classes Fundamentals of Java.
Resources. Android Resources We’ve already talked about the different types of Android Resources DirectoryResource Type anim/XML files that define tween.
Introduction to Android Chapter 1 1. Objectives Understand what Android is Learn the differences between Java and Android Java Examine the Android project.
Cosc 4735 Nougat API 24+ additions.
Introduction to android
Adapting to Display Orientation
GUI Programming Fundamentals
Mobile Application Development Chapter 3 [Using Eclipse Android Studio for Android Development] IT448-Fall 2017 IT448- Fall2017.
Android Studio, Android System Basics and Git
Android Boot Camp for Developers Using Java, 3E
Activities, Fragments, and Events
Mobile Application Development BSCS-7 Lecture # 6
Cosc 5/4735 AdMob for Android.
Activities and Intents
Chapter 3: Using Methods, Classes, and Objects
Mobile Application Development Chapter 4 [Android Navigation and Interface Design] IT448-Fall 2017 IT448- Fall2017.
The Android Activity Lifecycle
Sensors, maps and fragments:
ANDROID UI – FRAGMENTS UNIT II.
HNDIT2417 Mobile Application Development
Chapter 3: Coding the GUI Programmatically, Layout Managers
CIS 470 Mobile App Development
CIS 470 Mobile App Development
Learning Objectives Build an app involving several activities
Chapter 9: Fragments.
CIS 470 Mobile App Development
CS5103 Software Engineering
Tutorial 19 - Microwave Oven Application Building Your Own Classes and Objects Outline Test-Driving the Microwave Oven Application Designing.
CIS 470 Mobile App Development
Chapter 2: Model View Controller, GUI Components, Events
Object-Oriented Programming: Inheritance and Polymorphism
CIS 470 Mobile App Development
CIS 470 Mobile App Development
Mobile Programming Dr. Mohsin Ali Memon.
SE4S701 Mobile Application Development
Activities and Fragments
Android Development Tools
Activities, Fragments, and Intents
CIS 694/EEC 693 Android Sensor Programming
Presentation transcript:

Chapter 15: In App Advertising

Learning Objectives Use Google Play Services Include advertising in an app Manage the life cycle of an ad inside an app

Advertising A significant issue is how to monetize an app. There are many free apps in Google Play. People are accustomed to free apps. We can have two apps: A $0.99 app with no ads A free app with ads

Stopwatch App We build a simple Stopwatch app and place an advertising banner at the bottom of the screen. We start with the Stopwatch. We will add the advertising banner in Version 3.

Version 0 There is no ad in Version 0. We divide the screen into three parts: A Chronometer at the top Two Buttons (start/stop and reset) A place for the ad at the bottom

Drawables for the Buttons (1 of 4) We create three drawable resources for the buttons (we only show two buttons at the time: start and reset or stop and reset). start_button.xml, stop_button.xml, and reset_button.xml. They are identical except for their outline color (green, start, gray).

Drawables for the Buttons (2 of 4) The outline color in start_button.xml is green. <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android= "http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#FFFF" /> <stroke android:width="2dp" android:color="#F0F0" /> </shape>

Drawables for the Buttons (3 of 4) stop_button.xml and reset_button.xml are identical to start_button.xml except for their outline colors. The outline color in stop_button.xml is red ( FF00). The outline color in reset_button.xml is gray ( F444).

Drawables for the Buttons (4 of 4) We add a style that we will use for the buttons’ text. <style name="textViewStyle" parent = "@android:style/TextAppearance"> <item name = "android:gravity">center</item> <item name = "android:textStyle">bold</item> <item name = "android:textSize">96sp</item> </style>

Chronometer Class The Chronometer class encapsulates a chronometer, which includes its visual representation. Thus we can use a Chronometer element in the activity_main.xml file. We use a LinearLayout to place the two buttons in it. We use another LinearLayout to hold space for the ad.

activity_main.xml (1 of 5) We use a LinearLayout to manage the screen. The Chronometer class encapsulates a chronometer, which includes its visual representation. Thus we can use a Chronometer element in the activity_main.xml file. We specify 4/9 of the vertical space for it. We use a LinearLayout to place the two buttons in it. We specify 4/9 of the vertical space for it. We use another LinearLayout to hold space for the ad. We specify 1/9 of the vertical space for it.

activity_main.xml (2 of 5) … <Chronometer android:layout_weight="4" android:layout_width="match_parent" android:layout_height="0dp" android:id="@+id/stop_watch " style="@style/textViewStyle" />

activity_main.xml (3 of 5) … <LinearLayout android:orientation="horizontal" android:layout_weight="4" android:layout_width="match_parent" android:layout_height="0dp" android:gravity="center" > We place the two buttons inside that LinearLayout.

activity_main.xml (4 of 5) Inside that LinearLayout, we place two LinearLayout, each containing a Button element. When we start, the left button says START and uses the start_button.xml drawable resource for it background. The right button says RESET and uses the reset_button.xml drawable resource for it background.

activity_main.xml (5 of 5) We give the LinearLayout that will hold the ad a gray color so we can see it. See Example 15.5 for the full code for activity_main.xml.

MainActivity The two buttons specify startStop and reset as the two methods called when the user clicks on them. We code the startStop and reset methods inside MainActivity as do-nothing methods for now. We code them in Version 1.

Version 1 (1 of 2) In Version 1, we enable the user to make the chronometer by using the start/stop button and the reset button.

Version 1 (2 of 2) When the user clicks on the start button (and change the appearance of the start button so that it looks like a stop button). We stop the chronometer when the user clicks on the stop button (and change the appearance of the stop button so that it looks like a start button). We reset the chronometer when the user clicks on the reset button.

MainActivity There is no change in the user interface. The only changes are in the MainActivity class. We add two instance variables: chrono, a reference to the Chronometer started, a boolean variable: it keeps track of whether the chronometer is running or not. false  not running; true  running

Chronometer Class The Chronometer class includes the following methods: Method Description void start( ) Start counting (or restart counting) void stop( ) Stop counting void setBase( long base ) Set the time of reference for the count

startStop Method (1 of 3) public void startStop( View view ) { // get a reference to the start_stop button if( started ) { // the chronometer was running // stop the chronometer and assign false to started // update the button so that it looks like a start button } else { // the chronometer was not running // start the chronometer and assign true to started // update the button so that it looks like a stop button } }

startStop Method (2 of 3) public void startStop( View view ) { Button startStopButton = ( Button ) findViewById( R.id.start_stop ); if( started ) { chrono.stop( ); started = false; startStopButton.setText( "START" ); startStopButton.setBackgroundResource( R.drawable.start_button ); } …

startStop Method (3 of 3) … } else { chrono.start( ); started = true; startStopButton.setText( "STOP" ); startStopButton.setBackgroundResource( R.drawable.stop_button ); } }

Reset Method (1 of 3) Inside the reset method: We only want to reset the chronometer if the chronometer was running and has been stopped (i.e., started is false). We need to call the setBase method of Chronometer with the appropriate argument.

Reset Method (2 of 3) The parameter of setBase, base, is typically set using the elapsedRealtime method of the SystemClock class. Its API is: public static long elapsedRealtime( ) The elapsedRealTime method returns, in milliseconds, the amount of time since the last boot, including sleep time

Reset Method (3 of 3) public void reset( View view ) { if( !started ) chrono.setBase( SystemClock.elapsedRealtime( ) ); }

Version 2 (1 of 3) There is one issue with Version 1: If we stop the clock and restart it later, it does not restart where we stopped it. In fact, when we stop the Chronometer, it keeps running in the background. In Version 2, we fix that problem so that when we stop the Chronometer at time t, it restarts at time t.

Version 2 (2 of 3) To implement this, when we start or restart the Chronometer, we need to subtract the time elapsed since we stopped the Chronometer from the value returned by the elapsedRealtime method. Rather than doing this inside the MainActivity class, the Controller, we create a utility class, ClockUtility, that includes a method that we can use to do that.

Version 2 (3 of 3) Example 15.8 shows the ClockUtility class. Its milliseconds static method converts a String that is formatted like a String displayed inside a Chronometer to its equivalent number of milliseconds. The format of that String is expected to be hh:mm:sss or mm:ss. We use that method each time we restart the chronometer. The Model for this app is now comprised of the Chronometer and ClockUtility classes. Furthermore, the functionality of the ClockUtility class is reusable in other apps.

MainActivity (1 of 2) We add the resetChrono method: it resets the base of the Chronometer to the time that we last stopped it. public void resetChrono( ) { String chronoText = chrono.getText( ).toString(); long idleMilliseconds = ClockUtility.milliseconds( chronoText ); chrono.setBase( SystemClock.elapsedRealtime( ) – idleMilliseconds ); }

MainActivity (2 of 2) Whenever the user restarts the Chronometer, we call resetChrono to reset its base time. public void startStop( View view ) { … } else { resetChrono( ); … }

Version 3: Advertising Now that we have a working app, we can place the ad at the bottom of the screen inside the last LinearLayout. Google allows us to place a fake ad at the development stage so that we can test our app.

Classes for Displaying and Managing a Google Ad Description AdView A subclass of View to display an ad banner AdSize Encapsulates the size of a banner ad AdRequest Encapsulates a set of marketing characteristics such as location, birthday, keywords, etc., so that the ad can target demographics related to the app

AdView, AdSize, and AdRequest These three classes are part of the com.google.android.gms.ads package. However, the com.google.android.gms.ads package is not part of the standard Android SDK, but it is part of Google Play services. Thus, in order to use them, we edit the build.gradle file.

Editing build.gradle We edit the build.gradle file as follows: … dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' compile 'com.google.android.gms:play-services:9.0.1' } Note: We should check what the latest version of Google Play services is and use that one.

Editing activity_main.xml We need to access the LinearLayout where we place the ad (that is the last LinearLayout in activity_main.xml). Thus, we give it an id ... <LinearLayout android:id="@+id/ad_view" android:orientation="horizontal" …

MainActivity We add the ad in the onCreate method. We create an AdView, set its size and its ad unit id. We defined the AdRequest and add it to the AdView. We retrieve the LinearLayout and add the AdView to it. We request an ad from Google.

Selected AdView Methods Description public AdView( Context context ) Constructs for AdView public void setAdSize( AdSize adSize ) Sets the size of the banner ad. The argument can be one of the constants of the AdSize class. public void setAdUnitId( String adUnitId ) Sets the ad unit id

Creating the AdView Inside MainActivity, this is an Activity and therefore a Context. We use it as the argument of the AdView constructor. AdView adView = new AdView( this ); To set the size of the banner, we use one of the constants from the AdSize class.

AdSize Constants Constant Data Type Description AUTO_HEIGHT int Causes the height of the ad to scale based on the height of the device. FULL_WIDTH Causes the width of the ad to match the width of the device. BANNER AdSize Mobile Marketing Association ad size of 320 × 50 dip. SMART_BANNER Dynamically sized to full width and auto height.

Setting the Banner Size We want the banner ad to fill the available width so we use the SMART_BANNER constant. AdView adView = new AdView( this ); // Set ad size adView.setAdSize( AdSize.SMART_BANNER );

Setting the Ad Unit id If we are a registered Android developer, we can get an ad unit id from Google. If we are not registered and want to test an app containing an AdView, Google provides a test ad unit id for this. Its value is ca-app-pub-3940256099942544/6300978111. String adUnitId = "ca-app-pub-3940256099942544/6300978111"; adView.setAdUnitId( adUnitId );

Creating the AdRequest Now we create the AdRequest. By doing this, we can target an ad to a more specific demographics, one that typically matches the nature of the app. Builder, a static inner class of AdRequest, includes methods to define the AdRequest and build it. These methods include specifying keywords, gender, location, and other attributes.

Selected Methods of AdRequest.Builder Description public AdRequest.Builder( ) Default constructor. public AdRequest.Builder addKeyword( String keyword ) Adds a keyword for targeting purposes and can be called several times to add several keywords.

Creating the AdRequest // Create the ad request using an AdRequest.Builder object AdRequest.Builder adRequestBuilder = new AdRequest.Builder( ); // Define target data for adRequest (this is optional) adRequestBuilder.addKeyword( "fitness" ); adRequestBuilder.addKeyword ( "workout" ); Note that all the AdRequest.Builder methods return the AdRequest.Builder that calls them, so method calls can be chained. The build method returns the AdRequest.

More Selected Methods of AdRequest.Builder Description public AdRequest.Builder addTestDevice( String deviceId ) Sets up a device to receive test ads rather than live ads. Use the constant DEVICE_ID_EMULATOR from the AdRequest class to use the emulator public AdRequest build( ) Constructs and returns an AdRequest with the attributes specified by this AdRequest.Builder

Creating the AdRequest AdRequest.Builder adRequestBuilder = new AdRequest.Builder( ); … // Create the AdRequest AdRequest adRequest = adRequestBuilder.build( );

Testing the App and the Ad (1 of 3) The addTestDevice method enables us to test our app on either the emulator or an Android device with fake ads served by Google. It is against Google policy to test an app with live ads. To test using the emulator: adRequestBuilder.addTestDevice( AdRequest.DEVICE_ID_EMULATOR );

Testing the App and the Ad (2 of 3) We can test on an Android device. We can obtain the device id, a 32-digit hexadecimal string, for a device we use to test our app. We can obtain it by looking at the Logcat output when running the app on a connected device.

Testing the App and the Ad (3 of 3) Here is the output (the device id is partially hidden) when running with the author’s tablet connected.

Adding the AdView (1 of 2) To add the AdView, we first retrieve the LinearLayout using its id, then we add the AdView to it. LinearLayout adLayout = ( LinearLayout ) findViewById( R.id.ad_view ); adLayout.addView( adView );

Adding the AdView (2 of 2) Method Description To request an ad from Google, we call the loadAd method with the AdView. adView.loadAd( adRequest ); Method Description public void loadAd( AdRequest request ) Loads the ad on a background thread

AndroidManifest.xml (1 of 3) We need to edit the AndroidManifest.xml and declare that the app is using the Internet, Google Play Services, and also includes an AdActivity. <!-- required permissions for Google Mobile Ads --> <uses-permission android:name="android.permission.INTERNET"/>

AndroidManifest.xml (2 of 3) <application … > <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

AndroidManifest.xml (3 of 3) … <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation| screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent" /> </application> Note that the android:configChanges="..." should be on one line.

Version 4 (1 of 2) Google recommends that an AdView be placed inside a fragment. In Version 4, we place the AdView in a fragment rather than a LinearLayout.

Version 4 (2 of 2) We need to do the following: Create an XML layout file for the fragment Change the last LinearLayout in the activity_main.xml file to a fragment Code the fragment class Update the MainActivity class

Fragment XML Layout File: fragment.ad.xml We place an AdView element inside a RelativeLayout. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout …> <com.google.android.gms.ads.AdView …> </com.google.android.gms.ads.AdView> </RelativeLayout>

fragment_ad.xml We need to define banner_ad_unit_id in strings.xml <com.google.android.gms.ads.AdView android:id="@+id/ad_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" ads:adSize="SMART_BANNER" ads:adUnitId="@string/banner_ad_unit_id"> </com.google.android.gms.ads.AdView> We need to define banner_ad_unit_id in strings.xml

strings.xml <resources> <string name="app_name">StopWatchV4</string> <string name="banner_ad_unit_id"> ca-app-pub-3940256099942544/6300978111</string> </resources> This is the test unit id provided by Google for non-developer.

activity_main.xml We replace the last LinearLayout with a fragment element. <fragment android:id="@+id/fragment_ad" android:name="com.jblearning.stopwatchv4.AdFragment" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" />

AdFragment Class (1 of 2) We defined the type of fragment to be AdFragment. android:name="com.jblearning.stopwatchv4.AdFragment” We need to code the AdFragment class. public class AdFragment extends Fragment {

AdFragment Class (2 of 2) Inside onActivityCreated: We retrieve the AdView specified in the fragment using its id. We build an AdRequest. We load it into the AdView. The code is similar to the Version 3 code in MainActivity. See Example 15.17.

onActivityCreated Method AdView adView = ( AdView ) getView( ).findViewById( R.id.ad_view ); // build the ad request AdRequest.Builder adRequestBuilder = new AdRequest.Builder( ); // Define target data for the ad request (optional) adRequestBuilder.addKeyword ( "workout" ); // request test (not live) ads for emulator adRequestBuilder.addTestDevice( AdRequest.DEVICE_ID_EMULATOR ); AdRequest adRequest = adRequestBuilder.build( ); // load the ad adView.loadAd( adRequest );

MainActivity Class Be careful to use test ads and not live ads when testing your app. Clicking on a live ad while testing an app on a device is against Google’s policy. When we are ready to publish our app, we should comment out the code that specifies the emulator or a specific device id to test the app.

Test Ads versus Live Ads Since all the banner ad–related code is in AdFragment, the MainActivity class is the same as the one in Version 2. It sets the GUI and manages the Chronometers.

Version 5 When the app goes in the background, there is no need to request an ad from Google. The AdView class provides life cycle methods so that we can manage the life cycle of the AdView. In Version 5, we update our code so that we only request an ad when the app is running.

Life Cycle Methods of AdView Description public void pause( ) Pauses any extra processing associated with this AdView public void resume( ) Resumes processing associated with this AdView following a call to pause public void destroy( ) Destroys this AdView

Life Cycle of the AdView (1 of 3) When the app goes in the background, we want to stop processing associated with the AdView. When the app comes back in the foreground, we want to resume processing associated with the AdView. When the user closes the app, we want to destroy the AdView.

Life Cycle of the AdView (2 of 3) When the app goes in the background, the onPause method of the Fragment class is automatically called (then the onPause method of the Activity class is automatically called). Inside the onPause method of the Fragment class, we want to call the onPause method of the AdView. We want to do something similar inside the onResume and onDestroy methods.

Life Cycle of the AdView (3 of 3) Since we want to call methods of the AdView with the AdView of the app inside these three methods, it is convenient to have a reference to the AdView. Thus we make it an instance variable. private AdView adView; Inside onActivityCreated, we instantiate it. adView = ( AdView ) getView( ).findViewById( R.id.ad_view );

onPause When the app goes in the background, the onPause methods of the Fragment and Activity classes are automatically called in that order. We want to pause the processing of the AdView (which is inside the Fragment) before pausing the Fragment itself. Thus, we call the super method last. public void onPause( ) { if( adView != null ) adView.pause( ); super.onPause( ); }

onResume When the app comes back in the foreground, the onResume methods of the Activity and Fragment classes are automatically called in that order. We want to resume of the Fragment before resuming the processing of the AdView (which is inside the Fragment). Thus, we call the super method first. public void onResume( ) { super.onResume( ); if( adView != null ) adView.resume( ); }

onDestroy When the user closes the app, the onDestroy methods of the Fragment and Activity classes are automatically called in that order. We want to destroy the AdView (which is inside the Fragment) before destroying the Fragment. Thus we call the super method last. public void onDestroy( ) { if( adView != null ) adView.destroy( ); super.onDestroy(); }