Download The following tutorial will walk you through the creation of a note

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
The following tutorial will walk you through the creation of a note taking application for
Android. While the application is pretty simple, it should give you a chance to see Android
programming in action.
We will actually implement the application as two Android activities that are loosely-coupled
by persistent local file storage.
Since there is a decent amount of code to implement in a limited amount of time. Instead of
typing all of this we’ll have you copy three files into your project from our solution. All three of
these files are straight forward Java code for working with file storage. Only one file (FileDAO)
contains any mention of the Android SDK (and we’ll discuss that).
After getting those three files copied into your project, we’ll take the final two classes
(MakeNote and ShowNote) piece-by-piece since this is where the Android specific code
resides.
The following table gives a quick description of the functionality provided by the four classes
and one interface that make up the note application.
Class
Description
MakeNote
Allow the user to type and save notes.
ShowNotes
Show a list of stored notes.
Note
A single note.
NoteDAO
Interface that defines how to add and remove notes from storage.
FileDAO
Implementation that adds and removes notes to a local file.
If you feel comfortable with the instructions, feel free to use this document to move at your
own pace. We’ll make announcements when we’re moving to a new step to allow everyone to
synchronize and decide whether they want to listen to the additional instruction and
discussion given for that step.
We’ve included three extra sections at the end of this tutorial that add some functionality
(Text-to-Speech, GPS, and removing notes) to this application. We hope that we’ll have time to
cover these sections, but if not take a look at these. These sections give you a nice feel for the
power of Android.
1
Step 1
Copy and import the NoteSolution project into Eclipse
You can find the full solution to the following note project at the following location:
http://trumpy.cs.elon.edu/joel/sigcse2011/NoteSolution.zip
or
http://dl.dropbox.com/u/8033817/sigcse2011/NoteSolution.zip
Step 1.1: Download the NoteSolution.zip file from either of the above website
(remember where you saved the zip file).
Step 1.2: Start Eclipse. Agree to the given workspace.
Step 1.3: If this is a new workspace for Android development, tell Eclipse where to find the
Android Development Tools (ADT).
In the Eclipse menu: Window → Preferences
Eclipse → Preferences
[for Windows]
[for Mac]
Select Android from the left panel.
Click “Browse” to fill in the empty field for SDK Location.
Browse (and select) where the ADT was installed
example: C:\Android\android-sdk-windows
Click “Apply”, then Click “OK”
Step 1.4: Import the NoteSolution project.
File → Import → General → Existing Projects into Workspace (“Next” button)
Select the “Select archive file” radio button
click the “Browse” button with the “Select archive file” line
browse to the NoteSolution.zip file then click the “Open” button
click “Finish” to import the project into your workspace
2
Step 2
Create and start an Android Emulator
We will need an emulator (unless you have an Android device) in which to run our application.
Let’s go ahead and create one and start it (it takes a while to start one). Once we have it
started we can leave it running while we’re working.
Step 2.1: In Eclipse, start the Android Virtual Device (AVD) Manager.
You can do this by clicking on the little green Android peeking over the box with an
arrow pointed downward.
Step 2.2: Create an Android 2.2 emulator.
Select “Virtual devices” from the left menu.
Click the “New” button on the far right.
Give your emulator a Name.
Choose “Android 2.2 - API Level 8” as the Target.
Click on “Create AVD” at the bottom.
Select your newly created emulator from the list (might be the only one).
Click the “Start” button.
Click the “Launch” button.
You can close the AVD Manager window if you want.
The Emulator will take a while to load. You only want to start it once.
Step 2.3: Play around with the emulator.
3
Step 3
Install and run the NoteSolution application
Step 3.1: In Eclipse, click-to-highlight the NoteSolution project name in the Package Explorer.
Step 3.2: Click on the green right-arrow button (“Run NoteSolution”).
Step 3.3: Choose “Android Application” from the pop-up window, then “OK”.
If Step3.2 does not work for you do the following instead:
Step 3.2: right-click the NoteSolution project folder
Step 3.3: choose Run As → Android Application
From now on you should be able to use the green right-arrow button
The application should automatically start once it has been loaded onto the emulator.
Step 3.4: Play around with the application. Use the “Back” button (the curved arrow back) on
the emulator to move from the list of notes back to where you can type a note.
4
Step 4
Create an Android Project in Eclipse
Step 4.1: In the Eclipse menu choose: File → New → Android Project
Label
Description
Project name
The Eclipse name for this project.
Build Target
Version of Android to build against.
Package name
Android requires packages.
Application name
Name that goes under the icon.
Create Activity
The starting Activity for this app.
Step 4.2: Fill in the five labels described above and click Finish.
Here’s the values used for this tutorial:
Project name: Note
Build Target: Android 2.2
Application name: Note
PackageName: edu.elon.sigcse2011
Create Activity: MakeNote
5
Eclipse will generate a new project called Note. We’ve expanded some of the folders to show
you how an Android project looks to the developer.
File/Folder
Description
MakeNote.java
This is the Activity where the application starts.
R.java
This is an auto-generated file for easy access to items in the
res folder. You should not edit this file.
res/
This is a folder for storing resources (images, XML files, etc.).
AndroidManifest.xml
This defines the application when it is packaged up for
installation.
6
Step 5
Copy the Note, NoteDAO, and FileDAO files into the Note project
The Note.java file contains a class that represents a single text note.
We maintain the following with each note:
• latitude, longitude → where the note was created
• date → time the note was created
• message → the text note
The NoteDAO.java file contains an interface defining the methods for storing Note objects in
a Data Access Object (DAO).
Any NoteDAO must contain the following methods:
• void add(Note note)
• void remove(Note note)
• ArrayList<Note> getAll()
The FileDAO.java file contains an implementation of a NoteDAO for saving Note objects to
a local file. The constructor for FileDAO accepts a Context object. Context is an Android
object that maintains information about the current application including a path to the
application folder. FileDAO uses the Context to determine a path so it can write a file to the
local filesystem.
Let’s copy the files into the Note project.
Step 5.1: right-click on Note.java in NoteSolution/src/edu.elon.sigcse2011
and choose “Copy”
Step 5.2: right-click on Note/src/edu.elon.sigcse2011 and choose “Paste”
Step 5.3: right-click on NoteDAO.java in NoteSolution/src/edu.elon.sigcse2011
and choose “Copy”
Step 5.4: right-click on Note/src/edu.elon.sigcse2011 and choose “Paste”
Step 5.5: right-click on FileDAO.java in NoteSolution/src/edu.elon.sigcse2011
and choose “Copy”
Step 5.6: right-click on Note/src/edu.elon.sigcse2011 and choose “Paste”
Now you should have four .java files in Note/src/:
FileDAO.java MakeNote.java Note.java NoteDAO.java
7
Step 6
Implement the Activity for Creating a Note
When we created our Android project in Step 4, we also created an Android activity named
MakeNote. Android implemented a minimal Activity for us:
import android.app.Activity;
import android.os.Bundle;
public class MakeNote extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
MakeNote.java
package edu.elon.sigcse2011;
Activities are controlled by the Android activity stack. When an activity is started, the activity is
placed on the top of the stack and becomes the currently running activity. If you have an
Android device, you will notice the heavy reliance on the “back” button to move between
applications.
An Activity usually represents a single screen in your application. We will have two Activities in
our Android application (MakeNote and ShowNotes). First, we wish to develop an Android
application that allows the user to type in and save a text note. We will implement this
functionality by changing the MakeNote class.
8
Before we get to the implementation, we need a quick discussion on the lifecycle of an
Android Activity. The following diagram shows the lifecycle of an Activity.
http://developer.android.com/reference/android/app/Activity.html
The methods shown in the rectangular boxes are Activity methods that we can override
during the development of our application. The lifecycle is designed to allow for an activity to
be replaced temporarily at the top of the activity stack. Android needs to handle real-world
events like phone calls. Also, this lifecycle allows us to connect existing Android activities into a
nicely integrated application. You can easily start things like web browsers, phone dialers, SMS
clients, and Google Maps.
9
Let’s start with the user interface layout of our note taking Activity. Android allows you to
implement user interface layout programmatically, in XML, or a combination of the two. Since
this is a fairly simple user interface (shown below), we’ll create the layout using XML.
This layout has a single area for text input (the large white area) and two buttons:
• Save → save the note for later retrieval
• Show List → show a list of saved notes (this will call our second Activity)
Step 6.1: In the Eclipse open res/layout/main.xml.
main.xml
<?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>
10
In order to see the actual XML code, you’ll need to select the main.xml tab.
You can toggle between seeing the XML code and a rough approximation of the layout by
moving between the main.xml and Graphical Layout tabs. The Graphical Layout will only show
things defined by the actual XML code so any programmatic user interface work will not be
seen.
11
The above XML layout is for a simple “Hello, world!” application. We want to replace this with
XML to define the layout shown on the page before. We’ll keep the vertical LinearLayout,
but we’ll replace the TextView with an EditText (for note input) and two Button tags.
Since we want the buttons to be placed horizontal to each other, we’ll place them in a
horizontal LinearLayout.
Step 6.2: Replace the TextView tag with an EditText tag in main.xml.
main.xml
<?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"
>
<EditText
android:id="@+id/note"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:autoText="true"
android:singleLine="false"
/>
</LinearLayout>
Notice the attributes for the EditText tag:
• id=”@+id/note” -- give this soon to be object a name
• layout_width=”fill_parent” -- width based on LinearLayout width
• layout_height=”fill_parent” -- height based on LinearLayout height
• layout_weight=”1” -- high priority for filling the screen
• autoText=”true” -- turn on auto correction
• singleLine=”false” -- allow multiple lines of input text
12
Step 6.3: Insert a horizontal LinearLayout after the EditText in main.xml.
main.xml
<?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"
>
<EditText
android:id="@+id/note"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:autoText="true"
android:singleLine="false"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="5"
>
</LinearLayout>
</LinearLayout>
13
Step 6.4: Insert two Button tags inside the horizontal LinearLayout.
main.xml
<?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"
>
<EditText
android:id="@+id/note"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:autoText="true"
android:singleLine="false"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="5"
>
<Button
android:id="@+id/save"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="Save"
/>
<Button
android:id="@+id/show"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="Show List"
/>
</LinearLayout>
</LinearLayout>
What you see above is the final version of the main.xml file. Take a look at your layout in the
Graphical Layout tab.
We’re done with main.xml so you can go ahead and close the editor tab for main.xml
when you’re done. We’re ready to start work in MakeNote.java now, so select that tab.
14
Step 6.5: Get a reference to the EditText object created by main.xml.
import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
public class MakeNote extends Activity {
MakeNote.java
package edu.elon.sigcse2011;
private EditText et;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// get a reference to the EditText created in main.xml
et = (EditText) findViewById(R.id.note);
}
}
Step 6.6: Create a NoteDAO object for local file storage of notes.
import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
public class MakeNote extends Activity {
MakeNote.java
package edu.elon.sigcse2011;
private EditText et;
private NoteDAO noteDAO;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// hook to the DAO
noteDAO = new FileDAO(this);
// get a reference to the EditText created in main.xml
et = (EditText) findViewById(R.id.note);
}
}
15
Step 6.7: Create an OnClickListener for the save Button.
import
import
import
import
import
android.app.Activity;
android.os.Bundle;
android.widget.EditText;
android.view.View.OnClickListener;
android.widget.Button;
MakeNote.java
package edu.elon.sigcse2011;
public class MakeNote extends Activity {
private EditText et;
private NoteDAO noteDAO;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// hook to the DAO
noteDAO = new FileDAO(this);
// get a reference to the EditText created in main.xml
et = (EditText) findViewById(R.id.note);
// get references to the Buttons created in main.xml
Button save = (Button) findViewById(R.id.save);
// attach ButtonListeners to the Buttons
save.setOnClickListener(saveButtonListener);
}
private OnClickListener saveButtonListener = new OnClickListener() {
public void onClick(View v) {
if (et.getText().length() > 0) {
Note note = new Note(et.getText().toString());
noteDAO.add(note);
et.setText(“”);
}
}
};
}
16
Step 6.8: Create an OnClickListener for the show list Button.
import
import
import
import
android.app.Activity;
android.os.Bundle;
android.view.View.OnClickListener;
android.widget.Button;
MakeNote.java
package edu.elon.sigcse2011;
public class MakeNote extends Activity {
private EditText et;
private NoteDAO noteDAO;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// hook to the DAO
noteDAO = new FileDAO(this);
// get a reference to the EditText created in main.xml
et = (EditText) findViewById(R.id.note);
// get references to the Buttons created in main.xml
Button save = (Button) findViewById(R.id.save);
Button show = (Button) findViewById(R.id.show);
// attach ButtonListeners to the Buttons
save.setOnClickListener(saveButtonListener);
show.setOnClickListener(showButtonListener);
}
private OnClickListener showButtonListener = new OnClickListener() {
public void onClick(View v) {
// leave this blank for now
}
};
private OnClickListener saveButtonListener = new OnClickListener() {
public void onClick(View v) {
if (et.getText().length() > 0) {
Note note = new Note(et.getText().toString());
noteDAO.add(note);
et.setText(“”);
}
}
};
}
17
At this point you have the ability to type and save notes to a file local to the Android device.
The “Show List” button does not work yet, but that is the next step. When we click that button
we want to show a list containing all of the notes currently saved. To do this, we’ll pause the
MakeNote activity and start a ListActivity called ShowNotes.
We will be using an Intent to request Android to load and switch to ShowNotes. Intents can
be used to start just about any existing functionality on the phone including the phone dialer
and a web browser. Intents make it very easy to use existing device functionality.
18
Step 7
Implement the Activity for Showing Saved Notes
We will need to create a new class for our second activity. This activity will show a list of notes.
Android provides a class called ListActivity for just this type of functionality.
19
Step 7.1: Click to highlight the edu.elon.sigcse2011 package under the Note/src/
folder.
Step 7.2: From the Eclipse menu, choose: File → New → Class
Step 7.3: Name the class ShowNotes.
Step 7.4: Click “Finish”.
public class ShowNotes {
}
ShowNotes.java
package edu.elon.sigcse2011;
20
Step 7.5: ShowNotes needs to extend ListActivity and implement onCreate().
import android.app.ListActivity;
import android.os.Bundle;
public class ShowNotes extends ListActivity {
ShowNotes.java
package edu.elon.sigcse2011;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Step 7.6: We need access to a FileDAO object in order to load the list with our data.
import android.app.ListActivity;
import android.os.Bundle;
public class ShowNotes extends ListActivity {
private NoteDAO noteDAO;
ShowNotes.java
package edu.elon.sigcse2011;
@Override
public void onCreate(Bundle savedInstancesState) {
super.onCreate(savedInstanceState);
noteDAO = new FileDAO(this);
}
}
21
Step 7.7: Setup the list adapter for showing notes.
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class ShowNotes extends ListActivity {
ShowNotes.java
package edu.elon.sigcse2011;
private NoteDAO noteDAO;
@Override
public void onCreate(Bundle savedInstancesState) {
super.onCreate(savedInstanceState);
noteDAO = new FileDAO(this);
// fills the list with data from noteDAO
setListAdapter(new ArrayAdapter<Note>(this,
android.R.layout.simple_list_item_1, noteDAO.getAll()));
}
}
The ArrayAdapter uses an Android-provided simple list layout and an ArrayList of notes
provided by our noteDAO to build the scrollable list of notes.
Before we can see our saved notes in a list, we need to do two more things.
1. Have the “Show List” button in MakeNote start the ShowNotes list-activity.
2. Tell the Notes application that ShowNotes is an Activity.
22
Step 7.8: Connect MakeNote’s “Show Lists” button to start ShowNotes.
import android.app.Activity;
import android.os.Bundle;
public class MakeNote extends Activity {
MakeNote.java
package edu.elon.sigcse2011;
private EditText et;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// get a reference to the EditText created in main.xml
et = (EditText) findViewById(R.id.note);
// get references to the Buttons created in main.xml
Button save = (Button) findViewById(R.id.save);
Button show = (Button) findViewById(R.id.show);
// attach ButtonListeners to the Buttons
save.setOnClickListener(saveButtonListener);
show.setOnClickListener(showButtonListener);
}
private OnClickListener showButtonListener = new OnClickListener() {
public void onClick(View v) {
startActivity(new Intent(MakeNote.this, ShowNotes.class));
}
};
private OnClickListener saveButtonListener = new OnClickListener() {
public void onClick(View v) {
if (et.getText().length() > 0) {
Note note = new Note(et.getText().toString());
noteDAO.add(note);
et.setText(“”);
}
}
};
}
23
Step 7.9: Add the ShowNotes ListActivity to the AndroidManifest.xml file.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.elon.sigcse2011"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<activity android:name=".MakeNote"
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=".ShowNotes" />
</application>
</manifest>
24
Step 7.10: Save and then close the tab for the AndroidManifest.xml file.
Give your note application a try. The latitude/longitude values will be 0 since we currently do
nothing with the GPS subsystem.
There are three additions to this application that follow which add some nice functionality.
1. Tag the note with the last know GPS location of the device. We will be able to fake a GPS
location by using Dalvik Debug Monitor Service (DDMS). DDMS also allows us to fake
incoming phone calls and other phone actions. If you are using an actual Android device, be
warned GPS functionality is very spotty in a building.
2. Let Android read your note back to you. Android has a vast suite of classes that help you do
some pretty interesting things easily. Android includes a Text-to-Speech subsystem. While
our example uses English, there is some support for other languages.
3. Allow long-clicks (that’s a click-down-and-hold) to remove notes from the list. Long-clicks are
supported by Android as a callback. We’ll remove a note from our noteDAO when a user
long-clicks a specific note.
Dalvik Debug Monitor Service (DDMS)
There are a number of ways to see DDMS in Eclipse, but we find the easiest way is to switch
the Eclipse perspective to DDMS. Here’s how you do that:
If the DDMS perspective is shown (at the top right) of your Eclipse window
then just click on DDMS.
More than likely it will not originally be seen. If that’s the case click on the
little window+ icon to the left of your currently highlighted perspective. From
the menu, find and choose DDMS (it might be in Other).
You can switch back and forth between the DDMS and Java perspectives as you need.
25
Extra 1
Tag the newly created note with your current GPS location.
Step E1.1: Get access to the device’s LocationManager in MakeNote.
public class MakeNote extends Activity {
private NoteDAO noteDAO;
private EditText et;
private LocationManager locMgr;
MakeNote.java
// add this to the other imports
import android.location.LocationManager;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// hook to the DAO
noteDAO = new FileDAO(this);
// get a reference to the EditText created in main.xml
et = (EditText) findViewById(R.id.note);
// get references to the Buttons created in main.xml
Button save = (Button) findViewById(R.id.save);
Button show = (Button) findViewById(R.id.show);
// attach ButtonListeners to the Buttons
save.setOnClickListener(saveButtonListener);
show.setOnClickListener(showButtonListener);
// request access to the shared location service
locMgr = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
}
...
26
Step E1.2: Enable and disable location updates based on the application’s state.
In this application we don’t really need to know every new location that the
LocationManager determines, but we do need the GPS system to start so we can get a
reasonable location.
Add the following code to the MakeNote class:
MakeNote.java
@Override
protected void onResume() {
super.onResume();
locMgr.requestLocationUpdates
(LocationManager.GPS_PROVIDER, 0, 0, locListener);
}
@Override
protected void onPause() {
super.onPause();
locMgr.removeUpdates(locListener);
}
private LocationListener locListener = new LocationListener() {
public void onLocationChanged(Location location) {}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status,
Bundle extras) {}
};
27
Step E1.3: Assign the last known location values to the newly created note.
Add the following code to the saveButtonListener in the MakeNote class:
public void onClick(View v) {
if (et.getText().length() > 0) {
Note note = new Note(et.getText().toString());
Location loc = locMgr.getLastKnownLocation
(LocationManager.GPS_PROVIDER);
if (loc != null) {
note.setLatitude(loc.getLatitude());
note.setLongitude(loc.getLongitude());
}
MakeNote.java
private OnClickListener saveButtonListener = new OnClickListener() {
noteDAO.add(note);
et.setText("");
}
}
};
We need to ask the Android system for permission to use the GPS.
Step E1.4: Add a request to use GPS in the project’s AndroidManifest.xml file.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="edu.elon.sigcse2011"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon"
android:label="@string/app_name">
<activity android:name=".MakeNote"
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=".ShowNotes" />
</application>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
28
Extra 2
Let the Android device read the note to you.
Step E2.1: Enable Text-To-Speech (TTS) for ShowNotes.
import
import
import
import
android.app.ListActivity;
android.os.Bundle;
android.widget.ArrayAdapter;
android.speech.tts.TextToSpeech;
public class ShowNotes extends ListActivity
implements TextToSpeech.OnInitListener
{
ShowNotes.java
package edu.elon.sigcse2011;
private NoteDAO noteDAO;
private TextToSpeech tts;
@Override
public void onCreate(Bundle savedInstancesState) {
super.onCreate(savedInstanceState);
noteDAO = new FileDAO(this);
// fills the list with data from noteDAO
setListAdapter(new ArrayAdapter<Note>(this,
android.R.layout.simple_list_item_1, noteDAO.getAll()));
// setup a TTS object
tts = new TextToSpeech(this, this);
}
// called on TTS initialization -- not used in this example
public void onInit(int status) {}
}
29
Step E2.2: Have TTS read the message when the list item is clicked.
import
import
import
import
import
import
android.app.ListActivity;
android.os.Bundle;
android.widget.ArrayAdapter;
android.speech.tts.TextToSpeech;
android.view.View;
android.widget.ListView;
ShowNotes.java
package edu.elon.sigcse2011;
public class ShowNotes extends ListActivity
implements TextToSpeech.OnInitListener
{
private NoteDAO noteDAO;
private TextToSpeech tts;
@Override
public void onCreate(Bundle savedInstancesState) {
super.onCreate(savedInstanceState);
noteDAO = new FileDAO(this);
// fills the list with data from noteDAO
setListAdapter(new ArrayAdapter<Note>(this,
android.R.layout.simple_list_item_1, noteDAO.getAll()));
// setup a TTS object
tts = new TextToSpeech(this, this);
}
// what to do when an item is clicked
@Override
public void onListItemClick(ListView parent, View v,
int position, long id) {
Note note = noteDAO.getAll().get(position);
tts.speak(note.getMessage(), TextToSpeech.QUEUE_FLUSH, null);
}
// called on TTS initialization -- not used in this example
public void onInit(int status) {}
}
30
Step E2.3: Shutdown TTS nicely when the activity exits. Add the following method to the
ShowNotes class.
ShowNotes.java
// when app exits, shutdown TTS
@Override
public void onDestroy() {
super.onDestroy();
if (tts != null) {
tts.stop();
tts.shutdown();
}
}
31
Extra 3
Removing notes from the list.
Step E3.1: Remove a note from the list when a long-click happens on that item.
import
import
import
import
import
import
import
import
android.app.ListActivity;
android.os.Bundle;
android.speech.tts.TextToSpeech;
android.view.View;
android.widget.AdapterView;
android.widget.AdapterView.OnItemLongClickListener;
android.widget.ListView;
android.widget.ArrayAdapter;
ShowNotes.java
package edu.elon.sigcse2011;
public class ShowNotes extends ListActivity implements
TextToSpeech.OnInitListener {
private NoteDAO noteDAO;
private TextToSpeech tts;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
noteDAO = new FileDAO(this);
// fills the list with data from NoteDAO
setListAdapter(new ArrayAdapter<Note>(this,
android.R.layout.simple_list_item_1, noteDAO.getAll()));
// setup a long-click listener
getListView().setOnItemLongClickListener(longClickListener);
// setup a TTS object
tts = new TextToSpeech(this, this);
}
// what to do when an item is clicked
@Override
public void onListItemClick(ListView parent, View v, int position,
long id) {
Note note = noteDAO.getAll().get(position);
tts.speak(note.getMessage(), TextToSpeech.QUEUE_FLUSH, null);
}
32
ShowNotes.java
// when app exits, shutdown TTS
@Override
public void onDestroy() {
super.onDestroy();
if (tts != null) {
tts.stop();
tts.shutdown();
}
}
// update the adapter
private void updateAdapter() {
setListAdapter(new ArrayAdapter<Note>(this,
android.R.layout.simple_list_item_1, noteDAO.getAll()));
}
private OnItemLongClickListener longClickListener =
new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<?> parent,
View view, int position, long id) {
Note note = noteDAO.getAll().get(position);
noteDAO.remove(note);
updateAdapter();
return true;
}
};
// called on TTS initialization -- not used in this example
public void onInit(int status) {}
}
We implemented the updateAdapter() method since longClickListener does not have
direct access to the setListAdapter() method. Android does provide means to
automatically update the ListAdapter when the underlying data has changed, but we felt
this quick approach was probably more easily understood in this context as is certainly
simpler looking.
33