Android Development: The Basics

23,987 views

Published on

Overview of the basics of Android software development. Presented to TechMaine's MaineJUG on June 21, 2011.

Published in: Technology
10 Comments
67 Likes
Statistics
Notes
No Downloads
Views
Total views
23,987
On SlideShare
0
From Embeds
0
Number of Embeds
1,229
Actions
Shares
0
Downloads
2,159
Comments
10
Likes
67
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Android Development: The Basics

    1. 1. Developing Android Apps: The Basics Mike Desjardins
    2. 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: @cereslogicDeveloping for Android:The Basics 2
    3. 3. What’s In This Presentation? • What is Android? • Activities and Intents • Views • Permissions • Other Facilities • MarketplaceDeveloping for Android:The Basics 3
    4. 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. 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. 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 filesDeveloping for Android:The Basics 6
    7. 7. 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.htmlDeveloping for Android:The Basics 7
    8. 8. Versions in the Wild, cont. Skicast Free Skicast Pro TidecastDeveloping for Android:The Basics 8
    9. 9. Handsets in the Wild Skicast Free Skicast Pro TidecastDeveloping for Android:The Basics 9
    10. 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. 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. 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. 13. I.e., Don’t Use Task Killers in a misguided attempt to extend battery life! Android Task Killer Apps = Worse Than UselessDeveloping for Android:The Basics 13
    14. 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.pngDeveloping for Android:The Basics 14
    15. 15. Demo Time!Developing for Android:The Basics 15
    16. 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. 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" 



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. 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" 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. 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" 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. 20. 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
    21. 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” classDeveloping for Android:The Basics 21
    22. 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. 23. 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
    24. 24. 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
    25. 25. 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
    26. 26. Demo TimeDeveloping for Android:The Basics 26
    27. 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. 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. 29. 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 tappedDeveloping for Android:The Basics 29
    30. 30. Demo TimeDeveloping for Android:The Basics 30
    31. 31. Yeah... that was pretty lame. Bacon makes everything better, so...Developing for Android:The Basics 31
    32. 32. 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
    33. 33. 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 appDeveloping for Android:The Basics 32
    34. 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. 35. 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 640x480Developing for Android:The Basics 34
    36. 36. 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 640x480Developing for Android:The Basics 34
    37. 37. 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 640x480Developing for Android:The Basics 34
    38. 38. 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 640x480Developing for Android:The Basics 34
    39. 39. 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 640x480Developing for Android:The Basics 34
    40. 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. 41. Bacon TimeDeveloping for Android:The Basics 36
    42. 42. 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
    43. 43. 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
    44. 44. 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
    45. 45. Blinky Bacon TimeDeveloping for Android:The Basics 40
    46. 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. 47. 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
    48. 48. 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
    49. 49. 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 ListViewDeveloping for Android:The Basics 44
    50. 50. 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
    51. 51. 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 stuffDeveloping for Android:The Basics 46
    52. 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. 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. 54. Et Voila!Developing for Android:The Basics 49
    55. 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 IntentsDeveloping for Android:The Basics 50
    56. 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. 57. 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 launchedDeveloping for Android:The Basics 52
    58. 58. 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 appsDeveloping for Android:The Basics 53
    59. 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. 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. 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 ContactsDeveloping for Android:The Basics 56
    62. 62. Common IdiomsDeveloping for Android:The Basics 57
    63. 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. 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 applicationDeveloping for Android:The Basics 59
    65. 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. 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. 67. Demo Time!Developing for Android:The Basics 61
    68. 68. 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
dont
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. 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) UnorderedDeveloping for Android:The Basics 63
    70. 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. 71. (Demo if there is time)Developing for Android:The Basics 65
    72. 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 slideDeveloping for Android:The Basics 66
    73. 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. 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 locationDeveloping for Android:The Basics 68
    75. 75. 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
    76. 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. 77. Developer ConsoleDeveloping for Android:The Basics 71
    78. 78. Developer Console stats (earlier in presentation) user comments error reports in-apppurchasesDeveloping for Android:The Basics 72
    79. 79. Developer Console - Error ReportsDeveloping for Android:The Basics 73
    80. 80. Developer Console - Error ReportsDeveloping for Android:The Basics 74
    81. 81. Questions?Developing for Android:The Basics 75

    ×