1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
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>
|