KEMBAR78
Android Development: The Basics | KEY
Developing Android Apps: The Basics
            Mike Desjardins
Who Am I?
            • Independent Consultant - Ceres Logic
                 Software Engineer at ELC Technologies
            • Professional Programmer 15 years
            • Mostly Java, lately lots of JRuby on Rails
            • Developed a several Android Apps in the
                 Android Market                            Hi.
            • Haven’t done much iOS
            • Twitter: @cereslogic
Developing for Android:
The Basics                                                       2
What’s In This Presentation?

              • What is Android?
              • Activities and Intents
              • Views
              • Permissions
              • Other Facilities
              • Marketplace
Developing for Android:
The Basics                                     3
What is Android?

              • Open Handset Alliance - 80 Firms incl.
                   Google, HTC, Dell, Motorola, LG, etc.
              • Custom Linux-based Kernel (forked)
              • Dalvik Virtual Machine
              • Apache Harmony
              • Native code can be written using the NDK
                   (non-standard C Library, Bionic)

Developing for Android:
The Basics                                                 4
Android’s Layers
                       User applications: Contacts, phone, browser, etc.
          Application managers: windows, content, activities, telephony,
                          location, notifications, etc.
                                   Android Runtime: Java via Dalvik VM
         Libraries: graphics, media, database, communications, browser
                                   engine, etc.

                                  Linux kernel, including device drivers
        Hardware device with specific capabilities such as GPS, camera,
                              Bluetooth, etc.
Abelson, W. Frank & Sen, Robi (2011) Unlocking Android, Second Edition (Fig. 1.4). Greenwich, CT: Manning Publications.

Developing for Android:
The Basics                                                                                                                5
What is Android: Dalvik VM
              • Created by Dan Bornstein
              • Register Based instead of Stack Based
              • Interprets .dex files
    .java                            .class
                            Java      .class
                                       .class                 .dex
   source                 Compiler     file      dx Compiler
                                        file
                                        files                   file
    code



              • Packaged w/ resources in .apk files
Developing for Android:
The Basics                                                           6
Versions in the Wild




  95% of Android Devices are between version 2.1 (Éclair)
              and version 2.3 (Gingerbread)
                          As of June 1, 2011
                          http://developer.android.com/resources/dashboard/platform-versions.html

Developing for Android:
The Basics                                                                                          7
Versions in the Wild, cont.



               Skicast Free              Skicast Pro




                              Tidecast
Developing for Android:
The Basics                                             8
Handsets in the Wild



            Skicast Free                    Skicast Pro




                                 Tidecast
Developing for Android:
The Basics                                                9
What is “Rooting” ?
              •    Processes in the Android system run under an
                   unprivileged user account

              •    Default user can’t access all of the filesystem, or
                   some of the more interesting APIs (e.g., enabling
                   mobile hotspot, setting CPU speed)

              •    “Rooting” is finding back door shell access, and
                   copying a program conceptually similar to su or
                   sudo onto your phone.

              •    Custom ROMs are something completely different.


Developing for Android:
The Basics                                                              10
Development Environment
              • Eclipse + ADT is the “default”
              • Android SDK comes w/ command line
                   tools and emulator (adb)




Developing for Android:
The Basics                                          11
Activities
              • Typical applications have (along with some
                   other stuff) a collection of “Activities”
              • An Activity roughly corresponds to a
                   screen
              • There is no correspondence among
                   Process/VM/Applications/Activities
              • Class inheriting from android.app.Activity
              • Started by “Intents” (more on those later)
Developing for Android:
The Basics                                                     12
I.e., Don’t Use Task Killers in a
               misguided attempt to extend
                         battery life!




            Android Task Killer Apps = Worse Than Useless
Developing for Android:
The Basics                                                  13
Activity Lifecycle
                                             Entire Lifetime - Between
                                             onCreate and onDestroy

                                             Visible Lifetime -
                                             Between onStart and onStop

                                             Foreground Lifetime -
                                             Between onResume and
                                             onPause


                            Image: http://developer.android.com/images/activity_lifecycle.png

Developing for Android:
The Basics                                                                                 14
Demo Time!




Developing for Android:
The Basics                             15
Views
              • Android allows you to be quite Model-
                   View-Controllery
              • Views contain UI elements displayed on the
                   screen by an Activity (controller)
              • Can be defined in XML or programatically
              • Views are nested, topmost is a LayoutView
              • setContentView(viewId) or
                   setContentView(view)
Developing for Android:
The Basics                                                   16
Our Hello World Demo View
            <?xml
version="1.0"
encoding="utf‐8"?>
            <LinearLayout
xmlns:android="http://schemas.android.com/apk/
            res/android"
            



android:orientation="vertical"
            



android:layout_width="fill_parent"
            



android:layout_height="fill_parent"
            



>
            <TextView


            



android:layout_width="fill_parent"

            



android:layout_height="wrap_content"

            



android:text="@string/hello"
            



/>
            </LinearLayout>




Developing for Android:
The Basics                                                                 17
Our Hello World Demo View
            <?xml
version="1.0"
encoding="utf‐8"?>
            <LinearLayout
xmlns:android="http://schemas.android.com/apk/
            res/android"
            



android:orientation="vertical"
            



android:layout_width="fill_parent"
                                                     Which direction
            



android:layout_height="fill_parent"   we’re filling
            



>
            <TextView


            



android:layout_width="fill_parent"

            



android:layout_height="wrap_content"

            



android:text="@string/hello"
            



/>
            </LinearLayout>




Developing for Android:
The Basics                                                                 18
Our Hello World Demo View
            <?xml
version="1.0"
encoding="utf‐8"?>
            <LinearLayout
xmlns:android="http://schemas.android.com/apk/
            res/android"
            



android:orientation="vertical"
            



android:layout_width="fill_parent"        fill_parent
            



android:layout_height="fill_parent"
            



>                                        match_parent
            <TextView


            



android:layout_width="fill_parent"

                                                         wrap_content
            



android:layout_height="wrap_content"

            



android:text="@string/hello"
            



/>
            </LinearLayout>




Developing for Android:
The Basics                                                                 19
Our Hello World Demo View
            <?xml
version="1.0"
encoding="utf‐8"?>
            <LinearLayout
xmlns:android="http://schemas.android.com/apk/
            res/android"
            



android:orientation="vertical"
            



android:layout_width="fill_parent"
            



android:layout_height="fill_parent"
            



>
            <TextView


            



android:layout_width="fill_parent"

            



android:layout_height="wrap_content"

            



android:text="@string/hello"               what the???
            



/>
            </LinearLayout>




Developing for Android:
The Basics                                                                 20
Resources
                           •   Resources go into the res
                               directory
                           •   Different Types: strings,
                               layouts, drawables, arbitrary
                               XML, styles, raw, etc.
                           •   Referenced in XML using
                               identifiers prefixed with an at
                               sign (@) followed by type
                           •   Handles / IDs end up in the
                               mysterious “R” class
Developing for Android:
The Basics                                                     21
R
                                                           • Autogenerated by
    /*
AUTO‐GENERATED
FILE.

DO
NOT
MODIFY.
    
*
    
*
This
class
was
automatically
generated
by
the
    
*
aapt
tool
from
the
resource
data
it
found.

It
    
*
should
not
be
modified
by
hand.                       Android’s compile
    
*/

    package
com.cereslogic.demo01;
                                                             tools
    public
final
class
R
{
    



public
static
final
class
attr
{                   • Scans res folder,
                                                             creates R in your
    



}
    



public
static
final
class
drawable
{
    







public
static
final
int
icon=0x7f020000;
    



}
    



public
static
final
class
layout
{
                                                             gen folder w/ the
    







public
static
final
int
main=0x7f030000;
    



}                                                    same package
                                                             name as your app.
    



public
static
final
class
string
{
    







public
static
final
int
app_name=0x7f040001;
    







public
static
final
int
hello=0x7f040000;
    



}
    }




Developing for Android:
The Basics                                                                       22
Referring to Resources in Java
             package
com.cereslogic.demo01;

             import
android.app.Activity;
             import
android.os.Bundle;

             public
class
Hello
extends
Activity
{
             



/**
Called
when
the
activity
is
first
created.
*/
             



@Override
             



public
void
onCreate(Bundle
savedInstanceState)
{
             







super.onCreate(savedInstanceState);
             







setContentView(R.layout.main);
             



}
             }

                                              Here’s an example!


Developing for Android:
The Basics                                                           23
Let’s add a Button!
    <?xml
version="1.0"
encoding="utf‐8"?>
    <LinearLayout
xmlns:android="http://
    schemas.android.com/apk/res/android"
    



android:orientation="vertical"
    



android:layout_width="fill_parent"
    



android:layout_height="fill_parent"
    



>
    <TextView


    



android:layout_width="fill_parent"

    



android:layout_height="wrap_content"

    



android:text="@string/hello"            First we’ll add
    



/>
    <Button                                     the button to
    




android:layout_height="wrap_content"    our view in
    




android:layout_width="wrap_content"
    




android:text="@string/deliver_bacon"      main.xml.
    




android:onClick="deliverBacon"
/>
    </LinearLayout>


Developing for Android:
The Basics                                                        24
Let’s add a Button!
          <?xml
version="1.0"
encoding="utf‐8"?>
          <resources>
          



<string
name="hello">Hello
World,
Hello!</string>
          



<string
name="app_name">AndroidPresentation</string>
          



<string
name="deliver_bacon">Please
Deliver
Bacon!</string>
          </resources>

                                                  add the string to
                                                     values.xml




                          Let’s try it out...
Developing for Android:
The Basics                                                                  25
Demo Time




Developing for Android:
The Basics                            26
Uh Oh!
       That’ll get you a one star review in the App Market.




                          Let’s check logcat to see
                            what went wrong...

Developing for Android:
The Basics                                                    27
DOH!
  E/AndroidRuntime(   523):   Uncaught handler: thread main exiting due to uncaught exception
  E/AndroidRuntime(   523):   java.lang.IllegalStateException: Could not find a method deliverBacon(View) in the activity
  E/AndroidRuntime(   523):   
 at android.view.View$1.onClick(View.java:2016)
  E/AndroidRuntime(   523):   
 at android.view.View.performClick(View.java:2344)
  E/AndroidRuntime(   523):   
 at android.view.View.onTouchEvent(View.java:4133)
  .
  .
  .



                                   OOPS.                    We forgot to write the
                                                              deliverBacon
                                                            method in our Activity.
                                                             It got called when
                                                             onClick was fired.

Developing for Android:
The Basics                                                                                                            28
Add a method for that...
           package
com.cereslogic.androidpreso;

           import
android.app.Activity;
           import
android.os.Bundle;
           import
android.util.Log;
           import
android.view.View;

           public
class
Hello
extends
Activity
{
           



/**
Called
when
the
activity
is
first
created.
*/
           



@Override
           



public
void
onCreate(Bundle
savedInstanceState)
{
           







super.onCreate(savedInstanceState);
           







setContentView(R.layout.main);
           



}

           



public
void
deliverBacon(View
view)
{
           




 Log.i("Demo
App",
"TODO:
Figure
Out
How
To
Deliver
Bacon!");
           



}
           }


                   the view passed in is the button that was tapped

Developing for Android:
The Basics                                                                      29
Demo Time




Developing for Android:
The Basics                            30
Yeah... that was pretty lame.
                 Bacon makes everything better, so...




Developing for Android:
The Basics                                              31
Yeah... that was pretty lame.
                      Bacon makes everything better, so...




                                   ...let’s add a picture of bacon!
Photo Credit: Shawn Zamechek (shawnzam), Licensed under Creative Commons (CC BY 2.0), http://www.flickr.com/photos/shawnzam/31302636/

Developing for Android:
The Basics                                                                                                                             31
Now Things Start To Get Ugly

              • We are supporting devices with multiple
                   screen densities.
              • Good News: Android provides a way to
                   support multiple screen densities
              • Bad News: We will probably want to
                   include four copies of our bacon picture in
                   our app

Developing for Android:
The Basics                                                       32
Screen Densities

              • Android currently generalizes screens into
                   four categories of screen density
              • LDPI (low) - QVGA, 120dpi, ~240x320
              • MDPI (medium) - HVGA, 160dpi, ~320x480
              • HDPI (high) - WVGA, 240dpi, ~480x800
              • XHDPI (xtra high) - ? 320dpi, Added in
                   Android 2.3 (Gingerbread)

Developing for Android:
The Basics                                                   33
Bacon should Fill the Screen!
              • We want Bacon to fill the width of the
                   screen in HIGH DEFINITION, so we will
                   make four sizes



        LDPI
                          MDPI
                          320x240
                                    HDPI
                                    480x360
                                                 XHDPI
                                                  640x480

Developing for Android:
The Basics                                                  34
Bacon should Fill the Screen!
              • We want Bacon to fill the width of the
                   screen in HIGH DEFINITION, so we will
                   make four sizes



        LDPI
                          MDPI
                          320x240
                                    HDPI
                                    480x360
                                                 XHDPI
                                                  640x480

Developing for Android:
The Basics                                                  34
Bacon should Fill the Screen!
              • We want Bacon to fill the width of the
                   screen in HIGH DEFINITION, so we will
                   make four sizes



        LDPI
                          MDPI
                          320x240
                                    HDPI
                                    480x360
                                                 XHDPI
                                                  640x480

Developing for Android:
The Basics                                                  34
Bacon should Fill the Screen!
              • We want Bacon to fill the width of the
                   screen in HIGH DEFINITION, so we will
                   make four sizes



        LDPI
                          MDPI
                          320x240
                                    HDPI
                                    480x360
                                                 XHDPI
                                                  640x480

Developing for Android:
The Basics                                                  34
Bacon should Fill the Screen!
              • We want Bacon to fill the width of the
                   screen in HIGH DEFINITION, so we will
                   make four sizes



        LDPI
                          MDPI
                          320x240
                                    HDPI
                                    480x360
                                                 XHDPI
                                                  640x480

Developing for Android:
The Basics                                                  34
Add Bacon...
                                  <?xml
version="1.0"
encoding="utf‐8"?>
                                  <LinearLayout
xmlns:android="http://schemas.android.com/
                                  apk/res/android"
                                  



android:orientation="vertical"
                                  



android:layout_width="fill_parent"
                                  



android:layout_height="fill_parent"
                                  



>
                                  <TextView


                                  



android:layout_width="fill_parent"

                                  



android:layout_height="wrap_content"

                                  



android:text="@string/hello"
                                  



/>


                                  <Button
                                  




android:layout_height="wrap_content"
                                  




android:layout_width="wrap_content"
                                  




android:text="@string/deliver_bacon"
                                  




android:onClick="deliverBacon"
/>
                                  <ImageView
                                  
 
 
android:layout_height="wrap_content"

                                  
 
 
android:layout_width="fill_parent"
                                  
 
 
android:src="@drawable/bacon"/>
                                  </LinearLayout>


                          Now let’s try that out...
Developing for Android:
The Basics                                                                               35
Bacon Time




Developing for Android:
The Basics                             36
Meh. That’s still pretty lame
           We could make the bacon only appear when
                     the button is clicked...
           1              Make the bacon’s default state hidden:



                                            visible, invisible, or gone
                          <ImageView
                          
 
 
android:visibility="invisible"
                          
 
 
android:layout_height="wrap_content"

                          
 
 
android:layout_width="fill_parent"
                          
 
 
android:src="@drawable/bacon"/>


Developing for Android:
The Basics                                                                37
Meh. That’s still pretty lame
           We could make the bacon only appear when
                     the button is clicked...
           2               Put an ID on our bacon:
                           The @+id in our XML is special magic that
                          causes the Android build tools to generate an
                           handle w/ an ID for the view in the R object
                           <ImageView
                           
 
 
android:id="@+id/bacon_image"
                           
 
 
android:visibility="invisible"
                           
 
 
android:layout_height="wrap_content"

                           
 
 
android:layout_width="fill_parent"
                           
 
 
android:src="@drawable/bacon"/>

Developing for Android:
The Basics                                                                38
Meh. That’s still pretty lame
           We could make the bacon only appear when
                     the button is clicked...
           3         Wire up the Button listener to do something:

             



public
void
deliverBacon(View
view)
{
             




 ImageView
i
=
(ImageView)findViewById(R.id.bacon_image);
             




 if
(i.getVisibility()
==
View.INVISIBLE)
{
             




 
 i.setVisibility(View.VISIBLE);
             




 }
else
{
             




 
 i.setVisibility(View.INVISIBLE);
             




 }
             



}


                          Let’s try that out!
Developing for Android:
The Basics                                                                    39
Blinky Bacon Time




Developing for Android:
The Basics                                    40
ListViews

              • Probably the most common UI Element is a
                   ListView
              • Allows you to scroll through a selection of
                   items and choose one
              • Next we’ll add a list of bacon-related treats
                   to our app!


Developing for Android:
The Basics                                                      41
Create a List of Treats
            1              Put our list entries into strings.xml

 <?xml
version="1.0"
encoding="utf‐8"?>
 <resources>
 



<string
name="hello">Hello
World,
Hello!</string>
 



<string
name="app_name">AndroidPresentation</string>
 



<string
name="deliver_bacon">Please
Deliver
Bacon!</string>
 



<string
name="show_bacon_treats">Show
me
treats!</string>
 



<string
name="bacon_treat_list">Bacon
Treat
List</string>
 



<string
name="bacon_plain">Bacon
(Plain)</string>
 



<string
name="bacon_lettuce_tomato_sandwich">Bacon,
Lettuce,
Tomato
sandwich</string>
 



<string
name="bacon_and_eggs">Bacon
and
Eggs</string>
 



<string
name="bacon_cheeseburger">Bacon
Cheeseburger</string>
 



<string
name="bacon_bits">Bacon
Bits</string>
 



<string
name="bacon_ice_cream">Bacon
Ice
Cream</string>
 



<string
name="bacon_chewing_gum">Bacon
Chewing
Gum</string>
 



<string
name="bacon_lollipop">Bacon
Lollipop</string>
 </resources>


Developing for Android:
The Basics                                                                             42
Create a List of Treats, cont.
            2             Create a TextView to hold our list entries

      <?xml
version="1.0"
encoding="utf‐8"?>
      <TextView
xmlns:android="http://schemas.android.com/apk/res/android"
      
 android:layout_width="fill_parent"
      
 android:layout_height="wrap_content"
      
 android:textSize="24.0dip"
      
 android:padding="4.0dip"
      
 android:id="@+id/empty_text_view">
      </TextView>


   Wait... a TextView? Don’t you mean ListView or something?
   Nope - this is what each list item will contain.
Developing for Android:
The Basics                                                                   43
Create a List of Treats, cont.
                          Create a new Activity class that inherits
            3                        from ListActivity
   public
class
BaconTreats
extends
ListActivity
{
   

@Override
   

protected
void
onCreate(Bundle
savedInstanceState)
{
   





super.onCreate(savedInstanceState);
   





//setContentView(R.layout.treat_list);
unneeded
ListActivity
provides
a
default
   






   





ArrayAdapter<String>
aa
=
new
ArrayAdapter<String>(this,R.layout.empty);
   





aa.add(getResources().getString(R.string.bacon_plain));
   





aa.add(getResources().getString(R.string.bacon_and_eggs));
   





aa.add(getResources().getString(R.string.bacon_bits));
   





aa.add(getResources().getString(R.string.bacon_cheeseburger));
   





aa.add(getResources().getString(R.string.bacon_chewing_gum));
   





aa.add(getResources().getString(R.string.bacon_ice_cream));
   





aa.add(getResources().getString(R.string.bacon_lettuce_tomato_sandwich));
   





aa.add(getResources().getString(R.string.bacon_lollipop));
   





setListAdapter(aa);
   

}
   }                      Converts objects to things appearing in ListView
Developing for Android:
The Basics                                                                             44
Create a List of Treats, cont.
                          Add the new Activity to the Manifest
            4             (hey waitaminute - what’s a Manifest?)
      <?xml
version="1.0"
encoding="utf‐8"?>
      <manifest
xmlns:android="http://schemas.android.com/apk/res/android"
      





package="com.cereslogic.androidpreso"
      





android:versionCode="1"
      





android:versionName="1.0">
      



<application
android:icon="@drawable/icon"
android:label="@string/app_name">
      







<activity
android:name=".Hello"
      

















android:label="@string/app_name">
      











<intent‐filter>
      















<action
android:name="android.intent.action.MAIN"
/>
      















<category
android:name="android.intent.category.LAUNCHER"
/>
      











</intent‐filter>
      







</activity>
      







<activity
android:name=".BaconTreats"
      

















android:label="@string/bacon_treat_list">
      







</activity>
      



</application>
      </manifest>


Developing for Android:
The Basics                                                                               45
Create a List of Treats, cont.
            4                  So... what is a Manifest?

              • AndroidManifest.xml in the root directory
                   of the project.
              • Describes Activities in your project and any
                   intents that should activate them (hey
                   waitaminute - what’s an Intent? We’ll get to
                   that in a minute)
              • Describes application permissions, version,
                   name, req’d API version, other stuff
Developing for Android:
The Basics                                                        46
ListActivity is ready
              • We’ve created our ListActivity, now how
                   do we get to it?
              • We’ll add an ugly little button in our Main
                   screen that launches the list:
                   <Button
                   




android:layout_height="wrap_content"
                   




android:layout_width="wrap_content"
                   




android:text="@string/show_bacon_treats"
                   




android:onClick="showBaconTreats"
/>


                                     Now we need to implement the
                                      showBaconTreats method...
Developing for Android:
The Basics                                                          47
showBaconTreats
 public
class
Hello
extends
Activity
{
 



/**
Called
when
the
activity
is
first
created.
*/         Hey - there’s one of
                                                               those Intent things
 



@Override
 



public
void
onCreate(Bundle
savedInstanceState)
{
 







super.onCreate(savedInstanceState);
 







setContentView(R.layout.main);
 



}
                                                                     again...
 



public
void
showBaconTreats(View
view)
{
 





Intent
intent
=
new
Intent(Intent.ACTION_VIEW);
 





intent.setComponent(
 







new
ComponentName("com.cereslogic.androidpreso","com.cereslogic.androidpreso.BaconTreats")
 





);
 





startActivity(intent);
 



}
 




 



public
void
deliverBacon(View
view)
{
 




 ImageView
i
=
(ImageView)findViewById(R.id.bacon_image);
 




 if
(i.getVisibility()
==
View.INVISIBLE)
{
 




 
 i.setVisibility(View.VISIBLE);
 




 }
else
{
 




 
 i.setVisibility(View.INVISIBLE);
 




 }
 



}
 }


Developing for Android:
The Basics                                                                                       48
Et Voila!




Developing for Android:
The Basics                            49
Intents
              •    In some ways, Android resembles a Service-
                   oriented Architecture (SOA)

              •    An Intent represents the user’s desire to
                   accomplish something

              •    An app can create an Intent without knowing or
                   caring what Activity will receive it

              •    Applications create Intent Filters in their
                   manifests, indicating Activities (or other things like
                   BroadcastReceivers) that would like to be notified
                   of Intents

Developing for Android:
The Basics                                                                  50
Intent Resolution
              • Two types of Intents:
              • Explicit - identifies a Component Name
                   (a specific Activity class) to be started. This
                   is how we launched our ListActivity earlier
              • Implicit - does not name a target
                   Activity, instead identifies an action, a
                   category, and data and/or data type
              • Typical “Actions”: ACTION_VIEW,
                   ACTION_DIAL, ACTION_EDIT, etc.

Developing for Android:
The Basics                                                          51
Examples of Implicit Intents
              •    Data is given in URL format: scheme://data

              •    ACTION_VIEW contacts://people/1
                   shows the contact who’s identifier is 1.

              •    ACTION_DIAL tel://2075551212 shows
                   the dialer with 207-555-1212 filled in.

              •    Normally the data type is inferred by the scheme,
                   but you can force it to a specific MIME type in the
                   Intent constructor

              •    “Categories” are sometimes used to further refine
                   which Activities may be launched

Developing for Android:
The Basics                                                              52
What if more than one intent
                       will work?
              • If more than one Activity is registered to
                   receive an intent, Android will ask the user
                   which Activity they want to launch




              • This is how people build things like
                   alternate dialers or text messaging apps
Developing for Android:
The Basics                                                        53
Declaring supported Intents
              • If an Activity wants to make itself available
                   to receive specific Intents, it declares them
                   in its application’s Manifest
                    <?xml
version="1.0"
encoding="utf‐8"?>
                    <manifest
xmlns:android="http://schemas.android.com/apk/res/android"
                    





package="com.cereslogic.androidpreso"
                    





android:versionCode="1"
                    





android:versionName="1.0">

  Allows our        



<application
android:icon="@drawable/icon"
android:label="@string/app_name">
                    







<activity
android:name=".Hello"
                    

















android:label="@string/app_name">

  app to be a       











<intent‐filter>
                    















<action
android:name="android.intent.action.MAIN"
/>
                    















<category
android:name="android.intent.category.LAUNCHER"
/>

   target for       











</intent‐filter>
                    







</activity>
                    







<activity
android:name=".BaconShare"
     photo          

















android:label="@string/bacon_share">
                    











<intent‐filter>

    sharing
                    















<action
android:name="android.intent.action.ACTION_SEND"
/>
                    















<data
android:mimeType="image/png"
/>
                    















<category
android:name="android.intent.category.DEFAULT"
/>
                    











</intent‐filter>


















                    







</activity>
                    



</application>
                    </manifest>

Developing for Android:
The Basics                                                                                             54
Declaring supported Intents
              • First Activity launched by your App gets the
                   MAIN/LAUNCHER intent:
                    <?xml
version="1.0"
encoding="utf‐8"?>
                    <manifest
xmlns:android="http://schemas.android.com/apk/res/android"
                    





package="com.cereslogic.androidpreso"
                    





android:versionCode="1"
                    





android:versionName="1.0">
                    



<application
android:icon="@drawable/icon"
android:label="@string/app_name">
                    







<activity
android:name=".Hello"
                    

















android:label="@string/app_name">
                    











<intent‐filter>
                    















<action
android:name="android.intent.action.MAIN"
/>
                    















<category
android:name="android.intent.category.LAUNCHER"
/>
                    











</intent‐filter>
                    







</activity>
                    







<activity
android:name=".BaconShare"
                    

















android:label="@string/bacon_share">
                    











<intent‐filter>
                    















<action
android:name="android.intent.action.ACTION_SEND"
/>
                    















<data
android:mimeType="image/png"
/>
                    















<category
android:name="android.intent.category.DEFAULT"
/>
                    











</intent‐filter>


















                    







</activity>
                    



</application>
                    </manifest>

Developing for Android:
The Basics                                                                                             55
Permissions
              • To use some of the facilities in the device,
                   you need to declare that you will use them
                   in the Manifest.
              • The user is informed of these permissions
                   when he or she downloads your
                   application.
              • Examples: Location (Fine and Coarse), WiFi
                   state, Network state, Call, Camera,
                   Internet, Send/Receive SMS, Read Contacts

Developing for Android:
The Basics                                                      56
Common Idioms




Developing for Android:
The Basics                                57
Common Idioms
              •    Android makes extensive use of callbacks

              •    Example of selecting an item from a ListView,
                   passing that value to the next activity, and exiting:
  listView.setOnItemClickListener(new
OnItemClickListener()
{
  

public
void
onItemClick(AdapterView<?>
parent,
View
view,
int
position,
long
id)
{
  



selected
=
(String)myListAdapter.getItem(position);
  



Intent
intent
=
new
Intent(Intent.ACTION_VIEW);
  



intent.setComponent(
  





new
ComponentName("com.cereslogic.androidpreso",
  























"com.cereslogic.androidpreso.NextActivity")
  



);
  



intent.putExtra("selected",
selected);
//
avail
to
NextActivity
via
getIntent()
  



startActivity(intent);
  



finish();

//
called
when
we
don’t
want
to
come
back
here
when
user
presses
back.
  

}
  });




Developing for Android:
The Basics                                                                                58
Common Idioms

              • Separate “Handler” with a
                   progress dialog when
                   asynchronous stuff may take a
                   while
              • If you don’t do this, Android may
                   just decide to kill your application

Developing for Android:
The Basics                                                59
Time-consuming Async Tasks
 private
class
BaconFryingTask
extends
AsyncTask<BaconInputType,
BaconProgressType,
BaconResultType>
{
 

@Override
 

protected
BaconResultType
doInBackground(BaconInputType...
params)
{
 



Bacon
bacon
=
BaconFactory.createInstance(params[0]);
 



bacon.sizzle(Bacon.CRISPY);







 



publishProgress(new
BaconProgressType(50));
 



bacon.flip();
 



bacon.sizzle(Bacon.CRISPY);







 



publishProgress(new
BaconProgressType(100));
 



return
bacon;
 

}

 

@Override
 

protected
void
onProgressUpdate(BaconProgressType...
params)
{
 



Integer
progress
=
params[0].getPercentCooked();
 



setProgressPercent(progress);




 

}

 

@Override
 

protected
void
onPostExecute(BaconResultType
result)
{
 



Log.d(“BaconFryingTask”,
“The
Bacon
is
ready!”);
 

}
 }

 To kick off the task...
 new
BaconFryingTask().execute(params);


Developing for Android:
The Basics                                                                                               60
Time-consuming Async Tasks
 private
class
BaconFryingTask
extends
AsyncTask<BaconInputType,
BaconProgressType,
BaconResultType>
{
 

@Override
 

protected
BaconResultType
doInBackground(BaconInputType...
params)
{
 



Bacon
bacon
=
BaconFactory.createInstance(params[0]);
 



bacon.sizzle(Bacon.CRISPY);







 



publishProgress(new
BaconProgressType(50));
 



bacon.flip();
 



bacon.sizzle(Bacon.CRISPY);







 



publishProgress(new
BaconProgressType(100));
 



return
bacon;
 

}

 

@Override
 

protected
void
onProgressUpdate(BaconProgressType...
params)
{
 



Integer
progress
=
params[0].getPercentCooked();
 



setProgressPercent(progress);




 

}

 

@Override
 

protected
void
onPostExecute(BaconResultType
result)
{
 



Log.d(“BaconFryingTask”,
“The
Bacon
is
ready!”);
 

}
 }

 To kick off the task...
 new
BaconFryingTask().execute(params);


Developing for Android:
The Basics                                                                                               60
Demo Time!




Developing for Android:
The Basics                             61
Code for the Bad Bacon Joke
       public
class
BadBaconJoke
extends
Activity
{
       

private
ProgressDialog
progressDialog;

       

@Override
       

public
void
onCreate(Bundle
savedInstanceState)
{
       



super.onCreate(savedInstanceState);
       



this.progressDialog
=

       




ProgressDialog.show(this,
"working...",

       























"Some
pancakes,
eggs,
and
bacon
walk
into
a
bar.
Bartender
looks
at
them
and
says...");
       




new
PunchlineTask().execute();
       

}
       

       

private
class
PunchlineTask
extends
AsyncTask<Void,
Void,
String>
{
       



@Override
       



protected
String
doInBackground(Void...
params)
{
       





try
{
       







Thread.sleep(8000);
       





}
catch
(InterruptedException
e)
{
/*
Don’t
ever
do
this
*/
}

       





return
"...hey!
We
don't
serve
breakfast
here!";
       



}

       



@Override
       



protected
void
onPostExecute(String
result)
{
       





progressDialog.dismiss();
       





new
AlertDialog.Builder(BadBaconJoke.this)
       









.setMessage(result).setCancelable(false).setTitle("Punchline")
       









.setPositiveButton("Groan",
new
DialogInterface.OnClickListener()
{
       











public
void
onClick(DialogInterface
dialog,
int
which)
{
       













Toast.makeText(getApplicationContext(),
"Sorry.",
Toast.LENGTH_LONG).show();
       











}
       









}).show();
       



}
       

}
       }

Developing for Android:
The Basics                                                                                                               62
BroadcastReceiver
              •    Used for receiving events. Intended for short
                   “trigger” style events, not long running activities (use
                   Services for those)
              •    Examples: Incoming Phone Call, Text Message
              •    Registered using Intent Filters, just like Activities
              •    No View associated with them
              •    Can be registered statically in the manifest, or at
                   runtime
              •    Instance goes away when you’re finished processing
              •    Ordered or (more typically) Unordered

Developing for Android:
The Basics                                                                    63
Trivial BroadcastReceiver Example
     Sorry, no Bacon this time...
    public
class
WiFiChangeReceiver
extends
BroadcastReceiver
{
    

private
final
static
String
TAG
=
"WiFiChangeReceiver";
    

    

@Override                                                         Receiver
    

public
void
onReceive(Context
context,
Intent
intent)
{
    



Log.d(TAG,
"In
onReceive.");                                     class
    



doSomethingAsynchronouslyInTheBackground();
    

}
    }




    <receiver
android:name="com.cereslogic.demo.WiFiChangeReceiver"

    









android:enabled="true">
    

<intent‐filter>
    



<action
android:name="android.net.wifi.WIFI_STATE_CHANGED"
/>   Manifest
      </intent‐filter>
    </receiver>




Developing for Android:
The Basics                                                                         64
(Demo if there is time)




Developing for Android:
The Basics                                          65
Services
              •    Long-running background processes

              •    Need to be started and stopped by an Application
                   (e.g., in a BroadcastReceiver), but otherwise run
                   independently of the applications with which
                   they’re associated

              •    “Foreground” services are less likely to be killed by
                   the OS

              •    Great way to drain batteries

              •    Big sloppy half-hearted example on the next slide

Developing for Android:
The Basics                                                                 66
Service Example
    public
class
LocalService
extends
Service
{
    

private
NotificationManager
notificationManager;
    

private
int
NOTIFICATION
=
R.string.local_service_started;

    

@Override
    

public
void
onCreate()
{
    



notificationManager
=
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    



showNotification();
    

}

    

@Override
    

public
int
onStartCommand(Intent
intent,
int
flags,
int
startId)
{
    



//
We
want
this
service
to
continue
running
until
it
is
explicitly
    



//
stopped,
so
return
sticky.
    



return
START_STICKY;
    

}

    

@Override
    

public
void
onDestroy()
{
    



notificationManager.cancel(NOTIFICATION);
    



Toast.makeText(this,
R.string.local_service_stopped,
Toast.LENGTH_SHORT).show();
    

}

    

private
void
showNotification()
{
    



CharSequence
text
=
getText(R.string.local_service_started);
    



Notification
notification
=
new
Notification(R.drawable.notification_icon,
text,
System.currentTimeMillis());
    



PendingIntent
contentIntent
=
PendingIntent.getActivity(this,
0,
new
Intent(this,
AnActivity.class),
0);
    



notification.setLatestEventInfo(this,
getText(R.string.local_service_label),
text,
contentIntent);
    



notificationManager.notify(NOTIFICATION,
notification);
    

}
    }

    Kick it off like this...
    context.startService(new
Intent(context,
LocalService.class));


Developing for Android:
The Basics                                                                                                              67
Location Services
              • A little weird to program for
              • Can’t just ask the system “hey, where am I
                   right now?”
              • Two Options:
               • Last known location
               • Sample location at rate X, and register to
                          be notified when location changes by
                          more than X from the previous location

Developing for Android:
The Basics                                                         68
Very Simple Location Example
    public
class
LocationClient
implements
LocationListener
{
    

private
static
final
Long
MIN_UPDATE_INTERVAL
=
1000L;
    

private
static
final
float
MIN_DISTANCE_SENSITIVITY
=
100.0f;
    

private
LocationManager
locationManager;
    

private
Location
location
=
null;

    

public
void
determineLocation()
{
    



this.locationManager
=
(LocationManager)this.getSystemService(LOCATION_SERVICE);
    



String
bestProvider
=
this.getBestLocationProvider();
    



this.locationManager.requestLocationUpdates(bestProvider,
MIN_UPDATE_INTERVAL,
MIN_DISTANCE_SENSITIVITY,
this);
    

}

    

private
String
getBestLocationProvider()
{
    



Criteria
criteria
=
new
Criteria();
    



criteria.setAccuracy(Criteria.ACCURACY_COARSE);
    



criteria.setAltitudeRequired(false);
    



criteria.setBearingRequired(false);
    



criteria.setSpeedRequired(false);
    



String
bestProvider
=
this.locationManager.getBestProvider(criteria,
true);
    



return
bestProvider;
    

}

    

//
Required
by
LocationListener...
    

public
void
onLocationChanged(Location
location)
{
    



this.location
=
location;
    



logLocation(location);
    



this.locationManager.removeUpdates(this);
    

}

    

public
Location
getLocation()
{
    



return
this.location;
    

}
    }



Developing for Android:
The Basics                                                                                                                69
Android Market
              • No wait to publish apps - upload in the
                   developer console, and it’s available to
                   everybody.
              • Buyer’s currency
              • In-app purchases
              • Google Checkout for purchases, 2.9%
                   discount rate
              • Google’s cut of app price: 30%
Developing for Android:
The Basics                                                    70
Developer Console




Developing for Android:
The Basics                                    71
Developer Console
                                           stats (earlier in presentation)
                           user comments                                     error reports


  in-app
purchases




Developing for Android:
The Basics                                                                                   72
Developer Console - Error Reports




Developing for Android:
The Basics                          73
Developer Console - Error Reports




Developing for Android:
The Basics                          74
Questions?




Developing for Android:
The Basics                             75

Android Development: The Basics

  • 1.
    Developing Android Apps:The Basics Mike Desjardins
  • 2.
    Who Am I? • Independent Consultant - Ceres Logic Software Engineer at ELC Technologies • Professional Programmer 15 years • Mostly Java, lately lots of JRuby on Rails • Developed a several Android Apps in the Android Market Hi. • Haven’t done much iOS • Twitter: @cereslogic Developing for Android: The Basics 2
  • 3.
    What’s In ThisPresentation? • What is Android? • Activities and Intents • Views • Permissions • Other Facilities • Marketplace Developing for Android: The Basics 3
  • 4.
    What is Android? • Open Handset Alliance - 80 Firms incl. Google, HTC, Dell, Motorola, LG, etc. • Custom Linux-based Kernel (forked) • Dalvik Virtual Machine • Apache Harmony • Native code can be written using the NDK (non-standard C Library, Bionic) Developing for Android: The Basics 4
  • 5.
    Android’s Layers User applications: Contacts, phone, browser, etc. Application managers: windows, content, activities, telephony, location, notifications, etc. Android Runtime: Java via Dalvik VM Libraries: graphics, media, database, communications, browser engine, etc. Linux kernel, including device drivers Hardware device with specific capabilities such as GPS, camera, Bluetooth, etc. Abelson, W. Frank & Sen, Robi (2011) Unlocking Android, Second Edition (Fig. 1.4). Greenwich, CT: Manning Publications. Developing for Android: The Basics 5
  • 6.
    What is Android:Dalvik VM • Created by Dan Bornstein • Register Based instead of Stack Based • Interprets .dex files .java .class Java .class .class .dex source Compiler file dx Compiler file files file code • Packaged w/ resources in .apk files Developing for Android: The Basics 6
  • 7.
    Versions in theWild 95% of Android Devices are between version 2.1 (Éclair) and version 2.3 (Gingerbread) As of June 1, 2011 http://developer.android.com/resources/dashboard/platform-versions.html Developing for Android: The Basics 7
  • 8.
    Versions in theWild, cont. Skicast Free Skicast Pro Tidecast Developing for Android: The Basics 8
  • 9.
    Handsets in theWild Skicast Free Skicast Pro Tidecast Developing for Android: The Basics 9
  • 10.
    What is “Rooting”? • Processes in the Android system run under an unprivileged user account • Default user can’t access all of the filesystem, or some of the more interesting APIs (e.g., enabling mobile hotspot, setting CPU speed) • “Rooting” is finding back door shell access, and copying a program conceptually similar to su or sudo onto your phone. • Custom ROMs are something completely different. Developing for Android: The Basics 10
  • 11.
    Development Environment • Eclipse + ADT is the “default” • Android SDK comes w/ command line tools and emulator (adb) Developing for Android: The Basics 11
  • 12.
    Activities • Typical applications have (along with some other stuff) a collection of “Activities” • An Activity roughly corresponds to a screen • There is no correspondence among Process/VM/Applications/Activities • Class inheriting from android.app.Activity • Started by “Intents” (more on those later) Developing for Android: The Basics 12
  • 13.
    I.e., Don’t UseTask Killers in a misguided attempt to extend battery life! Android Task Killer Apps = Worse Than Useless Developing for Android: The Basics 13
  • 14.
    Activity Lifecycle Entire Lifetime - Between onCreate and onDestroy Visible Lifetime - Between onStart and onStop Foreground Lifetime - Between onResume and onPause Image: http://developer.android.com/images/activity_lifecycle.png Developing for Android: The Basics 14
  • 15.
    Demo Time! Developing forAndroid: The Basics 15
  • 16.
    Views • Android allows you to be quite Model- View-Controllery • Views contain UI elements displayed on the screen by an Activity (controller) • Can be defined in XML or programatically • Views are nested, topmost is a LayoutView • setContentView(viewId) or setContentView(view) Developing for Android: The Basics 16
  • 17.
    Our Hello WorldDemo View <?xml
version="1.0"
encoding="utf‐8"?> <LinearLayout
xmlns:android="http://schemas.android.com/apk/ res/android" 



android:orientation="vertical" 



android:layout_width="fill_parent" 



android:layout_height="fill_parent" 



> <TextView

 



android:layout_width="fill_parent"
 



android:layout_height="wrap_content"
 



android:text="@string/hello" 



/> </LinearLayout> Developing for Android: The Basics 17
  • 18.
    Our Hello WorldDemo View <?xml
version="1.0"
encoding="utf‐8"?> <LinearLayout
xmlns:android="http://schemas.android.com/apk/ res/android" 



android:orientation="vertical" 



android:layout_width="fill_parent" Which direction 



android:layout_height="fill_parent" we’re filling 



> <TextView

 



android:layout_width="fill_parent"
 



android:layout_height="wrap_content"
 



android:text="@string/hello" 



/> </LinearLayout> Developing for Android: The Basics 18
  • 19.
    Our Hello WorldDemo View <?xml
version="1.0"
encoding="utf‐8"?> <LinearLayout
xmlns:android="http://schemas.android.com/apk/ res/android" 



android:orientation="vertical" 



android:layout_width="fill_parent" fill_parent 



android:layout_height="fill_parent" 



> match_parent <TextView

 



android:layout_width="fill_parent"
 wrap_content 



android:layout_height="wrap_content"
 



android:text="@string/hello" 



/> </LinearLayout> Developing for Android: The Basics 19
  • 20.
    Our Hello WorldDemo View <?xml
version="1.0"
encoding="utf‐8"?> <LinearLayout
xmlns:android="http://schemas.android.com/apk/ res/android" 



android:orientation="vertical" 



android:layout_width="fill_parent" 



android:layout_height="fill_parent" 



> <TextView

 



android:layout_width="fill_parent"
 



android:layout_height="wrap_content"
 



android:text="@string/hello" what the??? 



/> </LinearLayout> Developing for Android: The Basics 20
  • 21.
    Resources • Resources go into the res directory • Different Types: strings, layouts, drawables, arbitrary XML, styles, raw, etc. • Referenced in XML using identifiers prefixed with an at sign (@) followed by type • Handles / IDs end up in the mysterious “R” class Developing for Android: The Basics 21
  • 22.
    R • Autogenerated by /*
AUTO‐GENERATED
FILE.

DO
NOT
MODIFY. 
* 
*
This
class
was
automatically
generated
by
the 
*
aapt
tool
from
the
resource
data
it
found.

It 
*
should
not
be
modified
by
hand. Android’s compile 
*/ package
com.cereslogic.demo01; tools public
final
class
R
{ 



public
static
final
class
attr
{ • Scans res folder, creates R in your 



} 



public
static
final
class
drawable
{ 







public
static
final
int
icon=0x7f020000; 



} 



public
static
final
class
layout
{ gen folder w/ the 







public
static
final
int
main=0x7f030000; 



} same package name as your app. 



public
static
final
class
string
{ 







public
static
final
int
app_name=0x7f040001; 







public
static
final
int
hello=0x7f040000; 



} } Developing for Android: The Basics 22
  • 23.
    Referring to Resourcesin Java package
com.cereslogic.demo01; import
android.app.Activity; import
android.os.Bundle; public
class
Hello
extends
Activity
{ 



/**
Called
when
the
activity
is
first
created.
*/ 



@Override 



public
void
onCreate(Bundle
savedInstanceState)
{ 







super.onCreate(savedInstanceState); 







setContentView(R.layout.main); 



} } Here’s an example! Developing for Android: The Basics 23
  • 24.
    Let’s add aButton! <?xml
version="1.0"
encoding="utf‐8"?> <LinearLayout
xmlns:android="http:// schemas.android.com/apk/res/android" 



android:orientation="vertical" 



android:layout_width="fill_parent" 



android:layout_height="fill_parent" 



> <TextView

 



android:layout_width="fill_parent"
 



android:layout_height="wrap_content"
 



android:text="@string/hello" First we’ll add 



/> <Button the button to 




android:layout_height="wrap_content" our view in 




android:layout_width="wrap_content" 




android:text="@string/deliver_bacon" main.xml. 




android:onClick="deliverBacon"
/> </LinearLayout> Developing for Android: The Basics 24
  • 25.
    Let’s add aButton! <?xml
version="1.0"
encoding="utf‐8"?> <resources> 



<string
name="hello">Hello
World,
Hello!</string> 



<string
name="app_name">AndroidPresentation</string> 



<string
name="deliver_bacon">Please
Deliver
Bacon!</string> </resources> add the string to values.xml Let’s try it out... Developing for Android: The Basics 25
  • 26.
    Demo Time Developing forAndroid: The Basics 26
  • 27.
    Uh Oh! That’ll get you a one star review in the App Market. Let’s check logcat to see what went wrong... Developing for Android: The Basics 27
  • 28.
    DOH! E/AndroidRuntime( 523): Uncaught handler: thread main exiting due to uncaught exception E/AndroidRuntime( 523): java.lang.IllegalStateException: Could not find a method deliverBacon(View) in the activity E/AndroidRuntime( 523): at android.view.View$1.onClick(View.java:2016) E/AndroidRuntime( 523): at android.view.View.performClick(View.java:2344) E/AndroidRuntime( 523): at android.view.View.onTouchEvent(View.java:4133) . . . OOPS. We forgot to write the deliverBacon method in our Activity. It got called when onClick was fired. Developing for Android: The Basics 28
  • 29.
    Add a methodfor that... package
com.cereslogic.androidpreso; import
android.app.Activity; import
android.os.Bundle; import
android.util.Log; import
android.view.View; public
class
Hello
extends
Activity
{ 



/**
Called
when
the
activity
is
first
created.
*/ 



@Override 



public
void
onCreate(Bundle
savedInstanceState)
{ 







super.onCreate(savedInstanceState); 







setContentView(R.layout.main); 



} 



public
void
deliverBacon(View
view)
{ 




 Log.i("Demo
App",
"TODO:
Figure
Out
How
To
Deliver
Bacon!"); 



} } the view passed in is the button that was tapped Developing for Android: The Basics 29
  • 30.
    Demo Time Developing forAndroid: The Basics 30
  • 31.
    Yeah... that waspretty lame. Bacon makes everything better, so... Developing for Android: The Basics 31
  • 32.
    Yeah... that waspretty lame. Bacon makes everything better, so... ...let’s add a picture of bacon! Photo Credit: Shawn Zamechek (shawnzam), Licensed under Creative Commons (CC BY 2.0), http://www.flickr.com/photos/shawnzam/31302636/ Developing for Android: The Basics 31
  • 33.
    Now Things StartTo Get Ugly • We are supporting devices with multiple screen densities. • Good News: Android provides a way to support multiple screen densities • Bad News: We will probably want to include four copies of our bacon picture in our app Developing for Android: The Basics 32
  • 34.
    Screen Densities • Android currently generalizes screens into four categories of screen density • LDPI (low) - QVGA, 120dpi, ~240x320 • MDPI (medium) - HVGA, 160dpi, ~320x480 • HDPI (high) - WVGA, 240dpi, ~480x800 • XHDPI (xtra high) - ? 320dpi, Added in Android 2.3 (Gingerbread) Developing for Android: The Basics 33
  • 35.
    Bacon should Fillthe Screen! • We want Bacon to fill the width of the screen in HIGH DEFINITION, so we will make four sizes LDPI MDPI 320x240 HDPI 480x360 XHDPI 640x480 Developing for Android: The Basics 34
  • 36.
    Bacon should Fillthe Screen! • We want Bacon to fill the width of the screen in HIGH DEFINITION, so we will make four sizes LDPI MDPI 320x240 HDPI 480x360 XHDPI 640x480 Developing for Android: The Basics 34
  • 37.
    Bacon should Fillthe Screen! • We want Bacon to fill the width of the screen in HIGH DEFINITION, so we will make four sizes LDPI MDPI 320x240 HDPI 480x360 XHDPI 640x480 Developing for Android: The Basics 34
  • 38.
    Bacon should Fillthe Screen! • We want Bacon to fill the width of the screen in HIGH DEFINITION, so we will make four sizes LDPI MDPI 320x240 HDPI 480x360 XHDPI 640x480 Developing for Android: The Basics 34
  • 39.
    Bacon should Fillthe Screen! • We want Bacon to fill the width of the screen in HIGH DEFINITION, so we will make four sizes LDPI MDPI 320x240 HDPI 480x360 XHDPI 640x480 Developing for Android: The Basics 34
  • 40.
    Add Bacon... <?xml
version="1.0"
encoding="utf‐8"?> <LinearLayout
xmlns:android="http://schemas.android.com/ apk/res/android" 



android:orientation="vertical" 



android:layout_width="fill_parent" 



android:layout_height="fill_parent" 



> <TextView

 



android:layout_width="fill_parent"
 



android:layout_height="wrap_content"
 



android:text="@string/hello" 



/>

 <Button 




android:layout_height="wrap_content" 




android:layout_width="wrap_content" 




android:text="@string/deliver_bacon" 




android:onClick="deliverBacon"
/> <ImageView 
 
 
android:layout_height="wrap_content"
 
 
 
android:layout_width="fill_parent" 
 
 
android:src="@drawable/bacon"/> </LinearLayout> Now let’s try that out... Developing for Android: The Basics 35
  • 41.
    Bacon Time Developing forAndroid: The Basics 36
  • 42.
    Meh. That’s stillpretty lame We could make the bacon only appear when the button is clicked... 1 Make the bacon’s default state hidden: visible, invisible, or gone <ImageView 
 
 
android:visibility="invisible" 
 
 
android:layout_height="wrap_content"
 
 
 
android:layout_width="fill_parent" 
 
 
android:src="@drawable/bacon"/> Developing for Android: The Basics 37
  • 43.
    Meh. That’s stillpretty lame We could make the bacon only appear when the button is clicked... 2 Put an ID on our bacon: The @+id in our XML is special magic that causes the Android build tools to generate an handle w/ an ID for the view in the R object <ImageView 
 
 
android:id="@+id/bacon_image" 
 
 
android:visibility="invisible" 
 
 
android:layout_height="wrap_content"
 
 
 
android:layout_width="fill_parent" 
 
 
android:src="@drawable/bacon"/> Developing for Android: The Basics 38
  • 44.
    Meh. That’s stillpretty lame We could make the bacon only appear when the button is clicked... 3 Wire up the Button listener to do something: 



public
void
deliverBacon(View
view)
{ 




 ImageView
i
=
(ImageView)findViewById(R.id.bacon_image); 




 if
(i.getVisibility()
==
View.INVISIBLE)
{ 




 
 i.setVisibility(View.VISIBLE); 




 }
else
{ 




 
 i.setVisibility(View.INVISIBLE); 




 } 



} Let’s try that out! Developing for Android: The Basics 39
  • 45.
    Blinky Bacon Time Developingfor Android: The Basics 40
  • 46.
    ListViews • Probably the most common UI Element is a ListView • Allows you to scroll through a selection of items and choose one • Next we’ll add a list of bacon-related treats to our app! Developing for Android: The Basics 41
  • 47.
    Create a Listof Treats 1 Put our list entries into strings.xml <?xml
version="1.0"
encoding="utf‐8"?> <resources> 



<string
name="hello">Hello
World,
Hello!</string> 



<string
name="app_name">AndroidPresentation</string> 



<string
name="deliver_bacon">Please
Deliver
Bacon!</string> 



<string
name="show_bacon_treats">Show
me
treats!</string> 



<string
name="bacon_treat_list">Bacon
Treat
List</string> 



<string
name="bacon_plain">Bacon
(Plain)</string> 



<string
name="bacon_lettuce_tomato_sandwich">Bacon,
Lettuce,
Tomato
sandwich</string> 



<string
name="bacon_and_eggs">Bacon
and
Eggs</string> 



<string
name="bacon_cheeseburger">Bacon
Cheeseburger</string> 



<string
name="bacon_bits">Bacon
Bits</string> 



<string
name="bacon_ice_cream">Bacon
Ice
Cream</string> 



<string
name="bacon_chewing_gum">Bacon
Chewing
Gum</string> 



<string
name="bacon_lollipop">Bacon
Lollipop</string> </resources> Developing for Android: The Basics 42
  • 48.
    Create a Listof Treats, cont. 2 Create a TextView to hold our list entries <?xml
version="1.0"
encoding="utf‐8"?> <TextView
xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="fill_parent" 
 android:layout_height="wrap_content" 
 android:textSize="24.0dip" 
 android:padding="4.0dip" 
 android:id="@+id/empty_text_view"> </TextView> Wait... a TextView? Don’t you mean ListView or something? Nope - this is what each list item will contain. Developing for Android: The Basics 43
  • 49.
    Create a Listof Treats, cont. Create a new Activity class that inherits 3 from ListActivity public
class
BaconTreats
extends
ListActivity
{ 

@Override 

protected
void
onCreate(Bundle
savedInstanceState)
{ 





super.onCreate(savedInstanceState); 





//setContentView(R.layout.treat_list);
unneeded
ListActivity
provides
a
default 





 





ArrayAdapter<String>
aa
=
new
ArrayAdapter<String>(this,R.layout.empty); 





aa.add(getResources().getString(R.string.bacon_plain)); 





aa.add(getResources().getString(R.string.bacon_and_eggs)); 





aa.add(getResources().getString(R.string.bacon_bits)); 





aa.add(getResources().getString(R.string.bacon_cheeseburger)); 





aa.add(getResources().getString(R.string.bacon_chewing_gum)); 





aa.add(getResources().getString(R.string.bacon_ice_cream)); 





aa.add(getResources().getString(R.string.bacon_lettuce_tomato_sandwich)); 





aa.add(getResources().getString(R.string.bacon_lollipop)); 





setListAdapter(aa); 

} } Converts objects to things appearing in ListView Developing for Android: The Basics 44
  • 50.
    Create a Listof Treats, cont. Add the new Activity to the Manifest 4 (hey waitaminute - what’s a Manifest?) <?xml
version="1.0"
encoding="utf‐8"?> <manifest
xmlns:android="http://schemas.android.com/apk/res/android" 





package="com.cereslogic.androidpreso" 





android:versionCode="1" 





android:versionName="1.0"> 



<application
android:icon="@drawable/icon"
android:label="@string/app_name"> 







<activity
android:name=".Hello" 

















android:label="@string/app_name"> 











<intent‐filter> 















<action
android:name="android.intent.action.MAIN"
/> 















<category
android:name="android.intent.category.LAUNCHER"
/> 











</intent‐filter> 







</activity> 







<activity
android:name=".BaconTreats" 

















android:label="@string/bacon_treat_list"> 







</activity> 



</application> </manifest> Developing for Android: The Basics 45
  • 51.
    Create a Listof Treats, cont. 4 So... what is a Manifest? • AndroidManifest.xml in the root directory of the project. • Describes Activities in your project and any intents that should activate them (hey waitaminute - what’s an Intent? We’ll get to that in a minute) • Describes application permissions, version, name, req’d API version, other stuff Developing for Android: The Basics 46
  • 52.
    ListActivity is ready • We’ve created our ListActivity, now how do we get to it? • We’ll add an ugly little button in our Main screen that launches the list: <Button 




android:layout_height="wrap_content" 




android:layout_width="wrap_content" 




android:text="@string/show_bacon_treats" 




android:onClick="showBaconTreats"
/> Now we need to implement the showBaconTreats method... Developing for Android: The Basics 47
  • 53.
    showBaconTreats public
class
Hello
extends
Activity
{ 



/**
Called
when
the
activity
is
first
created.
*/ Hey - there’s one of those Intent things 



@Override 



public
void
onCreate(Bundle
savedInstanceState)
{ 







super.onCreate(savedInstanceState); 







setContentView(R.layout.main); 



} again... 



public
void
showBaconTreats(View
view)
{ 





Intent
intent
=
new
Intent(Intent.ACTION_VIEW); 





intent.setComponent( 







new
ComponentName("com.cereslogic.androidpreso","com.cereslogic.androidpreso.BaconTreats") 





); 





startActivity(intent); 



} 



 



public
void
deliverBacon(View
view)
{ 




 ImageView
i
=
(ImageView)findViewById(R.id.bacon_image); 




 if
(i.getVisibility()
==
View.INVISIBLE)
{ 




 
 i.setVisibility(View.VISIBLE); 




 }
else
{ 




 
 i.setVisibility(View.INVISIBLE); 




 } 



} } Developing for Android: The Basics 48
  • 54.
    Et Voila! Developing forAndroid: The Basics 49
  • 55.
    Intents • In some ways, Android resembles a Service- oriented Architecture (SOA) • An Intent represents the user’s desire to accomplish something • An app can create an Intent without knowing or caring what Activity will receive it • Applications create Intent Filters in their manifests, indicating Activities (or other things like BroadcastReceivers) that would like to be notified of Intents Developing for Android: The Basics 50
  • 56.
    Intent Resolution • Two types of Intents: • Explicit - identifies a Component Name (a specific Activity class) to be started. This is how we launched our ListActivity earlier • Implicit - does not name a target Activity, instead identifies an action, a category, and data and/or data type • Typical “Actions”: ACTION_VIEW, ACTION_DIAL, ACTION_EDIT, etc. Developing for Android: The Basics 51
  • 57.
    Examples of ImplicitIntents • Data is given in URL format: scheme://data • ACTION_VIEW contacts://people/1 shows the contact who’s identifier is 1. • ACTION_DIAL tel://2075551212 shows the dialer with 207-555-1212 filled in. • Normally the data type is inferred by the scheme, but you can force it to a specific MIME type in the Intent constructor • “Categories” are sometimes used to further refine which Activities may be launched Developing for Android: The Basics 52
  • 58.
    What if morethan one intent will work? • If more than one Activity is registered to receive an intent, Android will ask the user which Activity they want to launch • This is how people build things like alternate dialers or text messaging apps Developing for Android: The Basics 53
  • 59.
    Declaring supported Intents • If an Activity wants to make itself available to receive specific Intents, it declares them in its application’s Manifest <?xml
version="1.0"
encoding="utf‐8"?> <manifest
xmlns:android="http://schemas.android.com/apk/res/android" 





package="com.cereslogic.androidpreso" 





android:versionCode="1" 





android:versionName="1.0"> Allows our 



<application
android:icon="@drawable/icon"
android:label="@string/app_name"> 







<activity
android:name=".Hello" 

















android:label="@string/app_name"> app to be a 











<intent‐filter> 















<action
android:name="android.intent.action.MAIN"
/> 















<category
android:name="android.intent.category.LAUNCHER"
/> target for 











</intent‐filter> 







</activity> 







<activity
android:name=".BaconShare" photo 

















android:label="@string/bacon_share"> 











<intent‐filter> sharing 















<action
android:name="android.intent.action.ACTION_SEND"
/> 















<data
android:mimeType="image/png"
/> 















<category
android:name="android.intent.category.DEFAULT"
/> 











</intent‐filter>

















 







</activity> 



</application> </manifest> Developing for Android: The Basics 54
  • 60.
    Declaring supported Intents • First Activity launched by your App gets the MAIN/LAUNCHER intent: <?xml
version="1.0"
encoding="utf‐8"?> <manifest
xmlns:android="http://schemas.android.com/apk/res/android" 





package="com.cereslogic.androidpreso" 





android:versionCode="1" 





android:versionName="1.0"> 



<application
android:icon="@drawable/icon"
android:label="@string/app_name"> 







<activity
android:name=".Hello" 

















android:label="@string/app_name"> 











<intent‐filter> 















<action
android:name="android.intent.action.MAIN"
/> 















<category
android:name="android.intent.category.LAUNCHER"
/> 











</intent‐filter> 







</activity> 







<activity
android:name=".BaconShare" 

















android:label="@string/bacon_share"> 











<intent‐filter> 















<action
android:name="android.intent.action.ACTION_SEND"
/> 















<data
android:mimeType="image/png"
/> 















<category
android:name="android.intent.category.DEFAULT"
/> 











</intent‐filter>

















 







</activity> 



</application> </manifest> Developing for Android: The Basics 55
  • 61.
    Permissions • To use some of the facilities in the device, you need to declare that you will use them in the Manifest. • The user is informed of these permissions when he or she downloads your application. • Examples: Location (Fine and Coarse), WiFi state, Network state, Call, Camera, Internet, Send/Receive SMS, Read Contacts Developing for Android: The Basics 56
  • 62.
    Common Idioms Developing forAndroid: The Basics 57
  • 63.
    Common Idioms • Android makes extensive use of callbacks • Example of selecting an item from a ListView, passing that value to the next activity, and exiting: listView.setOnItemClickListener(new
OnItemClickListener()
{ 

public
void
onItemClick(AdapterView<?>
parent,
View
view,
int
position,
long
id)
{ 



selected
=
(String)myListAdapter.getItem(position); 



Intent
intent
=
new
Intent(Intent.ACTION_VIEW); 



intent.setComponent( 





new
ComponentName("com.cereslogic.androidpreso", 























"com.cereslogic.androidpreso.NextActivity") 



); 



intent.putExtra("selected",
selected);
//
avail
to
NextActivity
via
getIntent() 



startActivity(intent); 



finish();

//
called
when
we
don’t
want
to
come
back
here
when
user
presses
back. 

} }); Developing for Android: The Basics 58
  • 64.
    Common Idioms • Separate “Handler” with a progress dialog when asynchronous stuff may take a while • If you don’t do this, Android may just decide to kill your application Developing for Android: The Basics 59
  • 65.
    Time-consuming Async Tasks private
class
BaconFryingTask
extends
AsyncTask<BaconInputType,
BaconProgressType,
BaconResultType>
{ 

@Override 

protected
BaconResultType
doInBackground(BaconInputType...
params)
{ 



Bacon
bacon
=
BaconFactory.createInstance(params[0]); 



bacon.sizzle(Bacon.CRISPY);






 



publishProgress(new
BaconProgressType(50)); 



bacon.flip(); 



bacon.sizzle(Bacon.CRISPY);






 



publishProgress(new
BaconProgressType(100)); 



return
bacon; 

} 

@Override 

protected
void
onProgressUpdate(BaconProgressType...
params)
{ 



Integer
progress
=
params[0].getPercentCooked(); 



setProgressPercent(progress);



 

} 

@Override 

protected
void
onPostExecute(BaconResultType
result)
{ 



Log.d(“BaconFryingTask”,
“The
Bacon
is
ready!”); 

} } To kick off the task... new
BaconFryingTask().execute(params); Developing for Android: The Basics 60
  • 66.
    Time-consuming Async Tasks private
class
BaconFryingTask
extends
AsyncTask<BaconInputType,
BaconProgressType,
BaconResultType>
{ 

@Override 

protected
BaconResultType
doInBackground(BaconInputType...
params)
{ 



Bacon
bacon
=
BaconFactory.createInstance(params[0]); 



bacon.sizzle(Bacon.CRISPY);






 



publishProgress(new
BaconProgressType(50)); 



bacon.flip(); 



bacon.sizzle(Bacon.CRISPY);






 



publishProgress(new
BaconProgressType(100)); 



return
bacon; 

} 

@Override 

protected
void
onProgressUpdate(BaconProgressType...
params)
{ 



Integer
progress
=
params[0].getPercentCooked(); 



setProgressPercent(progress);



 

} 

@Override 

protected
void
onPostExecute(BaconResultType
result)
{ 



Log.d(“BaconFryingTask”,
“The
Bacon
is
ready!”); 

} } To kick off the task... new
BaconFryingTask().execute(params); Developing for Android: The Basics 60
  • 67.
    Demo Time! Developing forAndroid: The Basics 61
  • 68.
    Code for theBad Bacon Joke public
class
BadBaconJoke
extends
Activity
{ 

private
ProgressDialog
progressDialog; 

@Override 

public
void
onCreate(Bundle
savedInstanceState)
{ 



super.onCreate(savedInstanceState); 



this.progressDialog
=
 




ProgressDialog.show(this,
"working...",
 























"Some
pancakes,
eggs,
and
bacon
walk
into
a
bar.
Bartender
looks
at
them
and
says..."); 




new
PunchlineTask().execute(); 

} 
 

private
class
PunchlineTask
extends
AsyncTask<Void,
Void,
String>
{ 



@Override 



protected
String
doInBackground(Void...
params)
{ 





try
{ 







Thread.sleep(8000); 





}
catch
(InterruptedException
e)
{
/*
Don’t
ever
do
this
*/
}
 





return
"...hey!
We
don't
serve
breakfast
here!"; 



} 



@Override 



protected
void
onPostExecute(String
result)
{ 





progressDialog.dismiss(); 





new
AlertDialog.Builder(BadBaconJoke.this) 









.setMessage(result).setCancelable(false).setTitle("Punchline") 









.setPositiveButton("Groan",
new
DialogInterface.OnClickListener()
{ 











public
void
onClick(DialogInterface
dialog,
int
which)
{ 













Toast.makeText(getApplicationContext(),
"Sorry.",
Toast.LENGTH_LONG).show(); 











} 









}).show(); 



} 

} } Developing for Android: The Basics 62
  • 69.
    BroadcastReceiver • Used for receiving events. Intended for short “trigger” style events, not long running activities (use Services for those) • Examples: Incoming Phone Call, Text Message • Registered using Intent Filters, just like Activities • No View associated with them • Can be registered statically in the manifest, or at runtime • Instance goes away when you’re finished processing • Ordered or (more typically) Unordered Developing for Android: The Basics 63
  • 70.
    Trivial BroadcastReceiver Example Sorry, no Bacon this time... public
class
WiFiChangeReceiver
extends
BroadcastReceiver
{ 

private
final
static
String
TAG
=
"WiFiChangeReceiver"; 
 

@Override Receiver 

public
void
onReceive(Context
context,
Intent
intent)
{ 



Log.d(TAG,
"In
onReceive."); class 



doSomethingAsynchronouslyInTheBackground(); 

} } <receiver
android:name="com.cereslogic.demo.WiFiChangeReceiver"
 









android:enabled="true"> 

<intent‐filter> 



<action
android:name="android.net.wifi.WIFI_STATE_CHANGED"
/> Manifest </intent‐filter> </receiver> Developing for Android: The Basics 64
  • 71.
    (Demo if thereis time) Developing for Android: The Basics 65
  • 72.
    Services • Long-running background processes • Need to be started and stopped by an Application (e.g., in a BroadcastReceiver), but otherwise run independently of the applications with which they’re associated • “Foreground” services are less likely to be killed by the OS • Great way to drain batteries • Big sloppy half-hearted example on the next slide Developing for Android: The Basics 66
  • 73.
    Service Example public
class
LocalService
extends
Service
{ 

private
NotificationManager
notificationManager; 

private
int
NOTIFICATION
=
R.string.local_service_started; 

@Override 

public
void
onCreate()
{ 



notificationManager
=
(NotificationManager)getSystemService(NOTIFICATION_SERVICE); 



showNotification(); 

} 

@Override 

public
int
onStartCommand(Intent
intent,
int
flags,
int
startId)
{ 



//
We
want
this
service
to
continue
running
until
it
is
explicitly 



//
stopped,
so
return
sticky. 



return
START_STICKY; 

} 

@Override 

public
void
onDestroy()
{ 



notificationManager.cancel(NOTIFICATION); 



Toast.makeText(this,
R.string.local_service_stopped,
Toast.LENGTH_SHORT).show(); 

} 

private
void
showNotification()
{ 



CharSequence
text
=
getText(R.string.local_service_started); 



Notification
notification
=
new
Notification(R.drawable.notification_icon,
text,
System.currentTimeMillis()); 



PendingIntent
contentIntent
=
PendingIntent.getActivity(this,
0,
new
Intent(this,
AnActivity.class),
0); 



notification.setLatestEventInfo(this,
getText(R.string.local_service_label),
text,
contentIntent); 



notificationManager.notify(NOTIFICATION,
notification); 

} } Kick it off like this... context.startService(new
Intent(context,
LocalService.class)); Developing for Android: The Basics 67
  • 74.
    Location Services • A little weird to program for • Can’t just ask the system “hey, where am I right now?” • Two Options: • Last known location • Sample location at rate X, and register to be notified when location changes by more than X from the previous location Developing for Android: The Basics 68
  • 75.
    Very Simple LocationExample public
class
LocationClient
implements
LocationListener
{ 

private
static
final
Long
MIN_UPDATE_INTERVAL
=
1000L; 

private
static
final
float
MIN_DISTANCE_SENSITIVITY
=
100.0f; 

private
LocationManager
locationManager; 

private
Location
location
=
null; 

public
void
determineLocation()
{ 



this.locationManager
=
(LocationManager)this.getSystemService(LOCATION_SERVICE); 



String
bestProvider
=
this.getBestLocationProvider(); 



this.locationManager.requestLocationUpdates(bestProvider,
MIN_UPDATE_INTERVAL,
MIN_DISTANCE_SENSITIVITY,
this); 

} 

private
String
getBestLocationProvider()
{ 



Criteria
criteria
=
new
Criteria(); 



criteria.setAccuracy(Criteria.ACCURACY_COARSE); 



criteria.setAltitudeRequired(false); 



criteria.setBearingRequired(false); 



criteria.setSpeedRequired(false); 



String
bestProvider
=
this.locationManager.getBestProvider(criteria,
true); 



return
bestProvider; 

} 

//
Required
by
LocationListener... 

public
void
onLocationChanged(Location
location)
{ 



this.location
=
location; 



logLocation(location); 



this.locationManager.removeUpdates(this); 

} 

public
Location
getLocation()
{ 



return
this.location; 

} } Developing for Android: The Basics 69
  • 76.
    Android Market • No wait to publish apps - upload in the developer console, and it’s available to everybody. • Buyer’s currency • In-app purchases • Google Checkout for purchases, 2.9% discount rate • Google’s cut of app price: 30% Developing for Android: The Basics 70
  • 77.
    Developer Console Developing forAndroid: The Basics 71
  • 78.
    Developer Console stats (earlier in presentation) user comments error reports in-app purchases Developing for Android: The Basics 72
  • 79.
    Developer Console -Error Reports Developing for Android: The Basics 73
  • 80.
    Developer Console -Error Reports Developing for Android: The Basics 74
  • 81.