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 This Presentation?
• 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 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
8. Versions in the Wild, cont.
Skicast Free Skicast Pro
Tidecast
Developing for Android:
The Basics 8
9. Handsets in the Wild
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 Use Task 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
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 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. 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
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. 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 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. 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. 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
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 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
31. Yeah... that was pretty lame.
Bacon makes everything better, so...
Developing for Android:
The Basics 31
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. 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
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 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
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
640x480
Developing for Android:
The Basics 34
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
640x480
Developing for Android:
The Basics 34
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
640x480
Developing for Android:
The Basics 34
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
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
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. 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. 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
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 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. 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. 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
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. 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
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
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 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
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 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
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
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
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 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 there is 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 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. 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