diff options
Diffstat (limited to 'docs/html/resources/faq/commontasks.jd')
-rw-r--r-- | docs/html/resources/faq/commontasks.jd | 821 |
1 files changed, 821 insertions, 0 deletions
diff --git a/docs/html/resources/faq/commontasks.jd b/docs/html/resources/faq/commontasks.jd new file mode 100644 index 0000000..fa487f7 --- /dev/null +++ b/docs/html/resources/faq/commontasks.jd @@ -0,0 +1,821 @@ +page.title=Common Tasks and How to Do Them in Android +parent.title=FAQs, Tips, and How-to +parent.link=index.html +@jd:body + +<ul> + <li><a href="#neweclipseandroidproject">Creating an Android Application using + the Eclipse plugin</a></li> + <li><a href="#newandroidprojectnoeclipse">Creating an Android Application without + the Eclipse plugin</a></li> + <li><a href="#addexternallibrary">Adding an External Library (.jar) using Eclipse</a></li> + <li><a href="#implementcallbacks">Implementing Activity callbacks</a> (Android + calls your activity at various key moments in its life cycle. You must know + how to handle each of these to draw your screen, initialize class members, + and acquire data.)</li> + <li><a href="#opennewscreen">Opening a new screen</a></li> + <li><a href="#listening">Listening for button clicks </a></li> + <li><a href="#configurewindowproperties">Configuring general window properties </a></li> + <li><a href="#localhostalias">Referring to localhost from the emulated environment</a></li> + <li><a href="#appstate">Storing and retrieving state</a></li> + <li><a href="{@docRoot}guide/topics/data/data-storage.html#preferences">Storing and retrieving preferences</a></li> + <li><a href="#storingandretrieving">Storing and retrieving larger or more complex + persistent data</a> (files and data) </li> + <li><a href="#playback">Playing audio, video, still, or other media files</a></li> + <li><a href="#broadcastreceivers">Listening for and broadcasting global messages + and setting alarms</a></li> + <li><a href="#alerts">Displaying alerts </a></li> + <li><a href="#progressbar">Displaying a progress bar</a> </li> + <li><a href="#addmenuitems">Adding items to the screen menu</a> </li> + <li><a href="#webpage">Display a web page</a> </li> + <li><a href="#binding">Binding to data</a></li> + <li><a href="#handle">Getting a Handle to a Screen Element</a></li> + <li><a href="#captureimages">Capture images from the phone camera </a></li> + <li><a href="#threading">Handling expensive operations in the UI thread</a></li> + <li><a href="#selectingtext">Selecting, highlighting, or styling portions of + text</a></li> + <li><a href="#querymap">Utilizing attributes in a Map query</a></li> + <li><a href="#filelist">List of files for an Android application</a></li> + <li><a href="#logging">Print messages to a log file</a></li> +</ul> +<p>The ApiDemos sample application includes many, many examples of common +tasks and UI features. See the code inside +<code><sdk>samples/ApiDemos</code> and the other sample applications +under the <code>samples/</code> folder in the SDK.</p> + + +<h2 id="neweclipseandroidproject">Creating an Android Application using the Eclipse Plugin</h2> + +<p>Using the Android Eclipse plugin is the fastest and easiest way +to start creating a new Android application. The plugin automatically generates +the correct project structure for your application, and keeps the resources +compiled for you automatically.</p> + +<p>It is still a good idea to know what is going on though. Take a look at <a +href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> +to understand the basics of how an Android application works.</p> + +<p>You should also take a look at the ApiDemos application and the other sample +applications included in the SDK, in the <code><sdk>/samples/</code> +folder in the SDK.</p> + +<p>Finally, a great way to started with Android development in Eclipse is to +follow both the <a href="{@docRoot}resources/tutorials/hello-world.html">Hello, +World</a> and <a +href="{@docRoot}resources/tutorials/notepad/index.html">Notepad</a> code +tutorials. In particular, the start of the Hello Android tutorial is an +excellent introduction to creating a new Android application in Eclipse.</p> + +<h2 id="newandroidprojectnoeclipse">Creating an Android Application without the Eclipse Plugin</h2> + +<p>This topic describes the manual steps in creating an Android application. +Before reading this, you should read <a +href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a> +to understand the basics of how an Android application works. You might also +want to look at the sample code included with the Android SDK, in the +<code><sdk>/samples/</code> directory. </p> + +<p>Here is a list of the basic steps in building an application.</p> +<ol> + <li><strong>Create your required resource files</strong> This includes + the AndroidManifest.xml global description file, string files that your application + needs, and layout files describing your user interface. A full list of optional + and required files and syntax details for each is given in <a href="#filelist">File + List for an Android Application</a>. </li> + <li><strong>Design your user interface</strong> See <a + href="{@docRoot}guide/topics/ui/index.html">User Interface</a> for + details on elements of the Android screen. </li> + <li><strong>Implement your Activity </strong>(this page)<strong> </strong> You + will create one class/file for each screen in your application. Screens will + inherit from an {@link android.app android.app} class, typically {@link android.app.Activity + android.app.Activity} for basic screens, {@link android.app.ListActivity + android.app.ListActivity} for list screens, or {@link android.app.Dialog + android.app.Dialog} for dialog boxes. You will implement the required callbacks + that let you draw your screen, query data, and commit changes, and also perform + any required tasks such as opening additional screens or reading data from + the device. Common tasks, such as opening a new screen or reading data from + the device, are described below. + The list of files you'll need for your application are described in <a href="#filelist">List + of Files for an Android Application</a>. </li> + <li><strong><a href="{@docRoot}guide/developing/other-ide.html#buildingwithant">Build and install your + package</a>.</strong> The Android SDK has some nice tools for generating + projects and debugging code. </li> +</ol> + +<h2 id="addexternallibrary">Adding an External Library (.jar) using Eclipse</h2> +<p> +You can use a third party JAR in your application by adding it to your Eclipse project as follows: +</p> +<ol> +<li> +In the <strong>Package Explorer</strong> panel, right-click on your project and select <strong>Properties</strong>. +<li> +Select <strong>Java Build Path</strong>, then the tab <strong>Libraries</strong>. +<li> +Press the <strong>Add External JARs...</strong> button and select the JAR file. +</ol> +<p> +Alternatively, if you want to include third party JARs with your package, create a new directory for them within your project and select <strong>Add Library...</strong> instead.</p> +<p> +It is not necessary to put external JARs in the assets folder. +</p> + +<a name="implementcallbacks" id="implementcallbacks"></a> +<h2>Implementing Activity Callbacks</h2> +<p>Android calls a number of callbacks to let you draw your screen, store data before + pausing, and refresh data after closing. You must implement at least some of + these methods. See <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Lifecycles</a> + discussion in Application Fundamentals to learn when and in what order these methods + are called. Here are some of the standard types of screen classes that Android provides:</p> +<ul> + <li>{@link android.app.Activity android.app.Activity} - This is a standard screen, + with no specialization.</li> + <li>{@link android.app.ListActivity android.app.ListActivity} - This is a screen + that is used to display a list of something. It hosts a ListView object, + and exposes methods to let you identify the selected item, receive callbacks + when the selected item changes, and perform other list-related actions. </li> + <li>{@link android.app.Dialog android.app.Dialog} - This is a small, popup dialog-style + window that isn't intended to remain in the history stack. (It is not resizeable + or moveable by the user.)</li> +</ul> + +<a name="opennewscreen" id="opennewscreen"></a><h2>Opening a New Screen</h2> +<p>Your Activity will often need to open another Activity screen as it progresses. + This new screen can be part of the same application or part of another application, + the new screen can be floating or full screen, it can return a result, and you + can decide whether to close this screen and remove it from the history stack + when you are done with it, or to keep the screen open in history. These next + sections describe all these options. </p> +<h3>Floating or full?<a name="floatingorfull" id="floatingorfull"></a></h3> +<p>When you open a new screen you can decide whether to make it transparent or floating, + or full-screen. The choice of new screen affects the event sequence of events + in the old screen (if the new screen obscures the old screen, a different + series of events is called in the old screen). See <a + href="{@docRoot}guide/topics/fundamentals.html#lcycles">Lifecycles</a> discussion + in Application Fundamentals for details. </p> +<p>Transparent or floating windows are implemented in three + standard ways: </p> +<ul> + <li>Create an {@link android.app.Dialog app.Dialog} class </li> + <li>Create an {@link android.app.AlertDialog app.AlertDialog} class </li> + <li>Set the {@link android.R.style#Theme_Dialog} <em>theme</em> attribute to <code>@android:style/Theme.Dialog</code> + in your AndroidManifest.xml file. For example: +</ul> +<blockquote> + <pre><activity class="AddRssItem" android:label="Add an item" android:theme="@android:style/Theme.Dialog"/> +</pre> +</blockquote> +<p>Calling startActivity() or startActivityForResult() will open a new screen in whatever + way it defines itself (if it uses a floating theme it will be floating, + otherwise it will be full screen). </p> +<h3>Opening a Screen </h3> +<p>When you want to open a new screen, you can either explicitly specify the activity + class to open, or you can let the operating system decide which screen to open, + based upon the data and various parameters you pass in. A screen is opened by + calling {@link android.app.Activity#startActivity(android.content.Intent) startActivity} + and passing in an {@link android.content.Intent Intent} object, which specifies + the criteria for the handling screen. To specify a specific screen, call Intent.setClass + or setClassName with the exact activity class to open. Otherwise, set a variety + of values and data, and let Android decide which screen is appropriate to open. + Android will find one or zero Activities that match the specified requirements; + it will never open multiple activities for a single request. More information + on Intents and how Android resolves them to a specific class is given in the + {@link android.content.Intent Intent} topic. </p> +<a name="intentexamples" id="intentexamples"></a><h3>Some Intent examples </h3> +<p>The following snippet loads the com.android.samples.Animation1 class, and + passes it some arbitrary data.:</p> +<pre>Intent myIntent = new Intent(); +myIntent.setClassName("com.android.samples", "com.android.samples.Animation1"); +myIntent.putExtra("com.android.samples.SpecialValue", "Hello, Joe!"); // key/value pair, where key needs current package prefix. +startActivity(myIntent); </pre> +<p>The next snippet requests that a Web page be opened by specifying the VIEW action, + and a URI data string starting with "http://" schema:</p> +<pre>Intent myIntent = new Intent(Intent.VIEW_ACTION, Uri.parse("http://www.google.com"));</pre> +<p>Here is the intent filter from the AndroidManifest.xml file for com.android.browser:</p> +<pre><intent-filter> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.DEFAULT" /> + <scheme android:name="http" /> + <scheme android:name="https" /> + <scheme android:name="file" /> +</intent-filter> </pre> +<p>Android defines a number of standard values, for instance the action constants + defined by {@link android.content.Intent}. You can define custom values, but + both the caller and handler must use them. See the <intent-filter> + tag description in <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml + File</a> for more information on the manifest syntax for the handling + application. </p> +<a name="returningaresult" id="returningaresult"></a><h3>Returning a Result from a Screen</h3> +<p>A window can return a result after it closes. This result will be passed back + into the calling Activity's {@link android.app.Activity#onActivityResult(int,int,android.content.Intent) + onActivityResult()} method, which can supply an Intent containing arbitrary data, along with + the request code passed to startActivityForResult(). Note that you must call the {@link + android.app.Activity#startActivityForResult(android.content.Intent,int) startActivityForResult()} + method that accepts a request code parameter to get this callback. The following + code demonstrates opening a new screen and retrieving a result. </p> +<pre>// Open the new screen. +public void onClick(View v){ + // Start the activity whose result we want to retrieve. The + // result will come back with request code GET_CODE. + Intent intent = new Intent(this, com.example.app.ChooseYourBoxer.class); + startActivityForResult(intent, CHOOSE_FIGHTER); +} + +// Listen for results. +protected void onActivityResult(int requestCode, int resultCode, Intent data){ + // See which child activity is calling us back. + switch (resultCode) { + case CHOOSE_FIGHTER: + // This is the standard resultCode that is sent back if the + // activity crashed or didn't doesn't supply an explicit result. + if (resultCode == RESULT_CANCELED){ + myMessageboxFunction("Fight cancelled"); + } + else { + myFightFunction(data); + } + default: + break; + } +} + +// Class SentResult +// Temporary screen to let the user choose something. + private OnClickListener mLincolnListener = new OnClickListener(){ + public void onClick(View v) { + Bundle stats = new Bundle(); + stats.putString("height","6\'4\""); + stats.putString("weight", "190 lbs"); + stats.putString("reach", "74\""); + setResult(RESULT_OK, "Lincoln", stats); + finish(); + } + }; + + private OnClickListener mWashingtonListener = new OnClickListener() { + public void onClick(View v){ + Bundle stats = new Bundle(); + stats.putString("height","6\'2\""); + stats.putString("weight", "190 lbs"); + stats.putString("reach", "73\""); + setResult(RESULT_OK, "Washington", Bundle); + finish(); + } + }; + </pre> +<h3>Lifetime of the new screen </h3> +<p>An activity can remove itself from the history stack by calling {@link android.app.Activity#finish() + Activity.finish()} on itself, or the activity that opened the screen can call + {@link android.app.Activity#finishActivity(int) Activity.finishActivity()} + on any screens that it opens to close them. </p> +<a name="listening" id="listening"></a><h2>Listening for Button Clicks</h2> +<p>Button click and other UI event capturing are covered in <a href="{@docRoot}guide/topics/ui/ui-events.html">Handling UI Events</a> on the UI Design page.</p> +<a name="configurewindowproperties" id="configurewindowproperties"></a><h2>Configuring General Window Properties</h2> +<p>You can set a number of general window properties, such as whether to display + a title, whether the window is floating, and whether it displays an icon, by + calling methods on the {@link android.view.Window Window} member + of the underlying View object for the window. Examples include calling {@link + android.app.Activity#getWindow() getWindow().requestFeature()} (or the convenience + method {@link android.app.Activity#requestWindowFeature(int) requestWindowFeature(<em>some_feature</em>)}) + to hide the title. Here is an example of hiding the title bar:</p> +<pre>//Hide the title bar +requestWindowFeature(Window.FEATURE_NO_TITLE); +</pre> +<p>A better way to achieve the same end is to specify a theme in your Android +Manifest file:</p> +<pre><application android:icon="@drawable/icon" android:theme="@android:style/Theme.NoTitleBar"> +</pre> +<p>This is preferable because it tells the system not to show a title bar while +your application is starting up. With the explicit method call, your application +will have a title bar visible to the user until <code>onCreate</code> runs.</p> +<p>(Note that this can be applied to either the <code><application></code> +tag or to individual <code><activity></code> tags.)</p> +<a name="localhostalias" id="localhostalias"></a><h2>Referring to localhost from the emulated environment</h2> +<p> +If you need to refer to your host computer's <em>localhost</em>, such as when you +want the emulator client to contact a server running on the same host, use the alias +<code>10.0.2.2</code> to refer to the host computer's loopback interface. +From the emulator's perspective, localhost (<code>127.0.0.1</code>) refers to its own +loopback interface. +</p> +<a name="appstate" id="appstate"></a><h2>Storing and Retrieving State</h2> +<p>If your application is dumped from memory because of space concerns, it will lose + all user interface state information such as checkbox state and text box values + as well as class member values. Android calls {@link android.app.Activity#onSaveInstanceState(android.os.Bundle) + Activity.onSaveInstanceState} before it pauses the application. This method hands in a {@link + android.os.Bundle Bundle} that can be used to store name/value pairs that will + persist and be handed back to the application even if it is dropped from memory. + Android will pass this Bundle back to you when it calls {@link android.app.Activity#onCreate(android.os.Bundle) + onCreate()}. This Bundle only exists while the application is still in the history + stack (whether or not it has been removed from memory) and will be lost when + the application is finalized. See the topics for {@link android.app.Activity#onSaveInstanceState} and + {@link android.app.Activity#onCreate} for + examples of storing and retrieving state.</p> +<p>Read more about the lifecycle of an application in <a href="{@docRoot}guide/topics/fundamentals.html">Application Fundamentals</a>.</p> +<h3>Storing and Retrieving Larger or More Complex Persistent Data<a name="storingandretrieving" id="storingandretrieving"></a></h3> +<p>Your application can store files or complex collection objects, and reserve them + for private use by itself or other activities in the application, or it can expose + its data to all other applications on the device. See <a href="{@docRoot}guide/topics/data/data-storage.html">Storing, + Retrieving, and Exposing Data</a> to learn how to store and retrieve private data, + how to store and retrieve common data from the device, and how to expose your + private data to other applications.</p> +<a name="playback" id="playback"></a><h2>Playing Media Files</h2> +<p>Please see the document <a href="{@docRoot}guide/topics/media/index.html">Audio and Video</a> for more details.</p> +<a name="broadcastreceivers" id="broadcastreceivers"></a><h2>Listening For and Broadcasting Global Messages, and Setting Alarms</h2> +<p>You can create a listening class that can be notified or even instantiated whenever + a specific type of system message is sent. +</p> +<p>The listening classes, called broadcast receivers, extend {@link android.content.BroadcastReceiver + BroadcastReceiver}. If you want Android to instantiate the object whenever an appropriate + intent notification is sent, define the receiver with a <code><receiver></code> element + in the AndroidManifext.xml file. If the caller is expected to instantiate the + object in preparation to receive a message, this is not required. The receiver + will get a call to their {@link android.content.BroadcastReceiver#onReceive(android.content.Context,android.content.Intent) + BroadcastReceiver.onReceive()} method. A receiver can define an <code><intent-filter></code> tag + that describes the types of messages it will receive. Just as Android's IntentResolver + will look for appropriate Activity matches for a startActivity() call, it will + look for any matching Receivers (but it will send the message to all matching + receivers, not to the "best" match). </p> +<p>To send a notification, the caller creates an {@link android.content.Intent Intent} + object and calls {@link android.app.Activity#sendBroadcast(android.content.Intent) + Context.sendBroadcast()} with that Intent. Multiple recipients can receive + the same message. You can broadcast an Intent message to an intent receiver in + any application, not only your own. If the receiving class is not registered + using <code><receiver></code> in its manifest, you can dynamically instantiate + and register a receiver by calling {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver,android.content.IntentFilter) + Context.registerReceiver()}. </p> +<p>Receivers can include intent filters to specify what kinds of intents they are + listening for. Alternatively, if you expect a single known caller to contact + a single known receiver, the receiver does not specify an intent filter, and + the caller specifies the receiver's class name in the Intent by calling {@link + android.content.Intent#setClassName(java.lang.String, java.lang.String) Intent.setClassName()} + with the recipient's class name. The recipient receives a {@link android.content.Context + Context} object that refers to its own package, not to the package of the sender.</p> +<p><em><strong>Note:</strong></em> If a receiver or broadcaster + enforces permissions, your application might need to request permission + to send or receive messages from that object. You can request permission by using + the <uses-permission> tag in the manifest. </p> +<p>Here is a code snippet of a sender and receiver. This example does not demonstrate + registering receivers dynamically. For a full code example, see the AlarmService + class in the ApiDemos project.</p> +<h3>Sending the message</h3> +<pre>// We are sending this to a specific recipient, so we will +// only specify the recipient class name. +Intent intent = new Intent(this, AlarmReceiver.class); +intent.putExtra("message","Wake up."); +sendBroadcast(intent); +</pre> +<h3>Receiving the message</h3> +<p><strong>Receiver AndroidManifest.xml </strong>(because there is no intent filter + child, this class will only receive a broadcast when the receiver class is specified + by name, as is done in this example):</p> +<pre> +<receiver class=".AlarmReceiver" /></pre> +<p><strong>Receiver Java code: </strong></p> +<pre> +public class AlarmReceiver extends BroadcastReceiver{ + // Display an alert that we've received a message. + @Override + public void onReceive(Context context, Intent intent){ + // Send a text notification to the screen. + NotificationManager nm = (NotificationManager) + context.getSystemService(Context.NOTIFICATION_SERVICE); + nm.notifyWithText(R.id.alarm, + "Alarm!!!", + NotificationManager.LENGTH_SHORT, + null); + } +} </pre> +<h3>Other system messages</h3> +<p>You can listen for other system messages sent by Android as well, such as USB + connection/removal messages, SMS arrival messages, and timezone changes. See + {@link android.content.Intent} for a list of broadcast messages to listen for. + Messages are marked "Broadcast Action" in the documentation. </p> +<h3>Listening for phone events<a name="phoneevents" id="phoneevents"></a></h3> +<p>The {@link android.telephony android.telephony} package overview page describes how to + register to listen for phone events. </p> +<a name="alarms" id="alarms"></a><h3>Setting Alarms </h3> +<p>Android provides an {@link android.app.AlarmManager AlarmManager} service that + will let you specify an Intent to send at a designated time. This intent is typically + used to start an application at a preset time. (Note: If you want to send + a notification to a sleeping or running application, use {@link android.os.Handler + Handler} instead.)</p> +<a name="alerts" id="alerts"></a><h2>Displaying Alerts</h2> +<p>There are two major kinds of alerts that you may display to the user: +(1) Normal alerts are displayed in response to a user action, such as +trying to perform an action that is not allowed. (2) Out-of-band alerts, +called notifications, are +displayed as a result of something happening in the background, such as the +user receiving new e-mail.</p> + +<a name="dialogsandalerts" id="dialogsandalerts"></a><h3>Normal Alerts</h3> + +<p>Android provides a number of ways for you to show popup notifications to your + user as they interact with your application. </p> +<table width="100%" border="1"> + <tr> + <th scope="col">Class</th> + <th scope="col">Description</th> + </tr> + <tr> + <td>{@link android.app.Dialog app.Dialog}</td> + <td>A generic floating dialog box with a layout that you design. </td> + </tr> + <tr> + <td><p>{@link android.app.AlertDialog app.AlertDialog}</p></td> + <td>A popup alert dialog with two buttons (typically OK and Cancel) that + take callback handlers. See the section after this table for more details. </td> + </tr> + <tr> + <td>{@link android.app.ProgressDialog ProgressDialog} </td> + <td>A dialog box used to indicate progress of an operation with a known progress + value or an indeterminate length (setProgress(bool)). See <strong>Views</strong> > <strong>Progress Bar</strong> in + ApiDemos for examples. </td> + </tr> + <tr> + <td>Activity</td> + <td>By setting the theme of an activity to + {@link android.R.style#Theme_Dialog + android:theme="@android:style/Theme.Dialog"}, + your activity will take on + the appearance of a normal dialog, floating on top of whatever was + underneath it. You usually set the theme through the + {@link android.R.attr#theme android:theme} attribute in your AndroidManifest.xml. + The advantage of this + over Dialog and AlertDialog is that Application has a much better managed + life cycle than dialogs: if a dialog goes to the background and is killed, + you cannot recapture state, whereas Application exposes a {@link android.os.Bundle + Bundle} of saved values in <code>onCreate()</code> to help you maintain state.</td> + </tr> +</table> +<h3>AlertDialog</h3> +<p>This is a basic warning dialog box that lets you configure a message, button text, + and callback. You can create one by calling using the {@link + android.app.AlertDialog.Builder} class, as shown here. </p> +<pre>private Handler mHandler = new Handler() { + public void handleMessage(Message msg) { + switch (msg.what) { + case ACCEPT_CALL: + answer(msg.obj); + break; + + case BOUNCE_TO_VOICEMAIL: + voicemail(msg.obj); + break; + + } + } +}; + + +private void IncomingMotherInlawCall(Connection c) { + String Text; + + // "Answer" callback. + Message acceptMsg = Message.obtain(); + acceptMsg.target = mHandler; + acceptMsg.what = ACCEPT_CALL; + acceptMsg.obj = c.getCall(); + + // "Cancel" callback. + final Message rejectMsg = Message.obtain(); + rejectMsg.target = mHandler; + rejectMsg.what = BOUNCE_TO_VOICEMAIL; + rejectMsg.obj = c.getCall(); + + new AlertDialog.Builder(this) + .setMessage("Phyllis is calling") + .setPositiveButton("Answer", acceptMsg) + .setOnCanceListener(new OnCancelListener() { + public void onCancel(DialogInterface dialog) { + rejectMsg.sendToTarget(); + }}); + .show(); +} </pre> + +<h3>Notifications</h3> + +<p>Out-of-band alerts should always be displayed using the +{@link android.app.NotificationManager}, which allows you to tell the user +about something they may be interested in without disrupting what they are +currently doing. A notification can be anything from a brief pop-up box +informing the user of the new information, through displaying a persistent +icon in the status bar, to vibrating, playing sounds, or flashing lights to +get the user's attention. In all cases, the user must explicitly shift their +focus to the notification before they can interact with it.</p> + +<p>The following code demonstrates using NotificationManager to display a basic text + popup when a new SMS message arrives in a listening service, and provides the + current message count. You can see several more examples in the ApiDemos application, + under app/ (named <em>notification</em>*.java).</p> +<pre>static void setNewMessageIndicator(Context context, int messageCount){ + // Get the static global NotificationManager object. + NotificationManager nm = NotificationManager.getDefault();</p> + + // If we're being called because a new message has been received, + // then display an icon and a count. Otherwise, delete the persistent + // message. + if (messageCount > 0) { + nm.notifyWithText(myApp.NOTIFICATION_GUID, // ID for this notification. + messageCount + " new message" + messageCount > 1 ? "s":"", // Text to display. + NotificationManager.LENGTH_SHORT); // Show it for a short time only. + } +}</pre> +<p>To display a notification in the status bar and have it launch an intent when + the user selects it (such as the new text message notification does), call {@link + android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()}, + and pass in vibration patterns, status bar icons, or Intents to associate with + the notification. </p> +<a name="progressbar" id="progressbar"></a><h2>Displaying a Progress Bar</h2> +<p>An activity can display a progress bar to notify the user that something is happening. + To display a progress bar in a screen, call {@link android.app.Activity#requestWindowFeature(int) + Activity.requestWindowFeature(Window.FEATURE_PROGRESS)}. To set the value + of the progress bar, call {@link android.view.Window#setFeatureInt(int,int) + Activity.getWindow().setFeatureInt(Window.FEATURE_PROGRESS, <em>level</em>)}. + Progress bar values are from 0 to 9,999, or set the value to 10,000 to make the + progress bar invisible. </p> +<p>You can also use the {@link android.app.ProgressDialog ProgressDialog} class, + which enables a dialog box with an embedded progress bar to send a "I'm working + on it" notification to the user. </p> +<a name="addmenuitems" id="addmenuitems"></a><h2>Adding Items to the Screen Menu</h2> +<p>See <a href="{@docRoot}guide/topics/ui/menus.html">Creating Menus</a>.</p> + +<a name="webpage" id="webpage"></a><h2>Display a Web Page</h2> +<p>Use the {@link android.webkit.WebView webkit.WebView} object. </p> +<a name="binding" id="binding"></a><h2>Binding to Data</h2> +<p>You can bind a ListView to a set of underlying data by using a shim class called + {@link android.widget.ListAdapter ListAdapter} (or a subclass). ListAdapter subclasses + bind to a variety of data sources, and expose a common set of methods such as + getItem() and getView(), and uses them to pick View items to display in its list. + You can extend ListAdapter and override getView() to create your own custom list + items. There are essentially only two steps you need to perform to bind to data: </p> +<ol> + <li>Create a ListAdapter object and specify its data source</li> + <li>Give the ListAdapter to your ListView object.</li> +</ol> +<p>That's it!</p> +<p>Here's an example of binding a ListActivity screen to the results from a cursor + query. (Note that the setListAdapter() method shown is a convenience method that + gets the page's ListView object and calls setAdapter() on it.)</p> +<pre>// Run a query and get a Cursor pointing to the results. +Cursor c = People.query(this.getContentResolver(), null); +startManagingCursor(c); + +// Create the ListAdapter. A SimpleCursorAdapter lets you specify two interesting things: +// an XML template for your list item, and +// The column to map to a specific item, by ID, in your template. +ListAdapter adapter = new SimpleCursorAdapter(this, + android.R.layout.simple_list_item_1, // Use a template that displays a text view + c, // Give the cursor to the list adapter + new String[] {People.NAME} , // Map the NAME column in the people database to... + new String[] {"text1"}); // The "text1" view defined in the XML template +setListAdapter(adapter);</pre> +<p>See view/List4 in the ApiDemos project for an example of extending ListAdapter + for a new data type. </p> + +<a name="handle"></a> + +<h2>Getting a Handle to a Screen Element</h2> +<p>You can get a handle to a screen element by calling {@link +android.app.Activity#findViewById(int) Activity.findViewById}. You can then use +the handle to set or retrieve any values exposed by the object. </p> +<a name="captureimages" id="captureimages"></a><h2>Capture Images from the Phone Camera</h2> +<p>You can hook into the device's camera onto your own Canvas object by using the + {@link android.hardware.Camera Camera} class. See that class's documentation, + and the ApiDemos project's Camera Preview application (Graphics/Camera Preview) + for example code. </p> + + +<a name="threading" id="threading"></a><h2>Handling Expensive Operations in the UI Thread</h2> +<p>Avoid performing long-running operations (such as network I/O) directly in the UI thread — +the main thread of an application where the UI is run — or your application may be blocked +and become unresponsive. Here is a brief summary of the recommended approach for handling expensive operations:</p> +<ol> +<li>Create a Handler object in your UI thread</li> +<li>Spawn off worker threads to perform any required expensive operations</li> +<li>Post results from a worker thread back to the UI thread's handler either through a Runnable or a {@link android.os.Message}</li> +<li>Update the views on the UI thread as needed</li> +</ol> + +<p>The following outline illustrates a typical implementation:</p> + +<pre> +public class MyActivity extends Activity { + + [ . . . ] + // Need handler for callbacks to the UI thread + final Handler mHandler = new Handler(); + + // Create runnable for posting + final Runnable mUpdateResults = new Runnable() { + public void run() { + updateResultsInUi(); + } + }; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + [ . . . ] + } + + protected void startLongRunningOperation() { + + // Fire off a thread to do some work that we shouldn't do directly in the UI thread + Thread t = new Thread() { + public void run() { + mResults = doSomethingExpensive(); + mHandler.post(mUpdateResults); + } + }; + t.start(); + } + + private void updateResultsInUi() { + + // Back in the UI thread -- update our UI elements based on the data in mResults + [ . . . ] + } +} +</pre> + +<p>For further discussions on this topic, see +<a href="{@docRoot}guide/practices/design/responsiveness.html">Designing for Responsiveness</a> +and the {@link android.os.Handler} documentation.</p> + +<a name="selectingtext" id="selectingtext"></a><h2>Selecting, Highlighting, or Styling Portions of Text</h2> +<p>You can highlight or style the formatting of strings or substrings of text in + a TextView object. There are two ways to do this:</p> +<ul> + <li>If you use a <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">string resource</a>, + you can add some simple styling, such as bold or italic using HTML notation. + The currently supported tags are: <code>B</code> (bold), + <code>I</code> (italic), <code>U</code> (underline), + <code>TT</code> (monospace), <code>BIG</code>, <code>SMALL</code>, + <code>SUP</code> (superscript), <code>SUB</code> (subscript), + and <code>STRIKE</code> (strikethrough). + So, for example, in res/values/strings.xml you could declare this:<br /> + <code><resource><br /> + <string>id="@+id/styled_welcome_message">We + are <b><i>so</i></b> glad to see you.</string><br /> + </resources></code></li> + <li>To style text on the fly, or to add highlighting or more complex styling, + you must use the Spannable object as described next. </li> +</ul> +<p>To style text on the fly, you must make sure the TextView is using {@link android.text.Spannable} + storage for the text (this will always be true if the TextView is an EditText), + retrieve its text with {@link android.widget.TextView#getText}, and call {@link + android.text.Spannable#setSpan}, passing in a new style class from the {@link + android.text.style} package and the selection range. </p> +<p>The following code snippet demonstrates creating a string with a highlighted section, + italic section, and bold section, and adding it to an EditText object. </p> +<pre>// Get our EditText object. +EditText vw = (EditText)findViewById(R.id.text); + +// Set the EditText's text. +vw.setText("Italic, highlighted, bold."); + +// If this were just a TextView, we could do: +// vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE); +// to force it to use Spannable storage so styles can be attached. +// Or we could specify that in the XML. + +// Get the EditText's internal text storage +Spannable str = vw.getText(); + +// Create our span sections, and assign a format to each. +str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); +str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); +str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); +</pre> + +<a name="querymap" id="querymap"></a><h2>Utilizing attributes in a Map query</h2> +<p> +When using a search intent to ask the Maps activity to search for something, the Maps activity responds to the following attributes in the optional context bundle: +</p> +<pre> + float "centerLatitude" default 0.0f + float "centerLongitude" default 0.0f + float "latitudeSpan" default 0.0f + float "longitudeSpan" default 0.0f + int "zoomLevel" default 10 +</pre> +<p> +This context information is used to center the search result in a particular area, and is equivalent to adjusting the Map activity to the described location and zoom level before issuing the query. +</p> +<p> +If the latitudeSpan, longitudeSpan, and zoomLevel attributes are not consistent, then it is undefined which one takes precedence. +</p> + +<a name="filelist" id="filelist"></a><h2>List of Files for an Android Application</h2> +<p>The following list describes the structure and files of an Android application. + Many of these files can be built for you (or stubbed out) by the android tool + shipped in the tools/ menu of the SDK. </p> +<table width="100%" border="0"> + <tr> + <td width="28%" valign="top">MyApp/<br /></td> + <td width="72%" valign="top"> </td> + </tr> + <tr> + <td valign="top"> AndroidManifest.xml</td> + <td valign="top">(<em>required</em>) Advertises the screens that this application provides, + where they can be launched (from the main program menu or elsewhere), + any content providers it implements and what kind of data they handle, + where the implementation classes are, and other application-wide + information. Syntax details for this file are described in <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml File</a>.</td> + </tr> + <tr> + <td valign="top"> src/<br /> + /<em>myPackagePath</em>/.../<em>MyClass</em>.java</td> + <td valign="top">(<em>required</em>) This folder holds all the source code files for your + application, inside the appropriate package subfolders. </td> + </tr> + <tr> + <td valign="top"> res/</td> + <td valign="top">(<em>required</em>) This folder holds all the <em>resources</em> for + your application. Resources are external data files or description files + that are compiled into your code at build time. Files in different folders + are compiled differently, so you must put the proper resource into the + proper folder. (See <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources</a> for details.)</td> + </tr> + <tr> + <td valign="top"> anim/<br /> + <em>animation1</em>.xml<br /> + <em>...</em></td> + <td valign="top">(<em>optional</em>) Holds any animation XML description files that the + application uses. The format of these files is described in <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources</a>. </td> + </tr> + <tr> + <td valign="top"> drawable/<br /> + <em>some_picture</em>.png<br /> + <em>some_stretchable</em>.9.png<br /> + <em>some_background</em>.xml<br /> + ...</td> + <td valign="top">(<em>optional</em>) Zero or more files that will be compiled to {@link + android.graphics.drawable android.graphics.drawable} resources. Files + can be image files (png, gif, or other) or XML files describing other + graphics such as bitmaps, stretchable bitmaps, or gradients. Supported + bitmap file formats are PNG (preferred), JPG, and GIF (discouraged), + as well as the custom 9-patch stretchable bitmap format. These formats + are described in <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources</a>. </td> + </tr> + <tr> + <td valign="top"> layout/<br /> + <em>screen_1_layout</em>.xml<br /> + ...<br /></td> + <td valign="top">(<em>optional</em>) Holds all the XML files describing screens or parts + of screens. Although you could create a screen in Java, defining them + in XML files is typically easier. A layout file is similar in concept + to an HTML file that describes the screen layout and components. See <a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> for more information about designing screens, and <a href="{@docRoot}guide/topics/resources/available-resources.html#layoutresources">Available Resource Types</a> for the syntax of these files.</td> + </tr> + <tr> + <td valign="top"> values/<br /> + arrays<br /> + classes.xml<br /> + colors.xml<br /> + dimens.xml<br /> + strings.xml<br /> + styles.xml<br /> + values.xml<br /></td> + <td valign="top"><p>(<em>optional</em>) XML files describing additional resources + such as strings, colors, and styles. The naming, quantity, and number + of these files are not enforced--any XML file is compiled, but these + are the standard names given to these files. However, the syntax + of these files is prescribed by Android, and described in <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources</a>. </p> + </td> + </tr> + <tr> + <td valign="top"> xml/</td> + <td valign="top">(<em>optional</em>) XML files that can be read at run time on the device. </td> + </tr> + <tr> + <td valign="top"> raw/</td> + <td valign="top">(<em>optional</em>) Any files to be copied directly to the device. </td> + </tr> +</table> + + +<a name="logging" ></a> +<h2>Print Messages to a Log File</h2> + +<p>To write log messages from your application:</p> +<ol><li>Import <code>android.util.Log</code>.</li> + <li>Use <code>Log.v()</code>, <code>Log.d()</code>, <code>Log.i()</code>, + <code>Log.w()</code>, or <code>Log.e()</code> to log messages. + (See the {@link android.util.Log} class.)<br/> E.g., + <code>Log.e(this.toString(), "error: " + err.toString())</code></li> + <li>Launch <a href="{@docRoot}guide/developing/tools/ddms.html">DDMS</a> from a terminal + by executing <code>ddms</code> in your Android SDK <code>/tools</code> path.</li> + <li>Run your application in the Android emulator.</li> + <li>From the DDMS application, select the emulator + (e.g., "emulator-5554") and click <b>Device > Run logcat...</b> + to view all the log data.</li> +</ol> +<p class="note"><strong>Note:</strong> If you are running Eclipse and +encounter a warning about the VM debug port when opening DDMS, you can ignore it +if you're only interested in logs. However, if you want to further inspect and +control your processes from DDMS, then you should close Eclipse before launching DDMS so that +it may use the VM debugging port.</p> + + |