Вы находитесь на странице: 1из 384

32.973.2-018.

1
004.43
66

., ., .

66 Android . .: , 2015. 384 .: . ( ).


ISBN 978-5-496-01517-2
, Java,
C#, C++, C, -, JavaScript, XML, Visual Basic, Visual C++, Perl, Python
.
, , , ,
Android Google Play. ,
16 Android. , Google Play
.
Android 4.3 4.4, Eclipse Android Studio.

12+ ( 29 2010 . 436-.)



32.973.2-018.1
004.43

Prentice Hall, Inc. Upper Sadle River, New Jersey 07458.


. .
, , , . , ,

, .

ISBN 978-0133570922 .
ISBN 978-5-496-01517-2

Prentice Hall
, 2015
, , 2015

........................................................................................... 16
...................................................................................... 17
...................................................................................................................... 17
............................................................................................................. 18
..................................................................................... 19
............................................................................................................................... 20
...................................................................................................................................... 21
.............................................................................................. 23
........................................... 23
Java Development Kit (JDK)....................................................................... 23
.................................................................................................. 24
Android 4.3 SDK................................................................................................................... 25
Android (AVD)
Android............................................................................................................................................. 26
Android ....................................................... 28
............................................................................................ 29
1. Android.................................................................. 31
1.1. .................................................................................................................................. 32
1.2. Android .......... 32
1.3. Android.......................................................................................................... 33
1.4. Android...................................................................................... 37
1.4.1. Android 2.2 (Froyo).................................................................................................. 38
1.4.2. Android 2.3 (Gingerbread)...................................................................................... 39
1.4.3. Android 3.03.2 (Honeycomb).............................................................................. 39
1.4.4. Android Ice Cream Sandwich................................................................................. 40
1.4.5. Android 4.14.3 (Jelly Bean).................................................................................. 41
1.4.6. Android 4.4 (KitKat)................................................................................................ 42

6
1.5. Google Play........................................................................... 43
1.6. ...................................................................................................................................... 45
1.7. Android Software Development Kit (SDK)................................................................... 46
1.8. - ....................... 49
1.8.1. .......................................................................................... 50
1.8.2. ...................................................................................................... 50
1.8.3. ................................................................................ 51
1.8.4. ..................................................................................... 51
1.8.5. ............................................................................. 51
1.8.6. ................................................... 51
1.8.7. ........................................................................................................... 52
1.8.8. ............................................................................................................. 52
1.8.9. - ............................. 52
1.9. Doodlz AVD............... 53
1.9.1. Doodlz AVD Nexus 4.................... 54
1.9.2. Doodlz App AVD......................................................... 64
1.9.3. Doodlz Android.......................... 64
1.10. Android-............................................................... 66
1.11. ............................................................................................ 68
1.12. ................................................................................................................................... 70
2. Welcome.............................................................. 72
2.1. .................................................................................................................................. 73
2.2. .................................................................................... 74
2.2.1. Android Developer Tools IDE................................................................................ 74
2.2.2. TextView ImageView............................................................................................ 74
2.2.3. .............................................................................................. 74
2.2.4. ............................................................................................................... 74
2.2.5. ........................................................................................... 75
2.3. ........................................................................................................ 75
2.3.1. Android Developer Tools... 75
2.3.2. ....................................................................................... 75
2.3.3. New Android Application...................................................... 75
2.3.4. Configure Project............................................................................................. 78
2.3.5. Configure Launcher Icon............................................................................... 78
2.3.6. Create Activity.................................................................................................. 80
2.3.7. Blank Activity................................................................................................... 81

2.4. Android Developer Tools.......................................................................................... 82


2.4.1. Package Explorer............................................................................................ 82
2.4.2. .......................................................................................................... 83
2.4.3. ........................................................................................................ 84
2.4.4. .............................................................................. 84
2.4.5. ................................................................................................. 85
2.4.6. ........................................................... 85
2.5. ............................................... 87
2.5.1. .................................................................... 87
2.5.2. Id RelativeLayout TextView . ........ 88
2.5.3. TextView ...................................................................... 89
2.6. Welcome................................................................................ 96
2.7. ....................................................................... 97
2.8. .............................................................................. 99
2.9. .................................................................................................................................... 104
3. TipCalculator.................................................... 105
3.1. ................................................................................................................................ 106
3.2. Tip Calculator................................................................. 107
3.3. .................................................................................. 108
3.3.1. Activity.......................................................................................................... 108
3.3.2. .......................................................... 108
3.3.3.
LinearLayout GridLayout............................................................................................. 109
3.3.4. ....................................... 110
3.3.5. ....... 111
3.3.6. TextWatcher
EditText .................................................................................................... 111
3.3.7. OnSeekBarChangeListener
SeekBar...................................................................... 112
3.3.8. AndroidManifest.xml ............................................................................................. 112
3.4. ............................................. 112
3.4.1. GridLayout................................................................................................ 112
3.4.2. TipCalculator........................................................................ 114
3.4.3. GridLayout ........................................................................... 115
3.4.4. TextView, EditText, SeekBar
LinearLayout.................................................................................................................... 116
3.4.5. ...................................................................................... 118

8
3.5. ........................................................ 123
3.6. AndroidManifest.xml ............................................................................................. 132
3.7. .................................................................................................................................... 133
4. Twitter Searches............................................ 135
4.1. ................................................................................................................................ 136
4.2. .............................................................................................. 137
4.2.1. ......................................................... 137
4.2.2. ................................................................................. 137
4.2.3. ............................................................................ 139
4.2.4. ...................................................................................... 140
4.2.5. ................................................................................................. 141
4.2.6. .................................................................................................... 142
4.2.7. ..................................................... 143
4.3. .................................................................................. 144
4.3.1. ListView...................................................................................................................... 144
4.3.2. ListActivity................................................................................................................ 145
4.3.3. ListActivity........................................................................... 145
4.3.4. ImageButton.............................................................................................................. 145
4.3.5. SharedPreferences . ................................................................................................. 145
4.3.6. ............................................................ 146
4.3.7. AlertDialog................................................................................................................ 147
4.3.8. AndroidManifest.xml.................................................................................. 148
4.4. ............................................. 148
4.4.1. ................................................................................................... 148
4.4.2. activity_main.xml........................................................................................ 149
4.4.3. GridLayout ........................................... 150
4.4.4. ................................................. 155
4.4.5. ListView: list_item.xml . ....................................................... 157
4.5. MainActivity................................................................................... 158
4.5.1. package import................................................................................... 159
4.5.2. ListActivity...................................................................................... 160
4.5.3. MainActivity .................................................................................. 161
4.5.4. onCreate .......................................... 162
4.5.5. ,
OnClickListener ................ 164
4.5.6. addTaggedSearch........................................................................................ 167

4.5.7. ,
OnItemClickListener ListView
............................................................................................................ 168
4.5.8. ,
OnItemLongClickListener ListView ,
......................................................................................................... 170
4.5.9. shareSearch.................................................................................................. 172
4.5.10. deleteSearch.............................................................................................. 174
4.6. AndroidManifest.xml.......................................................................................................... 175
4.7. .................................................................................................................................... 176
5. FlagQuiz............................................................ 177
5.1. ................................................................................................................................ 178
5.2. Flag Quiz.......................................................................... 179
5.2.1. ......................................................... 179
5.2.2. .......................................................................................... 180
5.2.3. ......................................................................... 180
5.3. .................................................................................. 184
5.3.1. ........................................................................................................................... 184
5.3.2. ................................................................................................................ 184
5.3.3. ......................................................... 185
5.3.4. .................................................................................... 186
5.3.5. Preference................................................................................................ 186
5.3.6. assets.............................................................................................................. 186
5.3.7. ....................................................................................................... 187
5.3.8. ................................. 187
5.3.9. .............................................................................. 188
5.3.10. ......................................................................... 188
5.3.11.
............................................................................................................ 189
5.3.12. ........................................................ 189
5.3.13. Log.e............................................... 189
5.3.14.
............................................................................... 190
5.3.15. Java..................................................................................... 190
5.4. ................................. 190
5.4.1. ................................................................................................... 190
5.4.2. strings.xml ............................................. 191

10
5.4.3. arrays.xml ................................................................................................................. 192
5.4.4. colors.xml.................................................................................................................... 193
5.4.5. dimens.xml................................................................................................................. 194
5.4.6. activity_settings.xml................................................................................. 194
5.4.7. activity_main.xml
.......................................................................................................................... 195
5.4.8. fragment_quiz.xml...................................................................................... 196
5.4.9. activity_main.xml ........ 198
5.4.10.
preferences.xml.................................................................................................................... 199
5.4.11. ................................................. 201
5.5. MainActivity............................................................................................................ 203
5.5.1. package, import ...................................................... 203
5.5.2. onCreate . ................................................................ 204
5.5.3. onStart . ................................................................... 206
5.5.4. onCreateOptionsMenu........................................ 207
5.5.5. onOptionsItemSelected....................................... 208
5.5.6. ,
OnSharedPreferenceChangeListener .......................................................................... 208
5.6. QuizFragment.......................................................................................................... 210
5.6.1. package import ................................................................ 210
5.6.2. ............................................................................................................................ 211
5.6.3. onCreateView......................................................... 212
5.6.4. updateGuessRows ..................................................................................... 214
5.6.5. updateRegions............................................................................................. 215
5.6.6. resetQuiz ..................................................................................................... 215
5.6.7. loadNextFlag .............................................................................................. 217
5.6.8. getCountryName........................................................................................ 219
5.6.9. ,
OnClickListener . .............................................................................................................. 220
5.6.10. disableButtons ......................................................................................... 222
5.7. SettingsFragment.................................................................................................... 223
5.8. SettingsActivity....................................................................................................... 223
5.9. AndroidManifest.xml ......................................................................................................... 224
5.10. ................................................................................................................................. 225
6. CannonGame.................................................... 227
6.1. ................................................................................................................................ 228

11

6.2. Cannon Game.................................................................. 229


6.3. .................................................................................. 230
6.3.1. ................. 230
6.3.2. raw................................................................. 230
6.3.3. ................................ 230
6.3.4. onTouchEvent View................................ 231
6.3.5. SoundPool AudioManager..................... 231
6.3.6. , SurfaceView
SurfaceHolder................................................................................................................... 232
6.3.7. .............................................................. 232
6.3.8. Paint Canvas........................................... 233
6.4. ............ 233
7.4.1. ................................................................................................... 233
6.4.2. strings.xml . ................................................................................................... 234
6.4.3. fragment_game.xml..................................................................................... 234
6.4.4. activity_main.xml ....................................................................................... 235
6.4.5. .................................................................... 235
6.5. Line.............................................................................................................................. 236
6.6. MainActivity............................................................................................................ 236
6.7. CannonGameFragment.......................................................................................... 237
6.8. CannonView............................................................................................................. 238
6.8.1. package import................................................................. 239
6.8.2. .......................................................... 239
6.8.3. ............................................................................................................. 241
6.8.4. onSizeChanged View.............................. 243
6.8.5. newGame...................................................................................................... 244
6.8.6. updatePositions.......................................................................................... 245
6.8.7. fireCannonball CannonView..................................................... 249
6.8.8. alignCannon................................................................................................. 249
6.8.9. drawGameElements................................................................................... 250
6.8.10. showGameOverDialog........................................................................... 252
6.8.11. stopGame releaseResources............................................................ 254
6.8.12. SurfaceHolder.Callback.............................................. 254
6.8.13. onTouchEvent...................................................... 255
6.8.14. CannonThread:
........................................................................................................................... 256
6.9. .................................................................................................................................... 258

12
7. Doodlz................................................................ 259
7.1. ................................................................................................................................ 260
7.2. .................................................................................. 261
7.2.1. SensorManager
.......................................................... 262
7.2.2. DialogFragment.......................................... 262
7.2.3. Canvas Bitmap . ........................................ 263
7.2.4.
Path................................................................................................................... 263
7.2.5. Android 4.4......................................................................... 263
7.2.6. GestureDetector SimpleOnGestureListener ............................................... 264
7.2.7. .................................................... 264
7.2.8. Android 4.4 PrintHelper
Android Support Library............................................................................................. 264
7.3. ............ 264
7.3.1. ................................................................................................... 265
7.3.2. strings.xml...................................................................................................... 265
7.3.3. dimens.xml..................................................................................................... 266
7.3.4. DoodleFragment ........................................................................................ 267
7.3.5. activity_main.xml MainActivity . ................................................. 268
7.3.6. fragment_doodle.xml DoodleFragment . ................ 269
7.3.7. fragment_color.xml ColorDialogFragment........... 269
7.3.8. fragment_line_width.xml
LineWidthDialogFragment . ........................................................................................... 272
7.3.9. EraseImageDialogFragment .......................................... 273
7.4. MainActivity............................................................................................................ 274
7.5. DoodleFragment...................................................................................................... 275
7.6. DoodleView.............................................................................................................. 282
7.7. ColorDialogFragment............................................................................................ 295
7.8. LineWidthDialogFragment.................................................................................. 299
7.9. EraseImageDialogFragment................................................................................. 302
7.10. ................................................................................................................................. 304
8. Address Book..................................................... 306
8.1. ................................................................................................................................ 307
8.2. Address Book................................................................... 309
8.3. .................................................................................. 311
8.3.1. FragmentTransaction..... 311

13

8.3.2.
........................................................................................................................ 311
8.3.3. onSaveInstanceState................................................................................. 312
8.3.4. GUI......................... 312
8.3.5. TextView........................................... 312
8.3.6. ListFragment ,
ListView..................................................................................................... 312
8.3.7. SQLite........................................................................... 313
8.3.8. GUI
AsyncTask......................................................................................... 313
8.4. .......... 313
8.4.1. ................................................................................................... 313
8.4.2. .......................................................................... 314
8.4.3. strings.xml...................................................................................................... 315
8.4.4. styles.xml........................................................................................................ 316
8.4.5. textview_border.xml .................................................................................. 317
8.4.6. MainActivity: activity_main.xml . ........................................... 317
8.4.7. DetailsFragment: fragment_details.xml ................................. 318
8.4.8. AddEditFragment: fragment_add_edit.xml . ..................................... 320
8.4.9. ........................................................................ 321
8.5. MainActivity............................................................................................................ 323
8.6. ContactListFragment............................................................................................. 329
8.7. AddEditFragment................................................................................................... 336
8.8. DetailsFragment...................................................................................................... 342
8.9. DatabaseConnector............................................................. 350
8.10. ................................................................................................................................. 356
9. Google Play ............... 358
9.1. ................................................................................................................................ 359
9.2. ..................................................................... 359
9.2.1. .................................................................................. 360
9.2.2. .................................................................................. 360
9.2.3. ........................................................................................................ 360
9.2.4. ........................................................................... 361
9.2.5.
................................................................................................ 362
9.2.6. .................................................................................................... 362
9.2.7. ............................... 362

14
9.2.8. ........................................................................................................ 363
9.2.9. ......................................................................... 364
9.3. : ?........................................................... 365
9.3.1. ........................................................................................... 366
9.3.2. ..................................................................................... 367
9.4. ............................. 368
9.5. ............................................................. 369
9.6. Google Play.............................................................................................. 371
9.7. Google Wallet.................................................................... 371
9.8. Google Play.......................................................................... 372
9.9. Play Store ................................................................................. 374
9.10. Google Play.............................................................. 375
9.11. Android................................................................... 375
9.12. ............................... 376
9.13. ................................................................................................. 377
9.14. ................................................................................................................................. 382

. ,
MIT, Bose Corporation.
,
,
.
, ,
, .



Android Android Software Development Kit (SDK),
Java, Android
Development Tools Eclipse,
Android Studio.
.
, , Android,
. ,
.
, .
.
www.deitel.com/books/AndroidFP2/. .
Android Android- . Android
2008 . ,
Strategy Analytics, 2013 Android
81,3% , Apple iPhone 13,4%,
Microsoft 4,1%, BlackBerry 1%1.
IDC, 2013 Android 56,5%
, 39,6% Apple iPad 3,7%
Microsoft Windows2.

Android3, 1,5 4.
IDC, Samsung

http://blogs.strategyanalytics.com/WSS/post/2013/10/31/Android-Captures-Record-81Percent-Share-of-Global-Smartphone-Shipments-in-Q3-2013.aspx

http://www.idc.com/getdoc.jsp?containerId=prUS24093213

http://www.android.com/kitkat

http://www.technobuffalo.com/2013/04/16/google-daily-android-activations-1-5-million

17

Android; III 2013 40%


.
Google Play Android Google . ,
Android, .

.
Android
Android.


Android-, ,
Deitel & Associates, Inc. , , Creative Commons Attribution 3.0 Unported
License (http://creativecommons.org/licenses/by/3.0/) ,
-
, .
, .

, .
.
- , deitel@deitel.com.


, Java - , XML.
Android- XML.
XML-, .
, , Java, - C#/.NET, Objective-C/Cocoa C++ ( ), ,
Java - .
Java,
Android-.
Java, :

18
Java for Programmers, 2/e (www.deitel.com/books/javafp2)
Java Fundamentals: Parts I and II LiveLessons videos (www.deitel.com/books/

LiveLessons)
Java How to Program, 10/e (www.deitel.com/books/jhtp10)

XML, :
http://www.ibm.com/developerworks/xml/newto
http://www.w3schools.com/xml/xml_whatis.asp
http://www.deitel.com/articles/xml_tutorials/20060401/XMLBasics
http://www.deitel.com/articles/xml_tutorials/20060401/XMLStructuringData


, . 28
, ,
, .
,
; ,
, Android API, .
Android SDK 4.3 4.4. , Android SDK (Software Development Kit) 4.3 4.4.
. 5
.
, ,
. ,
;
8.
.
Android (, ..)
.
ADT (Android Development Tools) Eclipse
. (IDE)
Android Development Tools (ADT), Eclipse ADT,
JDK (Java Development Kit)
, Android, (, Google Play) ..

19

Android Studio. Android. Android Studio ,



http://www.deitel.com/books/AndroidFP2
, .
, , .
, deitel@deitel.com.
.
,
. ,
, Back,
Home Recent Apps .
. Android 4.4 KitKat
: Wi-Fi , , ..
Android, .
Android.
Android (. ),
,
. 1 Android, .
.
Android, , , ,
.
Google Play. 9 Google
Play . , Google Play, ,

. ,
. 9 1.


, , .
deitel@deitel.com.

www.deitel.com/books/AndroidFP2

20
Facebook, Twitter, Google+, LinkedIn Deitel Buzz Online.
www.deitel.com, :
;
-

;
;
Deitel Buzz Online,

, www.deitel.com/newsletter/subscribe.html;
Dive Into Series,

(Barbara Deitel)
Android,
.

Pearson.
18- . (MarkL.
Taub), Pearson Technology Group.
. (Kim Boedigheimer)
Android
, Android. ,
(Chuti Prasertsith) (Sandra Schroeder)
. (John Fuller)
Deitel Developer Series.
(Tracy Johnson), .
. (Carole Snyder)
.
(Bob Engelhardt) .
, Deitel & Associates,
Inc., Android- Imerj,
, iPhone for Programmers: An App-Driven Approach.
.

21

Android for Programmers: An App-Driven Approach


Android How to Program
.
: (Paul Beusterien), Mobile
Developer Solutions); . (Eric J. Bowden),
Safe Driving Systems, LLC; (Tony Cantrell) (- ); . (Ian G. Clifton),
Android;
(Daniel Galpin), Android Intro to Android Application
Development; (Jim Hathaway), Kellogg;
(Douglas Jones), -, Fullpower
Technologies; (Charles Lasky), ;
- (Enrique Lopez-Manas),
Android , ;
(Sebastian Nykopp), , Reaktor; , Android, Mobiata; (Ronan Zero
Schwarz), , OpenIntents;
(Arijit Sengupta), Wright State;
(Donald Smith), ; (Jesus Ubaldo),
, , ; (Dawn Wick), ; (Frank Xu), .
, !
Android. , , !



. (Paul J. Deitel),
Deitel & Associates, Inc., (MIT)
(Information Technology). Java Certified Programmer, Java Certified Developer Oracle
Java Champion. Deitel& Associates, Inc.
, Cisco, IBM, Siemens, Sun Microsystems,
Dell, Fidelity, NASA ( ),
, -, Rogue Wave
Software, Boeing, SunGard Higher Education, Stratus, Cambridge Technology Partners,
One Wave, Hyperion Software, Adra Systems, Entergy, CableData Systems, Nortel
Networks, Puma, iRobot, Invensys . , -

22
. ,
, , .
. (Dr. Harvey M. Deitel),
Deitel & Associates, Inc., 50-
. .
1960- , IBM, Advanced Computer Techniques Computer Usage Corporation,
1970- .

. 1991
. Deitel & Associates, Inc.

LiveLessons.
, , , , , , , , , , ,
. , , .
(Abbey Deitel), Deitel & Associates, Inc.,
Tepper -
.
Deitel & Associates, Inc. 16 .
Deitel & Associates
Android for Programmers: An App-Driven
Approach, 2/e, iPhone for Programmers: An App-Driven Approach, Internet &
World Wide Web How to Program, 5/e, Visual Basic 2012 How to Program, 6/e
Simply Visual Basic 2010, 5/e.


, . Android
. ,
http://www.deitel.com/books/AndroidFP2/
, .

Android Windows,
Linux Mac OS X.

http://developer.android.com/sdk/requirements.html
( SYSTEM REQUIREMENTS). , , :
Java SE 7 Software Development Kit;
Android SDK/ADT Bundle Eclipse;
Android SDK, 4.3 4.4.

, , .

Java Development Kit (JDK)


Android- Java Development Kit ( JDK)
7 (JDK 7) 6 (JDK 6). JDK 7. JDK
Windows, OS X Linux,
http://www.oracle.com/technetwork/java/javase/downloads/index.html

24
JDK. 32- 64-
.
64-
. 32-
, 32- JDK.
http://docs.oracle.com/javase/7/docs/webnotes/install/index.html


Google Android.
Android SDK/ADT Eclipse -

Android Software Development Kit (SDK)


Android Development Tools (ADT).
Android SDK 4.4 ADT 22.3.
Android Studio Android IntelliJ

IDEA; , .
Android SDK/ADT Android
. Android Studio, 2013, .
Android SDK/ADT.
Android SDK/ADT
Android SDK/ADT,
http://developer.android.com/sdk/index.html
Download the SDK ADT Bundle. , ZIP- .
eclipse Eclipse sdk Android SDK.
JDK, 32- 64- . 32-
Android SDK/ADT 32-
JDK, 64- 64- 64-bit JDK.
Android Studio
, ,
Android SDK/ADT.
Android Studio. Android Studio,
http://developer.android.com/sdk/installing/studio.html
Download Android Studio. , . [:

25

Android 4.4 Android Studio


Java SE7, <>, catch, String switch try .]
Java

Android Java SE 7.
, Eclipse ,
Java SE 6. .
1. Eclipse (

) eclipse ,
Android SDK/ADT.
2. Workspace Launcher, OK.
3. WindowPreferences, Preferences. Mac
OS X ADTPreferences
4. Java Compiler. JDK Compliance (Compiler compliance level) 1.6 ( ,
Eclipse ,
Java SE 6).
5. GeneralEditors TextEditors. ,
Show line numbers . OK.
6. Eclipse.

Android 4.3 SDK


Android SDK 4.3 4.4. 4.4 Android
SDK/ADT Android Studio. Android 4.3 ( , ).
Android,
( 1 2, Eclipse ).
1. Eclipse.

.
2. Workspace Launcher, OK.
3. Mac OS X Could not find SDK folder /Users/
YourAccount/android-sdk-macosx/, Open Preferences, Browse sdk , Android SDK/ADT.
4. WindowAndroid SDK Manager; Android SDK
Manager (. 0.1).

26

. 0.1. Android SDK Manager

5. Name , (, API Google ,


Maps), .
Installed. Packages Tools, Android 4.4 (API19),
Android 4.3 (API18) Extras, , ,
Install # packages (# ),
Choose Packages to Install. Extras .
Android Support Library Google Play.
Google USB Driver Windows,
Android.
6. Choose Packages to Install
. , Accept License
Install. Android SDK Manager.

Android (AVD)
Android
Android, Android SDK, Android ,
Android. , Android, ,
, .
(developer.android.com/tools/devices/emulator.html#acceleration).

Android (AVD) Android27

, Android
Virtual Device (AVD). ,
: (),
, , SD, , .
Android,
AVD .
AVF Android ( Nexus 4, Nexus 7
Nexus 10) Android.
AVD, .
1. Eclipse.
2. WindowAndroid Virtual Device Manager.
Android Virtual Device Manager Device Definitions (. 0.2).

. 0.2. Android Virtual Device Manager

3. Google ,
AVD. Nexus 4 by Google Create AVD,
Create new Android Virtual Device (AVD) (. 0.3).
, , OK,
AVD. Hardware keyboard present,
, AVD,
.
, Emulated Front
Camera Back Camera. AVD
, config.ini. ,
;

http://developer.android.com/tools/devices/managing-avds.html

28

. 0.3. AVD Nexus 4 Android 4.3

4. AVD Android 4.3, Nexus 7 Nexus 10, .


.0.4. AVD
Android 4.4 Nexus 4, Nexus 7 Nexus 10, : AVD_for_Nexus_4_KitKat, AVD_for_Nexus_7_KitKat AVD_for_Nexus_10_KitKat.

Android
, AVD .
Android, . ,
. ,
Android,
http://developer.android.com/tools/device.html

Android (AVD) Android29

. 0.4. AVD Nexus 7 Nexus 10

Microsoft Windows,
Windows USB Android.
USB-, .
USB-, ,

http://developer.android.com/tools/extras/oem-usb.html


, ,
http://www.deitel.com/books/AndroidFP2/
-, www.deitel.
com Register. .
, .

30

.
deitel.com ,
.
deitel.com,
. ,
, Deitel Buzz Online
www.deitel.com/newsletter/subscribe.html
www.deitel.com , Login
. http://
www.deitel.com/books/AndroidFP2/. Examples,
Zip- . , . ,
.
Android
Google Android. ,
. Eclipse Android Studio
, , - . , deitel@deitel.com
:
Facebook facebook.com/DeitelFan
Google+ google.com/+DeitelFan

.
, , Android-
. !

Android


Android Android SDK
Google Play Store
Android,
Android

,
Android, Android SDK, Java SDK, Eclipse Android Studio
Android
Android Eclipse
Android

32 1 Android

1.1.
Android! ,
Android . . 2- ,
.
Java.
, , Java,
- (C#/,
Objective-C/Cocoa C++ ),
, Java -
Java
Android.
Android,
. .
Eclipse ( ), Java Android
SDK (Software Development Kit), .
,
Eclipse.
.
- . ,
, .
, , - www.
deitel.com/books/AndroidFP2/.
, Eclipse, Android Studio.
Android Studio ,
Android Studio .
.

1.2. Android

Android
Android.
Android 2008.

2013 Strategy Analytics , Android

1.3. Android33

81,3% 13,4% Apple, 4,1%


Microsoft 1% Blackberry.1
IDC, 2013 Android -

56,5% 39,6%
Apple iPad 3,7% Microsoft Windows.2
2013 1,5

Android ( , ..).3
-

Android-.4
Android , ,

, , , NASA, ,
, , , , ,
( , GPS, , ..) .5

1.3. Android
Android . Android
. Android ,
.
Android. (http://source.android.com/source/report-bugs.html)
Open Source Project (http://source.android.com/
community/index.html). Android
, Google
(. 1.1). . 1.2 ,
Android, ,
, .
http://blogs.strategyanalytics.com/WSS/post/2013/10/31/Android-Captures-Record-81Percent-Share-of-Global-Smartphone-Shipments-in-Q3-2013.aspx

http://www.idc.com/getdoc.jsp?containerId=prUS24093213

http://www.technobuffalo.com/2013/04/16/google-daily-android-activations-1-5-million

http://venturebeat.com/2013/09/03/android-hits-1b-activations-and-will-be-called-kitkatin-next-version

http://www.businessweek.com/articles/2013-05-29/behind-the-internet-of-things-is-androidand-its-everywhere

34 1 Android
1.1. Android
URL

http://en.wikipedia.org/wiki/List_of_
open_source_Android_applications

, (,
.)

http://developer.android.com/tools/
samples/index.html

Google
Android; 60
(, , -)

http://github.com/

GitHub
,

http://sourceforge.net

SourceForge
,

http://f-droid.org/

Android, Adblock Plus,


aMetro,
AnySoftKeyboard ( ),
Apollo, , DroidWeight, Earth Live
Wallpaper

http://blog.interstellr.com/
post/39321551640/14-great-androidapps-that-are-also-open-source

14 Android, ,

http://www.openintents.org/en/
libraries

100 ,

http://www.androidviews.net

http://www.stackoverflow.com

Stack Overflow .
,

1.2. Android

URL

Android

http://source.android.com/source/downloading.html

Governance Philosophy

http://source.android.com/about/philosophy.html

http://source.android.com/source/licenses.html

FAQ

http://source.android.com/source/faqs.html

1.3. Android35

.
iOS Apple, Apple, Android
(OEM, Original
Equipment Manufacturer) .
, .
Java
Android Java
. Java Android, ,
, .
Java Android-,
Google Android API (Application Programming Interface)
.
Java -,
, .

,
, .
,
Eclipse Android Studio, , ,
, .
, Android.

Android
, -, MP3-, , . .
, ,
, - .. ,
( Android
).


, . 1.3.

Android ,
,

36 1 Android
1.3. , Android

,
Google Maps -.

,
,

(, ).



(
)

. (Phone), (People), (EMail),


(Browser), (Camera) .
-
- (web services) , , (
) .
- (mashups), -, ,
. , 100 Destinations
(www.100destinations.co.uk)
Google Maps,
.
Programmableweb (http://www.programmableweb.com/)
9400 API 7000 ,
. .1.4 -.
Programmableweb, API
Google Maps, Twitter YouTube. 4 -
Twitter.

1.4. Android37

1.4. - (www.programmableweb.com/apis/
directory/1?sort=mashups)
-

Google Maps

Twitter

YouTube

Facebook

Instagram

Foursquare

LinkedIn

Groupon

Netflix

eBay

Wikipedia

PayPal

Last.fm

Amazon eCommerce

Salesforce.com

Skype

Microsoft Bing

Bing

Flickr

Zillow

Yahoo Search

Yahoo!

WeatherBug

1.4. Android
Android Android, Inc.,
2005 Google. 2007
Open Handset Alliance,
84 (http://www.openhandsetalliance.com/oha_members.html).
, Android, ,
Android .
Android
Android ,
- (. 1.5).

38 1 Android
1.5. Android
Android

Android 1.5

Cupcake

Android 1.6

Donut

Android 2.02.1

clair

Android 2.2

Froyo

Android 2.3

Gingerbread

Android 3.03.2

Honeycomb

Android 4.0

Ice Cream Sandwich

Android 4.14.3

Jelly Bean

Android 4.4

KitKat

1.4.1. Android 2.2 (Froyo)


Android 2.2, Froyo ( ),
2010 . ,
( Android). C2DM (Android Cloud to Device Messaging,
)
,
() ,
, .
.

,
. Android C2DM

, Android,
. , 1. C2DM
Google Cloud Messaging.
Android 2.2
OpenGL ES 2.0, ..
http://developer.android.com/about/versions/android-2.2-highlights.html

http://code.google.com/android/c2dm/

1.4. Android39

1.4.2. Android 2.3 (Gingerbread)


Android 2.3 Gingerbread ( ),
2010 ,
, , .
(, , ),
( API ) (
, ).
Android 2.3 NFC
(Near-Field Communication)
, , .
NFC . NFC (,
Android NFS ),
(, ..), ..
Android 2.3
http://developer.android.com/about/versions/android-2.3-highlights.html

1.4.3. Android 3.03.2 (Honeycomb)


Android 3.0 Honeycomb ( )
,
( ):
, ,
.
Android 3.0:
, ,

;
, -

;
-

, ,
;
Holo,

;
;

40 1 Android
-

;
Bluetooth (, -

, ..);

.
Android 3.0 ,
http://developer.android.com/about/versions/android-3.0-highlights.html

1.4.4. Android Ice Cream Sandwich


Android 4.0 Ice Cream Sandwich ( ),
2011, Android 2.3 (Gingerbread) Android 3.0 (Honeycomb)
,
Android. Android , Honeycomb (
, ..), .
, . Ice Cream Sandwich
API ,
(,
), .. (.1.6). API
Android4.0
http://developer.android.com/about/versions/android-4.0.html
1.6. Android Ice Cream Sandwich
(http://developer.android.com/about/versions/android-4.0.html)

Face detection ( )


,
.
,
,

Virtual camera operator


( )

Android Beam

Android Beam
(, , ) Android

1.4. Android41

Wi-Fi Direct

Wi
-
Fi

P
2
P
(
Peer
-
to
-
Peer
)
API
Android Wi-Fi.

,
Bluetooth

Social API


( )

Calendar API

,
, , ..

Accessibility API


API
(
..).
Explore
-
by
-
touch

Android@Home framework (
Android@Home)

Android,

: , ,
..

Bluetooth Health Devices

,
Bluetooth: , ..

1.4.5. Android 4.14.3 (Jelly Bean)


Android Jelly Bean ( ), 2012 ,
, , (,
)
(.1.7). Jelly Bean

http://developer.android.com/about/versions/jelly-bean.html
1.7. Android Jelly Bean
(http://developer.android.com/about/versions/jelly-bean.html)

Android Beam


Android

Beam


Bluetooth

42 1 Android
1.7 ()

, ,
,

Photo Sphere

API
, ,
Google Maps Street View

Daydreams

, -.
Daydreams
,

,
(
, , ..)

, ,

1.4.6. Android 4.4 (KitKat)


Android 4.4 KitKat, 2013 , , Android, ,
.1
KitKat
Android . ,
,
.
Android KitKat ,
, .. .1.8
KitKat.
http://developer.android.com/about/versions/kitkat.html

http://techcrunch.com/2013/10/31/android-4-4-kitkat-google/

1.5. Google Play43

1.8. Android KitKat


(http://developer.android.com/about/versions/kitkat.html)


(Immersive mode)


,
.
,
, ( Back, Home
Recent Apps)

,
Wi-Fi ,

,
, (, )

SMS

SMS (Short Message Service) MMS


(Multimedia Messaging Service)


SMS API.

Captioning Manager API


(,
..)

Chromium WebView

-,
HTML5, CSS3 JavaScript

, , , ,

Host Card Emulator (HCE)

HCE

NFC
(, )
SIM-

1.5. Google Play


Google Play
, .1 Play Store, .
en.wikipedia.org/wiki/Google_Play

44 1 Android
Google Play : http://play.google.com ,
Android, .
WiFi 3G/4G. 9
, (
), ..
1.9. Android- Google Play

Kindle, Wikipedia, Audible for Android, Google Play Books

Office Suite Pro 7, Job Search, Square Register, GoToMeeting

ComicRack, Memedroid Pro, Marvel Comics, Comic Strips

Facebook Messenger, Skype, GrooVe IP

Duolingo: Learn Languages Free, TED, Mobile Observatory

SketchBook Mobile, Netflix, Fandango Movies, iFunny :)

Mint.com Personal Finance, Google Wallet, PayPal

MinecraftPocket Edition, Fruit Ninja, Angry Birds

Wheres My Water?, Draw Something, Can You Escape

Solitaire, Slots Delux, UNO & Friends, DH Texas Poker

Candy Crush Saga, Hardest Game Ever 2, Game Dev Story

RunKeeper, Calorie Counter, Workout Trainer, WebMD

Zillow Real Estate, Epicurious Recipe App, Family Locator

PicsArt, GO Launcher EX, Beautiful Widgets Pro

MX Player, YouTube, KeepSafe Vault, RealPlayer

Epocrates, ICE: In Case of Emergency, Medscape

Pandora, Shazam, Spotify, Ultimate Guitar Tabs & Chords

Flipboard, Pulse News, CNN, Engadget, Drippler

Beautiful Widgets Pro, Zedge, GO Launcher EX

Camera ZOOM FX, Photo Grid, InstaPicFrame for Instagram

Adobe Reader, Dropbox, Google Keep, SwiftKey Keyboard

eBay, Amazon Mobile, Groupon, The Coupons App

Facebook, Instagram, Vine, Twitter, Snapchat, Pinterest

SportsCenter for Android, NFL13, Team Stream

Titanium Backup PRO, Google Translate, Tiny Flashlight

Uber, Trapster, Lyft, Hailo, Ulysse Speedometer

Waze, GasBuddy, KAYAK, TripAdvisor, OpenTable

WeatherBug, AccuWeather, The Weather Channel

Zillow, DailyHoroscope, Starbucks, Family Locator

1.6. 45

1.6.
Android ,
.
Android, Java Google.
Android,
. Android-,
Android
(http://developer.android.com/design/index.html). . 1.10 ,
. Android
- developer.android.com/reference/packages.html.
1.10. Android Java, , ,

android.app


Android ( Tip Calculator 3)

android.content

( Cannon Game 6)

android.content.res

, (, , ,
), ,
( Flag Quiz 5)

android.database

,
( Address Book 8)

android.database.sqlite

SQLite
( Address Book 8)

android.graphics

,
( Flag Quiz 5 Doodlz
7)

android.hardware

(
Doodlz 7)

android.media

,
( Cannon Game 6)

android.net

c ( Twitter Searches
4)

android.os

( Tip Calculator
3)

android.preference


( Flag Quiz 5)

android.provider

Android ( Doodlz
7)

46 1 Android
1.10 ()

android.support.v4.print


Android

Support

Library
Android 4.4 ( Doodlz 7)

android.text

( Tip Calculator 3)

android.util

XML ( Cannon Game 6)

android.widget

, ( Tip Calculator 3)

android.view

,

( Favorite Twitter Searches 4)

java.io

,
( Flag Quiz 5)

java.text

( Twitter
Searches 4)

java.util

( Twitter Searches
4)

android.graphics.drawable

, (, ) ( Flag Quiz
5)

1.7. Android Software Development Kit (SDK)


Android SDK , Android. - Android Developers
( ).
,
Android-, Java SE, Android SDK/ADT
( Eclipse) Android Studio IDE.
Android SDK/ADT
Android SDK/ADT ( Eclipse) Android-.
Android-
. Eclipse :
;
( );
;

1.7. Android Software Development Kit (SDK)47

;
.

Eclipse 1.9 Doodlz. 2, Welcome,


Eclipse .
Android Studio
Android Studio, Android JetBrains IntelliJ IDEA (http://www.jetbrains.com/idea/),
2013. Google Android . Android Studio
.
Eclipse, Android Studio:
http://www.deitel.com/books/AndroidFP2
Android Studio,
Eclipse,
http://developer.android.com/sdk/installing/studio.html
Android Development Tools (ADT) Eclipse
ADT (Android Development Tools, Android, Android SDK/ADT) Eclipse Eclipse.
, Android,
(, Google Play)
. ADT
. ADT
2.
Android
Android, Android SDK,
Android Windows, Mac OS X
Linux.
Android. ,
Android . , Google Play
Android-.
AVD (Android Virtual
Device, Android). Android, :
, , ,
.

48 1 Android
Android, AVD
(, testdroid.com
appthwack.com), .
,
Android.
Android (. 1.11) (. 1.12), . , ,
Android. ,
GPS- , , GPS.
( /
), (
) ,
. Sensor Simulator,
AVD
:
https://code.google.com/p/openintents/wiki/SensorSimulator
1.11. Android

( Tip Calculator 3)

( Cannon Game
6)

,
( Cannon Game 6)

, , , ( Address Book 8)

Ctrl. , . , , ,

1.12. Android
(
http://developer.android.com/tools/help/emulator.html)
Android

Back ()

Esc

F3

Ctrl-KEYPAD_5, Ctrl-F3

1.8. - 49
Android

F4

Home ()

Home button

( )

F2 or Page Up button

F7

F5

* ( )

Shift-F2 or Page Down button

KEYPAD_7, Ctrl-F11

KEYPAD_9, Ctrl-F12

F8

KEYPAD_PLUS, Ctrl-F5

KEYPAD_MINUS, Ctrl-F6

.1.13 Android, . , Android


. AVD
Android- Welcome 2.
1.13. Android,
(http://developer.android.com/tools/devices/emulator.html)
Android,

( )
Bluetooth
USB



/ SD-
(, , , , )

1.8. -

Android - , .
.

50 1 Android
, , . ( , 3, ,
)
. , ,
, , .
(, , ) (,
, ). ,
- .
- .

1.8.1.
,
. , , . ,
? , -
.
, . ,
. ,
, , ,
. ,
, .
,
, , . ,
. , ,
( !), , .

1.8.2.

- .
,
, .
, , .

1.8. - 51

, , , .
, , , ,
, ,
.
, ,
.

1.8.3.
, ,
,
. .
.

1.8.4.
,
. .
,

, . , ,
.

1.8.5.
,
( ).
.
, . , deposit
, .

1.8.6.

, , ,
, . ,
(

52 1 Android
).
. . , ,
,
.
, , , . . , bankaccount
, .
bankaccount ,
.
.

1.8.7.
(
).
, ,
.
.

1.8.8.
.
,
. , .
, , .

1.8.9. -
, ? , , ,
.
, ,
, , , ?
1000 ,
?
.

1.9. Doodlz AVD53

, ( , )
, (
, ).

( ).

- , , - ().
, Java, -.
, - (), -
.

1.9. Doodlz
AVD
Android. Doodlz
,
. 7.
, Eclipse
(AVD) Nexus 4 (c AVD ,
). ,
Android. AVD,
; .
Android SDK/ADT Android Studio
, ,
, Windows 7, Java SE 7 SDK Android SDK/
ADT (. ). Android Studio
,
Android Studio :
www.deitel.com/books/AndroidFP2
, Google. Android SDK/ADT Android Studio
Android, AVD,
.

54 1 Android

1.9.1. Doodlz AVD


Nexus 4
Doodlz, .
1. . ,
, ,
.
2. Eclipse. eclipse ,
Android SDK/ADT, Eclipse (
).
3. .
Workspace Launcher, , , OK. workspace
. (workspace)
, , .
,
, Eclipse.

,
Android-, Java- -,
. Eclipse
, Welcome!, . 1.1.

. 1.1. Welcome! Eclipse

4. Nexus 4 AVD. Nexus 4, Android 4.4 (KitKat)


; 1.9.2 ,
AVD . AVD ,

1.9. Doodlz AVD55

. Nexus 4 AVD,
WindowAndroid Virtual Device Manager;
Android Virtual Device Manager (. 1.2). Nexus 4 AVD Android
KitKat Start, Launch
Launch Options. AVD.
AVD (.1.3), AVD,
.

. 1.2. Android Virtual Device Manager

. 1.3. Nexus 4 AVD ( Android 4.4) AVD

56 1 Android
5. Doodlz. FileImport,
Import (. 1.4, ). General, Existing Projects into Workspace Next>,
Import Projects (. 1.4, ). Browse Select root

. 1.4. :
Import; Import Projects

1.9. Doodlz AVD57


directory. Browse For Folder Doodlz, , Open. Finish,
Eclipse. Package Explorer
Eclipse (. 1.5). Package Explorer ,
WindowShow ViewPackage Explorer.

. 1.5. Package Explorer

6. Doodlz. Eclipse
Doodlz Package Explorer Run AsAndroid
Application (. 1.6). Doodlz
, 4 (. 1.7).
7. AVD . AVD ,
. ( AVD)

. 1.6. Doodlz

58 1 Android

. 1.7. Doodlz Android (AVD)

Android. Back ()

, .
Home () .
Recent Apps ( )
.
(app bar),
,
(COLOR LINE WIDTH
. 1.7), ( ).
7. Android 4.4
(immersive mode), .
,
, .
,
.
8. . ,
, ( ) (
). .1.8,
Nexus 4 AVD, . 1.8,
Nexus 7 AVD

1.9. Doodlz AVD59

(). COLOR,
. LINE WIDTH
. Eraser
,
. Clear ,
, (
). Save Image . Android 4.4 Print
, PDF ( ).
.

. 1.8. Doodlz:
Nexus 4 AVD; Nexus 7 AVD

9. . ,
Color (. 1.9).
ARGB,
( 0 255) : - (), , .
- 0 , 255
. , 0
, 255 .
SeekBar,
,
. SeekBar,
. ,
Red , . 1.9.
Set Color, .

60 1 Android

. 1.9.

10. . ,
LINE WIDTH ; Choose
Line Width. SeekBar,
, (. 1.10). Set Line Width,
.

. 1.10.

11. . , ,
( ) , (.1.11).
12. -. ,
, COLOR
Choose Color. - ,
Green SeekBar , Red Blue (. 1.12, ).
13. .
, LINE WIDTH. Choose Line Width. SeekBar,
, (. 1.12, ). ,
, . 12
13 ,
(. 1.13).

1.9. Doodlz AVD61

. 1.11.

. 1.12. - :
- ;

14. . , .
(. 1.14, ) (. 1.14, ).

62 1 Android

. 1.13.

, ,
(. 1.15).
15. . Gallery. Save .
, , Gallery.
16. . , Print
. ,
PDF.
, Save as PDF
. , ,
Google Cloud Print .

http://www.google.com/cloudprint/learn/
17. . AVD,
Home ( ) AVD. Gallery,

, AVD.
Gallery .

1.9. Doodlz AVD63

. 1.14. :
;

. 1.15.

64 1 Android

1.9.2. Doodlz App AVD


AVD, AVD,
4 1.9.1, Nexus 4 AVD Nexus 7 AVD.
Doodlz Eclipse Package
Explorer Run AsAndroid Application.
AVD, Android Device Chooser
(. 1.16), AVD .
AVD Nexus 4 Nexus 7, Android .
Nexus 7 AVD OK.
( ) . AVD ( ),
( ). .1.17
Nexus 7 AVD. AVD , AVD Ctrl+F12 ( Mac
fn+control+F12).
Ctrl Control.

. 1.16. Android Device Chooser

1.9.3. Doodlz Android


Android, .
1. .
. Settings,

1.9. Doodlz AVD65

. 1.17. Nexus 7 AVD

, About Phone ( About Tablet),


Build Number ( )
, You are now a developer.
Settings Developer Options.
2. . Settings,
Developer Options , USB debugging

.
3. .
USB, .
Windows, ,
, USB .
:
developer.android.com/tools/device.html
developer.android.com/tools/extras/oem-usb.html
4. Doodlz Android. Eclipse
Package Explorer, Doodlz
Run AsAndroid Application. AVD,
Android,
.
AVD / , Android Device Chooser (. 1.16).
AVD .

66 1 Android

, Google
Play ,
. ,
.
, AVD,
, . ,
AVD.
config.ini AVD,
Setting hardware emulation options
developer.android.com/guide/developing/tools/avd.html
config.ini , Android Virtual
Device Manager.
Android .

1.10. Android-
Google Play 800000 .1
Android, , , ? , , ,
. ,
Google Play
Android.
,
? . 1.14
.
1.14.

http://www.pureoxygenmobile.com/how-many-apps-in-each-app-store/

1.10. Android-67

/

,
;



( , ..)

( , ,
, ..)
(
, , ..)

Android, Android



Android


,


(
)
, Google Play

, ,
( )
(http://developer.android.com/
guide/topics/ui/accessibility/index.html)

(, Facebook
Twitter)

68 1 Android
1.14 ()

, ( , ,
..)
(. 2) , (,
,
..)
,


Android
, , Google Play
(http://
android-developers.blogspot.com/2010/06/future-proofing-your-app.html)

1.11.
. 1.15 Android
Developer. Android-
, ,
.. Android,
(. 1.16). . 1.17 ,
, Android.
1.15. Android-

URL

http://developer.android.com/guide/components/index.html


Android

http://developer.android.com/tools/devices/emulator.html

http://developer.android.com/reference/packages.html

http://developer.android.com/reference/classes.html

http://developer.android.com/design/index.html

http://developer.android.com/guide/topics/data/backup.html

http://developer.android.com/training/articles/security-tips.
html


Eclipse ADT

http://developer.android.com/guide/developing/projects/
projects-eclipse.html

1.11. 69

URL

Android Studio

http://developer.android.com/sdk/installing/studio.html

http://developer.android.com/tools/debugging/index.html

http://developer.android.com/tools/help/index.html

http://developer.android.com/training/articles/perf-tips.html

http://developer.android.com/training/articles/perf-anr.html

( Google Play)

http://developer.android.com/distribute/googleplay/publish/
preparing.html

http://developer.android.com/distribute/googleplay/publish/
register.html

http://developer.android.com/training/articles/memory.html


Google

Play

http://play.google.com/about/developer-distributionagreement.html

1.16. Android

Android Discuss

Google
Groups:
android-discuss

:
android-discusssubscribe@googlegroups.com

Android,

Stack Overflow

http://stackoverflow.com/
questions/tagged/android


Android,
Java

Eclipse
,

Android Developers

http://groups.google.com/
forum/?fromgroups#!forum/
android-developers

, ,
..

Android Forums

http://www.androidforums.
com

,


Android

70 1 Android
1.17. Android
, ,

URL

Android-
Google

http://code.google.com/p/apps-for-android/

Android-
(OReilly)

http://answers.oreilly.com/topic/862-ten-tips-forandroid-application-development/


Bright

Hub
Android-

http://www.brighthub.com/mobile/google-android.aspx

The Android Developers Blog

http://android-developers.blogspot.com/

The Sprint Application Developers


Program

http://developer.sprint.com/site/global/develop/mobile_platforms/android/android.jsp

HTCs Developer Center for Android

http://www.htcdev.com/


Android
- Motorola

http://developer.motorola.com/

Top Android Users on Stack Overflow

http://stackoverflow.com/tags/android/topusers

AndroidDev Weekly Newsletter

http://androiddevweekly.com/

Codependent ( )

http://graphics-geek.blogspot.com/

http://cyrilmottier.com/

http://www.curious-creature.org/category/android/

Android-
YouTube

http://www.youtube.com/user/androiddevelopers

Android

http://developer.android.com/develop/index.html


Android-

http://www.youtube.com/watch?v=lmv1dTnhLH4

Google I/O
2013 Developer Conference

http://developers.google.com/events/io/sessions

1.12.
Android
. , ,

1.12. 71

.
Android Market
Google Play , .
Java, Android Google,
Android; .
Java Android SDK, Android,
Android .
, ,
, . Doodlz
Android. 2
Android-, .
.
Android-.

Welcome



Android-
( Eclipse ADT),
,
Android-


( )

Android


,
Android TalkBack Explore-by-Touch
,

2.1. 73

2.1.
Welcome.
,
. ADT ,
Android. ,
, ,
. Android- (.2.1)
,
. , Android (
Android, ). , ,

, . http://www.deitel.com/
books/AndroidFP2
Android Studio. , , 1.9.

. 2.1. Welcome Android

74 2 Welcome

2.2.
, .

2.2.1. Android Developer Tools IDE


Android Developer
Tools (ADT). (. 2.3).
, Hello
world!.

(. 2.5).

2.2.2. TextView ImageView


TextView, ImageView. ,
, TextView,
, , ..
(. 2.5.3).
ImageView (. 2.5.4).

2.2.3.
,
res . 2.5.3
, (,
TextView) (, ). Android
TextView.

2.2.4.
Android , . ,
TalkBack ,
( , )
. Android
Explore by Touch , TalkBack
. 2.7 ,

.

2.3. 75

2.2.5.
Android .
, ,
.
2.8 , Welcome
TextView ImageView
AVD, .

2.3.
Android Developer Tools
(22.x) Android SDK (4.3 4.4), . , Java SE Development Kit
(JDK) Android Developer Tools,
1.9. ,
IDE, IDE .

2.3.1.
Android Developer Tools
IDE, eclipse Android SDK/
ADT Eclipse icon (

,
).
Welcome (. .2.1).
, HelpAndroid IDE.

2.3.2.
(,
), .
. New Android Application Welcome, New Android Application (. 2.2).
: FileNewAndroid Application Project
New (
)
Android Application Project.

2.3.3. New Android Application


New Android Application
(. 2.2), Next>:

76 2 Welcome
1. Application Name: . Welcome.

. 2.2. New Android Application

2. Project Name: ,
Package Explorer IDE. IDE
,
, , Address Book AddressBook. ,
Project Name:.
3. Package Name: Java . Android Google Play
, .
, . , deitel.com, com.
deitel. .
.
IDE , com.example, ,
.

2.3. 77

4. Minimum Required SDK: Android API,


.
API . 18, Android 4.3 , .
. 2.1 Android SDK
API. SDK .
Android, ,
http://developer.android.com/about/dashboards/index.html
2.1. Android SDK API
(http://developer.android.com/about/dashboards/index.html)
SDK

API

4.4

19

4.3

18

4.2.x

17

4.1.x

16

4.0.3-4.0.4

15

4.0.1

14

3.2

13

2.3.3-2.3.7

10

2.2

2.1

1.6

5. Target SDK: API. 19 (Android 4.4). 26%


Android 10.

. , Android 2.3.3
(98% Android), Minimum Required
SDK 10. API,
TargetSDK, ,
API Minimum Required SDK API
.
Android Lint, IDE ,
.
6. Compile With: API, .
Target SDK,
API, .

78 2 Welcome
7. Theme: , Android.
Holo Light, Holo Dark Holo Light with Dark Action Bars
( IDE ).
Holo Light Holo Dark.
, .
:
http://developer.android.com/design/style/themes.html

2.3.4. Configure Project


New Android Application Configure Project (. 2.3) Next>.
(Activity) ,
.

. 2.3. New Android Application ( 2)

2.3.5. Configure Launcher Icon


, ,

2.3. 79


. Android .
,
, . Android ,
( )
(DPI, dots per inch). 3.

http://developer.android.com/training/multiscreen/index.html

http://developer.android.com/design/style/iconography.html
Configure Launcher Icon (. 2.4) , .
, 4848, 7272, 9696 144144
.
DeitelOrange.png. , Browse
Image File:, images ,

. 2.4. New Android Application ( 3)

80 2 Welcome
DeitelOrange.png Open.
Preview .
. . ,
Google Play,
. 9
Google Play ,
( ).
Next>, .

2.3.6. Create Activity


Create Activity (. 2.5) (Activity) . , .
. 2.2 , . 2.5.
Blank Activity Next>.
.

. 2.5. New Android Application ( 4)

2.3. 81

2.2. Activity

Blank Activity

,
.
, ,

Fullscreen Activity

(
Blank Activity), ,

Master/Detail Flow

( Email People).

.
,

2.3.7. Blank Activity


(. 2.6) .
Blank Activity :
Activity Name ( IDE MainActivity).

Activity, .
3
.

Layout Name ( IDE


activity_main.xml).

XML. ( 2.5)
.
Navigation Type ( IDE None).

Welcome . , ,
.
.

Finish, .

82 2 Welcome

. 2.6. New Android Application ( 5)

2.4. Android Developer Tools


IDE MainActivity.java activity_main.
xml. MainActivity.java, IDE ,
.2.7. IDE
. ,
Welcome. IDE .

2.4.1. Package Explorer


Package Explorer . . 2.8
Welcome Package Explorer. Welcome . IDE
. .
res, 2.4.4;
, .

2.4. Android Developer Tools83

. 2.7. Welcome Android Developer Tools

2.4.2.
Package Explorer .2.7
(Graphical Layout). Package Explorer,
(
). Java Java.
XML, (, activity_main.
xml), .

84 2 Welcome

. 2.8. Project Explorer

2.4.3.
Outline IDE (. 2.7).
.
, . Java
, .

2.4.4.
, activity_main.xml ( res/layout), res .
. . 2.3 , Welcome; (menu, animator, anim, color, raw xml)
, .
2.3. ,

drawable

,
drawable
, .
XML
, (, ,
)

layout

,
layout
,
XML
, activity_main.xml

2.4. Android Developer Tools85

values

, values,
(
arrays
.
xml
), (
colors
.
xml
), (
dimen
.
xml
; , , ), (
strings
.
xml
) (
styles
.
xml
). ,
.
,
Java. ,
, ,
Java

2.4.5.
IDE activity_main.xml
(. 2.9).
activity_main.xml res/layout .

Android .
Android. ,
(AVD), Google Nexus4.
, .
Nexus 4,
.2.9. ,
Nexus4,
, Nexus 4.
, , .

2.4.6.
(. 2.9) Blank Page
RelativeLayout - ( , ) TextView "Hello world!".
RelativeLayout , RelativeLayout
, ,
. TextView

86 2 Welcome
. 2.5.

. 2.9.

2.5. 87

2.5.

Welcome.
(Graphical Layout)
GUI,
Button, TextView, ImageView . ,
Blank App XML- activity_main.xml res/layout.
Outline .
Android ,
.

2.5.1.
Deitel
(bug.png) Android (android.png). images/
Welcome . ( , )
.
Android , (DPI, Dot Per Inch),
,
. res
, drawable.
(. 2.4).
2.4. Android

drawable-ldpi

120

drawable-mdpi

160

drawable-hdpi

240

drawable-xhdpi

320

drawable-xxhdpi

480

drawable-xxxhdpi

640

, Google Nexus4,
AVD, drawable-hdpi. (, ) drawable-xhdpi drawable-xxhdpi.

88 2 Welcome

Android drawable-mdpi drawable-ldpi .
.
Android drawable, ( ,
).
2.1
.
,
, .

2.2
Android
http://developer.android.com/guide/practices/screens_
support.html.

, .
1. Package Explorer res .
2. Welcome images .
res/drawable-hdpi. ,
File Operation Copy Files,
OK. PNG, JPG
GIF .
.

2.5.2. Id RelativeLayout
TextView
,
(Properties) Outline
XML.
,
Outline (. 2.10).

. 2.10.

2.5. 89

,
(
).
Id.
, XML. , Id
RelativeLayout.
RelativeLayout,
Id
@+id/welcomeRelativeLayout

+ @+id (
), /.
TextView Id
@+id/welcomeTextView

, . 2.11.

. 2.11. Id RelativeLayout
TextView

2.5.3. TextView
Welcome TextView, .

90 2 Welcome
Text TextView
Android (http://developer.android.
com/guide/topics/resources/index.html), ,
, , , ,
res , Java- .
. , , ,
.
,
,
. res values,
strings.xml. .
, values
( 2.8).
Text TextView,
strings.xml.
1. , TextView.
2. Text, , . ,
, Resource Chooser.
3. Resource Chooser New String, Create New Android String, . 2.12.
4. String New R.string (. . 2.12), Replace in
all XML file for different configurations, OK,
Resource Chooser. String ,
TextView, R.string , Text TextView.
5. welcome . OK,
.
Text , .2.13.
@string ,
strings.xml ( res/values ), welcome
.
Text Size TextView ,

GUI Android (. 2.5). ,
, -
developer.android.com/guide/practices/screens_support.html

2.5. 91

GUI
, ,
, .

. 2.12. Create New Android String

. 2.13. Text TextView


2.5.

px

dp dip

sp

in

mm

92 2 Welcome
, (dp dip),
Android .
, ,
160 dpi ( ). 240 dpi , ,
240/160 ( 1,5). , , 100 , ,
150 .
120
120/160 ( 0,75). , 100
75 . , , , ,
, ,
.
TextView
TextView, .
:
1. , welcomeTextView.
2. Text Size .
, Resource Chooser.
3. Resource Chooser New Dimension
4. Name welcome_textsize,
Value 40sp. OK,
Resource Chooser. sp 40sp ,
, . dp (, 10dp) , .
welcome_textsize . OK,
.
TextView
TextView.
Text Color @android:color/holo_blue_dark. Android

.
@android:color/ Text Color,
(. 2.14). @android:color/holo_blue_dark,
-.

, , TextView,
Gravity center. Value
, ,

2.5. 93

Select Flag Values Gravity (. 2.15).


center, OK, .

. 2.14. Text Color TextView


@android:color/holo_blue_dark

. 2.15. Gravity

, . 2.16.
ImageView

ImageView , ,
2.5.1. ImageView

94 2 Welcome
Images&Media .
.
1. Images & Media Ima
geView (. 2.17). ImageView
welcomeTextView.
, . , , ,
. . 2.17 , ImageView
(
, ) welcomeTextView (
).

. 2.16.
TextView

. 2.17.
ImageView

2. Resource Chooser
(. 2.18), . , drawable, IDE
( ),
.

2.5. 95

, android.png
android. android
OK, .
,
.

. 2.18. android Resource Chooser

3. IDE Id ImageView @+id/


imageView1. @+id/droidImageView. Update References?
. Yes. Rename Resource
. OK, .
4. 13 bugImageView. ImageView droidImageView,
Resource Chooser
Id @+id/bugImageView . .
,
. 2.19.

96 2 Welcome

. 2.19.

2.6. Welcome
AVD , 1.9.1. . 2.20
Nexus 4 AVD, .
(
). AVD
( ),
. , ,
, .
1.9.3,
Android. AVD

2.7. 97

. 2.20. Welcome AVD

, .
, , ,
, ; , .

2.7.
Android ,
. Android TalkBack ( ,

), . Explore by Touch, , .
TalkBack, ,
, . Android

98 2 Welcome
. , TalkBack
,
TextView, TalkBack . TalkBack
Settings ( Accessibility).
Android ,
(,
). , TalkBack AVD, , TalkBack
, . TalkBack Android
TalkBack Explore by Touch.
TalkBack ImageView
Welcome TextView,
TalkBack TextView. ImageView
, ,
. Android TalkBack
Content Description , .
IDE ,
( ) ImageView. ( Android Lint) ,
Content Description .
.
ImageView .
Content Description ImageView
( Android Lint), .
1. droidImageView .
2. Content
Description, Resource Chooser.
3. New String, Create New Android String.
4. String "Android logo", R.string android_logo.
OK.
5. android_logo Resource
Chooser. OK, Content
Description droidImageView.
6. bugImageView,
Create New Android String String "Deitel double-thumbs-up bug
logo", R.string "deitel_logo". .
Content Description ImageView
( ) ImageView.

2.8. 99

TalkBack
TalkBack. TextView ImageView
.

.
.
Android Android ,
:
http://developer.android.com/design/patterns/accessibility.html
http://developer.android.com/guide/topics/ui/accessibility/index.html
http://developer.android.com/guide/topics/ui/accessibility/checklist.html

2.8.
, Android . , ,
. ,
, (, ..) .

, .
. , Android ,
.


( ) , ,
XML .
, . Android
, .

XML- , ,
res . Android

, values-fr strings.xml

100 2 Welcome
, values-es strings.xml .
, valuesen-rUS values-en-rGB strings.xml ,
, .
, Android
( values res).

.

Welcome strings.
xml, ,
values-es. :
1. Package Explorer res
NewFolder, New Folder.
2. Folder name: values-es. Finish.
, ,
values-XX.
strings.xml values-es
strings.xml values values-es.
:
1. Package Explorer values res,
strings.xml Copy.
2. values-es Paste,
strings.xml.

TextView,
, ImageView ,
.
strings.xml. strings.xml.
, , .
, Google Play Developer Console (
Google Play) ,
.
Google Play Developer Console
9
developer.android.com/distribute/googleplay/publish/index.html

2.8. 101


"Welcome to Android App Development!"
"Android logo"
"Deitel double-thumbs-up bug logo"

"Bienvenido al Desarrollo de App Android!"
"Logo de Android"
"El logo de Deitel que tiene el insecto con dedos pulgares hacia arriba"

:
1. Package Explorer strings.xml valueses, Android. welcome (. 2.21).

. 2.21. Android welcome

2. Value "Welcome to Android App Development!"


"Bienvenido al Desarrollo de App Android!".
,
res/values-es/strings.xml
Welcome ( WelcomeInternationalized ).
Value, ,
Paste.
3. android_logo Value "Logo de Android".
4. , deitel_logo Value "El logo
de Deitel que tiene el insecto con dedos pulgares hacia arriba".

102 2 Welcome
5. app_name, action_settings hello_world,
Remove.
. strings.xml
.
app_name. , .
6. strings.xml FileSave
.


, Android ( ).
1. Home (
2. (
( ).

) .
), Settings

3. Settings PERSONAL,
Language & input.
4. Language ( )
Espaol (Espaa).

Language & input, .


Welcome IDE; . . 2.22 ,
. Android
AVD ( ), , AVD (
) , welcome,
android_logo deitel_logo, res/values-es/strings.xml
. ,

. ,
app_name res/values-es/strings.xml. , :
Android , res/values/strings.xml.
2.1
.
Android
. , ,
, .

2.8. 103

. 2.22. Welcome
AVD Nexus 4

AVD ( )
AVD ( ) :
1. Home (

) .

2. ( ), Settings
( ) Ajustes.
3. Idioma y entrada de texto, .
4. Idioma English (United States).
TalkBack
TalkBack , ,
, .
Welcome TalkBack,
TalkBack .
TalkBack,
Android . TalkBack

104 2 Welcome
, , . .


Android Localization Checklist :
developer.android.com/distribute/googleplay/publish/localizing.html

2.9.
Android Developer Tools IDE
Welcome app, - .

.
TextView,
ImageView. TextView , ,
. ImageView
. ,
res .
, . ,
TalkBack , . Android
Explore by Touch , TalkBack
.
ImageView ,
TalkBack Explore by Touch.
, Android
, .
Welcome TextView
ImageView,
AVD, .
Android Java.
Tip Calculator ;

, Java .

TipCalculator

GridLayout, LinearLayout, EditText, SeekBar, , NumberFormat


Java


LinearLayout GridLayout
Outline
GUI LinearLayout GridLayout
TextView, EditText SeekBar
- Java,
, , ,
,
Android

GUI

EditText SeekBar


106 3 TipCalculator

3.1.
Tip Calculator (. 3.1, ) .

( 15% ).
0% 30% ( 18%).
Seekbar,
, Seekbar (.
3.1, ). 18%,
,
. . 3.1
- Android
AVD ,
.

. 3.1. :
; 34,56
20%


. ,
.

3.2. Tip Calculator107

(GUI) (Graphical Layout editor)


Android Developer Tools Outline.
.
3.2 3.4 Android Studio http://
www.deitel.com/books/AndroidFP2.

3.2. Tip Calculator



Android Developer Tools
Tip Calculator. .
1. AVD Nexus 4, . Nexus 4
AVD, WindowAndroid Virtual Device Manager;
Android Virtual Device Manager. Nexus 4 AVD
Start, Launch Launch Options.
2. FileImport, Import.
3. Tip Calculator. Import
General, Existing Projects into Workspace
Next> Import Projects. Select root directory
Browse. Browse For Folder TipCalculator
( ), OK. ,
Copy projects into workspace . Finish, . Package Explorer.
4. Tip Calculator.
TipCalculator Package Explorer,
Run AsAndroid Application.

34,56. 3456
.
, (
), .
TextView (15%
18% )
. TextView
.

Seekbar .
Seekbar 20% (. 3.1, ). .

108 3 TipCalculator
Seekbar 0
100, 30.

3.3.
Java Android,
Tip Calculator. ,
- Java. ,
:
Android ;
Android;
;
Android Activity,

Tip Calculator;

3.3.1. Activity
Java, Android main.
(activities), (services),
(broadcast receivers). , Activity ( android.app).
(views), GUI.
Android 3.0 . 5,
(fragments).
, .
,
.

3.3.2.

( ),
. :

3.3. 109

.
,

(, ).
,, -

, . , .
Android
(
Activity):
http://developer.android.com/reference/android/app/Activity.html

onCreate. Android
,
. : onStart, onPause, onRestart, onResume, onStop
onDestroy. .
; .
,
Activity , ,
.

3.3.3.
LinearLayout GridLayout
(layouts)
. LinearLayout ( android.widget)
( ), , .
TextView ,
.
GridLayout ( android.widget) Android 4.0

. ,
. GridLayout
TableLayout,
;
TableRow,
TableRow. GridLayout API
14 . Android Support Library

110 3 TipCalculator
GridLayout
, Android. , ,
http://developer.android.com/tools/support-library/index.html
GridLayout ,

. TextView
LinearLayout.
TextView GridLayout , .

http://developer.android.com/reference/android/widget/package-summary.html

3.3.4.
TextView, EditText SeekBar
IDE (. 2) Outline,
IDE Outline
.
XML-, res .
EditText ( )
TextView (. 2);
, . EditText ,
.
SeekBar ( 0100).
,
. SeekBar , 0 30.
, (. 3.2).
. , TextView
View,
TextView , TextView,
View , View.

3.3. 111

. 3.2. TextView

3.3.5.

NumberFormat ( java.text)

. , 2.72.8,
.

3.3.6. TextWatcher
EditText
TextWatcher ( android.text),
EditText . ,
onTextChanged , ,
.

112 3 TipCalculator

3.3.7. OnSeekBarChangeListener
SeekBar
SeekBar.OnSeekBarChangeListener ( android.
widget), SeekBar. ,
onProgressChanged ,
SeekBar.

3.3.8. AndroidManifest.xml
AndroidManifest.xml . ,
New Android Application: , ,
SDK, , .. (Android Manifest editor) ,
,
. ,
( ).

3.4.

Tip
Calculator.
, .3.1.
, , IDE.

3.4.1. GridLayout
GridLayout (. 3.3) GUI . GridLayout
, , , .
, .
GridLayout .

.
.

3.4. 113

. 3.3. GridLayout Tip Calculator

. , . GridLayout

. GridLayout

http://developer.android.com/reference/android/widget/GridLayout.html
Id
.3.4 Id .
Id
Java.

. 3.4. Tip Calculator


Id


amountDisplayTextView amountEditText,
. ,
, .

114 3 TipCalculator
.
100,
amountDisplayTextView.
3456 amountDisplayTextView
$0.03, $0.34, $3.45 $34.56.
Id LinearLayout
.3.5 Id
LinearLayout GridLayout.

. 3.5. LinearLayout Id

3.4.2. TipCalculator
Android Developer Tools
,
, TipCalculator, 3.2.
Delete. , Delete project contents on
disk , OK. ,
,
.

Android. New Android
Project , Next>:
Application Name: Tip Calculator
Project Name: TipCalculator
Package Name: com.deitel.tipcalculator

3.4. 115

Minimum Required SDK: API18: Android 4.3


Target SDK: API19: Android 4.4
Compile With: API19: Android 4.4
Theme: Holo Light with Dark Action Bar
Create Activity: TipCalculator
Build Target: , Android 4.3

New Android Project Next>. Configure Launcher Icon Browse,


DeitelGreen.png ( images ) Open,
Next>. Create Activity Blank Activity (
) Next>. Blank Activity
, Finish .
Nexus 4 (. . 2.9)
.

3.4.3. GridLayout
Blank App RelativeLayout. GridLayout.
TextView Outline
Delete, . RelativeLayout Outline Change
Layout. Change Layout GridLayout OK.
GridLayout1. gridLayout Id .
Orientation GridLayout horizontal; ,
( ).
GridLayout

, . 3.3 . , gridLayout Outline, Column Count 2 ( GridLayout ).


GridLayout (,
). Use Default Margins GridLayout true, . GridLayout
(8dp),
http://developer.android.com/design/style/metrics-grids.html

116 3 TipCalculator

3.4.4. TextView, EditText, SeekBar


LinearLayout
.3.3. . 3.4.5 .
Id .3.43.5.
Id , ,
(
Outline), Edit ID Id
Rename Resource.
Outline GridLayout.
,
. Outline ,
.
. ,
Outline.
1:
amountTextView amountEditText amountDisplayTextView .
, gridLayout Outline,
,
Row Column. , amountEditText amountDisplayTextView
.
TextView
.
TextView Large, Medium Small ( Form Widgets)
. Text
Appearance TextView .
, , TextView EditText.
1. Medium TextView Form Widgets gridLayout Outline.
TextView textView1 gridLayout.
"Medium Text".
Id TextView amountTextView.
6 ( 3.4.5).
2. ,
100 . Text Fields

3.4. 117

EditText (, , , , ).
EditText, ,
EditText. EditText , .
Text Fields Number EditText ( 42)
gridLayout Outline. Id EditText
amountEditText. EditText
GridLayout.
3. Medium TextView gridLayout Outline
Id amountDisplayTextView.
TextView GridLayout.
GridLayout ,
Row Column TextView ( Layout Parameters
) 0 1 .
2:
GridLayout TextView SeekBar. :
1. Medium TextView (customPercentTextView) Form
Widgets gridLayout Outline.
2. SeekBar (customTipSeekBar) Form Widgets
gridLayout Outline.
3:
GridLayout LinearLayout TextView.
1. Linear Layout (Horizontal) (percentLinearLayout)
gridLayout Outline.
2. Medium TextView (percent15TextView) percentLinear
Layout Outline. TextView
LinearLayout.
3. Medium TextView (percentCustomTextView)
percentLinearLayout Outline.
4. percentLinearLayout TextView GridLayout.
, percentLinearLayout Outline
Column 1.
4:
GridLayout TextView LinearLayout,
TextView:

118 3 TipCalculator
1. Medium TextView (tipTextView) gridLayout
Outline.
2. Linear Layout (Horizontal) (tipLinearLayout) gridLayout.
3. Medium TextView (tip15TextView tipCustomTextView)
tipLinearLayout.
5:
, 4, Id: totalTextView, totalLinearLayout, total15TextView
totalCustomTextView.

Outline .3.6.
Outline 3.4.5.

. 3.6. Outline
GridLayout: a ; Outline
Tip Calculator

3.4.5.
, ,
. 2.5,
strings.xml.
, (, ,
..), dimens.xml.

3.4. 119

6:
amountTextView, customPercentTextView,
percent15TextView, percentCustomTextView, tipTextView totalTextView:
1. amountTextView Outline.
2. Text.
3. Resource Chooser New String.
4. Create New Android String Amount String
amount New R.string, OK.
5. Resource Chooser OK, Text amountTextView amount.
TextView, . 3.1.
3.1.

String

New R.String

customPercentTextView

Custom %

custom_tip_percentage

percent15TextView

15%

fifteen_percent

percentCustomTextView

18%

eighteen_percent

tipTextView

Tip

tip

totalTextView

Total

total

7: TextView
. 3.3 TextView .
amountTextView, customPercentTextView, tipTextView totalTextView
Gravity ( Layout Parameters )
right.
8: Label For amountTextView
, EditText TextView
, EditText ( ) Android Lint
. , Id
EditText Label For TextView.
amountTextView Label For ( View ) @+id/amountEditText.
+ , TextView
EditText, EditText
XML- .

120 3 TipCalculator
9: amountEditText
amountEditText amountDisplayTextView
, .
amountEditText .
1. Layout Parameters Width Height
wrap_content. , EditText
, .
2. Gravity (fill_horizontal),
. fill_horizontal .
3. Ems, EditText ,
M ( ) .
GridLayout ,
.
4. TextView Digits 0123456789
,
, , . ,
Digits ,
. ,
Show Advanced Properties ( ) .
5. ,
, , 9999,99. TextView
Max Length 6.
10: amountDisplayTextView
amountDisplayTextView,
.
1. Layout Parameters Width Height
wrap_content. , TextView
.
2. Text .
3. Layout Parameters Gravity fill_
horizontal. , TextView
GridLayout.
4. View Background @android:color/holo_blue_
bright. ( @android:color) Android Holo.
Background,
. ,
, RGB.

3.4. 121

0255.
( 16),
RGB 00FF. Android
- ( ) 0 (
) 255 ( ). -, #AARRGGBB,
(AA) -.
, #RGB #ARGB. , #9AC #99AACC,
#F9AC #FF99AACC.
5. TextView.
textview_padding,
GUI. Padding . View
Padding. New
Dimension, . Name
textview_padding, Value 8dp, OK.
OK.
11: customPercentTextView
: customPercentTextView
customTipSeekBar. ,
. Layout Parameters
Gravity right right|center_vertical.
(|) Gravity
, TextView , . Width
Height customPercentTextView wrap_content.
12: customTipSeekBar
, SeekBar
0 100, Progress.
0 30, 18.
Max SeekBar 30, Progress
18. Width Height wrap_content.
13: percent15TextView percentCustomTextView
, GridLayout
. percent15TextView percentCustomTextView LinearLayout, . Weight
( , LinearLayout) (
) . ,
Weight.

122 3 TipCalculator
Weight, 1, percent15TextView
percentCustomTextView , ,
, . ,
percentLinearLayout GridLayout Gravity
fill_horizontal,
. LinearLayout ,
TextView LinearLayout.
, TextView
. Gravity ( TextView )
center. TextView,
Gravity .
14: tip15TextView, tipCustomTextView,
total15TextView totalCustomTextView
TextView
.
1. TextView.
2. Text .
3. Background @android:color/holo_orange_light.
4. Gravity center.
5. Weight 1.
6. Width 0dp
Weight .
7. Gravity TextView center.
8. Padding TextView @dimen/textview_padding
(, ).
TextView tipLinearLayout totalLinearLayout. ,
8dp tip15TextView total15TextView. Layout Parameters Margin Right
8dp; textview_margin. Right total15TextView.
15: tipTextView
totalTextView
tipTextView
totalTextView , Gravity right right|center_vertical.

3.5. 123

totalTextView, GridLayout
. Space ( Layout
) gridLayout Outline. , . , Space
.
, .3.7.

. 3.7.

3.5.
MainActivity ( 3.13.8)
Tip Calculator. 15% ,

. ,
src/com.deitel/tipcalculator MainActivity.java.
3.13.8.
package import
3.1 package import MainActivity.java.
package 3 . Java , import
. ,
import.
3.1. package import MainActivity
1
2
3
4
5
6
7
8
9
10

// MainActivity.java
// 15% .
package com.deitel.tipcalculator;
import java.text.NumberFormat; //
import
import
import
import

android.app.Activity; //
android.os.Bundle; //
android.text.Editable; // EditText
android.text.TextWatcher; // EditText

124 3 TipCalculator
11
12
13
14
15

import
import
import
import

android.widget.EditText; //
android.widget.SeekBar; // %
android.widget.SeekBar.OnSeekBarChangeListener; // SeekBar
android.widget.TextView; //

514 , :
NumberFormat java.text ( 5)

(,
).

Activity android.app ( 7)

Bundle android.os ( 8) -

. Android , (,
).
, , ( ,
), (
, ).
, ,
,
.

Editable android.text ( 9) -

TextWatcher android.text ( 10) -

EditText.

android.widget ( 1114) (

) , Android.
EditText ( 11), SeekBar ( 12)
TextView ( 14).

SeekBar.OnSeekBarChangeListener android.widget (-

13) ,
SeekBar.

SourceOrganize Imports ,
import .
, import.
Tip Calculator
MainActivity ( 3.23.8) Activity
Tip Calculator. Tip Calculator

3.5. 125

Activity Activity onCreate ( 3.3). Activity


. MainActivity
onCreateOptionsMenu, , . onCreate .
3.2. MainActivity Activity
16 // MainActivity Tip Calculator
17 public class MainActivity extends Activity
18 {


2032 3.3 MainActivity. NumberFormat ( 2023)
. getCurrencyInstance
NumberFormat NumberFormat,
, . getPercentInstance

.
3.3. MainActivity
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

//
private static final NumberFormat currencyFormat =
NumberFormat.getCurrencyInstance();
private static final NumberFormat percentFormat =
NumberFormat.getPercentInstance();
private
private
private
private
private
private
private
private

double billAmount = 0.0; // ,


double customPercent = 0.18; // %
TextView amountDisplayTextView; //
TextView percentCustomTextView; // %
TextView tip15TextView; // 15%
TextView total15TextView; // 15%
TextView tipCustomTextView; //
TextView totalCustomTextView; //
//

, amountEditText,
double billAmount ( 25). ( 030),
Seekbar, 0,01; double
customPercent (26).
, SeekBar 25, customPercent 0,25,
0,25 25% .

126 3 TipCalculator
27 TextView ,
. 28
TextView , SeekBar (18% . 3.1, ). 2932
TextView,
.
onCreate Activity
onCreate (. 3.4) .
onCreate Activity
GUI. ,
. ,
, ANR (Application Not
Responding, ).
. ,
, 8.
3.4. onCreate Activity
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

//
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); //
setContentView(R.layout.activity_main); // GUI
// TextView,
// MainActivity
amountDisplayTextView =
(TextView) findViewById(R.id.amountDisplayTextView);
percentCustomTextView =
(TextView) findViewById(R.id.percentCustomTextView);
tip15TextView = (TextView) findViewById(R.id.tip15TextView);
total15TextView = (TextView) findViewById(R.id.total15TextView);
tipCustomTextView = (TextView) findViewById(R.id.tipCustomTextView);
totalCustomTextView =
(TextView) findViewById(R.id.totalCustomTextView);
// GUI billAmount customPercent
amountDisplayTextView.setText(
currencyFormat.format(billAmount));
updateStandard(); // TextView 15%-
updateCustom(); // TextView
// TextWatcher amountEditText
EditText amountEditText =
(EditText) findViewById(R.id.amountEditText);
amountEditText.addTextChangedListener(amountEditTextWatcher);
// OnSeekBarChangeListener customTipSeekBar

3.5. 127
65
66
67
68
69

SeekBar customTipSeekBar =
(SeekBar) findViewById(R.id.customTipSeekBar);
customTipSeekBar.setOnSeekBarChangeListener(customSeekBarListener);
} // onCreate

Bundle onCreate
,
.
.
onCreate Bundle
Activity ( ). , onPause
onSaveInstanceState ( ). 38 onCreate ;
onCreate.
R

(, strings.xml activity_main.
xml) R,
, res . R
gen , . ,
R.. . , R, static final int,
(
, ). , R:
drawable drawable (,

), drawable res.

id ( ),

XML-.

layout ,

(, activity_main.xml).

string ,
strings.xml.


setContentView ( 39) R.layout.activity_main,
XML- MainActivity,
main.xml. setContentView
XML, .
(inflating) .

128 3 TipCalculator

,

. findViewById Activity.
int, ,
. R.id Id,
. ,
amountEditText R.id.amountEditText.
4351 TextView, .
4344 amountDisplayTextView,
. 4546
percentCustomTextView,
. 4751 TextView,
.
TextView
5455 amountDisplayTextView billAmount (0.00),
( format
currencyFormat). 5657 updateStandard (
3.5) updateCustom ( 3.6)
TextView.

6061 amountEditText , 62 addTextChangedListener
TextChangedListener, ,
EditText. ( 3.8)
,
amountEditTextWatcher.
6566 customTipSeekBar, 67
setOnSeekBarChangeListener
OnSeekBarChangeListener, ,
customTipSeekBar . ( 3.7) ,
customSeekBarListener.
updateStandard MainActivity
updateStandard ( 3.5) TextView
15% , . billAmount
. 7879
.

3.5. 129

3.5. updateStandard 15%



70
71
72
73
74
75
76
77
78
79
80
81

// TextView 15%
private void updateStandard()
{
// 15%
double fifteenPercentTip = billAmount * 0.15;
double fifteenPercentTotal = billAmount + fifteenPercentTip;
// 15%
tip15TextView.setText(currencyFormat.format(fifteenPercentTip));
total15TextView.setText(currencyFormat.format(fifteenPercentTotal));
} // updateStandard

updateCustom MainActivity
updateCustom ( 3.6) TextView , customTipSeekBar,
. 86
percentCustomTextView customPercent,
. 8990 customTip
customTotal, 9394
.
3.6. updateCustom

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

// TextView
private void updateCustom()
{
// percentCustomTextView
customPercent %
percentCustomTextView.setText(percentFormat.format(customPercent));
//
double customTip = billAmount * customPercent;
double customTotal = billAmount + customTip;
//
tipCustomTextView.setText(currencyFormat.format(customTip));
totalCustomTextView.setText(currencyFormat.format(customTotal));
} // updateCustom

,
OnSeekBarChangeListener
98120 3.7
customSeekBarListener, customTipSeekBar.
, :
http://bit.ly/AnonymousInnerClasses

130 3 TipCalculator
67 ( 3.4) customSeekBarListener OnSeekBarChangeListener customTipSeekBar.
,
, onCreate .
3.7. ,
OnSeekBarChangeListener customSeekBar
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

// SeekBar
private OnSeekBarChangeListener customSeekBarListener =
new OnSeekBarChangeListener()
{
// customPercent, updateCustom
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser)
{
// customPercent SeekBar
customPercent =
progress / 100.0;
updateCustom(); // TextView
} // onProgressChanged
@Override
public void onStartTrackingTouch(SeekBar seekBar)
{
} // onStartTrackingTouch
@Override
public void onStopTrackingTouch(SeekBar seekBar)
{
} // onStopTrackingTouch
}; // OnSeekBarChangeListener

onProgressChanged
OnSeekBarChangeListener
102119 OnSeekBarChangeListener.
onProgressChanged SeekBar.
107 customPercent progress
int, SeekBar.
100. 108
updateCustom .
onStartTrackingTouch onStopTrackingTouch
OnSeekBarChangeListener
Java
. , (onStartTrackingTouch)
(onStopTrackingTouch),
( 111119), .

3.5. 131

, TextWatcher
123156 3.8
amountEditTextWatcher, amountEditText. 62
amountEditText,
.
3.8. ,
amountEditText
122 // , amountEditText
123 private TextWatcher amountEditTextWatcher = new TextWatcher()
124 {
125 // ,
126 @Override
127 public void onTextChanged(CharSequence s, int start,
128 int before, int count)
129 {
130 // amountEditText double
131 try
132 {
133 billAmount = Double.parseDouble(s.toString()) / 100.0;
134 } // try
135 catch (NumberFormatException e)
136 {
137 billAmount = 0.0; //
138 } // catch
139
140 // display currency formatted bill amount
141 amountDisplayTextView.setText(currencyFormat.format(billAmount));
142 updateStandard(); //
143 updateCustom(); //
144 } // onTextChanged
145
146 @Override
147 public void afterTextChanged(Editable s)
148 {
149 } // afterTextChanged
150
151 @Override
152 public void beforeTextChanged(CharSequence s, int start, int count,
153 int after)
154 {
155 } // beforeTextChanged
156 }; // amountEditTextWatcher
157 } // MainActivity

onTextChanged TextWatcher
onTextChanged ( 126144) ,
amountEditText. .
CharSequence s, amountEditText. ,

132 3 TipCalculator
, count,
start, before.
133 , amountEditText, double. ,

100 , 2495, 24,95.
142143 updateStandard updateCustom
.
amountEditTextWatcher
,
(beforeTextChanged) (afterTextChanged),
TextWatcher
( 146155), .

3.6. AndroidManifest.xml
AndroidManifest.xml, , ,
.
.
(Android Manifest editor),
AndroidManifest.xml Package Explorer.
Application (. 3.8), MainActivity Application
Nodes . MainActivity Attributes
for com.deitel.tipcalculator.MainActivity.
MainActivity
,
. .
. Tip
Calculator
,
. MainActivity , . Attributes for com.deitel.
tipcalculator.MainActivity Screen orientation
portrait.
MainActivity
Tip Calculator
.
Attributes for com.deitel.tipcalculator.MainActivity Window

3.7. 133

. 3.8. Application
soft input mode stateAlwaysVisible. ,

3.7.

Android Tip Calculator.

134 3 TipCalculator
,
.
Android Developer Tools,
Outline . MainActivity Activity,
.
GridLayout GUI .
TextView,
EditText SeekBar.
MainActivity -
Java, , , , . ,
XML . Android Activity
. , onCreate
. onCreate findViewById
Activity ,
.
, TextWatcher,
EditText.
,
OnSeekBarChangeListener,
SeekBar.
, AndroidManifest.xml , , MainActivity ,
MainActivity .
, Outline, ,
XML AndroidManifest.xml.
Twitter Searches. .
ListActivity,
ListView, ArrayList<String>.
-.

Twitter Searches

SharedPreferences, , ImageButton, ListView,


ListActivity, ArrayAdapter, AlertDialog

( )
ListActivity , ListView

ImageButton
ScrollView ,


SharedPreferences ,
, /
/
SharedPreferences.Editor
ArrayAdapter ListView
AlertDialog AlertDialog.
Builder
-

136 4 Twitter Searches

4.1.
, 500 .
(. 4.2),
, ,
. Twitter Searches
(. 4.1)
, () (.4.1,).
,
(.4.1, ). ,
, .
, .
. ,
GUI .
, , . .
, .

. 4.1. Twitter Searches:


; Deitel

4.2. 137

4.2.
Twitter Searches .
Android Developer Tools Twitter
Searches. 3, Nexus 4 AVD (
Android ) . , , Nexus 4.

4.2.1.
.
1. Import FileImport
2. Twitter Searches. General
Existing Projects into Workspace, Next > Import Projects. Select root directory,
Browse. TwitterSearches, ,
OK. , Copy projects into
workspace . Finish .
Package Explorer.
3. Twitter Searches.
TwitterSearches Package Explorer Run AsAndroid
Application AVD.
(.4.2).

4.2.2.
EditText from:deitel
from: .
.4.1 ;
.
http://bit.ly/TwitterSearchOperators.
4.1. T

deitel iOS6

, deitel iOS6

deitel OR iOS6

,
deitel iOS6 ( )

how to program

, (how to program)

138 4 Twitter Searches


4.1 ()

deitel ?


deitel
,

deitel -sue

, deitel,
sue

deitel :)

:) , deitel

deitel :(

:( , deitel

since:2013-10-01

,
( --)

near:New York City

from:deitel

@deitel

to:deitel

, @deitel

. 4.2. Twitter Searches

EditText Deitel (. 4.3, ).


.
,

4.2. 139

, Deitel Tagged
Searches (. 4.3, ). ,
, , ,
4.5.5.

. 4.3. : ( );

4.2.3.
, Deitel. , URL-,
. URL , ( ), -.
(. 4.4). ,
Back (
), Twitter Searches,
, ,
.

140 4 Twitter Searches

. 4.4.

4.2.4.
, .
, (
). AVD, , .
Deitel AlertDialog (. 4.5, ) Share,
Edit Delete Deitel.
, Cancel.
Deitel, Edit .
EditText .
, 1 2013 ,
since:2013-10-01 (. 4.5, ) EditText. since: ,

4.2. 141

. 4.5. : Edit
;
Deitel

( --). , ,
(. 4.6), Deitel Tagged Searches .
[:

.]

4.2.5.
Android
, (SMS),
Facebook, Google+ ..
Share AlertDialog. (. 4.7,),
,

142 4 Twitter Searches

. 4.6. Deitel

. , ( AVD!)
, : Facebook, Gmail, Google+, Messaging
( ) Twitter.
, .
,
. . 4.7,
Compose Gmail .
Gmail To (
).

4.2.6.
,
AlertDialog Delete.
(. 4.8) Cancel
, Delete .

4.2. 143

. 4.7. : a
; Compose Gmail

. 4.8. AlertDialog

4.2.7.
. 4.9 10 ,
.
, .
ListView (. 4.3.1). , ( AVD) Tagged Searches.
,
.

144 4 Twitter Searches

. 4.9. ,

4.3.
, .

4.3.1. ListView
. , ; ;
.. ,
, , ..
ListView ( android.widget)
, , .
ListView;
TextView. , ListView
, .

4.3. 145

4.3.2. ListActivity
, ListActivity ( android.app).
, ListView
. ListView AdapterView ( android.widget)
GUI, Adapter (
android.widget). ArrayAdapter ( android.widget)
, ListView
ArrayList. (data
binding). AdapterView,
Adapter. 8 ListView . Android

http://developer.android.com/guide/topics/ui/binding.html

4.3.3. ListActivity
ListActivity
ListView ,
Android (. . 2.1).
ListActivity ListView, ListActivity subclass.
MainActivity Twitter Searches
, MainActivity . ListActivity
ListView, Id "@android:id/
list" , ListActivity ListView.

4.3.4. ImageButton
,
.
ImageButton ( android.widget). ImageButton ImageView ,
Button ( android.widget) .

4.3.5. SharedPreferences
,
/ ( ). searches,

146 4 Twitter Searches


() (),
.
SharedPreferences.Editor ( android.content).
(String), .
onCreate

. , Android
, , UI-;
.
GUI . /
(, ) UI-,
. , /
.

4.3.6.
(
) Android (intents). , ,
.
AndroidManifest.xml. , , ,

; , android.intent.action.MAIN, ,
.
,
.
, , URL-, . ,
Intent URL
startActivity,
Activity. URL startActivity
.
Intent startActivity , .
, ,
.

, , (im
plicit) -,
Android

4.3. 147

. , startActivity,
, ,
. , startActivity
ActivityNotFoundException.
. ,
Android, , , -.
,
.

http://developer.android.com/guide/components/intents-filters.html

4.3.7. AlertDialog
AlertDialog ,
. ,
.
,
AlertDialog.Builder,
AlertDialog.
AlertDialog , , ,
.
AlertDialog ,
.
(

).
, .
(

OK ).
, .
, -

, . , ,
, .
AlertDialog .
, EditText -

. .

, .

148 4 Twitter Searches


( ,

Delete).
Android
http://developer.android.com/guide/topics/ui/dialogs.html

4.3.8. AndroidManifest.xml
3, AndroidManifest.xml
. ,
. AndroidManifest.xml
http://developer.android.com/guide/topics/manifest/manifest-intro.html

4.4.

Twitter Searches.
XML; ListView .

4.4.1.
, Android Developer Tools IDE ,
TwitterSearches, 4.2.
Delete. ,
Delete project contents
on disk, OK. , ,
.

C Android Application Project.
New Android Project (New Android Application)
Next>:
Application Name: Twitter Searches
Project Name: TwitterSearches

4.4. 149

Package Name: com.deitel.twittersearches


Minimum Required SDK: API18: Android 4.3
Target SDK: API19: Android 4.4
Compile With: API19: Android 4.4
Theme: Holo Light with Dark Action Bar

New Android Project (New Android Application)


Next >. Configure Launcher Icon
Browse ( images ),
Open Next >. Create Activity Blank Activity
Next >. Blank Activity
Finish, .
Nexus 4 (. . 2.9) ,
.

4.4.2. activity_main.xml
3, activity_main.xml
GridLayout (. 4.10). GridLayout
. .4.11 GUI.

. 4.10. GridLayout Twitter Searches

150 4 Twitter Searches

. 4.11. Twitter Searches


Id

4.4.3. GridLayout
. 4.104.11 ,
3. ,
. ,
GUI Outline.
,
.
GridLayout Outline. GUI,
. 4.11;
,
Java. ,
strings.xml ( res/values).
1: RelativeLayout GridLayout
3.4.3, TextView
RelativeLayout GridLayout.
2: GridLayout
Outline GridLayout
, ,
:

4.4. 151

Id: @+id/gridLayout
Column Count ( GridLayout): 1 GUI, -

GridLayout, .
GridLayout ,
Width Height ( Layout Parameters
) match_parent.
Padding Left Padding Right
@dimen/activity_horizontal_margin
dimens.xml res/values . 16dp,
GridLayout 16dp.
.
Padding Top Padding Bottom @dimen/activity_vertical_
margin 16dp. ,
GridLayout 16dp.
4.1
Android 16dp ;
(, ) .

3: GridLayout
EditText. Plain Text
Text Fields GridLayout Outline,
Id @+id/queryEditText. TextView
Ems, .
, :
Width ( Layout Parameters): wrap_content
Height ( Layout Parameters): wrap_content
Gravity ( Layout Parameters): fill_horizontal ,

queryEditText .
Gravity ,
, .
Hint: @string/queryPrompt ( -

) "Enter Twitter search query


here". EditText , .
Android TalkBack ,
EditText ,
.

152 4 Twitter Searches


4.2
Android , , , ,
, .
http://developer.android.com/
design/style/writing.html.

IME Options ( TextView): actionNext ,


EditText Next ( tagEditText).

.
EditText,

EditText, .
4: GridLayout
LinearLayout EditText Image
Button. ,
.
1. LinearLayout (Horizontal) Layouts
GridLayout Outline.
2. Plain Text Text Fields LinearLayout
Id @+id/tagEditText.
3. ImageButton Images & Media
LinearLayout. Resource Chooser (. 4.12),
.
Project Resources,
( res/drawable ).
Android
( . 4.12). , System
Resources, ic_menu_save OK. Id
@+id/saveButton.
tagEditText Ems,
. .
Width ( Layout Parameters): 0dp

, Weight,
.
Height ( Layout Parameters): wrap_content.
Gravity ( Layout Parameters): bottom|fill_horizontal
tagEditText saveButton , tagEditText
.

4.4. 153

. 4.12. Resource Chooser


Weight ( Layout Parameters): 1 tagEditText

, saveButton . Android ,
saveButton , tagEditText
.

Hint: @string/tagPrompt "Tag your


query".

IME Options ( TextView): actionDone ,


queryEditText Done,

saveButton Weight ( Layout Parameters),


.
Width ( Layout Parameters): wrap_content.
Height ( Layout Parameters): wrap_content.
Content Description: @string/saveDescription -

"Touch this button to save your tagged search".

5: GridLayout
LinearLayout TextView ListView.
, :

154 4 Twitter Searches


1. LinearLayout (Vertical) Layouts GridLayout Outline.
2. Medium Text Form Widgets
LinearLayout. TextView,
.
3. ListView Composite
LinearLayout, Id @android:id/list ,
ListView
ListActivity.
4.3
, Android ,
GUI TalkBack. ,
(, ImageButton),
Content Description .

LinearLayout :
Height ( Layout Parameters): 0dp
Gravity.

Gravity ( Layout Parameters): fill LinearLayout

Top ( Margins Layout Parameters): @dimen/activity_vertical_margin -

LinearLayout LinearLayout GUI.

Background ( View): @android:color/holo_blue_bright -

Android .

Padding Left/Right ( View): @dimen/activity_horizontal_margin ,

, LinearLayout,
16dp.

Padding Top ( View): @dimen/activity_vertical_margin , -

, LinearLayout,
16dp.

TextView
:
Width ( Layout Parameters): match_parent.
Height ( Layout Parameters): wrap_content.
Gravity ( Layout Parameters): fill_horizontal TextView

LinearLayout ( ).

4.4. 155

Gravity ( TextView): center_horizontal TextView.


Text: @string/taggedSearches "Tagged
Searches".

Padding Top ( View): @dimen/activity_vertical_margin , -

, LinearLayout,
16dp.

ListView .
Width ( Layout Parameters): match_parent.
Height ( Layout Parameters): 0dp

, Weight,
.

Weight ( Layout Parameters): 1.


Gravity ( Layout Parameters): fill ListView

Padding Top ( View): @dimen/activity_vertical_margin , -

, LinearLayout,
16dp.

Top Bottom ( Margins Layout Parameters): @dimen/tagged_searches_

padding tagged_searches_padding dimension,


Top.
Resource Chooser New Dimension, .
Name tagged_searches_padding, Value
8dp. OK,
OK. Bottom .
, TextView ListView,
ListView LinearLayout
8dp.

4.4.4.
MainActivity . (. 4.13) ,
,
. ,
,
Preview Representative Sample Preview All Screen Sizes.
+ ,
. . 4.2
.

156 4 Twitter Searches

. 4.13.

4.2.

Android
, ,
,
.

Nexus
4,
Nexus
7
Nexus
10 ( ). . 4.13 Nexus 4


Activity

Fragment
,

(. 2.8) , ,

API


API
.
API
. ,
API

4.4. 157

4.4.5. ListView: list_item.xml


ListView ,
.
( String)
. ,
, TextView
. .
1. Package Explorer res ,
layout NewOther;
New.
2. Android Android XML Layout File Next>;
, . 4.14. , .
list_item.xml, TextView.
3. Finish, .

. 4.14.

158 4 Twitter Searches


. TextView Outline .
Id: @+id/textView GUI

Height ( Layout Parameters): ?android:attr/listPreferredItemHeight

Android,
.
4.4
Android ,
, , 4848 dp.
http://developer.
android.com/design/style/metrics-grids.html.

Gravity ( Layout Parameters): center_vertical TextView

ListView.

Text Appearance ( TextView): ?android:attr/textAppearanceMedium -

, .

,
,
, ;
android:id.
Android
Android ,
Height Text Appearance .

http://developer.android.com/reference/android/R.attr.html
, ?android:attr/
.

4.5. MainActivity
4.14.10 Twitter Searches
MainActivity, ListActivity. MainActivity
onCreateOptionsMenu, , , onCreateOptionsMenu 5.
, String
, .

4.5. MainActivity159

4.5.1. package import


4.1 package import . package
( 4 ) ,
com.deitel.twittersearches. 626 , .
4.1. package import MainActivity
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

// MainActivity.java
//
//
package com.deitel.twittersearches;
import java.util.ArrayList;
import java.util.Collections;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.AlertDialog;
android.app.ListActivity;
android.content.Context;
android.content.DialogInterface;
android.content.Intent;
android.content.SharedPreferences;
android.net.Uri;
android.os.Bundle;
android.view.View;
android.view.View.OnClickListener;
android.view.inputmethod.InputMethodManager;
android.widget.AdapterView;
android.widget.AdapterView.OnItemClickListener;
android.widget.AdapterView.OnItemLongClickListener;
android.widget.ArrayAdapter;
android.widget.EditText;
android.widget.ImageButton;
android.widget.TextView;

67 ArrayList Collections java.util.


ArrayList ,
Collections , .
import , , :
AlertDialog android.app ( 9) -

ListActivity android.app ( 10)

MainActivity, ListView
.

Context android.content ( 11) -

, ,

160 4 Twitter Searches


Android.
, ,
.
DialogInterface android.content ( 12) -

OnClickListener.
, AlertDialog.

Intent android.content ( 13)

, ,
Android .
,
.

SharedPreferences android.content ( 14)

/ , .

Uri android.net ( 15) URL

, Intent, .

View android.view (17)

; GUI, .

View OnClickListener (18).

,
ImageButton .

InputMethodManager android.view.inputmethod ( 19) -

android.widget (2026) , -

Android. AdapterView (20) ListView;


ListView ( ListView).
AdapterView.OnItemClickListener ( 21)
ListView. AdapterView.OnItemLongClickListener ( 22) ListView. ArrayAdapter
(23) ListView. ImageButton
( 25) .

4.5.2. ListActivity
MainActivity ( 4.24.10) -

Twitter Searches. TwitterSearches, MainActivity Activity


onCreate,

4.5. MainActivity161

Activity. ListActivity ( 4.2, 28).


ListActivity,
import.
SourceOrganize Imports. Eclipse .
, .
, import,
, ,
.
4.2. MainActivity ListActivity
28 public class MainActivity extends ListActivity
29 {

4.5.3. MainActivity
4.3 MainActivity ( ). SEARCHES ( 31)
, . 3334
EditText, .
35 savedSearches SharedPreferences; /,
.
36 ArrayList<String>
. 37
ArrayAdapter<String>, ArrayList<String>
, ListView MainActivity.
4.1
, String ( ), ( ,
strings.xml).

4.3. MainActivity
30
31
32
33
34
35
36
37
38

// XML- SharedPreferences
private static final String SEARCHES = "searches";
private
private
private
private
private

EditText queryEditText; // EditText


EditText tagEditText; // EditText
SharedPreferences savedSearches; //
ArrayList<String> tags; //
ArrayAdapter<String> adapter; // ListView

162 4 Twitter Searches

4.5.4. onCreate
onCreate ( 4.4) :
;
-

, ;
, -

, .
Activity GUI
, . 43 onCreate . , setContentView ( 44) R.layout.
activity_main activity_main.xml.
4.4. onCreate Activity
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

// MainActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// EditText
queryEditText = (EditText) findViewById(R.id.queryEditText);
tagEditText = (EditText) findViewById(R.id.tagEditText);
// SharedPreferences
savedSearches = getSharedPreferences(SEARCHES, MODE_PRIVATE);
// ArrayList
tags = new ArrayList<String>(savedSearches.getAll().keySet());
Collections.sort(tags, String.CASE_INSENSITIVE_ORDER);
// ArrayAdapter ListView
adapter = new ArrayAdapter<String>(this, R.layout.list_item, tags);
setListAdapter(adapter);
//
ImageButton saveButton =
(ImageButton) findViewById(R.id.saveButton);
saveButton.setOnClickListener(saveButtonListener);
//
getListView().setOnItemClickListener(itemClickListener);
// ,
getListView().setOnItemLongClickListener(itemLongClickListener);
} // onCreate

4.5. MainActivity163

EditText
4748 queryEditText tagEditText
.
SharedPreferences
51 getSharedPreferences (
Context) SharedPreferences, SEARCHES ( , ).
.
; .
MODE_PRIVATE . -

MODE_WORLD_READABLE

MODE_WORLD_WRITABLE

(|).
,
onCreate.
4.1
UI, ANR (Application Not
Responding) ,
5 . , ,
http://developer.android.com/guide/practices/design/responsiveness.html.

SharedPreferences
, . 54 String, SharedPreferences, tags (ArrayList<String>).
getAll SharedPreferences
Map ( java.util) /.
keySet, Set
( java.util) .
tags.

55 Collections.sort .

, ,

164 4 Twitter Searches


Collections.sort String.
CASE_INSENSITIVE_ORDER ( Comparator<String>).
ArrayAdapter ListView
ListView, ArrayAdapter<String>
(58), tags TextView ,
ListView MainActivity.
ArrayAdapter<String> .
(this), ListView;
MainActivity.

(R.layout.list_item) , -

ListView.

List<String> ; tags

ArrayList<String>, List<String>, tags


List<String>.

59 ListActivity setListAdapter
ListView ArrayAdapter, ListView .
saveButton ListView
6263 saveButton,
64 saveButtonListener ,
OnClickListener ( 4.5). 67 ListActivity
getListView ListView ,
OnItemClickListener ListView
itemClickListener
, ( 4.8).
70 OnItemLongClickListener
ListView itemLongClickListener , ( 4.9).

4.5.5. ,
OnClickListener

4.5 saveButton
Listener, ,
OnClickListener. 64 (4.4)
saveButtonListener saveButton. 76109 onClick OnClickListener.
( 8081), 8384 addTaggedSearch

4.5. MainActivity165

(4.7) , 8586
EditText. 8890 .
4.5. ,
OnClickListener saveButton

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

// saveButtonListener "" SharedPreferences


public OnClickListener saveButtonListener = new OnClickListener()
{
@Override
public void onClick(View v)
{
// , queryEditText tagEditText
if (queryEditText.getText().length() > 0 &&
tagEditText.getText().length() > 0)
{
addTaggedSearch(queryEditText.getText().toString(),
tagEditText.getText().toString());
queryEditText.setText(""); // queryEditText
tagEditText.setText(""); // tagEditText
((InputMethodManager) getSystemService(
Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
tagEditText.getWindowToken(), 0);
}
else //
{
// AlertDialog Builder
AlertDialog.Builder builder =
new AlertDialog.Builder(MainActivity.this);
//
builder.setMessage(R.string.missingMessage);
// OK
builder.setPositiveButton(R.string.OK, null);
// AlertDialog AlertDialog.Builder
AlertDialog errorDialog = builder.create();
errorDialog.show(); //

}
} // onClick
}; // OnClickListener

AlertDialog
/ , 92108
AlertDialog . AlertDialog.Builder (9596) AlertDialog.
, ,
MainActivity, this.

166 4 Twitter Searches


this , this
. 99 ("Enter both a Twitter
search query and a tag") R.string.missingMessage.

4.5
AlertDialog (
) setTitle AlertDialog.Builder.
Android (http://developer.android.
com/design/building-blocks/dialogs.html),
.
,
, , ... ,
, ,
.

strings.xml
(, R.string.missingMessage),
strings.xml res/values. , Resources strings.xml.
Resources Add . 4.15.
String OK, Name Value, (, missingMessage)
. strings.xml .
Resources ,
.

. 4.15.

4.5. MainActivity167

AlertDialog
AlertDialog ,
.
(. 4.14, 102) , , . setPositiveButton
( R.string.OK) .
, null.
, .
AlertDialog
AlertDialog create AlertDialog.Builder (
105), show AlertDialog
( 106).

4.5.6. addTaggedSearch
4.4 addTaggedSearch
MainActivity ( 4.6) savedSearches .
4.6. addTaggedSearch MainActivity
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

//
private void addTaggedSearch(String query, String tag)
{
// SharedPreferences.Editor
SharedPreferences.Editor preferencesEditor = savedSearches.edit();
preferencesEditor.putString(tag, query); //
preferencesEditor.apply(); //

//
if (!tags.contains(tag))
{
tags.add(tag); //
Collections.sort(tags, String.CASE_INSENSITIVE_ORDER);
adapter.notifyDataSetChanged(); // ListView
}

SharedPreferences
SharedPreferences ,
edit, SharedPreferences.Editor
( 115). /,
/, ,

168 4 Twitter Searches


SharedPreferences. 116 putString
SharedPreferences.Editor () ( ) SharedPreferences,
. 117
apply SharedPreferences.Editor .
ArrayAdapter
ListView,
. 120125 , . , 122123
tags, tags. 124 notifyDataSetChanged
- ArrayAdapter, tags.
ListView .

4.5.7. ,
OnItemClickListener
ListView
4.7 itemClick
Listener, ,
OnItemClickListener. 67 (4.4) itemClickListener ListView,
ListView. 131145
onItemClick OnItemClickListener. :
AdapterView, . ? AdapterView<?>

Java, ,
onItemClick AdapterView ListView<String>.

View, AdapterView,

TextView .

, (

!)
, ,

,
(.8).
4.7. ,
OnItemClickListener ListView

128
129
130

// itemClickListener
OnItemClickListener itemClickListener = new OnItemClickListener()
{

4.5. MainActivity169
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
// URL-
String tag = ((TextView) view).getText().toString();
String urlString = getString(R.string.searchURL) +
Uri.encode(savedSearches.getString(tag, ), UTF-8);
//
Intent webIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse(urlString));
startActivity(webIntent); //

}
}; // itemClickListener


136 View ,
ListView. 137138 , URL-
. 137
Activity getString
searchURL, URL- :
http://mobile.twitter.com/search/
, ,
strings.xml.
SharedPreferences
138 URL-
urlString. getString SharedPreferences ,
. , ("" ). 138 encode Uri,
URL (, ?, /, : ..)
URL. , -,
, URL- .

141142 Intent,
.
. Intent
. Intent.ACTION_VIEW ,
. Intent , , , .
(142) Uri (Uniform Resource Identifier),

170 4 Twitter Searches


, . parse Uri
, URL (Uniform Resource Locator), Uri.

144 Intent Activity startActivity,
. ,
URI,
-.
.

4.5.8. ,
OnItemLongClickListener ListView
,
4.8 itemLong
ClickListener, ,
OnItemLongClickListener. 70 (4.4) itemLongClickListener ListView,
ListView. 153210 onItemLongClick OnItemLongClickListener.
4.8. ,
OnItemLongClickListener ListView ,

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170

// itemLongClickListener
//
OnItemLongClickListener itemLongClickListener =
new OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id)
{
// ,
final String tag = ((TextView) view).getText().toString();
// AlertDialog
AlertDialog.Builder builder =
new AlertDialog.Builder(MainActivity.this);
// AlertDialog
builder.setTitle(
getString(R.string.shareEditDeleteTitle, tag));
//
builder.setItems(R.array.dialog_items,
new DialogInterface.OnClickListener()

4.5. MainActivity171
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

// ,
//
@Override
public void onClick(DialogInterface dialog, int which)
{
switch (which)
{
case 0: //
shareSearch(tag);
break;
case 1: //
// EditText
tagEditText.setText(tag);
queryEditText.setText(
savedSearches.getString(tag, ""));
break;
case 2: //
deleteSearch(tag);
break;
}
}
} // DialogInterface.OnClickListener
); // builder.setItems
// AlertDialog
builder.setNegativeButton(getString(R.string.cancel),
new DialogInterface.OnClickListener()
{
// "Cancel"
public void onClick(DialogInterface dialog, int id)
{
dialog.cancel(); // AlertDialog
}
}
); // setNegativeButton
builder.create().show(); // AlertDialog
return true;
} // onItemLongClick
}; // OnItemLongClickListener


158 ,
, tag final. ,
, final.
AlertDialog
161166 AlertDialog.Builder, , tag

172 4 Twitter Searches


R.string.shareEditDeleteTitle (
"Share, Edit or Delete the search tagged as \"%s\"").
166 Activity getString, .
, , ,
.
, AlertDialog ListView.
169194 ,
R.array.dialog_items ( "Share", "Edit" "Delete"); ,

.
strings.xml
strings.xml. strings.xml, .
1. 4.5.5, , String Array String . 4.15 OK.
2. Name (dialog_items).
3. .
4. Add OK, .
5. Value.
Share, Edit Delete ( ),
strings.xml.

170193 , , . Share, shareSearch
( 180). Edit, 184186 EditText. Delete,
deleteSearch (189).

197206 ,
, ,
. 208 .

4.5.9. shareSearch
shareSearch (4.9) 4.8,
. 217218

4.5. MainActivity173
String, . 221227 Intent URL- ,
Intent.ACTION_SEND (222).

4.9. shareSearch MainActivity


213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233

// URL-
private void shareSearch(String tag)
{
// URL-,
String urlString = getString(R.string.searchURL) +
Uri.encode(savedSearches.getString(tag, ""), "UTF-8");
// Intent urlString
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_SUBJECT,
getString(R.string.shareSubject));
shareIntent.putExtra(Intent.EXTRA_TEXT,
getString(R.string.shareMessage, urlString));
shareIntent.setType(text/plain);

//
startActivity(Intent.createChooser(shareIntent,
getString(R.string.shareSearch)));


Intent Bundle (extras),
Activity, . ,
, , CC BCC, . 223226
putExtra Intent / Bundle, Intent.
String, ,
. , , Bundle
putExtra Intent.
223224
R.string.shareSubject ("Twitter search that might interest you"). ,
(, ), . 225226
, urlString
R.string.shareMessage ("Check out the results of this Twitter
search: %s"). 227 MIME text/plain
, .

174 4 Twitter Searches



, .4.8, ,
Intent createChooser Intent (
230). R.string.shareSearch ("Share Search to:")
. ,
. ,
, ,
,
. createChooser Intent,
startActivity .

4.5.10. deleteSearch
4.8 deleteSearch (4.10),
Delete.
AlertDialog
. 241242 , tag
R.string.confirmMessage ("Are you sure you want to delete
the search \"%s\"?"). 245254 . R.string.cancel
"Cancel". 257275 . R.string.delete "Delete". 263
tags, 266269 SharedPreferences.Editor
SharedPreferences . 272
ArrayAdapter ,
ListView .
4.10. deleteSearch MainActivity
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

//
private void deleteSearch(final String tag)
{
// AlertDialog
AlertDialog.Builder confirmBuilder = new AlertDialog.Builder(this);
// AlertDialog
confirmBuilder.setMessage(
getString(R.string.confirmMessage, tag));
// AlertDialog
confirmBuilder.setNegativeButton(getString(R.string.cancel),
new DialogInterface.OnClickListener()
{
// "Cancel"
public void onClick(DialogInterface dialog, int id)
{

4.6. AndroidManifest.xml175
251
dialog.cancel(); //
252
}
253
}
254
); // setNegativeButton
255
256
// AlertDialog
257
confirmBuilder.setPositiveButton(getString(R.string.delete),
258
new DialogInterface.OnClickListener()
259
{
260
// "Cancel"
261
public void onClick(DialogInterface dialog, int id)
262
{
263
tags.remove(tag); // tags
264
265
// SharedPreferences.Editor
266
SharedPreferences.Editor preferencesEditor =
267
savedSearches.edit();
268
preferencesEditor.remove(tag); //
269
preferencesEditor.apply(); //
270
271
//
272
adapter.notifyDataSetChanged();
273
}
274
} // OnClickListener
275
); // setPositiveButton
276
277
confirmBuilder.create().show(); // AlertDialog
278
} // deleteSearch
279 } // MainActivity

4.6. AndroidManifest.xml
3.6 AndroidManifest.xml.
, Tip Calculator

, Tip Calculator.
, .
,
.
, Twitter Searches . GUI EditText,Android
. , EditText (

176 4 Twitter Searches


).
, EditText.
3.6 Window soft input
mode, stateAlwaysHidden.

4.7.
Twitter Searches.
(GUI).
ListView,
. ListView,
. ,
Java.
SharedPreferences, . . SharedPreferences.Editor ,
SharedPreferences.
Uri- startActivity
Context. Intent
, .
AlertDialog.Builder
AlertDialog, . ,
AndroidManifest.xml , ,
.
5 Flag Quiz,
, ,
.
,
.

FlagQuiz

, , AssetManager, , ,


Activity

PreferenceFragment

assets
AssetManager
View
Handler
Toast


java.util

Android

178 5 FlagQuiz

5.1.
Flag Quiz 10
(. 5.1).
. ,
. ,
( ) TextView, . ,
: ,
, ,
.
, ,
,
.
Settings. ,

. (. 5.2)
, ,
.

. 5.1. Flag Quiz


5.2. Flag Quiz179

. 5.2. Flag Quiz

, , . .
.

5.2. Flag Quiz


Flag Quiz. (AVD)
.
Nexus 4 Nexus 7.

5.2.1.
, IDE:
1. Import. FileImport.
2. Flag Quiz. Import General Existing Projects into Workspace. Next > Import Projects. ,

180 5 FlagQuiz
Select root directory, Browse FlagQuiz
, OK. ,
Copy projects into workspace . Finish,
; Package Explorer.
3. Flag Quiz.
FlagQuiz Run AsAndroid Application,
AVD . (. 5.1 5.2).

5.2.2.
,
.
,
; ().
, AVD
( , . 5.1). Settings;
Flag Quiz Settings (. 5.3, ). AVD

(. 5.2). ,
(. 5.3, ), Number of Choices. (
AVD , .) ,
.
, 6 9 OK; , Cancel, Flag Quiz Settings.
.
Regions (. 5.4, ), , (. . 5.4, ).
,
. Africa, Asia, Europe, Oceania South America,
. OK,
. , AVD
Back (
), .
AVD
.

5.2.3.
,
.
, ( ) .

5.2. Flag Quiz181

. 5.3. Flag Quiz Number of Choices: a ,


Number of Choices;

. 5.4. Flag Quiz Regions: ,


Regions;

182 5 FlagQuiz

(. 5.5, ),
(.5.5, ).
.

. 5.5. : a ;


(. 5.6, ),
, , ,
Incorrect! (. 5.6, ). , .

,
, AlertDialog,
(. . 5.7). Reset
Quiz .

5.2. Flag Quiz183

. 5.6. Flag Quiz: a


; Incorrect

. 5.7.

184 5 FlagQuiz

5.3.
,
Flag Quiz.

5.3.1.
MainActivity ( ) .
Settings, . ,
,
.
Menu ( android.view).
Menu, onCreateOptionsMenu Activity
(5.5.4) Menu . , onOptionsItemSelected Activity (5.5.5) .

5.3.2.
(fragment) ,
.
.
,
. ,
(. 8).
Fragment ( android.app).
Flag Quiz Fragment (
).
QuizFragment ( 5.6) Fragment; -

. Activity
Fragment ,
, . QuizFragment 5.4.8.
MainActivity
.

SettingsFragment ( 5.7) PreferenceFragment (

android.preference),

5.3. 185

SharedP references . ,
XML- , Pre
ferenceFragment (. 5.35.4).
, QuizFragment

, DialogFragment ( android.
app), AlertDialog (5.6.9).

. , MainActivity . (
) SettingsActivity ( 5.8) SettingsFragment,
MainActivity .
Android 3.0, (
Android) Android Support Library.

http://developer.android.com/tools/support-library/index.html

5.3.3.
, ,
, .
.
onCreate ( SettingsFragment)

. QuizFragment SettingsFragment
, DialogFragment,
, .

onCreateView ( QuizFragment)

onCreate; View . , LayoutInflater,



, XML.

.

http://developer.android.com/guide/components/fragments.html

186 5 FlagQuiz

5.3.4.

FragmentManager ( android.app), getFragmentManager Activity. ,
Id,
findFragmentById
FragmentManager. 8, FragmentManager FragmentTransaction ( android.app)
, .

5.3.5. Preference
5.2.2 . PreferenceFragment
Preference ( android.preference)
. Preference ListPreference
, , Preference MultiSelectListPreference
, . ListPreference , MultiSelectListPreference
.
PreferenceManager ( android.preference).

5.3.6. assets
1 ,
. assets .
, assets
. images/FlagQuizImages
.
drawable,
, assets , (
). ,
assets, AssetManager
( android.content.res),
, assets,
.

- www.free-country-flags.com.

5.3. 187

5.3.7.
2.4.4 drawable, layout values,
res .
menu, anim xml.
.5.1 ( animator, color
raw).
5.1. , res

anim

,
anim
,
XML
- , ,
, .
5.4.11,
5.6.9,

animator

, animator, XML-
,
. Java
, set- get-

color

,
color
,
XML
- (, , , ..)

raw

, raw,
(, ),
. 6

menu

,
menu
,
XML
- . IDE
Settings

xml

, xml, XML-,
.
XML, .
5.4.10 XML ,
SettingsFragment

5.3.8.
2.5.1 , Android , (DPI, Dots Per Inch). ,

, Android . , 2.8 ,

188 5 FlagQuiz
. Android
,

. ,
5.3.7.
MainActivity
, .
, MainActivity :
activity_main.xml res/layout .
activity_main.xml res/layout-large-land

(, ), (land)
.
:
-
,
(-). 18 ,
. .
res
http://developer.android.com/guide/topics/resources/providing-resources.html#
AlternativeResources

5.3.9.
,
(5.5.4).
, Android WindowManager
( android.view) Display
.
.

5.3.10.
Toast ( android.widget ) ,
. Toast (,

5.3. 189

).
, Toast . Toast
,
,
.

5.3.11.

,
, . Handler ( android.os). postDelayed Handler Runnable .
Runnable
, Handler. ,
, GUI-,
GUI -.

5.3.12.
, , ImageView Animation ( android.view.animation).
loadAnimation AnimationUtils
XML-, . ( setRepeatCount Animation).
ImageView startAnimation
View ( Animation) ImageView.

5.3.13. Log.e
( )
Android . Android Log
( android.util) , .
LogCat IDE,
Android logcat.
-
http://developer.android.com/reference/android/util/Log.html

190 5 FlagQuiz

5.3.14.

, SettingsActivity (5.8). 4 ,
URL- . 5.5.5
,
.

5.3.15. Java
java.util.

ArrayList<String>. shuffle Collections
ArrayList<String> .
ArrayList<String> , 10 . Set<String>
.
ArrayList<String> List<String>
Java,
, .

5.4.

(, , ,
, ) Flag Quiz.

5.4.1.
, FlagQuiz, 5.2,
Delete. ,
Delete project contents on disk , OK.

Android Application Project.
New Android Project (New Android Application)
Next >:

5.4. 191

Application Name: Flag Quiz


Project Name: FlagQuiz
Package Name: com.deitel.flagquiz
Minimum Required SDK: API18: Android 4.3
Target SDK: API19: Android 4.4
Compile With: API19: Android 4.4
Theme: Holo Light with Dark Action Bar

New Android Project (New Android Application) Next >. Configure Launcher Icon Browse ( images
), Open Next >. Create Activity Blank
Activity Next >. Blank Activity
Finish, .
Nexus 4 ,
.

5.4.2. strings.xml
,

(. 5.2). strings.xml res/values,
.
5.2. , Flag Quiz

settings_activity

Flag Quiz Settings

number_of_choices

Number of Choices

number_of_choices_description

Display 3, 6 or 9 guess buttons

world_regions

Regions

world_regions_description

Regions to include in the quiz

guess_country

Guess the Country

results

%1$d guesses, %2$.02f%% correct

incorrect_answer

Incorrect!

default_region_message

Setting North America as the default region. One region


must be selected.

restarting_quiz

Quiz will restart with your new settings

192 5 FlagQuiz
5.2 ()

ok

OK

question

Question %1$d of %2$d

reset_quiz

Reset Quiz

image_description

Image of the current flag in the quiz

default_region

North_America


results question ,
format String. String , . results 1$ %1$d
format String ,
%1$d. 2$ %2$.02f
format ,
%2$.02f. d ,
, f
. strings.xml %1$d %2$.02f
. %1$d,
%2$.02f .

5.4.3. arrays.xml
4.5.8 strings.xml . res/values .

. ,
arrays.xml, colors.xml, strings.xml
values.xml.
, arrays.xml:
regions_list ,


,
SettingsFragment;

regions_list_for_settings , -

SettingsFragment
;

guesses_list 3, 6 9

SettingsFragment .

5.4. 193

.5.3 .
5.3. , arrays.xml

regions_list

Africa, Asia, Europe, North_America, Oceania, South_America

regions_list_for_settings

Africa, Asia, Europe, North America, Oceania, South America

guesses_list

3, 6, 9

, .
1. res values
NewAndroid XML File. New Android
XML File. values, Values values.
2. File arrays.xml Finish,
.
3. XML,
Resources , .
4. , Add,
String Array OK.
5. Name regions_list .
6. Add,
.5.3.
7. 46 regions_list_for_settings guesses_list
arrays. Add , Create
a new element at the top level in Resources.

5.4.4. colors.xml
,
. , , XML,
Java.
colors.xml, .
3.4.5, RGB ARGB.
,
.
1. res values NewAndroid XML File. New
Android XML File.

194 5 FlagQuiz
2. File colors.xml Finish,
.
3. XML, Resources ,
.
4. , Add, Color OK.
5. Name Value correct_answer #00CC00 ,
.
6. 4 5 incorrect_answer #FF0000.

5.4.5. dimens.xml
,
(. 5.4).
dimens.xml res/values,
. spacing GUI, answer_size
answerTextView. 2.5.3,
, (sp),

( ).
5.4. , Flag Quiz

spacing

8dp

answer_size

40sp

5.4.6. activity_settings.xml
SettingsActivity (5.8),
SettingsFragment (5.7). SettingsActivity
LinearLayout, SettingsFragment. ,
.
, .
1. res layout
NewAndroid XML File. New Android

5.4. 195
XML File. layout, Layout.

2. File activity_settings.xml.
3. Root Element LinearLayout Finish,
.
4. Layouts LinearLayout Outline.
5. Choose Fragment Class.
, .
Create New, New Java Class.
6. Name SettingsFragment
Superclass android.preference.PreferenceFragment. Finish,
. Java,
.
7. activity_settings.xml.

5.4.7. activity_main.xml

MainActivity ( 5.5), . 5.4.9.
( QuizFragment 5.6),
.
1. activity_main.xml res/layout.
2. Fragment Layouts RelativeLayout
Outline.
3. Choose Fragment Class Create New,
New Java Class.
4. Name QuizFragment Finish, .
Java,
.
5. activity_main.xml QuizFragment Outline. Id
@+id/quizFragment, Width Height Layout Parameters match_parent.
6. activity_main.xml.

196 5 FlagQuiz

5.4.8. fragment_quiz.xml
. (-) res/layout XML , .
SettingsFragment ,

PreferenceFragment.
QuizFragment (fragment_quiz.xml).
res/layout ,
. .5.8
QuizFragment.

. 5.8. Flag Quiz


Id

fragment_quiz.xml
fragment_quiz.xml, .
1. res layout NewAndroid XML File. New
Android XML File.
2. File fragment_quiz.xml.
3. Root Element LinearLayout (Vertical) Finish,
.

5.4. 197

4. Outline ,
. 5.9. ID. questionNumberTextView
guessCountryTextView Medium Text
Form Widgets . Small Button, , .

. 5.9. Outline
fragment_quiz.xml

5. 4 GUI .5.5. Height flagImageView


0dp, Weight 1,
, ,
.
Width=0dp Weight=1 LinearLayout. fitCenter Scale Type
flagImageView , ImageView
.
Adjust View Bounds ImageView true, ,
ImageView Drawable.
5.5. fragment_quiz.xml
GUI

questionNumberTextView

Layout Parameters
Width
Height
Gravity

wrap_content
wrap_content
center_horizontal

Other Properties
Text

@string/question

198 5 FlagQuiz
5.5 ()
GUI

flagImageView

Layout Parameters
Width
Height
Gravity
Weight
Margins
Left/Right
Top/Bottom

guessCountryTextView

LinearLayout ()

wrap_content
0dp
center
1
@dimen/activity_horizontal_margin
@dimen/activity_vertical_margin

Other Properties
Adjust View Bounds
Content Description
Scale Type

true
@string/image_description
fitCenter

Layout Parameters
Width
Height
Gravity

wrap_content
wrap_content
center_horizontal

Other Properties
Text

@string/guess_country

Layout Parameters
Width
Height
Margins
Bottom

match_parent
wrap_content
@dimen_spacing

Button ()

Layout Parameters
Width
Height
Weight

0dp
fill_parent
1

answerTextView

Layout Parameters
Width
Height
Gravity

wrap_content
wrap_content
center|bottom

Other Properties
Gravity
Text Size
Text Style

center_horizontal
@dimen/answer_size
bold

5.4.9. activity_main.xml

5.4.7 MainActivity ,
QuizFragment.

5.4. 199
MainActivity ,
SettingsFragment, QuizFragment.

.
1. res
NewFolder. Folder layout-large-land Finish.
large land , ,
, ,
.
2. layout-large-land
NewAndroid XML File. New Android XML File.
File activity_main.xml. Root Element
LinearLayout (Horizontal) Finish, .
3. LineerLayout Base Aligned
false.
4. Fragment Layouts
LinearLayout Outline. Choose Fragment Class
SettingsFragment OK.
5. 4 QuizFragment, OK.
6. SettingsFragment Outline. Layout Parameters
Width 0dp, Height match_parent,
Weight 1.
7. QuizFragment Outline. Layout Parameters
Width 0dp, Height match_parent,
Weight 2.
(Weight) QuizFragment SettingsFragment 2 1 , QuizFragment 2/3 .

5.4.10.
preferences.xml
preferences.xml, Settings
Fragment . :
1. res
NewFolder. Folder xml Finish.
2. xml NewAndroid
XML File. New Android XML File.
3. File preferences.xml.

200 5 FlagQuiz
4. , Resource Type Preference,
Root Element PreferenceScreen,
.
5. Finish, . XML, Structure .
6. PreferenceScreen Add.
7. ListPreference OK.
.
8. PreferenceScreen Add.
9. MultiSelectListPreference
OK. .
.
10. ListPreference .5.6.
11. MultiSelectListPreference
.5.7.
12. preferences.xml.
5.6. ListPreference

Entries

@array/guesses_list

Entry values

@array/guesses_list

,
Entries
.
SharedPreferences

Key

pref_numberOfChoices

,
SharedPreferences

Title

@string/number_of_choices

,
GUI

Summary

@string/number_of_choices_description

Persistent

true


true
, PreferenceFragment

Default value


Entries
,

5.4. 201

5.7. MultiSelectListPreference

Entries

@array/regions_list_for_
settings

Entry values

@array/regions_list

,

Entries
.
SharedPreferences

Key

pref_regionsToInclude

,
SharedPreferences

Title

@string/world_regions

, GUI

Summary

@string/world_regions_description

Persistent

true

Default value

@array/regions_list

5.4.11.
,
. 5.6.9 , .
.
1. res NewFolder, Folder name anim
Finish.
2. anim NewAndroid
XML File New Android XML File.
3. File incorrect_shake.xml.
4. , Resource Type is Tween Animation Root Element
.
5. Finish, .
XML.
6. , , XML
5.1.

202 5 FlagQuiz
5.1. (incorrect_shake.xml),

1 <?xml version="1.0" encoding="utf-8"?>
2
3 <set xmlns:android="http://schemas.android.com/apk/res/android"
4
android:interpolator="@android:anim/decelerate_interpolator">
5
6
<translate android:fromXDelta="0" android:toXDelta="-5%p"
7
android:duration="100"/>
8
9
<translate android:fromXDelta="-5%p" android:toXDelta="5%p"
10
android:duration="100" android:startOffset="100"/>
11
12
<translate android:fromXDelta="5%p" android:toXDelta="-5%p"
13
android:duration="100" android:startOffset="200"/>
14 </set>

View . ,
( 314) ,
. alpha (), scale ( ), translate
() rotate ().
translate. translate View
. Android , .
translate ( 67) View
. android:fromXDelta
View ( ),
android:toXDelta View .
:
( );
View;
View.

android:fromXDelta 0.
android:toXDelta -5%p, , View ( ) 5% ( p).
, 5% View, p .
android:duration ( ).
, , 67,
View 5%
100.

5.5. MainActivity203

( 910) ,
. View , -5%p,
, %5p, 100 .
, , ,
android:startOffset ( )
. .
100 . ( 1213)
,
200 .

5.5. MainActivity
MainActivity ( 5.25.7) QuizFragment SettingsFragment
QuizFragment .

5.5.1. package, import


5.2 package import, MainActivity.
621 Java Android,
. import;
5.3,
5.5.25.5.6.
5.2. package, import MainActivity
1 // MainActivity.java
2 // QuizFragment
3 // QuizFragment SettingsFragment
4 package com.deitel.flagquiz;
5
6 import java.util.Set;
7
8 import android.app.Activity;
9 import android.content.Intent;
10 import android.content.SharedPreferences;
11 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
12 import android.content.pm.ActivityInfo;
13 import android.content.res.Configuration;
14 import android.graphics.Point;
15 import android.os.Bundle;
16 import android.preference.PreferenceManager;
17 import android.view.Display;

204 5 FlagQuiz
18
19
20
21
22
23
24
25
26
27
28
29
30
31

import
import
import
import

android.view.Menu;
android.view.MenuItem;
android.view.WindowManager;
android.widget.Toast;

public class MainActivity extends Activity


{
// SharedPreferences
public static final String CHOICES = "pref_numberOfChoices";
public static final String REGIONS = "pref_regionsToInclude";
private boolean phoneDevice = true; //
private boolean preferencesChanged = true; // ?

2627 ,
5.4.10.
. phoneDevice (29) ,
, , . preferencesChanged
( 30) , , ,
onStart MainActivity (5.5.3) updateGuessRows ( 5.6.4) updateRegions ( 5.6.5) QuizFragment
. true,
.

5.5.2. onCreate
onCreate Activity (5.3)
setContentView ( 36) MainActivity.
Android activity_main.xml res/layout, , res/layout-large-land,
.
5.3. onCreate MainActivity
32
33
34
35
36
37
38
39
40
41
42
43

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// SharedPreferences
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
// SharedPreferences
PreferenceManager.getDefaultSharedPreferences(this).
registerOnSharedPreferenceChangeListener(

5.5. MainActivity205
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

preferenceChangeListener);
//
int screenSize = getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK;
// phoneDevice false
if (screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||
screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE )
phoneDevice = false; //
//
if (phoneDevice)
setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} // onCreate


39 ,
setDefaultValues PreferenceManager
SharedPreferences , ,
preferences.xml. .
(this), .
XML- (R.xml.preferences), -

5.4.10.

, ,

setDefaultValues, false
,
.
, ,
MainActivity updateGuessRows updateRegions
QuizFragment ( , ). MainActivity OnSharedPreferenceChangedListener (4244), . getDefaultSharedPreferences
PreferenceManager SharedPreferences, , registerOnSharedPreferenc
eChangeListener SharedPreferences ,
5.5.6.

4753 , :
? getResources
Resources ( android.content.res),

206 5 FlagQuiz
. getConfiguration Resources Configuration (
android.content.res) (public) screenLayout,
. screenLayout Configuration.SCREENLAYOUT_SIZE_MASK
(&). SCREENLAYOUT_SIZE_LARGE SCREENLAYOUT_SIZE_XLARGE Configuration
( 5152). ,
. ,
, 5758 Activity
setRequestedOrientation, MainActivity
.

5.5.3. onStart
onStart ( 5.4) .
onStart onCreate.

onStart ,

.

, -

SettingsActivity, MainActivity
SettingsActivity. MainActivity,
onStart.
, .
, preferencesChanged true, onStart updateGuessRows ( 5.6.4) updateRegions (5.6.5)
QuizFragment .
QuizFragment , 7172
Activity getFragmentManager FragmentManager,
findFragmentById. 7376
updateGuessRows updateRegions QuizFragment,
SharedPreferences ,
. 77 .
5.4. onStart MainActivity
61
62
63
64

// onCreate
@Override
protected void onStart()
{

5.5. MainActivity207
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

super.onStart();
if (preferencesChanged)
{
// , ,
// QuizFragment
QuizFragment quizFragment = (QuizFragment)
getFragmentManager().findFragmentById(R.id.quizFragment);
quizFragment.updateGuessRows(
PreferenceManager.getDefaultSharedPreferences(this));
quizFragment.updateRegions(
PreferenceManager.getDefaultSharedPreferences(this));
quizFragment.resetQuiz();
preferencesChanged = false;
}
} // onStart

5.5.4. onCreateOptionsMenu
onCreateOptionsMenu (5.5) . Menu, .
. 8788 WindowManager
Display
, .
, .
89 Point ,
90 Display getRealSize, x y Point.
( 93), 95 menu.xml
, .
getMenuInflater, Activity, MenuInflater,
inflate
, , Menu,
. onCreateOptionsMenu true,
, .
5.5. onCreateOptionsMenu MainActivity
82
83
84
85
86
87
88
89

//
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Display
Display display = ((WindowManager)
getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
Point screenSize = new Point(); //

208 5 FlagQuiz
90
91
92
93
94
95
96
97
98
99
100
101

display.getRealSize(screenSize); // screenSize
//
if (screenSize.x < screenSize.y) // x - , y -
{
getMenuInflater().inflate(R.menu.main, menu); //
return true;
}
else
return false;
} // onCreateOptionsMenu

5.5.5. onOptionsItemSelected
onOptionsItemSelected (5.6) .
,
, Settings; ,
, Settings. 106
SettingsActivity. Intent
, , ,
(SettingsActivity.class).
startActivity .
5.6. onOptionsItemSelected MainActivity
102
103
104
105
106
107
108
109
110

// SettingsActivity
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
Intent preferencesIntent = new Intent(this, SettingsActivity.class);
startActivity(preferencesIntent);
return super.onOptionsItemSelected(item);
}

5.5.6. ,
OnSharedPreferenceChangeListener
preferenceChangeListener (5.7)
, OnSharedPreferenceChangeListener.
onCreate
SharedPreferences . ,
onSharedPreferenceChanged preferencesChanged true( 120), QuizFragment (122123)

5.5. MainActivity209

. CHOICES, 127128
updateGuessRows resetQuiz QuizFragment.
5.7. ,
OnSharedPreferenceChangeListener
111
// SharedPreferences
112
private OnSharedPreferenceChangeListener preferenceChangeListener =
113
new OnSharedPreferenceChangeListener()
114
{
115
//
116
@Override
117
public void onSharedPreferenceChanged(
118
SharedPreferences sharedPreferences, String key)
119
{
120
preferencesChanged = true; //
121
122
QuizFragment quizFragment = (QuizFragment)
123
getFragmentManager().findFragmentById(R.id.quizFragment);
124
125
if (key.equals(CHOICES)) //
126
{
127
quizFragment.updateGuessRows(sharedPreferences);
128
quizFragment.resetQuiz();
129
}
130
else if (key.equals(REGIONS)) //
131
{
132
Set<String> regions =
133
sharedPreferences.getStringSet(REGIONS, null);
134
135
if (regions != null && regions.size() > 0)
136
{
137
quizFragment.updateRegions(sharedPreferences);
138
quizFragment.resetQuiz();
139
}
140
else //
141
{
// ( )
142
SharedPreferences.Editor editor = sharedPreferences.edit();
143
regions.add(
144
getResources().getString(R.string.default_region));
145
editor.putStringSet(REGIONS, regions);
146
editor.commit();
147
Toast.makeText(MainActivity.this,
148
R.string.default_region_message,
149
Toast.LENGTH_SHORT).show();
150
}
151
}
152
153
Toast.makeText(MainActivity.this,
154
R.string.restarting_quiz, Toast.LENGTH_SHORT).show();
155
} // onSharedPreferenceChanged
156
}; //
157 } // MainActivity

210 5 FlagQuiz
REGIONS , 132133
Set<String> . getStringSet SharedPreferences
Set<String> .
, Set<String> , 137138
updateRegions resetQuiz QuizFragment.
142146 REGIONS
, 147149
. makeText Toast ,
Toast, . show Toast.
, , 153154
, .
Toast,
, . 5.10.

. 5.10. ,

5.6. QuizFragment
QuizFragment (5.85.16) .

5.6.1. package import


5.8 package import QuizFragment. 533 Java Android, . import;
5.3, ,
( 5.6.25.6.10).
5.8. package import QuizFragment
1
2
3
4
5
6
7
8
9
10

// QuizFragment.java
// Flag Quiz
package com.deitel.flagquiz;
import
import
import
import
import
import

java.io.IOException;
java.io.InputStream;
java.security.SecureRandom;
java.util.ArrayList;
java.util.Collections;
java.util.List;

5.6. QuizFragment211
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

import java.util.Set;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.app.Fragment;
android.content.DialogInterface;
android.content.SharedPreferences;
android.content.res.AssetManager;
android.graphics.drawable.Drawable;
android.os.Bundle;
android.os.Handler;
android.util.Log;
android.view.LayoutInflater;
android.view.View;
android.view.View.OnClickListener;
android.view.ViewGroup;
android.view.animation.Animation;
android.view.animation.AnimationUtils;
android.widget.Button;
android.widget.ImageView;
android.widget.LinearLayout;
android.widget.TextView;

5.6.2.
5.9
QuizFragment. TAG ( 38)
Log (5.13),
, .
FLAGS_IN_QUIZ (40) .
5.9. QuizFragment
35 public class QuizFragment extends Fragment
36 {
37
// ,
38
private static final String TAG = "FlagQuiz Activity";
39
40
private static final int FLAGS_IN_QUIZ = 10;
41
42
private List<String> fileNameList; //
43
private List<String> quizCountriesList; //
44
private Set<String> regionsSet; //
45
private String correctAnswer; //
46
private int totalGuesses; //
47
private int correctAnswers; //
48
private int guessRows; //
49
private SecureRandom random; //
50
private Handler handler; //
51
private Animation shakeAnimation; //
52

212 5 FlagQuiz
53
54
55
56
57

private
private
private
private

TextView questionNumberTextView; //
ImageView flagImageView; //
LinearLayout[] guessLinearLayouts; //
TextView answerTextView; // Correct! Incorrect!

fileNameList (42)
. quizCountriesList
(43) ,
. regionsSet (44) .
correctAnswer ( 45) . totalGuesses (46)
.
correctAnswers (47) ;
, FLAGS_IN_QUIZ.
guessRows ( 48) LinearLayout
c , .
random (49) , , ,
LinearLayout. ,
, Handler (50)
.
shakeAnimation (51)
, ,
. 5356 ,
GUI
.

5.6.3. onCreateView
onCreateView QuizFragment (5.10) GUI QuizFragment guessRows
regionsSet , MainActivity updateGuessRows
updateRegions QuizFragment. onCreateView
(63) QuizFragment (6465),
LayoutInflater, onCreateView .
inflate LayoutInflater :
, ;
ViewGroup ( ), ; -

onCreateView;

, ,

ViewGroup ,

5.6. QuizFragment213
false , ,
true

inflate View, . view,


onCreateView
QuizFragment.
5.10. onCreateView QuizFragment
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

// QuizFragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View view =
inflater.inflate(R.layout.fragment_quiz, container, false);
fileNameList = new ArrayList<String>();
quizCountriesList = new ArrayList<String>();
random = new SecureRandom();
handler = new Handler();
//
shakeAnimation = AnimationUtils.loadAnimation(getActivity(),
R.anim.incorrect_shake);
shakeAnimation.setRepeatCount(3); // 3
// GUI
questionNumberTextView =
(TextView) view.findViewById(R.id.questionNumberTextView);
flagImageView = (ImageView) view.findViewById(R.id.flagImageView);
guessLinearLayouts = new LinearLayout[3];
guessLinearLayouts[0] =
(LinearLayout) view.findViewById(R.id.row1LinearLayout);
guessLinearLayouts[1] =
(LinearLayout) view.findViewById(R.id.row2LinearLayout);
guessLinearLayouts[2] =
(LinearLayout) view.findViewById(R.id.row3LinearLayout);
answerTextView = (TextView) view.findViewById(R.id.answerTextView);
//
for (LinearLayout row : guessLinearLayouts)
{
for (int column = 0; column < row.getChildCount(); column++)
{
Button button = (Button) row.getChildAt(column);
button.setOnClickListener(guessButtonListener);
}
}
// questionNumberTextView

214 5 FlagQuiz
101
102
103
104
105

questionNumberTextView.setText(
getResources().getString(R.string.question, 1, FLAGS_IN_QUIZ));
return view; //
} // onCreateView

6768 ArrayList<String>,

. 69 SecureRandom . 70
- Handler,
,
.
7374 ,
. loadAnimation AnimationUtils
XML-, R.anim.incorrect_
shake. Context, ,
, getActivity
Activity, Fragment. Activity Context. 75 setRepeatCount Animation
.
7888 GUI,
. 9198
gue]ssLinearLayout
guessButtonListener ( 5.6.9) OnClickListener.
101102 questionNumberTextView ,
format String. format
R.string.question
( 5.4.2). Fragment
getResources Resources ( android.content.res),
. getString
R.string.question, Question
%1$d of %2$d.
103 QuizFragment.

5.6.4. updateGuessRows
updateGuessRows (5.11) MainActivity , ,
, . 110111 SharedPreferences ,
MainActivity.CHOICES, , SettingsFragment
. 112

5.6. QuizFragment215

int , guessRows, guessLinearLayout (


). 115116
guessLinearLayout, 119120
guessLinearLayout guessRows.
5.11. updateGuessRows QuizFragment
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

// guessRows SharedPreferences
public void updateGuessRows(SharedPreferences sharedPreferences)
{
//
String choices =
sharedPreferences.getString(MainActivity.CHOICES, null);
guessRows = Integer.parseInt(choices) / 3;
// LinearLayout
for (LinearLayout layout : guessLinearLayouts)
layout.setVisibility(View.INVISIBLE);

// LinearLayout
for (int row = 0; row < guessRows; row++)
guessLinearLayouts[row].setVisibility(View.VISIBLE);

5.6.5. updateRegions
updateRegions (5.12) MainActivity
, , .
126127 SharedPreferences
Set<String>. MainActivity.
REGIONS , SettingsFragment
.
5.12. updateregions QuizFragment
123
124
125
126
127
128
129

// SharedPreferences
public void updateRegions(SharedPreferences sharedPreferences)
{
regionsSet =
sharedPreferences.getStringSet(MainActivity.REGIONS, null);
}

5.6.6. resetQuiz
resetQuiz (5.13) . ,
, , assets .

216 5 FlagQuiz
, AssetManager ( 134) getAssets .
135 fileNameList,
, .
140147 . list AssetManager (143)
, paths.
145146 .png,
fileNameList. list AssetManager
IOException, (
). - , assets, 149152
Android. e Log
. Log
http://developer.android.com/reference/android/util/Log.html
5.13. resetQuiz QuizFragment
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

//
public void resetQuiz()
{
// AssetManager
AssetManager assets = getActivity().getAssets();
fileNameList.clear(); //
try
{

//
for (String region : regionsSet)
{
//
String[] paths = assets.list(region);
for (String path : paths)
fileNameList.add(path.replace(".png", ""));

}
}
catch (IOException exception)
{
Log.e(TAG, Error loading image file names, exception);
}
correctAnswers = 0; //
totalGuesses = 0; //
quizCountriesList.clear(); //
int flagCounter = 1;
int numberOfFlags = fileNameList.size();
// FLAGS_IN_QUIZ quizCountriesList

5.6. QuizFragment217
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

while (flagCounter <= FLAGS_IN_QUIZ)


{
int randomIndex = random.nextInt(numberOfFlags);
//
String fileName = fileNameList.get(randomIndex);

// ,
if (!quizCountriesList.contains(fileName))
{
quizCountriesList.add(fileName); //
++flagCounter;
}

loadNextFlag(); //
} // resetQuiz

154156 ,
(correctAnswers), (totalGuesses),
quizCountriesList.
162175 quizCountriesList FLAGS_IN_QUIZ (10) . ,
0 ,
1.
fileNamesList. quizCountriesList ,
quizCountriesList flagCounter.
, FLAGS_IN_QUIZ . 177 loadNextFlag (5.14) .

5.6.7. loadNextFlag
loadNextFlag (5.14) . quizCountriesList

-
.png. regionName countryName ,
(_).
5.14. loadNextFlag QuizFragment
180
181
182
183
184

//
private void loadNextFlag()
{
//
String nextImage = quizCountriesList.remove(0);

218 5 FlagQuiz
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

correctAnswer = nextImage; //
answerTextView.setText(""); // answerTextView
//
questionNumberTextView.setText(
getResources().getString(R.string.question,
(correctAnswers + 1), FLAGS_IN_QUIZ));
//
String region = nextImage.substring(0, nextImage.indexOf('-'));
// AssetManager
AssetManager assets = getActivity().getAssets();
try
{

// InputStream
InputStream stream =
assets.open(region + / + nextImage + .png);
// Drawable flagImageView
Drawable flag = Drawable.createFromStream(stream, nextImage);
flagImageView.setImageDrawable(flag);

}
catch (IOException exception)
{
Log.e(TAG, "Error loading " + nextImage, exception);
}

Collections.shuffle(fileNameList); //
// fileNameList
int correct = fileNameList.indexOf(correctAnswer);
fileNameList.add(fileNameList.remove(correct));
// 3, 6 9 guessRows
for (int row = 0; row < guessRows; row++)
{
// currentTableRow
for (int column = 0;
column < guessLinearLayouts[row].getChildCount(); column++)
{
// Button
Button newGuessButton =
(Button) guessLinearLayouts[row].getChildAt(column);
newGuessButton.setEnabled(true);

// newGuessButton
String fileName = fileNameList.get((row * 3) + column);
newGuessButton.setText(getCountryName(fileName));

//
int row = random.nextInt(guessRows); //

5.6. QuizFragment219
240
241
242
243
244
245

int column = random.nextInt(3); //


LinearLayout randomRow = guessLinearLayouts[row]; //
String countryName = getCountryName(correctAnswer);
((Button) randomRow.getChildAt(column)).setText(countryName);
} // loadNextFlag

184 quizCountriesList nextImage.


correctAnswer
. answerTextView
questionNumberTextView (189191) R.string.question.
194 nextImage ,
assets, .
AssetManager try InputStream ( java.io),
. createFromStream
Drawable, Drawable ( android.graphics.drawable).
Drawable flagImageView
setImageDrawable. ,
(211).
214 fileNameList , 217218 correctAnswer
fileNameList
.
221236 guessLinearLayout
guessRows. :
228229 ;
230 ;
233 fileNameList;
234 ,
getCountryName ( 5.6.8);

239243 (
guessRows) , .

5.6.8. getCountryName
getCountryName (5.15)
. , ,
. replace
String (_) .

220 5 FlagQuiz
5.15. getCountryName QuizFragment
246
247
248
249
250
251

//
private String getCountryName(String name)
{
return name.substring(name.indexOf('-') + 1).replace('_', ' ');
}

5.6.9. ,
OnClickListener
9198 (5.10) guessButtonListener ( 5.16)
. guessButtonListener
, OnClickListener
. v.
( 259) ( 260),
totalGuesses.
( 263), correctAnswers.
answerTextView ,
, R.color.correct_answer
(). disableButtons (5.6.10), .
5.16. , OnClickListener
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

//
private OnClickListener guessButtonListener = new OnClickListener()
{
@Override
public void onClick(View v)
{
Button guessButton = ((Button) v);
String guess = guessButton.getText().toString();
String answer = getCountryName(correctAnswer);
++totalGuesses; //
if (guess.equals(answer)) //
{
++correctAnswers; //
//
answerTextView.setText(answer + "!");
answerTextView.setTextColor(
getResources().getColor(R.color.correct_answer));
disableButtons(); //

5.6. QuizFragment221
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

// FLAGS_IN_QUIZ
if (correctAnswers == FLAGS_IN_QUIZ)
{
// DialogFragment
DialogFragment quizResults =
new DialogFragment()
{
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setCancelable(false);
builder.setMessage(
getResources().getString(R.string.results,
totalGuesses, (1000 / (double) totalGuesses)));
// "Reset Quiz"
builder.setPositiveButton(R.string.reset_quiz,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,
int id)
{
resetQuiz();
}
} //
); // setPositiveButton
return builder.create(); // AlertDialog
} // onCreateDialog
}; // DialogFragment
// FragmentManager DialogFragment
quizResults.show(getFragmentManager(), quiz results);

}
else // ,
{
//
handler.postDelayed(
new Runnable()
{
@Override
public void run()
{
loadNextFlag();
}
}, 2000); // (2000 )
}

}
else //
{
flagImageView.startAnimation(shakeAnimation); //

222 5 FlagQuiz
329
330
331
332
333
334
335
336
337
338

// "Incorrect!"
answerTextView.setText(R.string.incorrect_answer);
answerTextView.setTextColor(
getResources().getColor(R.color.incorrect_answer));
guessButton.setEnabled(false); //

}
}
}; // guessButtonListener

correctAnswers FLAGS_IN_QUIZ ( 275),


. 278307 ,
DialogFragment,
. onCreateDialog DialogFragment AlertDialog.
Builder AlertDialog, .
Reset Quiz ,
resetQuiz, ( 300).
DialogFragment, 310 show, FragmentManager, getFragmentManager String.
getFragmentByTag FragmentManager
DialogFragment
.
correctAnswers FLAGS_IN_QUIZ, 315323 postDelayed handler.
, Runnable,
(loadNextFlag), . (2000).
, 328 startAnimation flagImageView
shakeAnimation, onCreateView.
answerTextView "Incorrect!"
( 331333), ,
, .

5.6.10. disableButtons
disableButtons (5.17)
.
5.17. disableButtons QuizFragment
339
340
341
342
343
344

// ,
private void disableButtons()
{
for (int row = 0; row < guessRows; row++)
{
LinearLayout guessRow = guessLinearLayouts[row];

5.8. SettingsActivity223
345
for (int i = 0; i < guessRow.getChildCount(); i++)
346
guessRow.getChildAt(i).setEnabled(false);
347
}
348
}
349 } // FlagQuiz

5.7. SettingsFragment
SettingsFragment (5.18) PreferenceFragment, .
onCreate ( 1116) SettingsFragment
SettingsActivity , MainActivity .
15 PreferenceFragment addPreferencesFromResource
.
preferences.xml,
5.4.10.
5.18. PreferenceFragment

1 // SettingsFragment.java
2 // PreferenceFragment
3 package com.deitel.flagquiz;
4
5 import android.os.Bundle;
6 import android.preference.PreferenceFragment;
7
8 public class SettingsFragment extends PreferenceFragment
9 {
10
// GUI preferences.xml res/xml
11
@Override
12
public void onCreate(Bundle savedInstanceState)
13
{
14
super.onCreate(savedInstanceState);
15
addPreferencesFromResource(R.xml.preferences); // XML
16
}
17 } // SettingsFragment

5.8. SettingsActivity
SettingsActivity (5.19) SettingsFragment
. ,
(com.deitel.flagquiz) NewClass,
New Java Class. Name
SettingsActivity, Superclass android.app.Activity
Finish.

224 5 FlagQuiz
onCreate (1116) setContentView
Activity, ,
activity_settings.xml ( 5.4.6), R.layout.activity_
settings.
5.19. SettingsFragment
1 // SettingsActivity.java
2 // SettingsFragment
3 package com.deitel.flagquiz;
4
5 import android.app.Activity;
6 import android.os.Bundle;
7
8 public class SettingsActivity extends Activity
9 {
10
// FragmentManager SettingsFragment
11
@Override
12
protected void onCreate(Bundle savedInstanceState)
13
{
14
super.onCreate(savedInstanceState);
15
setContentView(R.layout.activity_settings);
16
}
17 } // SettingsActivity

5.9. AndroidManifest.xml
AndroidManifest.
xml ; Android ,
, .
MainActivity AndroidManifest.xml. SettingsActivity, .
1. AndroidManifest.xml Application
.
2. Application Nodes Add,
Activity OK.
3. Application Nodes ,
Attributes for Activity.
4. Name .SettingsActivity. (.) SettingsActivity
(com.deitel.
flagquiz).
5. Label @string/settings_activity SettingsActivity.

5.10. 225


http://developer.android.com/guide/topics/manifest/manifest-intro.html

5.10.
Flag Quiz .

.
QuizFragment SettingsFragment

. PreferenceFragment
,
DialogFragment AlertDialog.
Fragment , FragmentManager
.
SettingsActivity, SettingsFragment.
SettingsActivity .
, Android WindowManager
Display, , . ,
SettingsFragment .
, assets
AssetManager. Drawable
, InputStream,
Drawable ImageView.
res menu
, anim xml
XML. ,
,
.
Toast
, . ,
Handler, Runnable . , Runnable
, Handler (UI- ).

226 5 FlagQuiz
XML ImageView
, . Android Log.
java.util, List, ArrayList,
Collections Set.
6 Cannon Game. , .
, ,
,

. .

CannonGame

, ,
, , ,
SurfaceView SurfaceHolder

,
SurfaceView
Paints Canvas
onTouchEvent View


SoundPool
AudioManager
onPause onDestroy
Fragment

228 6 CannonGame

6.1.
Cannon Game 10 , (. 6.1).
, , , ,
. , .
, ,
.
AlertDialog, , ,
(. 6.2).

. 6.1. Cannon Game

10 .
,
. , .
, .
.
. , .
, , .
. ,
.

6.2. Cannon Game229

. 6.2. AlertDialog Cannon Game


: a AlertDialog
; AlertDialog ,

[: - Android
.]

6.2. Cannon Game



Eclipse Cannon Game.
.
1. Import FileImport.
2. Cannon Game. Import General Existing Projects into Workspace.
Next > Import Projects. ,
Select root directory, Browse Browse
For Folder CannonGame OK.
Finish Eclipse.
Package Explorer, Eclipse.

230 6 CannonGame
3. Cannon Game. Eclipse
CannonGame Package Explorer,
Run AsAndroid Application.

, .
, .
AVD, . . ,
.

6.3.
,
Cannon Game.
.

6.3.1.

, View
, CannonView ( 6.8),
SurfaceView (. ). XML-
, ( ), View ,
.
CannonView 6.4.3.

6.3.2. raw
(, ), Cannon Game, res/raw. , ,
6.4.5; .

6.3.3.
, 5
( ),
.

6.3. 231

, onCreate, onStart, onResume, onPause, onStop onDestroy. , ( ,


).
onPause
onDestroy. onPause , , ,
. , , , onPause .
CannonView CannonGameFragment (6.7).
onPause CannonView, , ( ).
.
onDestroy, onDestroy ,
. CannonFragment
CannonView.
.

http://developer.android.com/reference/android/app/Activity.html #ActivityLifecycle

http://developer.android.com/guide/components/fragments.html#Lifecycle

6.3.4. onTouchEvent View


, .
.
CannonView,
onTouchEvent View ( 6.8.13),
MotionEvent ( android.view)
.

6.3.5. SoundPool
AudioManager
SoundPool
( android.media), ,

232 6 CannonGame
.
Android, , , , , .. Android

. setVolumeControlStream Activity
. AudioManager (
android.media),
.

6.3.6. ,
SurfaceView SurfaceHolder

, . Thread run, CannonView
, .
run .
, GUI. Android
, GUI, ,

ANR (Application Not Responding). , ,
. Android
SurfaceView View,
, , GUI-.
SurfaceView SurfaceHolder,
Canvas, .
SurfaceHolder ,
Canvas , SurfaceView
. SurfaceView
SurfaceHolder.Callback, ,
, ( )
SurfaceView.

6.3.7.
CannonView
- CannonView, . 6.8. ,
,

6.4. 233

.
.

6.3.8. Paint Canvas


Canvas ( android.graphics) , . Canvas Bitmap
View. Canvas Paint ( android.graphics) , ,
, .
drawGameElements, 6.8.
Paint
developer.android.com/reference/android/graphics/Paint.html

6.4.

main.xml.

6.4.1.
Android CannonGame.
New Android Project .
Application name: Cannon Game
Project Name: Cannon Game
Package name: com.deitel.cannongame
Minimum Required SDK: API18: Android 4.3
Target SDK: API19: Android 4.4
Compile With: API19: Android 4.4
Theme: Holo Light with Dark Action Bar

New Android Project (New Android Application)


Next >. Configure Launcher Icon
Next >. Create Activity Blank Activity Next >. Blank Activity
Finish, .
activity_main.xml.
Nexus 4 TextView "Hello world!".

234 6 CannonGame

.
, 3.6,
.

6.4.2. strings.xml
,

(. 6.1). strings.xml res/values,
.
6.1. , Cannon Game

results_format

Shots fired: %1$d\nTotal time: %2$.1f

reset_game

Reset Game

win

You win!

lose

You lose!

time_remaining_format

Time remaining: %.1f seconds

6.4.3. fragment_game.xml
fragment_game.xml CannonGameFragment
FrameLayout CannonView. FrameLayout
CannonView.
CannonGameFragment CannonView.
fragment_game.xml, .
1. res/layout Package Explorer.
2. values NewAndroid
XML File. New Android XML File.
3. File fragment_game.xml Finish,
.
4. Root Element FrameLayout Finish.
5. Advanced view ( v)
.
6. Choose Custom View Class. Create New, New Java Class.

6.4. 235

7. Name CannonView. Superclass android.view.View android.view.SurfaceView. ,


Constructors from superclass , Finish. CannonView.java.
,
. CannonView.java.
8. fragment_game.xml view1 Outline. Layout
Parameters Properties Width Height match_parent.
9. Outline view1,
Edit ID, view1 cannonView OK.
10. fragment_game.xml.

6.4.4. activity_main.xml
activity_main.xml MainActivity
CannonGameFragment .
, .
1. activity_main.xml .
2. Layouts
RelativeLayout Outline.
3. Choose Fragment Class. Create New,
New Java Class.
4. Name CannonGameFragment
Superclass android.app.Fragment. Finish, .
Java, .
5. activity_main.xml.

6.4.5.
, res/raw .
blocker_hit.wav, target_hit.
wav cannon_fire.wav, sounds .
, .
1. res
NewFolder.
2. raw Finish, .
3. res/raw.

236 6 CannonGame

6.5. Line
:
Line (6.1);
MainActivity ( Activity; 6.6);
CannonGameFragment ( 6.7);
CannonView ( 6.8).

Line,
( Point).
. Line , .
1. src Package Explorer.
2. (com.deitel.cannongame) NewClass
New Java Class.
3. Name Line Finish.
4. , 6.4, Line.java. Point
x y Point .
6.1. Line
1
2
3
4
5
6
7
8
9
10
11

// Line.java
// Line .
package com.deitel.cannongame;
import android.graphics.Point;
public class Line
{
public Point start = new Point(); // --(0,0)
public Point end = new Point(); // --(0,0)
} // Line

6.6. MainActivity
MainActivity (6.2) CannonGameFragment Cannon Game. onCreate
Activity, .
6.2. MainActivity CannonGameFragment
1 // MainActivity.java
2 // MainActivity CannonGameFragment
3 package com.deitel.cannongame;

6.7. CannonGameFragment237
4
5
6
7
8
9
10
11
12
13
14
15
16
17

import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity
{
//
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState); // onCreate
setContentView(R.layout.activity_main); //
}
} // MainActivity

6.7. CannonGameFragment
CannonGameFragment (6.3) Fragment:
onCreateView ( 1728) 5.3.3,

onCreate Fragment
View, . 2223
. 26
CannonView CannonGameFragment, ;

onActivityCreated (3138) -

. 37 setVolumeControlStream
Activity,
;

onPause (4146) MainActivity ( -

, ) onPause CannonGameFragment.
45 stopGame CannonView (6.8.11)
;

onDestroy ( 4954) MainActivity

onDestroy onDestroy CannonGameFragment. 46


releaseResources CannonView ( 6.8.11)

6.3. CannonGameFragment
CannonView
1
2
3
4
5
6
7

// CannonGameFragment.java
// CannonGameFragment CannonView
package com.deitel.cannongame;
import android.app.Fragment;
import android.media.AudioManager;
import android.os.Bundle;

238 6 CannonGame
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

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class CannonGameFragment extends Fragment
{
private CannonView cannonView; //
//
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View view =
inflater.inflate(R.layout.fragment_game, container, false);

// CannonView
cannonView = (CannonView) view.findViewById(R.id.cannonView);
return view;

//
@Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);

//
getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);

// MainActivity
@Override
public void onPause()
{
super.onPause();
cannonView.stopGame(); //
}
// MainActivity
@Override
public void onDestroy()
{
super.onDestroy();
cannonView.releaseResources();
}
} // CannonGameFragment

6.8. CannonView
CannonView ( 6.46.17), View,
Cannon Game .

6.8. CannonView239

6.8.1. package import


6.4 package import CannonView. 6.3 ,
CannonView. 6.4 .
6.4. package import CannonView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

// CannonView.java
// Cannon Game
package com.deitel.cannongame;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.content.Context;
android.content.DialogInterface;
android.graphics.Canvas;
android.graphics.Color;
android.graphics.Paint;
android.graphics.Point;
android.media.AudioManager;
android.media.SoundPool;
android.os.Bundle;
android.util.AttributeSet;
android.util.Log;
android.util.SparseIntArray;
android.view.MotionEvent;
android.view.SurfaceHolder;
android.view.SurfaceView;

6.8.2.
6.5
CannonView. ,
.
6.5. CannonView
25 public class CannonView extends SurfaceView
26
implements SurfaceHolder.Callback
27 {
28
private static final String TAG = "CannonView"; //
29
30
private CannonThread cannonThread; //
31
private Activity activity; // GUI
32
private boolean dialogIsDisplayed = false;
33
34
// ,
35
public static final int TARGET_PIECES = 7; //
36
public static final int MISS_PENALTY = 2; // (.)

240 6 CannonGame
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

public static final int HIT_REWARD = 3; // (.)


//
private boolean gameOver; // ?
private double timeLeft; //
private int shotsFired; //
private double totalElapsedTime; //
//
private Line blocker; //
private int blockerDistance; //
private int blockerBeginning; //
private int blockerEnd; //
private int initialBlockerVelocity; //
private float blockerVelocity; //
private
private
private
private
private
private
private

Line target; //
int targetDistance; //
int targetBeginning; //
double pieceLength; //
int targetEnd; //
int initialTargetVelocity; //
float targetVelocity; //

private int lineWidth; //


private boolean[] hitStates; // ?
private int targetPiecesHit; // ( 7)
//
private Point cannonball; //
private int cannonballVelocityX; //
private int cannonballVelocityY; //
private boolean cannonballOnScreen; // ?
private int cannonballRadius; //
private int cannonballSpeed; //
private int cannonBaseRadius; //
private int cannonLength; //
private Point barrelEnd; //
private int screenWidth;
private int screenHeight;
//
private static final int TARGET_SOUND_ID = 0;
private static final int CANNON_SOUND_ID = 1;
private static final int BLOCKER_SOUND_ID = 2;
private SoundPool soundPool; //
private SparseIntArray soundMap; // SoundPool
//
private Paint
private Paint
private Paint
private Paint
private Paint
private Paint

Paint
textPaint; //
cannonballPaint; //
cannonPaint; //
blockerPaint; //
targetPaint; //
backgroundPaint; //

6.8. CannonView241

6.8.3.
6.6 CannonView. View ,
Context AttributeSet. ,
CannonGameFragment CannonView, ( android.util)
CannonView, XML- . ( 96),
View,
XML- . 97 MainActivity, AlertDialog GUI- .
6.6. CannonView
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

//
public CannonView(Context context, AttributeSet attrs)
{
super(context, attrs); //
activity = (Activity) context; // MainActivity
// SurfaceHolder.Callback
getHolder().addCallback(this);
// Line Point
blocker = new Line(); // blocker Line
target = new Line(); // target Line
cannonball = new Point(); // cannonball Point
// hitStates
hitStates = new boolean[TARGET_PIECES];
// SoundPool
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
// Map
soundMap = new SparseIntArray(3); // SparseIntArray
soundMap.put(TARGET_SOUND_ID,
soundPool.load(context, R.raw.target_hit, 1));
soundMap.put(CANNON_SOUND_ID,
soundPool.load(context, R.raw.cannon_fire, 1));
soundMap.put(BLOCKER_SOUND_ID,
soundPool.load(context, R.raw.blocker_hit, 1));
// Paint , ,
// , ;
// onSizeChanged
textPaint = new Paint();
cannonPaint = new Paint();
cannonballPaint = new Paint();
blockerPaint = new Paint();
targetPaint = new Paint();
backgroundPaint = new Paint();
} // CannonView

242 6 CannonGame
SurfaceHolder.Callback
100 this ( CannonView) , SurfaceHolder.Callback ,
, SurfaceView. SurfaceView
getHolder SurfaceHolder SurfaceView, addCallback SurfaceHolder ,
SurfaceHolder.Callback.
,
103105 (blocker) (target) Line,
(cannonball) Point. hitStates , ( , ).
SoundPool
111120 , . SoundPool ,
, .
, .
, 1.
, . ,
AudioManager, SoundPool

(AudioManager.STREAM_MUSIC). ,
,
( 0).
114 SparseIntArray ( soundMap),
. SparseIntArray
HashMap<Integer,Integer>,
/. (. 6.5, 7981)
, load SoundPool ( 6.6,
116, 118 120).
( ). load SoundPool
(Context) ; ; . ,
, ,
1.
Paint,
124129 Paint,
. onSizeChanged ( 6.8.4),

6.8. CannonView243

Paint
, .

6.8.4. onSizeChanged View


6.7 onSizeChanged
View, View,
View View
. ,
onSizeChanged , onCreate
.
View ( 0).
.
,
. 170175 Paint,
.
177 newGame (. 6.8).
6.7. onSizeChanged
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

// surfaceChanged SurfaceView // , View


@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
screenWidth = w; // CannonView
screenHeight = h; // CannonView
cannonBaseRadius = h / 18; //
// 1/18
cannonLength = w / 8; // 1/8
cannonballRadius = w / 36; // 1/36
cannonballSpeed = w * 3 / 2; //
lineWidth = w / 24; // a 1/24
// ,
blockerDistance = w * 5 / 8; // 5/8
blockerBeginning = h / 8; //
// 1/8
blockerEnd = h * 3 / 8; //
// 3/8
initialBlockerVelocity = h / 2; //
blocker.start = new Point(blockerDistance, blockerBeginning);
blocker.end = new Point(blockerDistance, blockerEnd);
// ,

244 6 CannonGame
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179

targetDistance = w * 7 / 8; // 7/8
targetBeginning = h / 8; //
// 1/8
targetEnd = h * 7 / 8; // - 7/8
pieceLength = (targetEnd - targetBeginning) / TARGET_PIECES;
initialTargetVelocity = -h / 4; //
target.start = new Point(targetDistance, targetBeginning);
target.end = new Point(targetDistance, targetEnd);
//
barrelEnd = new Point(cannonLength, h / 2);
// Paint
textPaint.setTextSize(w / 20); // 1/20
textPaint.setAntiAlias(true); //
cannonPaint.setStrokeWidth(lineWidth * 1.5f); //
blockerPaint.setStrokeWidth(lineWidth); //
targetPaint.setStrokeWidth(lineWidth); //
backgroundPaint.setColor(Color.WHITE); //
newGame(); //
} // onSizeChanged

6.8.5. newGame
newGame (6.8) ,
. gameOver true (
), 203 gameOver, 204205
CannonThread ,
. 6.8.14.
6.8. newGame CannonView
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

//
public void newGame()
{
// hitStates false ( )
for (int i = 0; i < TARGET_PIECES; i++)
hitStates[i] = false;
targetPiecesHit = 0; //
blockerVelocity = initialBlockerVelocity; //
targetVelocity = initialTargetVelocity; //
timeLeft = 10; // 10
cannonballOnScreen = false; //
shotsFired = 0; //
totalElapsedTime = 0.0; //
//
blocker.start.set(blockerDistance, blockerBeginning);
blocker.end.set(blockerDistance, blockerEnd);
target.start.set(targetDistance, targetBeginning);

6.8. CannonView245
199
200
201
202
203
204
205
206
207
208

target.end.set(targetDistance, targetEnd);
if (gameOver) //
{
gameOver = false; //
cannonThread = new CannonThread(getHolder()); //
cannonThread.start(); //
} // if
} // newGame

6.8.6. updatePositions
updatePositions (6.9) run CannonThread
( 6.8.14) .
(),
. ,
,
. 6.8.14.
6.9. updatePositions CannonView
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

// CannonThread
private void updatePositions(double elapsedTimeMS)
{
double interval = elapsedTimeMS / 1000.0; //
if (cannonballOnScreen) //
{
//
cannonball.x += interval * cannonballVelocityX;
cannonball.y += interval * cannonballVelocityY;
//
if (cannonball.x + cannonballRadius > blockerDistance &&
cannonball.x - cannonballRadius < blockerDistance &&
cannonball.y + cannonballRadius > blocker.start.y &&
cannonball.y - cannonballRadius < blocker.end.y)
{
cannonballVelocityX *= -1; //
timeLeft -= MISS_PENALTY; //
//
soundPool.play(soundMap.get(BLOCKER_SOUND_ID), 1, 1, 1, 0, 1f);

}
//
else if (cannonball.x + cannonballRadius > screenWidth ||
cannonball.x - cannonballRadius < 0)
{

246 6 CannonGame
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

cannonballOnScreen = false; //
}
//
else if (cannonball.y + cannonballRadius > screenHeight ||
cannonball.y - cannonballRadius < 0)
{
cannonballOnScreen = false; //
}
//
else if (cannonball.x + cannonballRadius > targetDistance &&
cannonball.x - cannonballRadius < targetDistance &&
cannonball.y + cannonballRadius > target.start.y &&
cannonball.y - cannonballRadius < target.end.y)
{
// (0 - )
int section =
(int) ((cannonball.y - target.start.y) / pieceLength);
// ,
if ((section >= 0 && section < TARGET_PIECES) &&
!hitStates[section])
{
hitStates[section] = true; //
cannonballOnScreen = false; //
timeLeft += HIT_REWARD; //
//
soundPool.play(soundMap.get(TARGET_SOUND_ID), 1,
1, 1, 0, 1f);

//
if (++targetPiecesHit == TARGET_PIECES)
{
cannonThread.setRunning(false); //
showGameOverDialog(R.string.win); //
gameOver = true;
}

//
double blockerUpdate = interval * blockerVelocity;
blocker.start.y += blockerUpdate;
blocker.end.y += blockerUpdate;
//
double targetUpdate = interval * targetVelocity;
target.start.y += targetUpdate;
target.end.y += targetUpdate;
// ,
if (blocker.start.y < 0 || blocker.end.y > screenHeight)
blockerVelocity *= -1;

6.8. CannonView247
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306

// ,
if (target.start.y < 0 || target.end.y > screenHeight)
targetVelocity *= -1;
timeLeft -= interval; //
//
if (timeLeft <= 0.0)
{
timeLeft = 0.0;
gameOver = true; //
cannonThread.setRunning(false); //
showGameOverDialog(R.string.lose); //
}
} // updatePositions


206 , ( ).
.

214 , .
, ,
.
( 217218). 221224 , .
, .
.
x ,

(blockerDistance), 221.
, , ,
.

x ,

( 222). ,
.

, ( 223).
, ( 224).

,
( 226),
( timeLeft MISS_PENALTY), play
soundPool , .
SoundPool soundMap
BLOCKER_SOUND_ID.

248 6 CannonGame

.
233237 , ,
. 233235
.

( 245248).
, .
, ,
. 251252 , , .
0 ( ) 6 (
).
hitStates ( 256).
hitStates true,
. HIT_REWARD
timeLeft, ,
(TARGET_SOUND_ID).
targetPiecesHit, , TARGET_PIECES
( 267). , ; CannonThread setRunning false,
showGameOverDialog , gameOver true.

, ,
. 278280 blockerVelocity , ;
x y. 283285
. ,
1 (
288289). 292293 ,
, , .

timeLeft ,
. timeLeft
, . timeLeft
0.0 ( ,
). gameOver true,
CannonThread setRunning false,
showGameOverDialog ,
.

6.8. CannonView249

6.8.7. fireCannonball CannonView


, (6.8.13) fireCannonball ( 6.10).
, . (
) . 313 alignCannon,
, . 316317
( ),
320 323
. cannonballOnScreen
true, drawGameElements (. 6.12),
shotsFired.
(CANNON_SOUND_ID).
6.10. fireCannonball CannonView
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

//
public void fireCannonball(MotionEvent event)
{
if (cannonballOnScreen) //
return; //
double angle = alignCannon(event); //
//
cannonball.x = cannonballRadius; // x
cannonball.y = screenHeight / 2; //
// x
cannonballVelocityX = (int) (cannonballSpeed * Math.sin(angle));
// y
cannonballVelocityY = (int) (-cannonballSpeed * Math.cos(angle));
cannonballOnScreen = true; //
++shotsFired; // shotsFired
//
soundPool.play(soundMap.get(CANNON_SOUND_ID), 1, 1, 1, 0, 1f);
} // fireCannonball

6.8.8. alignCannon
alignCannon (6.11) . 335
x y MotionEvent,
.
,
( 345).

250 6 CannonGame
, Math.PI ( 349).
cannonLength angle x y
.
.
6.11. alignCannon CannonView
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

//
public double alignCannon(MotionEvent event)
{
//
Point touchPoint = new Point((int) event.getX(), (int) event.getY());
//
// y
double centerMinusY = (screenHeight / 2 - touchPoint.y);
double angle = 0; // angle 0
//
if (centerMinusY != 0) // 0
angle = Math.atan((double) touchPoint.x / centerMinusY);
//
if (touchPoint.y > screenHeight / 2)
angle += Math.PI; //
//
barrelEnd.x = (int) (cannonLength * Math.sin(angle));
barrelEnd.y =
(int) (-cannonLength * Math.cos(angle) + screenHeight / 2);
return angle; //
} // alignCannon

6.8.9. drawGameElements
drawGameElements ( 6.12) , , SurfaceView. Canvas,
CannonThread ( 6.8.14) SurfaceHolder
SurfaceView.
6.12. drawGameElements CannonView
359
360
361
362
363
364

//
public void drawGameElements(Canvas canvas)
{
//
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(),
backgroundPaint);

6.8. CannonView251
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

//
canvas.drawText(getResources().getString(
R.string.time_remaining_format, timeLeft), 30, 50, textPaint);
// ,
if (cannonballOnScreen)
canvas.drawCircle(cannonball.x, cannonball.y, cannonballRadius,
cannonballPaint);
//
canvas.drawLine(0, screenHeight / 2, barrelEnd.x, barrelEnd.y,
cannonPaint);
//
canvas.drawCircle(0, (int) screenHeight / 2,
(int) cannonBaseRadius, cannonPaint);
//
canvas.drawLine(blocker.start.x, blocker.start.y, blocker.end.x,
blocker.end.y, blockerPaint);
Point currentPoint = new Point(); //
// currentPoint
currentPoint.x = target.start.x;
currentPoint.y = target.start.y;
//
for (int i = 0; i < TARGET_PIECES; i++)
{
// ,
if (!hitStates[i])
{
//
if (i % 2 != 0)
targetPaint.setColor(Color.BLUE);
else
targetPaint.setColor(Color.YELLOW);

canvas.drawLine(currentPoint.x, currentPoint.y, target.end.x,


(int) (currentPoint.y + pieceLength), targetPaint);

// currentPoint
currentPoint.y += pieceLength;

}
} // drawGameElements

Canvas drawRect
drawRect Canvas ( 363364), Canvas,
.

252 6 CannonGame
, Paint,
(backgroundPaint
).
drawText Canvas
drawText Canvas ( 367368) .
, x y textPaint (
170171), ( ,
).
drawCircle Canvas
, 372373
drawCircle Canvas .
, . Paint,
.
, drawLine Canvas
drawLine Canvas (376
377), ( 384385) ( 405406).
, Paint,
(, ).
drawCircle Canvas
380381 drawCircle Canvas
. ,
.
SurfaceView.
drawLine Canvas
390411 . , ( ,
). ,
.

6.8.10. showGameOverDialog
showGameOverDialog ( 6.13) DialogFragment (. 5.6.9) AlertDialog,
/,
. setPositiveButton ( 433444)
.

6.8. CannonView253

6.13. showGameOverDialog CannonView


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

// AlertDialog
private void showGameOverDialog(final int messageId)
{
// DialogFragment
final DialogFragment gameResult =
new DialogFragment()
{
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
// messageId
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setTitle(getResources().getString(messageId));
//
builder.setMessage(getResources().getString(
R.string.results_format, shotsFired, totalElapsedTime));
builder.setPositiveButton(R.string.reset_game,
new DialogInterface.OnClickListener()
{
// "Reset Game"
@Override
public void onClick(DialogInterface dialog, int which)
{
dialogIsDisplayed = false;
newGame(); //
}
} //
); // setPositiveButton
return builder.create(); // AlertDialog
} // onCreateDialog
}; // DialogFragment
// UI- FragmentManager DialogFragment
activity.runOnUiThread (
new Runnable() {
public void run()
{
dialogIsDisplayed = true;
gameResult.setCancelable(false); //
gameResult.show(activity.getFragmentManager(), "results");
}
} // Runnable
); // runOnUiThread
} // showGameOverDialog

onClick ,
, newGame .
GUI, 451460

254 6 CannonGame
runOnUiThread Activity Runnable,
GUI . , Runnable.

6.8.11. stopGame releaseResources


onPause onDestroy ( 6.14) CannonGame ( Activity)
stopGame releaseResources CannonView ( 7.19)
. stopGame ( 464468)
onPause Activity (
).
releaseResources ( 471475) release SoundPool, , SoundPool.
6.14. stopGame releaseResources CannonView
463
464
465
466
467
468
469
470
471
472
473
474
475
476

// ; onPause CannonGameFragment
public void stopGame()
{
if (cannonThread != null)
cannonThread.setRunning(false); //
}
// ; onDestroy CannonGame
public void releaseResources()
{
soundPool.release(); // , SoundPool
soundPool = null;
}

6.8.12. SurfaceHolder.Callback
6.15 surfaceChanged, surfaceCreated
surfaceDestroyed SurfaceHolder.Callback. surfaceChanged
, .
SurfaceView
. surfaceCreated (485494)
SurfaceView ,
. surfaceCreated CannonThread,
. surfaceDestroyed ( 497515)
SurfaceView , .
CannonThread. 502
setRunning CannonThread false, ,

6.8. CannonView255

, 504515
. SurfaceView
surfaceDestroyed.
6.15. SurfaceHolder.Callback
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

//
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height)
{
}
//
@Override
public void surfaceCreated(SurfaceHolder holder)
{
if (!dialogIsDisplayed)
{
cannonThread = new CannonThread(holder); //
cannonThread.setRunning(true); //
cannonThread.start(); //
}
}
//
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
//
boolean retry = true;
cannonThread.setRunning(false); // cannonThread
while (retry)
{
try
{
cannonThread.join(); // cannonThread
retry = false;
}
catch (InterruptedException e)
{
Log.e(TAG, "Thread interrupted", e);
}
}
} // surfaceDestroyed

6.8.13. onTouchEvent
onTouchEvent View (6.16)
. MotionEvent
. 523 getAction

256 6 CannonGame
MotionEvent .
526527 , (MotionEvent.
ACTION_DOWN) (MotionEvent.ACTION_MOVE).
529 fireCannonball cannonView
. 532 true , .
6.16. onTouchEvent View
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

//
@Override
public boolean onTouchEvent(MotionEvent e)
{
// ,
int action = e.getAction();
//
if (action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_MOVE)
{
fireCannonball(e); //
}
return true;
} // onTouchEvent

6.8.14. CannonThread:

6.17 Thread,
. SurfaceHolder SurfaceView (
538) , , .
run ( 556587) ( ).
, .
559 ,
. 561586
, threadIsRunning false.
6.17. Runnable,
TIME_INTERVAL
535
536
537
538
539
540

// Thread,
private class CannonThread extends Thread
{
private SurfaceHolder surfaceHolder; // Canvas
private boolean threadIsRunning = true; //

6.8. CannonView257
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

// SurfaceHolder
public CannonThread(SurfaceHolder holder)
{
surfaceHolder = holder;
setName("CannonThread");
}
//
public void setRunning(boolean running)
{
threadIsRunning = running;
}
//
@Override
public void run()
{
Canvas canvas = null; //
long previousFrameTime = System.currentTimeMillis();
while (threadIsRunning)
{
try
{
// Canvas
canvas = surfaceHolder.lockCanvas(null);
// surfaceHolder
synchronized(surfaceHolder)
{
long currentTime = System.currentTimeMillis();
double elapsedTimeMS = currentTime - previousFrameTime;
totalElapsedTime += elapsedTimeMS / 1000.0;
updatePositions(elapsedTimeMS); //
drawGameElements(canvas); //
previousFrameTime = currentTime; //
//
}

577
578
}
579
finally
580
{
581
// Canvas CannonView
582
// Canvas
583
if (canvas != null)
584
surfaceHolder.unlockCanvasAndPost(canvas);
585
}
586
} // while
587
} // run
588
} // CannonThread
589 } // CannonView

Canvas, SurfaceView,
lockCanvas SurfaceHolder ( 566). SurfaceView ,

258 6 CannonGame
SurfaceHolder. (),
. 574
updatePositions, ;
.

. (
),
.
( ),
. ,
575 Canvas SurfaceView,
576 currentTime previousFrameTime
.

6.9.
Cannon Game, 10- .
, .
,
SurfaceView. , XML,
.
Activity: onPause ,
, onDestroy
. onTouchEvent Activity
. res/
raw SoundPool,
AudioManager
.
,
SurfaceView . Thread
run,
Canvas. SurfaceHolder SurfaceView
Canvas, ,
, .
.
7 Doodlz,
Android .
, Android 4.4, .

Doodlz

, Canvas Bitmap, ,
SensorManager, ,
MediaStore, ,

, ,



SensorManager
Paint
Path , Canvas Bitmap

Android 4.4

Android 4.4 Print


Helper Android Support Library

260 7 Doodlz

7.1.
Doodlz
(.7.1). Android 4.4, ,
.

. 7.1. Doodlz

.
Choose Color (. 7.2, ) SeekBar ()
- (), , ,
ARGB (. 1.9).
SeekBar SeekBar
. Choose Line Width,
.7.2,, SeekBar . (. 7.3) (Eraser),
(Clear), (Save)
Android 4.4 .
, .

7.2. 261

, .
1.9, .
AVD,
. [: - Gallery,
,
Doodlz .]

. 7.2. Doodlz:
a ;

. 7.3. Doodlz
Android 4.4

7.2.
,
Doodlz.

262 7 Doodlz

7.2.1. SensorManager

, ,
. Android ,
.
Android , , , , , , ,
, . Sensor, ,
http://developer.android.com/reference/android/hardware/Sensor.html
7.5.
Android
http://developer.android.com/guide/topics/sensors/sensors_overview.html

7.2.2. DialogFragment
( ) AlertDialog
DialogFragment . AlertDialog , ,
, DialogFragment
. AlertDialog
.
DialogFragment.
ColorDialogFragment ( 7.7) AlertDialog

, GUI
ARGB.

LineWidthDialogFragment ( 7.8) AlertDialog -

, GUI
.

EraseImageDialogFragment ( 7.9) AlertDialog

ColorDialogFragment EraseImageDialog
Fragment . DialogFragment
Fragment.
onAttach , -

7.2. 263

onDetach ,



, . , onAttach
onDetach , ,
. , .

7.2.3. Canvas Bitmap


Bitmap ( android.graphics).
Bitmap Canvas, Canvas
Bitmap; (. .7.6). Bitmap

Save.

7.2.4.
Path
,
. Path
( android.graphics), .
onTouchEvent View ( 7.6). MotionEvent
( android.view )
, .
Path.
,
, .

7.2.5. Android 4.4


Android 4.4 (7.6),
, .
Android 4.4 .

264 7 Doodlz

7.2.6. GestureDetector SimpleOnGestureListener


/
GestureDetector ( android.
view). GestureDetector , , ,
GestureDetector.OnGestureListener GestureDetector.
OnDoubleTapListener. GestureDetector.SimpleOnGestureListener
-, ,

. 7.6 GestureDetector SimpleOnGestureListener,
.

7.2.7.
Save . ContentResolver
( android.content) , . ContentResolver (7.6)
insertImage MediaStore.Images.Media
. MediaStore ,
, .

7.2.8. Android 4.4 PrintHelper


Android Support Library
Android 4.4 . PrintHelper
( 7.6) .
PrintHelper , ,
Bitmap . PrintHelper Android Support Library
,
Android. (, PrintHelper) Android.

7.3.

,
Doodlz.

7.3. 265

7.3.1.
Android Doodlz.
New Android Project , Finish.
Application name: Doodlz
Project Name: Doodlz
Package Name: com.deitel.doodlz
Minimum Required SDK: API18: Android 4.3
Target SDK: API19: Android 4.4
Compile With: API19: Android 4.4
Theme: Holo Light with Dark Action Bar

New Android Project (New Android Application)


Next >. Configure Launcher Icon
Next >. Create Activity Blank Activity, Next >. Blank Activity
Finish, . Nexus 4
TextView Hello world!.

Android Support Library. , Android Support Library .

http://developer.android.com/tools/support-library/index.html
http://developer.android.com/tools/support-library/setup.html

7.3.2. strings.xml
,

(. 7.1). strings.xml res/values,
.
7.1. , Doodlz

app_name

Doodlz

button_erase

Erase Image

button_cancel

Cancel

266 7 Doodlz
7.1 ()

button_set_color

Set Color

button_set_line_width

Set Line Width

line_imageview_description

This displays the line thickness

label_alpha

Alpha

label_red

Red

label_green

Green

label_blue

Blue

menuitem_clear

Clear

menuitem_color

Color

menuitem_eraser

Eraser

menuitem_line_width

Line Width

menuitem_save

Save

menuitem_print

Print

message_erase

Erase the drawing?

message_error_saving

There was an error saving the image

message_saved

Your painting has been saved to the Gallery

message_error_printing

Your device does not support printing

title_color_dialog

Choose Color

title_line_width_dialog

Choose Line Width

7.3.3. dimens.xml
.7.2 ,
dimens.xml. dimens.xml res/values,
. line_imageview_height ImageView LineWidthDialogFragment,
color_view_height View
ColorDialogFragment.
7.2. , Doodlz

line_imageview_height

50dp

color_view_height

80dp

7.3. 267

7.3.4. DoodleFragment
5 Settings Flag Quiz , .
, main.xml
res/menu . DoodleFragment.
Android
DoodleFragment Android4.3
Android 4.4 .
Android 4.4 , Print
. res/menu,
res/menu-v19 (19 Android API, Android4.4).
Android res/menu-v19
Android 4.4 . res/menu-v19,
res, NewFolder,
menu-v19 Finish.
Android 4.3
Android 4.3 ,
.
1. res/menu New
Android XML File.
2. doodle_fragment_menu.xml
Finish. .
3. Add, Layout ,
Item OK.
.
4. Id @+id/color, Title @string/
menuitem_color, Show as action ifRoom. ifRoom
,
;
. Show as
action
http://developer.android.com/guide/topics/resources/menu-resource.html
5. 3 4 lineWidth, eraser, clear save (.7.3). : Add
, Create a new element at the top level in Menu.
6. doodle_fragment_menu.xml.

268 7 Doodlz
7.3. DoodleFragment

@+id/lineWidth

@string/menuitem_line_width

@+id/eraser

@string/menuitem_eraser

@+id/clear

@string/menuitem_clear

@+id/save

@string/menuitem_save

Android 4.4
Android 4.4 , .
1. doodle_fragment_menu.xml res/menu,
res/menu-v19 .
2. Add, Create a new element at the
top level in Menu, Item OK.
3. Id @+id/print, Title @string/menuitem_print, Show as action ifRoom.

7.3.5. activity_main.xml MainActivity


activity_main.xml MainActivity
DoodleFragment. ,
.
1. activity_main.xml .
2. Fragment Layouts
RelativeLayout Outline.
3. Choose Fragment Class. Create New,
New Java Class.
4. Name DoodleFragment
Superclass android.app.Fragment. Finish,
. Java,
.
5. (Id) @+id/doodleFragment
.

7.3. 269

7.3.6. fragment_doodle.xml
DoodleFragment
fragment_doodle.xml DoodleFragment
FrameLayout, DoodleView.
DoodleFragment DoodleView. fragment_
doodle.xml, .
1. res/layout Package Explorer.
2. res/layout
NewAndroid XML File. New Android XML File.
3. File fragment_doodle.xml.
4. Root Element FrameLayout Finish.
5. Advanced view ( v)
.
6. Choose Custom View Class. Create
New, New Java Class.
7. Name DoodleView. , Constructors
from superclass , Finish. DoodleView.java.
, .
DoodleView.java.
8. fragment_doodle.xml view1 Outline.
Layout Parameters Properties Width Height match_
parent.
9. Outline view1,
Edit ID, view1 doodleView OK.
10. fragment_doodle.xml.

7.3.7. fragment_color.xml
ColorDialogFragment
fragment_color.xml ColorDialogFragment
GridLayout
. ColorDialogFragment
ColorDialogFragment. fragment_color.xml,
.

270 7 Doodlz
1. res/layout Package Explorer.
2. res/layout New
Android XML File. New Android XML File.
3. File fragment_color.xml.
4. Root Element GridLayout Finish.
5. Outline GridLayout
Id @+id/colorDialogGridLayout.
6. , TextView,
SeekBar View colorDialogGridLayout Outline.
.7.4;
.

. 7.4. Outline fragment_color.xml

7. 6 GUI
.7.4. fragment_color.xml.
7.4. GUI fragment_color.xml

colorDialogGridLayout

Column Count
Orientation
Use Default Margins

2
vertical
true

alphaTextView

Layout Parameters
Column
Gravity
Row
Other Properties
Text

alphaSeekBar

Layout Parameters
Column
Gravity
Row
Other Properties
Max

0
right|center_vertical
0
@string/label_alpha
1
fill_horizontal
0
255

7.3. 271

redTextView

Layout Parameters
Column
Gravity
Row
Other Properties
Text

redSeekBar

greenTextView

greenSeekBar

blueTextView

blueSeekBar

colorView

Layout Parameters
Column
Gravity
Row
Other Properties
Max
Layout Parameters
Column
Gravity
Row
Other Properties
Text
Layout Parameters
Column
Gravity
Row
Other Properties
Max
Layout Parameters
Column
Gravity
Row
Other Properties
Text
Layout Parameters
Column
Gravity
Row
Other Properties
Max
Layout Parameters
Height
Column
Column Span
Gravity

0
right|center_vertical
1
@string/label_red
1
fill_horizontal
1
255
0
right|center_vertical
2
@string/label_red
1
fill_horizontal
2
255
0
right|center_vertical
3
@string/label_red
1
fill_horizontal
3
255
@dimen/color_view_height
0
2
fill_horizontal

272 7 Doodlz
ColorDialogFragment
ColorDialogFragment , .
1. com.deitel.doodlz src NewClass. New Java Class.
2. Name ColorDialogFragment.
3. Superclass android.app.DialogFragment.
4. Finish, .

7.3.8. fragment_line_width.xml
LineWidthDialogFragment
fragment_line_width.xml LineWidthDialogFragment GridLayout
. LineWidthDialogFragment
LineWidthDialogFragment. fragment_line_width.xml,
.
1. res/layout Package Explorer.
2. layout NewAndroid
XML File. New Android XML File.
3. File fragment_line_width.xml.
4. Root Element GridLayout Finish.
5. Outline GridLayout Id @+id/lineWidthDialogGridLayout.
6. , ImageView
SeekBar lineWidthDialogGridLayout Outline. , . 7.5. .

. 7.5. Outline
fragment_line_width.xml

7. 6 GUI
.7.5. fragment_line_width.xml.

7.3. 273

7.5. GUI fragment_line_width.xml

lineWidthDialogGridLayout

Column Count
Orientation
Use Default Margins

1
vertical
true

widthImageView

Layout Parameters
Height
Gravity
Other Properties
Content Description

widthSeekBar

Layout Parameters
Gravity
Other Properties
Max

@dimen/line_imageview_height
fill_horizontal
@string/line_imageview_description
fill_horizontal
50

LineWidthDialogFragment
LineWidthDialogFragment ,
.
1. com.deitel.doodlz src
NewClass. New
Java Class.
2. Name LineWidthDialogFragment.
3. Superclass android.app.DialogFragment.
4. Finish, .

7.3.9. EraseImageDialogFragment
EraseImageDialogFragment ,
AlertDialog . EraseImageDialog
Fragment, .
1. com.deitel.doodlz src
NewClass. New Java
Class.
2. Name EraseImageDialogFragment.
3. Superclass android.app.DialogFragment.
4. Finish, .

274 7 Doodlz

7.4. MainActivity
.
MainActivity (7.1)

DoodleFragment ( 7.5) DoodleView -

DoodleView ( 7.6) , -

ColorDialogFragment (7.7) DialogFragment,

COLOR .

LineWidthDialogFragment ( 7.8) DialogFragment,

LINE WIDTH .

EraseImageDialogFragment ( 7.9) DialogFragment,

CLEAR
.

onCreate MainActivity (7.1) ( 16), , 5.2.2,


MainActivity.
( 24), ( 2526);
(2829).
7.1. MainActivity
1 // MainActivity.java
2 // MainActivity
3 package com.deitel.doodlz;
4
5 import android.app.Activity;
6 import android.content.pm.ActivityInfo;
7 import android.content.res.Configuration;
8 import android.os.Bundle;
9
10 public class MainActivity extends Activity
11 {
12
@Override
13
protected void onCreate(Bundle savedInstanceState)
14
{
15
super.onCreate(savedInstanceState);
16
setContentView(R.layout.activity_main);
17
18
//
19
int screenSize =
20
getResources().getConfiguration().screenLayout &

7.5. DoodleFragment275
21
Configuration.SCREENLAYOUT_SIZE_MASK;
22
// ,
23
// .
24
if (screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE)
25
setRequestedOrientation(
26
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
27
else
28
setRequestedOrientation(
29
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
30
}
31 } // MainActivity

7.5. DoodleFragment
DoodleFragment (7.27.9) DoodleView ( 7.6), ,
.
package, import
7.2 ,
DoodleFragment. 7.2.
doodleView DoodleView ( 22) . , 2325,
(
, ). 29 ,
,
. 26 , false;
. ,
, Choose
Color, .
7.2. DoodleFragment: package, import
1
2
3
4
5
6
7
8
9
10
11
12

// DoodleFragment.java
// , DoodleView
package com.deitel.doodlz;
import
import
import
import
import
import
import
import

android.app.Fragment;
android.content.Context;
android.graphics.Color;
android.hardware.Sensor;
android.hardware.SensorEvent;
android.hardware.SensorEventListener;
android.hardware.SensorManager;
android.os.Bundle;

276 7 Doodlz
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

import
import
import
import
import
import

android.view.LayoutInflater;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
android.view.View;
android.view.ViewGroup;

public class DoodleFragment extends Fragment


{
private DoodleView doodleView; //
private float acceleration;
private float currentAcceleration;
private float lastAcceleration;
private boolean dialogOnScreen = false;
//
private static final int ACCELERATION_THRESHOLD = 100000;

onCreateView
onCreateView (7.3) DoodleFragment
. , ,
.
setHasOptionsMenu true. ,
(
).
7.3. onCreateView
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

//
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
View view =
inflater.inflate(R.layout.fragment_doodle, container, false);
setHasOptionsMenu(true); //
// DoodleView
doodleView = (DoodleView) view.findViewById(R.id.doodleView);

//
acceleration = 0.00f;
currentAcceleration = SensorManager.GRAVITY_EARTH;
lastAcceleration = SensorManager.GRAVITY_EARTH;
return view;

7.5. DoodleFragment277

43 DoodleView, 4648 ,
, . currentAcceleration lastAcceleration
GRAVITY_EARTH SensorManager, ,
. SensorManager
;

http://developer.android.com/reference/android/hardware/SensorManager.html
onStart enableAccelerometerListening
, DoodleFragment .
onStart ( 7.4, 5358),
enableAccelerometerListening (6172)
. SensorManager
.
7.4. onStart enableAccelerometerListening
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

//
@Override
public void onStart()
{
super.onStart();
enableAccelerometerListening(); //
}
//
public void enableAccelerometerListening()
{
// SensorManager
SensorManager sensorManager =
(SensorManager) getActivity().getSystemService(
Context.SENSOR_SERVICE);

//
sensorManager.registerListener(sensorEventListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);

enableAccelerometerListening getSystemService
SensorManager, . 6971
,
registerListener SensorManager, :

278 7 Doodlz
SensorEventListener, ( -

7.6).

Sensor, , -

, getDefaultSensor
SensorManager (Sensor.TYPE_ACCELEROMETER
).

. SENSOR_DELAY_

NORMAL

, .

onPause disableAccelerometerListening
,
DoodleFragment , onPause ( 7.5; 7580),
disableAccelerometerListening ( 8393). disableAccelerometerListening
unregisterListener SensorManager .
7.5. enableAccelerometerListening disableAccelerometerListening
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

//
@Override
public void onPause()
{
super.onPause();
disableAccelerometerListening(); //
}
//
//
public void disableAccelerometerListening()
{
// SensorManager
SensorManager sensorManager =
(SensorManager) getActivity().getSystemService(
Context.SENSOR_SERVICE);

//
sensorManager.unregisterListener(sensorEventListener,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER));

, SensorEventListener

7.6 onSensorChanged SensorEventListener
( 100125), .
,

7.5. DoodleFragment279

. ,
123 confirmErase ( 7.7),
EraseImageDialogFragment ( 7.9)
. SensorEventListener onAccuracyChanged
( 128131). ,
.
7.6. ,
SensorEventListener
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

//
private SensorEventListener sensorEventListener =
new SensorEventListener()
{
//
@Override
public void onSensorChanged(SensorEvent event)
{
//
if (!dialogOnScreen)
{
// x, y z SensorEvent
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
//
lastAcceleration = currentAcceleration;
//
currentAcceleration = x * x + y * y + z * z;
//
acceleration = currentAcceleration *
(currentAcceleration - lastAcceleration);
//
if (acceleration > ACCELERATION_THRESHOLD)
confirmErase();

}
} // onSensorChanged

// SensorEventListener
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}
}; //

,
. onSensorChanged
, ( 104).

280 7 Doodlz
,
, .
.
SensorEvent
.
,
( /2) x (/), y (/) z (/
). , API SensorEvent,
:
developer.android.com/reference/android/hardware/SensorEvent.html
x, y z SensorEvent
.
107109. (
), . currentAcceleration 112.
115 x, y z,
currentAcceleration. currentAcceleration
lastAcceleration acceleration, ACCELERATION_THRESHOLD. , ,

. confirmErase.
confirmErase
confirmErase ( 7.7) EraseImageDialogFragment
( 7.9) show DialogFragment .
7.7. confirmErase EraseImageDialogFragment
134
135
136
137
138
139
140

//
private void confirmErase()
{
EraseImageDialogFragment fragment = new EraseImageDialogFragment();
fragment.show(getFragmentManager(), "erase dialog");
}

onCreateOptionsMenu onOptionsItemSelected
7.8 onCreateOptionsMenu Fragment
( 142147), Menu
MenuInflater . ,
onOptionsItemSelected ( 150180) .

7.5. DoodleFragment281

7.8. onCreateOptionsMenu
onOptionsItemSelected
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

//
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.doodle_fragment_menu, menu);
}
//
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// MenuItem
switch (item.getItemId())
{
case R.id.color:
ColorDialogFragment colorDialog = new ColorDialogFragment();
colorDialog.show(getFragmentManager(), "color dialog");
return true; //
case R.id.lineWidth:
LineWidthDialogFragment widthdialog =
new LineWidthDialogFragment();
widthdialog.show(getFragmentManager(), "line width dialog");
return true; //
case R.id.eraser:
doodleView.setDrawingColor(Color.WHITE); //
return true; //
case R.id.clear:
confirmErase(); //
return true; //
case R.id.save:
doodleView.saveImage(); //
return true; //
case R.id.print:
doodleView.printImage(); //
return true; //
} // switch
return super.onOptionsItemSelected(item); //
} // onOptionsItemSelected

getItemID MenuItem ( 154) ,


. .
R . i d . c o l o r 157158
ColorDialogFragment (7.7),

282 7 Doodlz
R.id.lineWidth 161163

LineWidthDialogFragment (7.8), -

R.id.eraser 166 doodleView ,

R.id.clear 169 confirmErase ( 7.7),

EraseImageDialogFragment ( 7.9) .

R.id.save 172 doodleView


saveImage, .

R.id.print 175 doodleView

printImage, PDF

getDoodleView setDialogOnScreen
getDoodleView setDialogOnScreen (7.9) DialogFragment, . getDoodleView
DoodleView ,
DialogFragment .
setDialogOnScreen
DialogFragment ; .
7.9. getDoodleView setDialogOnScreen
182
183
184
185
186
187
188
189
190
191
192
193 }

// DoodleView
public DoodleView getDoodleView()
{
return doodleView;
}
//
public void setDialogOnScreen(boolean visible)
{
dialogOnScreen = visible;
}

7.6. DoodleView
DoodleView (7.107.23)
.

7.6. DoodleView283

package import
7.10 package import, DoodleView.
.
7.2,
DoodleView.
7.10. package import DoodleView
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

// DoodleView.java
// Doodlz.
package com.deitel.doodlz;
import java.util.HashMap;
import java.util.Map;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import

android.content.Context;
android.graphics.Bitmap;
android.graphics.Canvas;
android.graphics.Color;
android.graphics.Paint;
android.graphics.Path;
android.graphics.Point;
android.os.Build;
android.provider.MediaStore;
android.support.v4.print.PrintHelper;
android.util.AttributeSet;
android.view.GestureDetector;
android.view.GestureDetector.SimpleOnGestureListener;
android.view.Gravity;
android.view.MotionEvent;
android.view.View;
android.widget.Toast;

DoodleView
DoodleView ( 7.11, 3043) , ,
. 38 pathMap,
( ) c Path .
3940 previousPointMap,
, .
DoodleView.
7.11.
DoodleView
26 // ,
27 public class DoodleView extends View
28 {

284 7 Doodlz
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

// ,
private static final float TOUCH_TOLERANCE = 10;
private
private
private
private

Bitmap bitmap; //
Canvas bitmapCanvas; // Bitmap
final Paint paintScreen; // Bitmap
final Paint paintLine; // Bitmap

// Path
private final Map<Integer, Path> pathMap = new HashMap<Integer, Path>();
private final Map<Integer, Point> previousPointMap =
new HashMap<Integer, Point>();
// /
private GestureDetector singleTapDetector;

doodleview
(7.12)
Map 7.11.
49 paintScreen Paint,
, 52 paintLine Paint, , .
paintLine 5357. setAntiAlias Paint
true .
, setStyle Paint Paint Paint.
Style.STROKE. STROKE, FILL FILL_AND_STROKE,
,
. , Paint.Style.FILL.
setStrokeWidth Paint. 5 .
setStrokeCap Paint (Paint.
Cap.ROUND). 6061 GestureDetector,
singleTapListener .
7.12. DoodleView
45
46
47
48
49
50
51
52
53
54
55
56
57

// DoodleView DoodleView
public DoodleView(Context context, AttributeSet attrs)
{
super(context, attrs); // View
paintScreen = new Paint(); //
//
paintLine = new Paint();
paintLine.setAntiAlias(true); //
paintLine.setColor(Color.BLACK); //
paintLine.setStyle(Paint.Style.STROKE); //
paintLine.setStrokeWidth(5); //
paintLine.setStrokeCap(Paint.Cap.ROUND); //

7.6. DoodleView285
58
59
60
61
62
63

// GestureDetector
singleTapDetector =
new GestureDetector(getContext(), singleTapListener);

onSizeChanged
DoodleView , MainActivity; ,
Bitmap, , onCreate .
onSizeChanged View (7.13),
DoodleView , .
onSizeChanged
Doodlz,

.
7.13. onSizeChanged
64
65
66
67
68
69
70
71
72
73

// onSizeChanged Bitmap Canvas


@Override
public void onSizeChanged(int w, int h, int oldW, int oldH)
{
bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
Bitmap.Config.ARGB_8888);
bitmapCanvas = new Canvas(bitmap);
bitmap.eraseColor(Color.WHITE); // Bitmap
}

createBitmap Bitmap Bitmap


Bitmap
DoodleView. createBitmap Bitmap, , Bitmap. Bitmap.
Config.ARGB_8888 , (
-, , ).
Canvas,
Bitmap. , eraseColor Bitmap Bitmap
( Bitmap ).
clear, setDrawingColor, getDrawingColor, setLineWidth getLineWidth
7.14 clear ( 7581), setDrawingColor
( 8487), getDrawingColor ( 9093), setLineWidth ( 9699)
getLineWidth ( 102105) DoodleView, DoodleFragment.
clear, EraseImageDialogFragment, pathMap
previousPointMap, Bitmap, ,

286 7 Doodlz
View invalidate, View. ,
onDraw View. setDrawingColor
, paintLine. setColor Paint
int, ARGB. getDrawingColor
, ColorDialogFragment.
setLineWidth paintLine . getLineWidth , LineWidthDialogFragment.
7.14. clear, setDrawingColor, getDrawingColor, setLineWidth
getLineWidth DoodleView
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

//
public void clear()
{
pathMap.clear(); //
previousPointMap.clear(); //
bitmap.eraseColor(Color.WHITE); //
invalidate(); //
}
//
public void setDrawingColor(int color)
{
paintLine.setColor(color);
}
//
public int getDrawingColor()
{
return paintLine.getColor();
}
//
public void setLineWidth(int width)
{
paintLine.setStrokeWidth(width);
}
//
public int getLineWidth()
{
return (int) paintLine.getStrokeWidth();
}

onDraw
, onDraw. 7.15 onDraw Bitmap ( ) DoodleView, drawBitmap
Canvas. Bitmap,

7.6. DoodleView287

x y Bitmap , Paint
. 115116
Path .
pathMap Path drawPath Canvas
paintLine,
.
7.15. onDraw View
107
108
109
110
111
112
113
114
115
116
117
118

//
@Override
protected void onDraw(Canvas canvas)
{
//
canvas.drawBitmap(bitmap, 0, 0, paintScreen);

//
for (Integer key : pathMap.keySet())
canvas.drawPath(pathMap.get(key), paintLine); //

hideSystemBars showSystemBars DoodleView


, Android
4.4, .
, SimplyOnGestureListener GestureDetector (7.17)
, . , hideSystemBars (7.16, 120
130); showSystemBars (7.16,
133140).
Android 4.4. , , Android (Build.VERSION_SDK_INT) Android 4.4 (API 19) Build.VERSION_CODES_KITKAT.
setSystemUiVisibility View
. , setSystemUiVisibility , (|), 124129.
, setSystemUiVisibility
137139. View , DoodleView
.
DoodleView DoodleView ,
. View.SYSTEM_UI_FLAG_IMMERSIVE
Android4.4.

http://developer.android.com/training/system-ui/immersive.html

288 7 Doodlz
7.16. hideSystemBars showSystemBars DoodleView
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

//
public void hideSystemBars()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_IMMERSIVE);
}
//
public void showSystemBars()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}

,
SimpleOnGestureListener
7.17 SimpleOnGestureListener
singleTapListener, 6061 ( 7.4) GestureDetector. , SimpleOnGestureListener -,
OnGestureListener OnDoubleTapListener.
false , . onSingleTap (146155),
. ,
( 149150), getSystemUiVisibilty View
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION.
0, , hideSystemBars;
showSystemBars. true ,
.
7.17. ,
SimpleOnGestureListener
142
143
144
145
146

// create SimpleOnGestureListener for single tap events


private SimpleOnGestureListener singleTapListener =
new SimpleOnGestureListener()
{
@Override

7.6. DoodleView289
147
148
149
150
151
152
153
154
155
156
157

};

public boolean onSingleTapUp(MotionEvent e)


{
if ((getSystemUiVisibility() &
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
hideSystemBars();
else
showSystemBars();
return true;
}

onTouchEvent View
onTouchEvent (7.18) . Android ,
. .
,
. Path,
, . Path
pathMap.
7.18. onTouchEvent View
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

//
@Override
public boolean onTouchEvent(MotionEvent event)
{
// ,
// KitKat
if (singleTapDetector.onTouchEvent(event))
return true;
int action = event.getActionMasked(); //
int actionIndex = event.getActionIndex(); // ()
// , : ,
// ,
if (action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_POINTER_DOWN)
{
touchStarted( event.getX(actionIndex), event.getY(actionIndex),
event.getPointerId(actionIndex));
}
else if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_POINTER_UP)
{
touchEnded(event.getPointerId(actionIndex));
}
else
{
touchMoved(event);

290 7 Doodlz
185
186
187
188
189
190

}
invalidate(); //
return true;
} // onTouchEvent

, 164 onTouchEvent singleTapDetector (GestureDetector) ,


.
.
getActionMasked ( 167) MotionEvent int
MotionEvent,
MotionEvent , . getActionIndex ( 168) MotionEvent , .
,
MotionEvent .
,
MotionEvent , ,
getPointerID (175 180) MotionEvent;
.
MotionEvent.ACTION_DOWN MotionEvent.ACTION_POINTER_
DOWN (171172), .
, , MotionEvent.ACTION_DOWN,
MotionEvent.ACTION_POINTER_DOWN.
touchStarted ( 7.19) . MotionEvent.ACTION_UP
MotionEvent.ACTION_POINTER_UP, ,
touchEnded (7.21)
Path .
touchMoved (7.20) .
187 View invalidate ,
188 true , .
touchStarted DoodleView
touchStarted (7.19)
.
. Path (198), reset Path
, Path .
Path, pathMap, Point previousPointMap. 213215 moveTo Path Path x y
Point.

7.6. DoodleView291

7.19. touchStarted DoodleView


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

//
private void touchStarted(float x, float y, int lineID)
{
Path path; //
Point point; //
// lineID Path
if (pathMap.containsKey(lineID))
{
path = pathMap.get(lineID); // Path
path.reset(); // Path
point = previousPointMap.get(lineID); // Path
}
else
{
path = new Path();
pathMap.put(lineID, path); // Path Map
point = new Point(); // Point
previousPointMap.put(lineID, point); // Point Map
}
//
path.moveTo(x, y);
point.x = (int) x;
point.y = (int) y;
} // touchStarted

touchMoved DoodleView
touchMoved ( 7.20)
. MotionEvent, onTouchEvent,
,
. getPointerCount MotionEvent (222)
, MotionEvent.
pointerID ( 225),
MotionEvent (226) pointerIndex.
Path pathMap (229).
, getX getY MotionEvent
pointerIndex. Path Point
pointerID HashMap,
Path
, TOUCH_TOLERANCE.
,
MotionEvent ,
.
, TOUCH_TOLERANCE, quadTo
Path ( 248249) (

292 7 Doodlz
) ,
.
7.20. touchMoved DoodleView
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

//
private void touchMoved(MotionEvent event)
{
// () MotionEvent
for (int i = 0; i < event.getPointerCount() ; i++)
{
//
int pointerID = event.getPointerId(i);
int pointerIndex = event.findPointerIndex(pointerID);
// Path,
if (pathMap.containsKey(pointerID))
{
//
float newX = event.getX(pointerIndex);
float newY = event.getY(pointerIndex);
// Path Point,
//
Path path = pathMap.get(pointerID);
Point point = previousPointMap.get(pointerID);
//
float deltaX = Math.abs(newX - point.x);
float deltaY = Math.abs(newY - point.y);
//
if (deltaX >= TOUCH_TOLERANCE || deltaY >= TOUCH_TOLERANCE)
{
//
path.quadTo(point.x, point.y, (newX + point.x) / 2,
(newY + point.y) / 2);

//
point.x = (int) newX;
point.y = (int) newY;

}
} // touchMoved

touchEnded DoodleView
touchEnded ( 7.21) ,
. (lineID),
. 262
Path. 263 drawPath bitmapCanvas Path

7.6. DoodleView293

Bitmap bitmap Path. Path


,
bitmap, . ,
, bitmap.
7.21. touchEnded DoodleView
259
260
261
262
263
264
265
266

//
private void touchEnded(int lineID)
{
Path path = pathMap.get(lineID); // Path
bitmapCanvas.drawPath(path, paintLine); // bitmapCanvas
path.reset(); // Path
}

saveImage DoodleView
saveImage (7.22) ,
. 271 ,
274276 , insertImage
MediaStore.Images.Media. :
ContentResolver,

Bitmap ;
;
.

insertImage ,
, null, . 278295
, , Toast.
7.22. saveImage DoodleView
267
268
269
270
271
272
273
274
275
276
277
278
279
280

//
public void saveImage()
{
// "Doodlz"
String name = "Doodlz" + System.currentTimeMillis() + ".jpg";
//
String location = MediaStore.Images.Media.insertImage(
getContext().getContentResolver(), bitmap, name,
Doodlz Drawing);
if (location != null) //
{
//

294 7 Doodlz
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297

Toast message = Toast.makeText(getContext(),


R.string.message_saved, Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER, message.getXOffset() / 2,
message.getYOffset() / 2);
message.show();

}
else
{
//
Toast message = Toast.makeText(getContext(),
R.string.message_error_saving, Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER, message.getXOffset() / 2,
message.getYOffset() / 2);
message.show();
}
} // saveImage

printImage DoodleView
Android 4.4 printImage (7.23)
PrintHelper Android Support Library .
301 , .
, 304 PrintHelper. 307 PrintHelper.
SCALE_MODE_FIT ,
. PrintHelper.SCALE_
MODE_FILL, (,
). , 308 printBitmap PrintHelper,
( ) Bitmap .
Android,
PDF .
7.23. printImage DoodleView
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313

//
public void printImage()
{
if (PrintHelper.systemSupportsPrint())
{
// PrintHelper
PrintHelper printHelper = new PrintHelper(getContext());
//
printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT);
printHelper.printBitmap(Doodlz Image, bitmap);

}
else
{
// ,
Toast message = Toast.makeText(getContext(),

7.7. ColorDialogFragment295
314
R.string.message_error_printing, Toast.LENGTH_SHORT);
315
message.setGravity(Gravity.CENTER, message.getXOffset() / 2,
316
message.getYOffset() / 2);
317
message.show();
318
}
319
}
320 } // DoodleView

7.7. ColorDialogFragment
ColorDialogFragment ( 7.247.28) DialogFragment AlertDialog, .
( 1924)
, ,
32- int, ARGB.
7.24. package, import
ColorDialogFragment
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

// ColorDialogFragment.java
// DoodleView
package com.deitel.doodlz;
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.content.DialogInterface;
android.graphics.Color;
android.os.Bundle;
android.view.View;
android.widget.SeekBar;
android.widget.SeekBar.OnSeekBarChangeListener;

//
public class ColorDialogFragment extends DialogFragment
{
private SeekBar alphaSeekBar;
private SeekBar redSeekBar;
private SeekBar greenSeekBar;
private SeekBar blueSeekBar;
private View colorView;
private int color;

onCreateDialog DialogFragment
onCreateDialog (7.25)
(3234), fragment_color.xml

296 7 Doodlz
, AlertDialog,
setView AlertDialog.Builder ( 35). 4250
SeekBar colorView . 5356
colorChangedListener ( 7.28)
SeekBar.
7.25. onCreateDialog DialogFragment
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

// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
View colorDialogView =
getActivity().getLayoutInflater().inflate(
R.layout.fragment_color, null);
builder.setView(colorDialogView); // GUI
// AlertDialog
builder.setTitle(R.string.title_color_dialog);
builder.setCancelable(true);
// SeekBar onChange
alphaSeekBar = (SeekBar) colorDialogView.findViewById(
R.id.alphaSeekBar);
redSeekBar = (SeekBar) colorDialogView.findViewById(
R.id.redSeekBar);
greenSeekBar = (SeekBar) colorDialogView.findViewById(
R.id.greenSeekBar);
blueSeekBar = (SeekBar) colorDialogView.findViewById(
R.id.blueSeekBar);
colorView = colorDialogView.findViewById(R.id.colorView);
// SeekBar
alphaSeekBar.setOnSeekBarChangeListener(colorChangedListener);
redSeekBar.setOnSeekBarChangeListener(colorChangedListener);
greenSeekBar.setOnSeekBarChangeListener(colorChangedListener);
blueSeekBar.setOnSeekBarChangeListener(colorChangedListener);
// SeekBar
final DoodleView doodleView = getDoodleFragment().getDoodleView();
color = doodleView.getDrawingColor();
alphaSeekBar.setProgress(Color.alpha(color));
redSeekBar.setProgress(Color.red(color));
greenSeekBar.setProgress(Color.green(color));
blueSeekBar.setProgress(Color.blue(color));
//
builder.setPositiveButton(R.string.button_set_color,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{

7.7. ColorDialogFragment297
72
73
74
75
76
77
78
79

doodleView.setDrawingColor(color);

}
); // setPositiveButton
return builder.create(); //
} // onCreateDialog

59 getDoodleFragment (7.26) DoodleFragment, getDoodleView


DoodleFragment DoodleView. 6064
DoodleView,
SeekBar. alpha, red, green blue Color
ARGB, setProgress SeekBar
. 6775 AlertDialog
DoodleView. 77 AlertDialog
.
getDoodleFragment
getDoodleFragment (7.26) FragmentManager
DoodleFragment.
7.26. getDoodleFragment
80
81
82
83
84
85
86

// DoodleFragment
private DoodleFragment getDoodleFragment()
{
return (DoodleFragment) getFragmentManager().findFragmentById(
R.id.doodleFragment);
}

onAttach onDetach
ColorDialogFragment
onAttach ( 7.27, 8896). 92 DoodleFragment.
null, 95 setDialogOnScreen
DoodleFragment Choose
Color. ColorDialogFragment
onDetach ( 99107). 106 setDialogOnScreen
DoodleFragment, , Choose Color
.
7.27.  onAttach onDetach

87
88

// DoodleFragment,
@Override

298 7 Doodlz
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

public void onAttach(Activity activity)


{
super.onAttach(activity);
DoodleFragment fragment = getDoodleFragment();
if (fragment != null)
fragment.setDialogOnScreen(true);

// DoodleFragment,
@Override
public void onDetach()
{
super.onDetach();
DoodleFragment fragment = getDoodleFragment();

if (fragment != null)
fragment.setDialogOnScreen(false);

,
OnSeekBarChangeListener SeekBar
7.28 , OnSeekBarChangeListener ,
SeekBar Choose Color. SeekBar 7.25 (5356). onProgressChanged
(115123) SeekBar.
SeekBar (118),
119121. argb Color
SeekBar Color int.
setBackgroundColor View colorView , SeekBar.
7.28.  ,
OnSeekBarChangeListener
SeekBar
109
110
111
112
113
114
115
116
117
118
119
120
121

// OnSeekBarChangeListener SeekBar
private OnSeekBarChangeListener colorChangedListener =
new OnSeekBarChangeListener()
{
//
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser)
{
if (fromUser) // SeekBar ( )
color = Color.argb(alphaSeekBar.getProgress(),
redSeekBar.getProgress(), greenSeekBar.getProgress(),
blueSeekBar.getProgress());

7.8. LineWidthDialogFragment299
122
colorView.setBackgroundColor(color);
123
}
124
125
@Override
126
public void onStartTrackingTouch(SeekBar seekBar) //
127
{
128
}
129
130
@Override
131
public void onStopTrackingTouch(SeekBar seekBar) //
132
{
133
}
134
}; // colorChanged
135 } // ColorDialogFragment

7.8. LineWidthDialogFragment
LineWidthDialogFragment ( 7.29) DialogFragment
AlertDialog, .
ColorDialogFragment,
. ImageView (22),
.
7.29. LineWidthDialogFragment
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

// LineWidthDialogFragment.java
// DoodleView
package com.deitel.doodlz;
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.content.DialogInterface;
android.graphics.Bitmap;
android.graphics.Canvas;
android.graphics.Paint;
android.os.Bundle;
android.view.View;
android.widget.ImageView;
android.widget.SeekBar;
android.widget.SeekBar.OnSeekBarChangeListener;

//
public class LineWidthDialogFragment extends DialogFragment
{
private ImageView widthImageView;
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)

300 7 Doodlz
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

AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
View lineWidthDialogView = getActivity().getLayoutInflater().inflate(
R.layout.fragment_line_width, null);
builder.setView(lineWidthDialogView); // GUI
// the AlertDialog
builder.setTitle(R.string.title_line_width_dialog);
builder.setCancelable(true);
// ImageView
widthImageView = (ImageView) lineWidthDialogView.findViewById(
R.id.widthImageView);
// widthSeekBar
final DoodleView doodleView = getDoodleFragment().getDoodleView();
final SeekBar widthSeekBar = (SeekBar)
lineWidthDialogView.findViewById(R.id.widthSeekBar);
widthSeekBar.setOnSeekBarChangeListener(lineWidthChanged);
widthSeekBar.setProgress(doodleView.getLineWidth());
//
builder.setPositiveButton(R.string.button_set_line_width,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
doodleView.setLineWidth(widthSeekBar.getProgress());
}
}
); // setPositiveButton

return builder.create(); //
} // onCreateDialog
// DoodleFragment
private DoodleFragment getDoodleFragment()
{
return (DoodleFragment) getFragmentManager().findFragmentById(
R.id.doodleFragment);
}
// DoodleFragment,
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
DoodleFragment fragment = getDoodleFragment();

if (fragment != null)
fragment.setDialogOnScreen(true);

// DoodleFragment,

7.8. LineWidthDialogFragment301
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 }

@Override
public void onDetach()
{
super.onDetach();
DoodleFragment fragment = getDoodleFragment();

if (fragment != null)
fragment.setDialogOnScreen(false);

// OnSeekBarChangeListener SeekBar
private OnSeekBarChangeListener lineWidthChanged =
new OnSeekBarChangeListener()
{
Bitmap bitmap = Bitmap.createBitmap(
400, 100, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); // Canvas
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser)
{
// Paint SeekBar
Paint p = new Paint();
p.setColor(
getDoodleFragment().getDoodleView().getDrawingColor());
p.setStrokeCap(Paint.Cap.ROUND);
p.setStrokeWidth(progress);

// Bitmap
bitmap.eraseColor(
getResources().getColor(android.R.color.transparent));
canvas.drawLine(30, 50, 370, 50, p);
widthImageView.setImageBitmap(bitmap);

@Override
public void onStartTrackingTouch(SeekBar seekBar)
//
{
}
@Override
public void onStopTrackingTouch(SeekBar seekBar)
//
{
}
}; // lineWidthChanged

onCreateDialog
onCreateDialog (2561)
( 3031), fragment_line_width.xml ,

302 7 Doodlz
AlertDialog, setView AlertDialog.Builder ( 32). 3940 ImageView,
. 4347 widthSeekBar,
lineWidthChanged ( 93127) SeekBar SeekBar. 5058 -

,
Set Line Width setLineWidth DoodleView. 60
AlertDialog .
,
OnSeekBarChangeListener widthSeekBar
93127 OnSeekBarChangeListener
lineWidthChanged, SeekBar Choose Line Width. 9697 Bitmap,
, . 98
Canvas Bitmap. onProgressChanged (100116) ,
SeekBar. 105109 Paint . setStrokeCap Paint (108)

(Paint.Cap.ROUND). 112113 bitmap
Android android.R.color.transparent eraseColor
Bitmap. canvas . , 115 bitmap widthImageView,
setImageBitmap ImageView.

7.9. EraseImageDialogFragment
EraseImageDialogFragment (7.30) DialogFragment AlertDialog, . ColorDialogFragment LineWidthDialogFragment,
onCreateDialog ( 1641).
AlertDialog .
2735 Erase Image , 32 clear
DoodleView . 38 Cancel
,
. 40 AlertDialog.
7.30. EraseImageDialogFragment
1 // EraseImageDialogFragment.java
2 //

7.9. EraseImageDialogFragment303
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

package com.deitel.doodlz;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
//
public class EraseImageDialogFragment extends DialogFragment
{
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
// AlertDialog
builder.setMessage(R.string.message_erase);
builder.setCancelable(false);
//
builder.setPositiveButton(R.string.button_erase,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
getDoodleFragment().getDoodleView().clear(); //
}
}
); // setPositiveButton
//
builder.setNegativeButton(R.string.button_cancel, null);
return builder.create(); //
} // onCreateDialog
// DoodleFragment
private DoodleFragment getDoodleFragment()
{
return (DoodleFragment) getFragmentManager().findFragmentById(
R.id.doodleFragment);
}
// DoodleFragment,
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
DoodleFragment fragment = getDoodleFragment();

304 7 Doodlz
57
if (fragment != null)
58
fragment.setDialogOnScreen(true);
59
}
60
61
// DoodleFragment,
62
@Override
63
public void onDetach()
64
{
65
super.onDetach();
66
DoodleFragment fragment = getDoodleFragment();
67
68
if (fragment != null)
69
fragment.setDialogOnScreen(false);
70
}
71 } // EraseImageDialogFragment

7.10.
Doodlz,
. : Android
SensorManager SensorEventListener,
( , Android ).
DialogFragment, AlertDialog, onAttach onDetach
,
.
, Canvas Bitmap,
Canvas Bitmap.
, .
Path. onTouchEvent View,
MotionEvent ,
. ,
Path.
, Android 4.4, ,
.
, GestureDetector
.
ContentResolver MediaStore.Images.Media.insertImage . ,
Android 4.4

7.10. 305

. Bitmap PrintHelper Android


Support Library. PrintHelper
PDF.
8 Address Book,
,
, .
; , ,
.

Address Book

ListFragment FragmentTransaction, , AsyncTask, CursorAdapter, SQLite GUI



ListFragment ListView


SQLite
SQLiteOpenHelper, ,
SQLite SQLiteDatabase
SimpleCursorAdapter ListView

Cursor

AsyncTask
GUI

GUI,

8.1. 307

8.1.
Address Book (. 8.1)
, SQLite . , .
, .

. 8.1. :
a ;

( ) ,
EditText (.8.2). ( )
(. 8.3).
( ), EditText
(.8.4). Save Contact . .8.5 .
.

308 8 Address Book

. 8.2. : a
;

. 8.3. : a
;

8.2. Address Book309

. 8.4. :
a ;

8.2. Address Book



Eclipse Address Book. .
1. FileImport Import.
2. Import General Existing
Projects into Workspace. Next> Import Projects. , Select root directory,
Browse. Browse For Folder AddressBook
OK. Finish
Eclipse. Package Explorer,
Eclipse.
3. Address Book. Eclipse
AddressBook Package Explorer,
Run AsAndroid Application.

310 8 Address Book



, No Contacts.
.
.
Save Contact
.
, Back .
.

(.8.5).

. 8.5. Address Book :




, , . .

.
EditTexts, .
Save Contact
.

8.3. 311

. .
, ,
.

8.3.
, Address Book (
).

8.3.1.
FragmentTransaction
, ,
, DialogFragment,
show. ,
. , , ,
, ,
.
FragmentManager FragmentTransaction. ,
Android , LIFO
(Last-In-First-Out) Back
Android , ,
.

8.3.2.

( )

, .
, . ,
MainActivity ,

312 8 Address Book


( , ),
.

8.3.3. onSaveInstanceState
onSaveInstanceState
, .
,
onCreate . (,
, ,
), GUI ( ,
). onSaveInstanceState 8.35.

8.3.4.
GUI
GUI XML ( 8.4.4).
, ( 8.4.7),
style. , ,
GUI,
. TextView,
.

8.3.5. TextView
, TextView . ,
Drawable android:background TextView.
Drawable ,
Drawable, XML-
( 8.4.5). Drawable drawable
textview_border.xml drawable-mdpi.

8.3.6. ListFragment
, ListView

, ListFragment ( android.app, 8.6)

8.4. 313

, ListActivity, 4.
ListFragment ListView .
ArrayAdapter
ListView CursorAdapter ( android.widget).

8.3.7. SQLite
SQLite.
SQLite (www.sqlite.org)
. , , SQLite DatabaseConnector ( 8.9).
SQLiteOpenHelper
( android.database.sqlite), SQLiteDatabase ( android.database.sqlite)
.
SQL (Structured Query Language),
Cursor ( android.database).

8.3.8.
GUI AsyncTask
( ,
, ) GUI.
ANR (Activity Not
Responding).
GUI, AsyncTask ( android.os)
GUI.
AsyncTask
, AsyncTask GUI.

8.4.

Java,
GUI.

8.4.1.
Android. New Android Project
, Finish.

314 8 Address Book


Application Name: Address Book
Project Name: AddressBook
Package Name: com.deitel.addressbook
Minimum Required SDK: API18: Android 4.3
Target SDK: API19: Android 4.4
Compile With: API19: Android 4.4
Theme: Holo Light with Dark Action Bar

New Android Project (New Android Application)


Next >. Configure Launcher Icon Next >. Create Activity
Blank Activity Next >. Blank Activity
Finish, . Nexus 4 TextView
Hello world!.

8.4.2.
.
MainActivity ( 8.5) -

ContactListFragment (8.6) ListFragment; -

AddEditFragment (8.7) Fragment; -

DetailsFragment (8.8) Fragment;

DatabaseConnector ( 8.9) Object;

SQLite.

MainActivity . , com.deitel.
addressbook src.
NewClass,
.

8.4. 315

8.4.3. strings.xml
.8.1
. strings.xml res/values,
.
8.1. , Address Book

no_contacts

No Contacts

menuitem_add

Add

menuitem_edit

Edit

menuitem_delete

Delete

button_save_contact

Save Contact

hint_name

Name (Required)

hint_email

E-Mail

hint_phone

Phone

hint_street

Street

hint_city

City

hint_state

State

hint_zip

Zip

label_name

Name:

label_email

E-Mail:

label_phone

Phone:

label_street

Street:

label_city

City:

label_state

State:

label_zip

Zip:

confirm_title

Are You Sure?

confirm_message

This will permanently delete the contact

ok

OK

error_message

You must enter a contact name

button_cancel

Cancel

button_delete

Delete

316 8 Address Book

8.4.4. styles.xml
TextView DetailsFragment,
( 8.4.7). ,
, res/values.
styles.xml .
,
GUI, , . , .
1. styles.xml res/values. ,
Resources.
2. Add, Style/Theme OK,
.
3. Name ContactLabelTextView .
4. , ContactLabelTextView.
Add OK, .
Name Value .
.8.2.
8.2. ContactLabelTextView
Name

Value

android:layout_width

wrap_content

android:layout_height

wrap_content

android:layout_gravity

right|center_vertical

5. 2 3 ContactTextView
Add, Create a new element at
the top level in Resources. 4 .8.3.
, styles.xml.
8.3. ContactTextView
Name

Value

android:layout_width

wrap_content

android:layout_height

wrap_content

android:layout_gravity

fill_horizontal

android:textSize

16sp

android:background

@drawable/textview_border

8.4. 317

8.4.5. textview_border.xml
ContactTextView, ,
TextView,
. Drawable ( )
@drawable/textview_border android:background attribute
TextView. Drawable
res/drawable-mdpi . Drawable
drawable , Android
. Drawable, .
1. res/drawable-mdpi
NewAndroid XML File.
2. File textview_border.xml, shape Finish.
3.
Drawable, XML 8.1
.
8.1. XML- Drawable,
TextView
1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android"
3
android:shape="rectangle" >
4
<corners android:radius="5dp"/>
5
<stroke android:width="1dp" android:color="#555"/>
6
<padding android:top="10dp" android:left="10dp" android:bottom="10dp"
7
android:right="10dp"/>
8 </shape>

android:shape shape ( 3) "rectangle"


( ), "oval", "line" "ring". corners
( 4) .
stroke ( 5) .
padding (67) , Drawable.
.
http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape

8.4.6. MainActivity: activity_main.xml


MainActivity
, ( res/layout ),

318 8 Address Book


res/layout-large. layout-large .
: activity_main.xml res/layout
activity_main.xml res/layout.
RelativeLayout Outline, Change Layout FrameLayout. FrameLayout @id/
fragmentContainer. FrameLayout .
: activity_main.xml res/layout-large
activity_main.xml res/layout-large. LinearLayout, ContactListFragment
FrameLayout. ContactListFragment, FrameLayout , 5.4.9.
.
LinearLayout: Weight Sum 3 -

ContactListFragment FrameLayout.

: Id @+id/contactListFragment,

Width 0, Height match_parent, Weight


1 Right @dimen/activity_horizontal_margin.

FrameLayout: Id @+id/rightPaneContainer,

Width 0, Height match_parent Weight

2.

Weight Sum LinearLayout 3, Weight


ContactListFragment FrameLayout 1 2 ,
, ContactListFragment 1/3
LinearLayout, FrameLayout 2/3.

8.4.7. DetailsFragment: fragment_details.xml


MainActivity,
DetailsFragment (. 8.6). (fragment_details.xml)
ScrollView GridLayout,
TextView. ScrollView , .
ScrollView ,
,
TextView .8.6. fragment_details.xml,
5.4.8, (Root Element) ScrollView.
Id ScrollView @+id/
detailsScrollView ScrollView GridLayout.

8.4. 319

. 8.6. GUI DetailsFragment

GridLayout
GridLayout Width match_parent,
Height wrap_content, Column Count 2 Use
Default Margins true. Height ScrollView GridLayout ,
.
TextView GridLayout, .8.6.
TextView
Id TextView
.8.6. , .
Row 0 6 ( ).
Column 0.
Text strings.xml.
Style ( View) @style/ContactLabelTextView ( -

@style/).

TextView
Id TextView
.8.6. , .
Row 0 6 ( ).
Column 1.
Style ( View) @style/ContactTextView.

320 8 Address Book

8.4.8. AddEditFragment: fragment_add_edit.xml


, MainActivity AddEditFragment (. 8.7)


(fragment_add_edit.xml), ScrollView
GridLayout. Id
ScrollView @+id/addEditScrollView. AddEditFragment , EditText
(. . 8.4).
, AddEditFragment
MainActivity. EditText
Input Type IME Options. , ,
Input Type ,
EditText.
,
. IME Options Next nameEditText, emailEditText, phoneEditText,
streetEditText, cityEditText stateEditText.
, EditText.
zipEditText,
Done.

. 8.7. GUI AddEditFragment id.


GUI ScrollView,
GridLayout

8.4. 321

GridLayout
GridLayout Width match_parent,
Height wrap_content, Column Count 1 Use
Default Margins true. , .8.7.
EditText
EditText Id . 8.7,
.
Width match_parent.
Height wrap_content.
Hint strings.xml.
IME Options actionNext , zipEditText (

actionDone).

Style ( View) @style/ContactLabelTextView ( -

@style/).

Input Type EditText .


nameEditText: textPersonName|textCapWords , -

phoneEditText: phone .
emailEditText: textEmailAddress .
streetEditText: textPostalAddress|textCapWords ,

cityEditText: textPostalAddress|textCapWords.
stateEditText: textPostalAddress|textCapCharacters ,

zipEditText: number .

8.4.9.
, 7.3.4,
res/menu:
fragment_contact_list_menu.xml .
fragment_details_menu.xml -

322 8 Address Book


ContactListFragment DetailsFragment , .
. 8.48.5 . Order in category
. Icon
Android. platforms
Android SDK ( data/res/drawable-hdpi ).
,
@android:drawable/_.
8.4. fragment_contact_list_menu.xml
Name

Value

Id

@id/action_add

Order in category

Title

@string/menuitem_add

Icon

@android:drawable/ic_menu_add

Show as action

ifRoom|withText

8.5. fragment_details_menu.xml
Name

Value

Edit
Id

@id/action_edit

Order in category

Title

@string/menuitem_edit

Icon

@android:drawable/ic_menu_edit

Show as action

ifRoom|withText

Delete
Id

@id/action_delete

Order in category

Title

@string/menuitem_delete

Icon

@android:drawable/ic_delete

Show as action

ifRoom|withText

8.5. MainActivity323

8.5. MainActivity
MainActivity ( 8.28.11)
. MainActivity
ContactListFragment.
MainActivity ContactListFragment DetailsFragment, AddEditFragment 2/3 .
package, import MainActivity
MainActivity ( 8.2) FragmentTransaction ( 6) . MainActivity
.
ContactListFragment.ContactListFragmentListener

, ContactListFragment MainActivity,
.

DetailsFragment.DetailsFragmentListener ,

DetailsFragment MainActivity,
.

AddEditFragment.AddEditFragmentListener ,

AddEditFragment MainActivity, .

ROW_ID (15) ,
MainActivity . contactListFragment ( 17) ContactListFragment
.
8.2. package, import MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// MainActivity.java
// Address Book
package com.deitel.addressbook;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.os.Bundle;
public class MainActivity extends Activity
implements ContactListFragment.ContactListFragmentListener,
DetailsFragment.DetailsFragmentListener,
AddEditFragment.AddEditFragmentListener
{
// Bundle,
public static final String ROW_ID = "row_id";
ContactListFragment contactListFragment; //

324 8 Address Book


onCreate MainActivity
onCreate (8.3) MainActivity
, , ContactListFragment.
8.6, (, ).

, savedInstanceState null.
(28), ContactListFragment
,
MainActivity, 24.
8.3. onCreate MainActivity
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

// ContactListFragment MainActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// , ;
// GUI .
if (savedInstanceState != null)
return;
// , fragmentContainer ( );
// ContactListFragment .
if (findViewById(R.id.fragmentContainer) != null)
{
// ContactListFragment
contactListFragment = new ContactListFragment();

// FrameLayout
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.add(R.id.fragmentContainer, contactListFragment);
transaction.commit(); // ContactListFragment

R.id.fragmentContainer MainActivity ( 32), . 35


ContactListFragment, 3841 FragmentTransaction ContactListFragment .
3839 beginTransaction FragmentManager
FragmentTransaction. 40 add
FragmentTransaction , FragmentTransaction
ContactListFragment ,
. , 41 commit

8.5. MainActivity325

FragmentTransaction
ContactListFragment.
onResume MainActivity
onResume ( 8.4) contactListFragment null
, , 5557 FragmentManager
ContactListFragment MainActivity.
8.4. onResume MainActivity
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

// MainActivity
@Override
protected void onResume()
{
super.onResume();

// contactListFragment null, ,
// ; FragmentManager
if (contactListFragment == null)
{
contactListFragment =
(ContactListFragment) getFragmentManager().findFragmentById(
R.id.contactListFragment);
}

onContactSelected MainActivity
onContactSelected (8.5) ContactListFragment.Con
tactListFragmentListener ContactListFragment MainActivity , .
( 65), 66
displayContact (8.6), ContactListFragment
fragmentContainer (. 8.4.6) DetailsFragment,
. 69
popBackStack FragmentManager
, 70 displayContact, rightPaneContainer (. 8.4.6) DetailsFragment
.
8.5. onContactSelected MainActivity
61
62
63
64
65
66

// DetailsFragment
@Override
public void onContactSelected(long rowID)
{
if (findViewById(R.id.fragmentContainer) != null) //
displayContact(rowID, R.id.fragmentContainer);

326 8 Address Book


67
68
69
70
71
72
73

else //
{
getFragmentManager().popBackStack(); //
displayContact(rowID, R.id.rightPaneContainer);
}

displayContact MainActivity
displayContact (8.6) DetailsFragment FragmentTransaction . ,
Bundle, , rowID ,
DetailsFragment , .
Bundle 80. 81 putLong
ROW_ID (String) rowID
(long). 82 Bundle setArguments
Bundle (. 8.8). 8586
FragmentTransaction, 87
replace FragmentTransaction; ,
FragmentTransaction DetailsFragment , . 88
addToBackStack FragmentTransaction DetailsFragment
. , Back
, MainActivity
.
8.6. displayContact MainActivity
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

//
private void displayContact(long rowID, int viewID)
{
DetailsFragment detailsFragment = new DetailsFragment();
// rowID DetailsFragment
Bundle arguments = new Bundle();
arguments.putLong(ROW_ID, rowID);
detailsFragment.setArguments(arguments);

// FragmentTransaction DetailsFragment
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.replace(viewID, detailsFragment);
transaction.addToBackStack(null);
transaction.commit(); // DetailsFragment

8.5. MainActivity327

onAddContact MainActivity
onAddContact ( 8.7) ContactListFragment.Contact
ListFragmentListener ContactListFragment MainActivity ,
. fragmentContainer , 97
displayAddEditFragment (8.8), AddEditFragment frag
mentContainer. 99 displayAddEditFragment
rightPaneContainer.
Bundle. null , .
8.7. onAddContact MainActivity
92
93
94
95
96
97
98
99
100
101

// AddEditFragment
@Override
public void onAddContact()
{
if (findViewById(R.id.fragmentContainer) != null) //
displayAddEditFragment(R.id.fragmentContainer, null);
else //
displayAddEditFragment(R.id.rightPaneContainer, null);
}

displayAddEditFragment MainActivity
displayAddEditFragment ( 8.8) , , AddEditFragment,
Bundle . null, ; Bundle ,
AddEditFragment . 105
AddEditFragment. Bundle null,
108 Fragment. 111115 FragmentTransaction,
, ,
.
8.8. displayAddEditFragment MainActivity
102
103
104
105
106
107
108
109
110
111
112
113

//
private void displayAddEditFragment(int viewID, Bundle arguments)
{
AddEditFragment addEditFragment = new AddEditFragment();
if (arguments != null) //
addEditFragment.setArguments(arguments);
// FragmentTransaction AddEditFragment
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.replace(viewID, addEditFragment);

328 8 Address Book


114
115
116
117

transaction.addToBackStack(null);
transaction.commit(); // AddEditFragment

onContactDeleted MainActivity
onContactDeleted (8.9) DetailsFragment.Details
FragmentListener DetailsFragment MainActivity
. 122 DetailsFragment . ,
125 updateContactList contactListFragment
.
8.9. onContactDeleted MainActivity
118
119
120
121
122
123
124
125
126
127

//
@Override
public void onContactDeleted()
{
getFragmentManager().popBackStack(); //
//
if (findViewById(R.id.fragmentContainer) == null) //
contactListFragment.updateContactList();
}

onEditContact MainActivity
onEditContact (8.10) DetailsFragment.Details
FragmentListener DetailsFragment MainActivity
, .
DetailsFragment Bundle ,
AddEditFragment . fragmentContainer, 133 displayAddEditFragment,
AddEditFragment fragmentContainer. 135 displayAddEditFragment AddEditFragment
rightPaneContainer.
8.10. onEditContact MainActivity
128
129
130
131
132
133
134
135
136
137

// AddEditFragment
@Override
public void onEditContact(Bundle arguments)
{
if (findViewById(R.id.fragmentContainer) != null) //
displayAddEditFragment(R.id.fragmentContainer, arguments);
else //
displayAddEditFragment(R.id.rightPaneContainer, arguments);
}

8.6. ContactListFragment329

onAddEditCompleted MainActivity
onAddEditCompleted (8.11) AddEditFragment.AddEdit
FragmentListener AddEditFragment MainActivity
,
. 142 AddEditFragment .
(144), 146
DetailsFragment ( ). 147
ContactListFragment, 150
rightPaneContainer.
8.11. onAddEditCompleted MainActivity
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 }

// GUI
@Override
public void onAddEditCompleted(long rowID)
{
getFragmentManager().popBackStack(); //
if (findViewById(R.id.fragmentContainer) == null) //
{
getFragmentManager().popBackStack(); //
contactListFragment.updateContactList(); //

//
displayContact(rowID, R.id.rightPaneContainer);

8.6. ContactListFragment
ContactListFragment (8.128.21) ListFragment
ListView,
.
package import ContactListFragment
8.12 p a c k a g e i m p o r t
ContactListFragment, .
8.12. package import ContactListFragment
1
2
3
4
5
6
7
8

// ContactListFragment.java
//
package com.deitel.addressbook;
import
import
import
import

android.app.Activity;
android.app.ListFragment;
android.database.Cursor;
android.os.AsyncTask;

330 8 Address Book


9
10
11
12
13
14
15
16
17
18
19

import
import
import
import
import
import
import
import
import
import

android.os.Bundle;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
android.view.View;
android.widget.AdapterView;
android.widget.AdapterView.OnItemClickListener;
android.widget.CursorAdapter;
android.widget.ListView;
android.widget.SimpleCursorAdapter;

ContactListFragmentListener
ContactListFragment
8.13 ContactListFragment. 2330
ContactListFragmentListener , MainActivity ( 26) , ,
(29). 32
listener, (MainActivity), . contactListView (34)
ContactListFragment, ListView;
. contactAdapter
CursorAdapter, ListView .
8.13. ContactListFragmentListener
ContactListFragment
20 public class ContactListFragment extends ListFragment
21 {
22
// , MainActivity
23
public interface ContactListFragmentListener
24
{
25
//
26
public void onContactSelected(long rowID);
27
28
//
29
public void onAddContact();
30
}
31
32
private ContactListFragmentListener listener;
33
34
private ListView contactListView; // ListView ListActivity
35
private CursorAdapter contactAdapter; // ListView
36

onAttach onDetach ContactListFragment


ContactListFragment onAttach onDetach
( 8.14) listener.
listener

8.6. ContactListFragment331

( 42) ContactListFragment null ( 50) ContactListFragment.


8.14. onAttach onDetach
ContactListFragment
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

// ContactListFragmentListener
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
listener = (ContactListFragmentListener) activity;
}
// ContactListFragmentListener
@Override
public void onDetach()
{
super.onDetach();
listener = null;
}

onViewCreated ContactListFragment
ListFragment ListView, , .
ContactListFragment , . ContactListFragment
onViewCreated (8.15),
onCreateView.
8.15. onViewCreated
ContactListFragment
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

//
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
setRetainInstance(true); //
setHasOptionsMenu(true); //
// ,
setEmptyText(getResources().getString(R.string.no_contacts));
// ListView ListView
contactListView = getListView();
contactListView.setOnItemClickListener(viewContactListener);
contactListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// TextView ListView
String[] from = new String[] { name };

332 8 Address Book


71
72
73
74
75
76

int[] to = new int[] { android.R.id.text1 };


contactAdapter = new SimpleCursorAdapter(getActivity(),
android.R.layout.simple_list_item_1, null, from, to, 0);
setListAdapter(contactAdapter); // ,

58 setRetainInstance Fragment true;


, ContactListFragment (
) , .
59 , ContactListFragment ,
(
). setEmptyText ListFragment ("No Contacts"),
ListView.
65 ListActivity getListView
ListView. 66
OnItemClickListener ListView viewContactListener (8.16),
ListView. 67 setChoiceMode
ListView ,
.
CursorAdapter,
ListView
ListView ,
CursorAdapter ( 7073), Cursor ,
ListView. SimpleCursorAdapter
CursorAdapter, Cursor TextView ImagesView, XML.
SimpleCursorAdapter, , GUI, ,
. 70 String,
, "name", 71
int . 4 ,
ListView.
android.R.layout.simple_list_item_1 ,
TextView android.R.id.text1. 7273 SimpleCursorAdapter. .
, ListView (, MainActivity).
, -

ListView.
Cursor, , -

null, Cursor .

8.6. ContactListFragment333

.
int GUI.
0.

74 ListActivity setListAdapter
ListView CursorAdapter, ListView .
viewContactListener ListView
viewContactListener (8.16) MainActivity ,
, . 84 id ( )
onContactSelected (8.5).
8.16. viewContactListener
ListView
77
78
79
80
81
82
83
84
85
86
87

// ListView
OnItemClickListener viewContactListener = new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id)
{
listener.onContactSelected(id); //
// MainActivity
}
}; // viewContactListener

onResume ContactListFragment
onResume (8.17)
AsyncTask ( 93) GetContactsTask (8.18),
contactAdapter
ListView ContactListFragment. execute
AsyncTask .
execute , , ,
doInBackground .
93 GetContactsTask ,
AsyncTask .
8.17. onResume ContactListFragment
88
89
90
91

// GetContactsTask
@Override
public void onResume()
{

334 8 Address Book


92
93
94
95

super.onResume();
new GetContactsTask().execute((Object[]) null);

GetContactsTask
GetContactsTask (8.18) AsyncTask.
DatabaseConnector (8.9)
GUI
ListView. AsyncTask -.
doInBackground

AsyncTask(103108) execute doInBackground . Object - null execute AsyncTask,


GetContactsTask

onProgressUpdate
AsyncTask GUI -

. , Object
-.
, onPostExecute AsyncTask

( 111116), GUI
ContactListFragment AsyncTask.

AsyncTask ,

, .
8.18. GetContactsTask AsyncTask
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

// GUI
private class GetContactsTask extends AsyncTask<Object, Object, Cursor>
{
DatabaseConnector databaseConnector =
new DatabaseConnector(getActivity());
// (Cursor)
@Override
protected Cursor doInBackground(Object... params)
{
databaseConnector.open();
return databaseConnector.getAllContacts();
}
// , doInBackground
@Override

8.6. ContactListFragment335
112
113
114
115
116
117
118

protected void onPostExecute(Cursor result)


{
contactAdapter.changeCursor(result); //
//
databaseConnector.close();
}
} // GetContactsTask

99100 DatabaseConnector,
( ContactListFragment). doInBackground
databaseConnector
. Cursor, getAllContacts,
onPostExecute, Cursor
changeCursor contactAdapter. ListView
ContactListFragment .
onStop ContactListFragment
onStop (8.19)
onPause, .
Cursor, ListView, , 123
getCursor CursorAdapter contactAdapter. 124 changeCursor
CursorAdapter null Cursor CursorAdapter.
127 close Cursor ,
Cursor.
8.19. onStop ContactListFragment
119
120
121
122
123
124
125
126
127
128
129
130
131

// contactAdapter
@Override
public void onStop()
{
Cursor cursor = contactAdapter.getCursor(); //
//
contactAdapter.changeCursor(null); //
if (cursor != null)
cursor.close(); //
}

super.onStop();

onCreateOptionsMenu onOptionsItemSelected
ContactListFragment
onCreateOptionsMenu (8.20, 133138)
MenuInflater fragment_contact_list_menu.xml,

336 8 Address Book


( ). , onOptionsItemSelected (141152)
onAddContact, MainActivity .
MainActivity AddEditFragment (8.7).
8.20. onCreateOptionsMenu
onOptionsItemSelected ContactListFragment
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

//
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_contact_list_menu, menu);
}
//
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_add:
listener.onAddContact();
return true;
}
}

return super.onOptionsItemSelected(item); //

updateContactList ContactListFragment
updateContactList (8.21) GetContactsTask
.
8.21. updateContactList ContactListFragment
154
//
155
public void updateContactList()
156
{
157
new GetContactsTask().execute((Object[]) null);
158
}
159 } // ContactListFragment

8.7. AddEditFragment
AddEditFragment (8.228.28) .

8.7. AddEditFragment337

package import AddEditFragment


8.22 package import AddEditFragment.
.
8.22. package, import AddEditFragment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

// AddEditFragment.java
//
package com.deitel.addressbook;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.app.Fragment;
android.content.Context;
android.os.AsyncTask;
android.os.Bundle;
android.view.LayoutInflater;
android.view.View;
android.view.View.OnClickListener;
android.view.ViewGroup;
android.view.inputmethod.InputMethodManager;
android.widget.Button;
android.widget.EditText;

public class AddEditFragment extends Fragment


{

AddEditFragmentListener
8.23 AddEditFragmentListener, onAddEditCompleted, MainActivity
.
8.23. AddEditFragmentListener
23
24
25
26
27
28
29

// , MainActivity
public interface AddEditFragmentListener
{
//
public void onAddEditCompleted(long rowID);
}

AddEditFragment
8.24 .
listener AddEditFragmentListener,

, Save Contact.

338 8 Address Book


rowID ,

contactInfoBundle null

Bundle .

3642
EditText .

8.24. AddEditFragmentListener
30
31
32
33
34
35
36
37
38
39
40
41
42
43

private AddEditFragmentListener listener;


private long rowID; //
private Bundle contactInfoBundle; //
// EditText
private EditText nameEditText;
private EditText phoneEditText;
private EditText emailEditText;
private EditText streetEditText;
private EditText cityEditText;
private EditText stateEditText;
private EditText zipEditText;

onAttach onDetach AddEditFragment


AddEditFragment onAttach onDetach
( 8.25) , listener
( 49)
AddEditFragment null (57) AddEditFragment.
8.25. onAttach onDetach
AddEditFragment
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

// AddEditFragmentListener
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
listener = (AddEditFragmentListener) activity;
}
// AddEditFragmentListener
@Override
public void onDetach()
{
super.onDetach();
listener = null;
}

8.7. AddEditFragment339

onCreateView AddEditFragment
7078 onCreateView ( 8.26) EditText . getArguments Bundle ( ).
AddEditFragment MainActivity Bundle ,
.
getArguments null. Bundle ( 82),
AddEditFragment DetailsFragment,
. 8491
Bundle getLong ( 84) getString, String
EditText . 9597 (8.27) Save Contact.
8.26. onCreateView AddEditFragment
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

//
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
setRetainInstance(true); //
setHasOptionsMenu(true); //
// GUI EditText
View view =
inflater.inflate(R.layout.fragment_add_edit, container, false);
nameEditText = (EditText) view.findViewById(R.id.nameEditText);
phoneEditText = (EditText) view.findViewById(R.id.phoneEditText);
emailEditText = (EditText) view.findViewById(R.id.emailEditText);
streetEditText = (EditText) view.findViewById(R.id.streetEditText);
cityEditText = (EditText) view.findViewById(R.id.cityEditText);
stateEditText = (EditText) view.findViewById(R.id.stateEditText);
zipEditText = (EditText) view.findViewById(R.id.zipEditText);
contactInfoBundle = getArguments(); // null
if (contactInfoBundle != null)
{
rowID = contactInfoBundle.getLong(MainActivity.ROW_ID);
nameEditText.setText(contactInfoBundle.getString("name"));
phoneEditText.setText(contactInfoBundle.getString("phone"));
emailEditText.setText(contactInfoBundle.getString("email"));
streetEditText.setText(contactInfoBundle.getString("street"));
cityEditText.setText(contactInfoBundle.getString("city"));
stateEditText.setText(contactInfoBundle.getString("state"));
zipEditText.setText(contactInfoBundle.getString("zip"));
}
// Save Contact
Button saveContactButton =
(Button) view.findViewById(R.id.saveContactButton);

340 8 Address Book


97
98
99
100

saveContactButton.setOnClickListener(saveContactButtonClicked);
return view;

OnClickListener Save Contact


Save Contact ,
saveContactButtonClicked (8.27). ,
. onClick ,
0 (107), , AsyncTask ( ). doInBackground
(113118) saveContact (8.28)
. onPostExecute (120131) (124128) MainActivity , (130).
nameEditText , 139153 DialogFragment
, .
8.27. onClickListener Save Contact
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

// ,
OnClickListener saveContactButtonClicked = new OnClickListener()
{
@Override
public void onClick(View v)
{
if (nameEditText.getText().toString().trim().length() != 0)
{
// AsyncTask
AsyncTask<Object, Object, Object> saveContactTask =
new AsyncTask<Object, Object, Object>()
{
@Override
protected Object doInBackground(Object... params)
{
saveContact(); //
return null;
}
@Override
protected void onPostExecute(Object result)
{
//
InputMethodManager imm = (InputMethodManager)
getActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(
getView().getWindowToken(), 0);
listener.onAddEditCompleted(rowID);
}
}; // AsyncTask

8.7. AddEditFragment341
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157

//
saveContactTask.execute((Object[]) null);

}
else // ,
{
DialogFragment errorSaving =
new DialogFragment()
{
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.error_message);
builder.setPositiveButton(R.string.ok, null);
return builder.create();
}
};
errorSaving.show(getFragmentManager(), "error saving contact");
}
} // onClick
}; // OnClickListener

saveContact AddEditFragment
saveContact (8.28) , EditText . 162163
DatabaseConnector, , contactInfoBundle
null. , ; 168175 EditText, insertContact
DatabaseConnector . null Bundle, .
EditText updateContact DatabaseConnector,
rowID , .
insertContact updateContact DatabaseConnector
.
8.28. saveContact AddEditFragment
158
159
160
161
162
163
164
165
166
167
168

//
private void saveContact()
{
// DatabaseConnector SQLite
DatabaseConnector databaseConnector =
new DatabaseConnector(getActivity());
if (contactInfoBundle == null)
{
//
rowID = databaseConnector.insertContact(

342 8 Address Book


169
nameEditText.getText().toString(),
170
phoneEditText.getText().toString(),
171
emailEditText.getText().toString(),
172
streetEditText.getText().toString(),
173
cityEditText.getText().toString(),
174
stateEditText.getText().toString(),
175
zipEditText.getText().toString());
176
}
177
else
178
{
179
databaseConnector.updateContact(rowID,
180
nameEditText.getText().toString(),
181
phoneEditText.getText().toString(),
182
emailEditText.getText().toString(),
183
streetEditText.getText().toString(),
184
cityEditText.getText().toString(),
185
stateEditText.getText().toString(),
186
zipEditText.getText().toString());
187
}
188
} // saveContact
189 } // AddEditFragment

8.8. DetailsFragment
DetailsFragment ( 8.298.38)
,
.
package import DetailsFragment
8.29 package, import
DetailsFragment. .
8.29. package import DetailsFragment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// DetailsFragment.java
//
package com.deitel.addressbook;
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.Activity;
android.app.AlertDialog;
android.app.Dialog;
android.app.DialogFragment;
android.app.Fragment;
android.content.DialogInterface;
android.database.Cursor;
android.os.AsyncTask;
android.os.Bundle;
android.view.LayoutInflater;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;

8.8. DetailsFragment343
18
19
20
21
22
23

import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class DetailsFragment extends Fragment
{

DetailsFragmentListener
8.30 DetailsFragmentListener, , MainActivity
( 28)
(31).
8.30. DetailsFragmentListener
24
25
26
27
28
29
30
31
32
33

// , MainActivity
public interface DetailsFragmentListener
{
//
public void onContactDeleted();
// Bundle
// c .
public void onEditContact(Bundle arguments);
}

DetailsFragment
8.31 . 34
listener, (MainActivity),
DetailsFragmentListener. rowID
. TextView
( 3743) .
8.31. DetailsFragment
34
35
36
37
38
39
40
41
42
43
44

private DetailsFragmentListener listener;


private
private
private
private
private
private
private
private

long rowID = -1;


TextView nameTextView;
TextView phoneTextView;
TextView emailTextView;
TextView streetTextView;
TextView cityTextView;
TextView stateTextView;
TextView zipTextView;

//
//
//
//
//
//
//
//

rowID

onAttach onDetach DetailsFragment


DetailsFragment onAttach onDetach
(8.32) ,

344 8 Address Book


listener
DetailsFragment.

8.32. onAttach onDetach


DetailsFragment
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

// DetailsFragmentListener
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
listener = (DetailsFragmentListener) activity;
}
// DetailsFragmentListener
@Override
public void onDetach()
{
super.onDetach();
listener = null;
}

onCreateView DetailsFragment
onCreateView (8.33) rowID ( 7079). , rowID
savedInstanceState;
Bundle . 8293
TextView.
8.33. onCreateView DetailsFragment
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

//
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreateView(inflater, container, savedInstanceState);
setRetainInstance(true); //
// , rowID
if (savedInstanceState != null)
rowID = savedInstanceState.getLong(MainActivity.ROW_ID);
else
{
// rowID
Bundle arguments = getArguments();

if (arguments != null)
rowID = arguments.getLong(MainActivity.ROW_ID);

// DetailsFragment

8.8. DetailsFragment345
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

View view =
inflater.inflate(R.layout.fragment_details, container, false);
setHasOptionsMenu(true); //

// EditText
nameTextView = (TextView) view.findViewById(R.id.nameTextView);
phoneTextView = (TextView) view.findViewById(R.id.phoneTextView);
emailTextView = (TextView) view.findViewById(R.id.emailTextView);
streetTextView = (TextView) view.findViewById(R.id.streetTextView);
cityTextView = (TextView) view.findViewById(R.id.cityTextView);
stateTextView = (TextView) view.findViewById(R.id.stateTextView);
zipTextView = (TextView) view.findViewById(R.id.zipTextView);
return view;

onResume DetailsFragment
onResume (8.34)
AsyncTask ( 102) LoadContactTask (8.37),
. execute
rowID .
102 LoadContactTask , ,
AsyncTask .
8.34. onResume DetailsFragment
97
98
99
100
101
102
103
104

// DetailsFragment
@Override
public void onResume()
{
super.onResume();
new LoadContactTask().execute(rowID); // rowID
}

onSaveInstanceState DetailsFragment
onSaveInstanceState ( 8.35) rowID
,
.
GUI , , , Bundle,
onSaveInstanceState.
8.35. onSaveInstanceState
DetailsFragment
105
106
107

// rowID
@Override
public void onSaveInstanceState(Bundle outState)

346 8 Address Book


108
109
110
111
112

{
}

super.onSaveInstanceState(outState);
outState.putLong(MainActivity.ROW_ID, rowID);

onCreateOptionsMenu onOptionsItemSelected
DetailsFragment
DetailsFragment . onCreateOptionsMenu (8.36, 114119) fragment_details_menu.xml. onOptionsItemSelected
(122146) MenuItem
, .
R.id.action_edit, 129137 Bundle , 138 Bundle
DetailsFragmentListener AddEditFragment.
R.id.action_delete, 141 deleteContact (8.38).
8.36. onCreateOptionsMenu
onOptionsItemSelected DetailsFragment
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

//
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_details_menu, menu);
}
//
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_edit:
// Bundle
Bundle arguments = new Bundle();
arguments.putLong(MainActivity.ROW_ID, rowID);
arguments.putCharSequence("name", nameTextView.getText());
arguments.putCharSequence("phone", phoneTextView.getText());
arguments.putCharSequence("email", emailTextView.getText());
arguments.putCharSequence("street", streetTextView.getText());
arguments.putCharSequence("city", cityTextView.getText());
arguments.putCharSequence("state", stateTextView.getText());
arguments.putCharSequence("zip", zipTextView.getText());
listener.onEditContact(arguments); // Bundle
//
return true;
case R.id.action_delete:

8.8. DetailsFragment347
141
142
143
144
145
146
147

}
}

deleteContact();
return true;

return super.onOptionsItemSelected(item);

LoadContactTask
LoadContactTask ( 8.37) AsyncTask.
DatabaseConnector (8.9)
. -.
Long ,

doInBackground AsyncTask. rowID, -

Object ,
onProgressUpdate AsyncTask. .

Cursor , onPostExecute

AsyncTask.

8.37. LoadContactTask
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

// GUI
private class LoadContactTask extends AsyncTask<Long, Object, Cursor>
{
DatabaseConnector databaseConnector =
new DatabaseConnector(getActivity());
//
@Override
protected Cursor doInBackground(Long... params)
{
databaseConnector.open();
return databaseConnector.getOneContact(params[0]);
}
// , doInBackground
@Override
protected void onPostExecute(Cursor result)
{
super.onPostExecute(result);
result.moveToFirst(); //
//
int nameIndex = result.getColumnIndex(name);
int phoneIndex = result.getColumnIndex("phone");
int emailIndex = result.getColumnIndex("email");
int streetIndex = result.getColumnIndex("street");
int cityIndex = result.getColumnIndex("city");

348 8 Address Book


175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

int stateIndex = result.getColumnIndex("state");


int zipIndex = result.getColumnIndex("zip");
// TextView
nameTextView.setText(result.getString(nameIndex));
phoneTextView.setText(result.getString(phoneIndex));
emailTextView.setText(result.getString(emailIndex));
streetTextView.setText(result.getString(streetIndex));
cityTextView.setText(result.getString(cityIndex));
stateTextView.setText(result.getString(stateIndex));
zipTextView.setText(result.getString(zipIndex));
result.close(); //
databaseConnector.close(); //
} // onPostExecute
} // LoadContactTask

151152 DatabaseConnector (8.9).


doInBackground ( 155160)
getOneContact DatabaseConnector, rowID, execute AsyncTask. doInBackground
rowID params[0].
Cursor onPostExecute ( 163189).
.
, moveToFirst
Cursor ( 167)
. [:
, moveToFirst true; ,
.]
getColumnIndex Cursor ( 170176)
contacts . ( ,
, ROW_ID MainActivity 8.2.)
1, . Cursor
getColumnIndexOrThrow, . 179185
getString Cursor String
Cursor, TextView.
187188 Cursor . (,
), .
deleteContact confirmDelete
deleteContact ( 8.38, 193197)
DialogFragment (200252)

8.8. DetailsFragment349

. , DialogFragment AsyncTask
. Delete,
222223 DatabaseConnector. 226241
AsyncTask, ( 244) Long,
, doInBackground,
. 232 deleteContact DatabaseConnector
. doInBackground , 239 onContactDeleted ,
MainActivity DetailsFragment .
8.38. deleteContact DialogFragment
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

//
private void deleteContact()
{
// FragmentManager confirmDelete
confirmDelete.show(getFragmentManager(), "confirm delete");
}
// DialogFragment
private DialogFragment confirmDelete =
new DialogFragment()
{
// AlertDialog
@Override
public Dialog onCreateDialog(Bundle bundle)
{
// Builder AlertDialog
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.confirm_title);
builder.setMessage(R.string.confirm_message);
// OK
builder.setPositiveButton(R.string.button_delete,
new DialogInterface.OnClickListener()
{
@Override
public void onClick(
DialogInterface dialog, int button)
{
final DatabaseConnector databaseConnector =
new DatabaseConnector(getActivity());
// AsyncTask
AsyncTask<Long, Object, Object> deleteTask =
new AsyncTask<Long, Object, Object>()
{
@Override
protected Object doInBackground(Long... params)
{
databaseConnector.deleteContact(params[0]);

350 8 Address Book


233
return null;
234
}
235
236
@Override
237
protected void onPostExecute(Object result)
238
{
239
listener.onContactDeleted();
240
}
241
}; // new AsyncTask
242
243
// AsyncTask rowID
244
deleteTask.execute(new Long[] { rowID });
245
} // onClick
246
} //
247
); // setPositiveButton
248
249
builder.setNegativeButton(R.string.button_cancel, null);
250
return builder.create(); // AlertDialog
251
}
252
}; // DialogFragment
253 } // DetailsFragment

8.9. DatabaseConnector
DatabaseConnector (8.398.46) SQLite UserContacts,
contacts.
package, import
8.39 package , import
DatabaseConnector. import , 8.3. DATABASE_NAME
(16) .
, . SQLiteDatabase (18)
SQLite /. DatabaseOpenHelper
( 19) ,
SQLiteOpenHelper; ,
(, ).
SQLiteOpenHelper 8.46.
8.39. package, import
DatabaseConnector
1 // DatabaseConnector.java
2 //
// UserContacts.
3 package com.deitel.addressbook;

8.9. DatabaseConnector351
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

import
import
import
import
import
import
import

android.content.ContentValues;
android.content.Context;
android.database.Cursor;
android.database.SQLException;
android.database.sqlite.SQLiteDatabase;
android.database.sqlite.SQLiteOpenHelper;
android.database.sqlite.SQLiteDatabase.CursorFactory;

public class DatabaseConnector


{
//
private static final String DATABASE_NAME = "UserContacts";
private SQLiteDatabase database; //
private DatabaseOpenHelper databaseOpenHelper; //

open close DatabaseConnector


DatabaseConnection ( 8.40, 2227) DatabaseOpenHelper (8.46),
. DatabaseOpenHelper 8.46. open ( 3034) , ,
SQLException. getWritableDatabase (33),
SQLiteOpenHelper, SQLiteDatabase.
, ; .

.
close (3741) SQLiteOpenHelper close.
8.40. open close DatabaseConnector
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

// DatabaseConnector
public DatabaseConnector(Context context)
{
// DatabaseOpenHelper
databaseOpenHelper =
new DatabaseOpenHelper(context, DATABASE_NAME, null, 1);
}
//
public void open() throws SQLException
{
// /
database = databaseOpenHelper.getWritableDatabase();
}
//
public void close()

352 8 Address Book


38
39
40
41
42

{
}

if (database != null)
database.close(); //

insertContact DatabaseConnector
insertContact ( 8.41)
.
ContentValues (4754),
.
5658 ,
. insert SQLiteDatabase (57) ContentValues , ,
"contacts" . ,
, nullColumnHack; ,
SQLite
insert ContentValues. ,
ContentValues,
nullColumnHack , NULL.
8.41. insertContact DatabaseConnector
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

//
public long insertContact(String name, String phone, String email,
String street, String city, String state, String zip)
{
ContentValues newContact = new ContentValues();
newContact.put(name, name);
newContact.put("phone", phone);
newContact.put("email", email);
newContact.put("street", street);
newContact.put("city", city);
newContact.put("state", state);
newContact.put("zip", zip);
open(); //
long rowID = database.insert(contacts, null, newContact);
close(); //
return rowID;
} // insertContact

updateContact DatabaseConnector
updateContact (8.42) insertContact, , update SQLiteDatabase (76)
. update
SQL WHERE ( WHERE),
. .

8.9. DatabaseConnector353

8.42. updateContact DatabaseConnector


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

//
public void updateContact(long id, String name, String phone,
String email, String street, String city, String state, String zip)
{
ContentValues editContact = new ContentValues();
editContact.put("name", name);
editContact.put("phone", phone);
editContact.put("email", email);
editContact.put("street", street);
editContact.put("city", city);
editContact.put("state", state);
editContact.put("zip", zip);

open(); //
database.update("contacts", editContact, "_id=" + id, null);
close(); //

getAllContacts
getAllContacts ( 8.43) query SqLiteDatabase
( 8384) , . :
, ;
String (_id name )

cnull ,
( , );

SQL WHERE ( WHERE) null

String , WHERE

?, null, WHERE ;

SQL GROUP BY ( GROUP BY) null,

SQL HAVING ( HAVING)

GROUP BY, , GROUP BY


null, null;

SQL ORDER BY ( ORDER BY)

null, .

Cursor, query, , ( ).

354 8 Address Book


Cursor.
8.43. getAllContacts DatabaseConnector
80
81
82
83
84
85
86

//
public Cursor getAllContacts()
{
return database.query(contacts, new String[] {_id, name},
null, null, null, null, name);
}

getOneContact
getOneContact (8.44) query SqLite
Database . .
8.44. getOneContact DatabaseConnector
87
88
89
90
91
92
93

//
public Cursor getOneContact(long id)
{
return database.query(
contacts, null, _id= + id, null, null, null, null);
}

deleteContact
deleteContact (8.45) delete SqLiteDatabase
( 98) . .
, , WHERE (
WHERE) WHERE
, WHERE (null ).
8.45. deleteContact DatabaseConnector
94
95
96
97
98
99
100
101

// ,
public void deleteContact(long id)
{
open(); //
database.delete(contacts, _id= + id, null);
close(); //
}

DatabaseOpenHelper
DatabaseOpenHelper (8.46) SQLiteOpenHelper,

8.9. DatabaseConnector355

. (105109)
, .
, .
null

.
CursorFactory null ,

CursorFactory, SQLite (
).
( 1).

onCreate onUpgrade .
, onCreate DatabaseOpenHelper
. , ,
, onUpgrade DatabaseOpenHelper
(,
).
8.46. DatabaseOpenHelper
102
private class DatabaseOpenHelper extends SQLiteOpenHelper
103
{
104
//
105
public DatabaseOpenHelper(Context context, String name,
106
CursorFactory factory, int version)
107
{
108
super(context, name, factory, version);
109
}
110
111
// contacts
112
@Override
113
public void onCreate(SQLiteDatabase db)
114
{
115
// contacts
116
String createQuery = "CREATE TABLE contacts" +
117
"(_id integer primary key autoincrement," +
118
"name TEXT, phone TEXT, email TEXT, " +
119
"street TEXT, city TEXT, state TEXT, zip TEXT);";
120
121
db.execSQL(createQuery); //
122
}
123
124
@Override
125
public void onUpgrade(SQLiteDatabase db, int oldVersion,
126
int newVersion)
127
{
128
}
129
} // DatabaseOpenHelper
130 } // DatabaseConnector

356 8 Address Book


onCreate (112122) , SQL CREATE
TABLE, String ( 116119).
contacts (_id),
,
. 121 execSQL SQLiteDatabase CREATE TABLE. ,
onUpgrade . SQLiteOpenHelper
onDowngrade,
( , ,
SQLiteOpenHelper).
, .
SQLiteDatabase, DatabaseConnector,
, ,
1 (, insertOrThrow
insert). , ,
.

8.10.
Address Book, , ,
, SQLite. GUI XML- style,
, , style. TextView,
Drawable android:background TextView, Drawable
XML- . Android
.
, , , ListFragment , ListView.
,
.
CursorAdapter, .
FragmentTransaction
GUI. Back,
,
.

8.10. 357

, ( ) , .
Bundle.
SQLiteOpenHelper
SQLiteDatabase,
. Cursor
. AsyncTask
GUI GUI,
Android
.
9 Android. , Google
Play, ;
Google Play.
, .
.
,
.
Google Play , .

Google Play



,


Google Play
Google Wallet
Google Play
Play Store
Android
,

9.2. 359

9.1.
28 Android.
( , Android),
Google Play(/ )
. ,
Google Play Google Wallet,
. ,
Google Play. Android , ,
.
, Android.

,
. ,
Android .

9.2.
Preparing for Release Dev Guide (http://developer.android.
com/tools/publishing/preparing.html) ,
Google Play. :
Android.
End User License Agreement

( ).
.
(, 1.0, 1.1, 2.0, 2.3, 3.0).

.
.

Launch Checklist (http://developer.android.com/distribute/googleplay/publish/


preparing.html) Tablet App Quality Checklist (http://developer.android.com/distribute/
googleplay/quality/tablet.html).

360 9 Google Play

9.2.1.
Google Play,
. ,
Android .
Google Play Developer Console - - Google+.

https://play.google.com/apps/publish/

9.2.2.

EULA (End User License Agreement). , .
,
, , .. ,
EULA . EULA

http://www.rocketlawyer.com/document/end-user-license-agreement.rl

9.2.3.

(), Google Play .
, . Android Asset Studio

http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html
:
xx-high (XXHDPI): 144144 ;
x-high (XHDPI): 9696 ;
high (HDPI): 7272 ;
medium (MDPI): 4848 .

,
Google Play. :
512512 ;

9.2. 361

32- PNG;
1 .

,
. , ,
. .9.1 ,
. ,
AndroidManifest.xml, android:icon android:label
application.
9.1. ,

URL-

glyphlab

http://www.glyphlab.com/icon_design/

Androidicons

http://www.androidicons.com

,
200
,

Iconiza

http://www.iconiza.com

Aha-Soft

http://www.aha-soft.com/icon-design.
htm

Rosetta

http://icondesign.rosetta.com/

Elance

http://www.elance.com

9.2.4.
( ) ( , Google Play)
. ,
1.0, 1.1 1.2,
2.0. ,
1 1 . Versioning Your Applications

http://developer.android.com/tools/publishing/versioning.html

362 9 Google Play

9.2.5.

Google Play , . ,
,
.
http://developer.android.com/google/play/licensing/index.html

9.2.6.
, Google Play, ,
.
ProGuard ( )
.apk ( Android,
),
,
1. ProGuard

http://developer.android.com/tools/help/proguard.html


http://www.techrepublic.com/blog/app-builder/protect-your-android-apps-withobfuscation/1724

9.2.7.
, Google Play
, .apk , .
, ..

(, , );
( ). Eclipse
. Google

http://developer.android.com/tools/help/proguard.html#enabling

9.2. 363

Play, 365 .
Signing
Your Applications
http://developer.android.com/tools/publishing/app-signing.html

9.2.8.
, Google Play (. 9.2),
, 7- 10- .
,
(
15 ).
,
.
9.2.

320 ,
3840 ( )

24
PNG

JPEG
- ()

Dalvik Debug Monitor Service (DDMS)


ADT Eclipse ,
; . .
1. (. 1.9).
2. Eclipse WindowOpen PerspectiveDDMS, DDMS.

. 9.1. Devices DDMS

364 9 Google Play


3. Devices ,
(. 9.1).
4. Screen Capture. Device Screen Capture (. 9.2).

. 9.2. Device Screen Capture


Tip Calculator ( 3)

5. , , Save
.
6. ,
Refresh Device Screen
Capture window.

9.2.9.
Google Play ULR , YouTube. .9.3
. , . .
.9.4 ( , ).
, YouTube. Upload .

9.3. : ? 365

Select files to upload, ,


.
9.3. Google Play

URL

Temple Run: Oz

http://www.youtube.com/watch?v=QM9sT1ydtj0

GT Racing: Motor Academy

http://www.youtube.com/watch?v=2Z9OPICdgoA

Beach Buggy Blitz

http://www.youtube.com/watch?v=YqDczawTsYw

Real Estate and Homes by Trulia

http://www.youtube.com/watch?v=rLn697AszGs

Zappos.com

http://www.youtube.com/watch?v=U-oNyK9kl_Q

Megopolis International

http://www.youtube.com/watch?v=JrqeEJ1xzCY

9.4.

URL

Animoto

http://animoto.com

Apptamin

http://www.apptamin.com

Movie Maker for Microsoft Windows

http://windows.microsoft.com/en-us/windows-live/
movie-maker

CamStudio

http://camstudio.org

Jing

http://www.techsmith.com/jing.html

Camtasia Studio

http://www.techsmith.com/camtasia.html

TurboDemo

http://www.turbodemo.com/eng/index.php

9.3. :
?
, Google
Play. ,
.
, ,
, . .9.5
.

366 9 Google Play


9.5.

Google Play
Android

(. 9.5)
, (. 9.4)

,

9.3.1.
. ,
AppBrain (http://www.appbrain.com), - $1,54, - $6.47.1
, ,
,
.
, .
?
? ?
, , ?
?
- ,
.
.
Google Play Google Wallet (http://google.com/wallet),
(AT&T, Sprint T-Mobile)

, . Google Wallet
.2
, Google Play.
http://www.appbrain.com/stats/android-market-app-categories

http://support.google.com/googleplay/android-developer/answer/137997?hl=en&ref_
topic=15867

9.3. : ? 367

9.3.2.
80% Android , .1
, , . , ,
.
,
Google Play .
(. 9.5). , AdMob,

.2

, (. 9.6).
9.6. , Android

Amazon Mobile

Amazon

Bank of America

Best Buy

Best Buy

CNN

Epicurious Recipe

,
Cond Nast, Gourmet
Bon Appetit

ESPN ScoreCenter


(
)

NFL Mobile

NFL, , NFL

http://www.gartner.com/newsroom/id/2592315

1
2

http://metrics.admob.com/wp-content/uploads/2009/08/AdMob-Mobile-Metrics-July-09.pdf

368 9 Google Play


9.6 ()

UPS Mobile

,
,

NYTimes

New York Times (


)

Pocket Agent

State Farm Insurance, , , ,


State Farm ..

Progressive Insurance

, ,

USA Today

USA Today

Wells Fargo Mobile


, ,

Womens Health Workouts Lite

9.4.

,
,
, -. , AdMob (http://www.admob.com/) Google AdSense for Mobile
(http://www.google.com/mobileads/publisher_home.html), ,
(. 9.13).
.

. ,
,
, , ,
.

9.5. 369

9.5.

Google Play (http://developer.android.


com/google/play/billing/index.html)
( ) Android 2.3
(.9.7). Google, ,
, ,
. 24 ,
Google Play, 23 .1 , Google Play;
,
. ,
, Google Play (. 9.6),
Google Wallet (. 9.7). Google 70% , .
(
), 2. , , Angry Birds, DragonVale,
Zynga Poker, Bejeweled Blitz, NYTimes Candy Crush Saga.
.
9.7.

,

http://developer.android.com/google/play/billing/billing_integrate.html

http://android-developers.blogspot.com/2012/05/in-app-subscriptions-in-google-play.html

http://www.businessinsider.com/its-morning-in-venture-capital-2012-5?utm_source=
readme&utm_medium=rightrail&utm_term=&utm_content=6&utm_campaign=recirc

370 9 Google Play


(,
, , ..)

http://developer.android.com/google/play/billing/billing_overview.html
Selling In-app Products

http://developer.android.com/training/in-app-billing/index.html
,

(. 9.11),
. ,
API (. 9.8),
Google Play . (, ).
- , ,
, , .
.
25 45 % .
9.8. ,

URL

PayPal Mobile
Payments Library

http://developer.paypal.com/
webapps/developer/docs/
classic/mobile/gs_MPL/

Pay
with PayPal,
PayPal,
Pay

Amazon In-App
Purchasing

http://developer.amazon.com/
sdk/in-app-purchasing.html

,
Amazon App Store for Android

Zong

http://www.zong.com/android

Buy ,
.

Samsung In-App
Purchase

http://developer.samsung.com/ android/tools-sdks/In-App,
Purchase-Library
Samsung

Boku

http://www.boku.com

Pay by
Mobile, , ,
,

9.7. Google Wallet371

9.6. Google Play


Google Play, - http://play.google.com/apps/publish.
$25.
, Google Play . ,
, Google Play
Developer Program Policies. ,
.

(. 9.9).
9.9. Google Play Content
Policy for Developers (http://play.google.com/about/developer-content-policy.
html#showlanguages)

( , )

-

,
18

9.7. Google Wallet


Google Play
Google Wallet, Google Play 32
(. 9.10).1 Google Wallet . Google Play (http://play.google.com/apps/publish/)
Financial Reports, Set up a merchant account.
:
, Google

;
http://support.google.com/googleplay/android-developer/answer/150324?hl=en&ref_
topic=15867

372 9 Google Play


,

;
, Google -

;
,

, , ,
.
9.10. , Google Wallet

Google Wallet
. Google Play .1 Google 70% .
Google Wallet ,
(, ,
).

9.8. Google Play


, , http://
developer.android.com/distribute/googleplay/publish/preparing.html.
Google Play http://play.google.com/apps/publish (. 9.6) Publish an Android App on Google Play, .
.
(.apk), ,

.
http://checkout.google.com/termsOfService?type=SELLER

9.8. Google Play373

, -

Google Play. Android,


7- 10- .
(512512 ),

Google Play.
Google Play,

Google, ( ).
180 120
, 24- PNG JPEG .
(
).
, Google Play ( ). -

URL- (,
YouTube c ).
:
1. . , . ,
(. 9.11).
2. , Google Play ( 30 ).
Android.
9.11. Google Play

()

()

()

(
)

()

()

()

()

()

374 9 Google Play


3. ( 4000 ).

, .
4. .
( 500 ).
5. . ,
( 80 ).
6. . : (Application) (Games).
7. . (. . 1.9),
.
8. . (Free).
, Google Wallet.
9. . . Rating your application content for
Google Play http://support.google.com/googleplay/android-developer/
answer/188189.
10. . ,
, Google Play .
,
.
11. . Google Play Visit
Developers Website. ,
, , , , ,
, ..
12. . Google Play
, ,
..
13. . ,
. .

9.9. Play Store



Play Store (Google Play)
( , ).
,

9.11. Android375

.
Play Store.
Play Store. -,
Google Play , , . ,
, Google Play,
, .
, Play Store,
, .
-,
Play Store.
, Play Store ,
Linking Your Products
http://developer.android.com/distribute/googleplay/promote/linking.html

9.10. Google Play


Google Play Developer Console
,
( 0 5 ), , (
).
Android,
.
, . ,
. Play Store,
, .
, , c
( Google ,
,
Terms of Service).

9.11. Android
Google Play, (. 9.12) -
, AndroidLicenser (http://www.androidlicenser.com).


http://developer.android.com/tools/publishing/publishing_overview.html

376 9 Google Play


9.12. Android

URL

Amazon Appstore

http://developer.amazon.com/welcome.html

Opera Mobile Store

http://apps.opera.com/en_us/index.php

Moborobo

http://www.moborobo.com

Appitalism

http://www.appitalism.com/index.html

Samsung Apps

http://apps.samsung.com/mars/main/getMain.as

GetJar

http://www.getjar.com

SlideMe

http://www.slideme.org

Handango

http://www.handango.com

Mplayit

http://www.mplayit.com

AndroidPit

http://www.androidpit.com

9.12.

ABI Research, 2013 56 14 .1


Android , iOS
( iPhone, iPad iPod Touch),
(.9.13). Android Windows, Linux Mac Java
. iOS
Macintosh, ,
Objective-C, .
Google J2ObjC, Java Objective-C
iOS. http://code.google.
com/p/j2objc/.
9.13. (http://www.
abiresearch.com/press/android-will-account-for-58-of-smartphone-app-down)

URL

Android

http://developer.android.com

58%
17%

http://www.abiresearch.com/press/android-will-account-for-58-of-smartphone-app-down.

9.13. 377

URL

iOS (Apple)

http://developer.apple.com/ios

33%
75%

Windows Phone 8

http://developer.windowsphone.com

4%
2%

BlackBerry (RIM)

http://developer.blackberry.com

3%

Amazon Kindle

http://developer.amazon.com

4%

9.13.
.1
,
Facebook, Twitter YouTube. .
Pew Research Center, 72%
, 67% Facebook.2 . 9.14 .

.
9.14.

URL

Facebook

http://www.facebook.com

Twitter

http://www.twitter.com

Google+

http://plus.google.com

Groupon

http://www.groupon.com

Foursquare

http://www.foursquare.com

Pinterest

http://www.pinterest.com

YouTube

http://www.youtube.com

LinkedIn

http://www.linkedin.com

Flickr

http://www.flickr.com

Android Android Apps Marketing:


Secrets to Selling Your Android App (Jeffrey Hughes).

http://pewinternet.org/Commentary/2012/March/Pew-Internet-Social-Networking-full-detail.
aspx

378 9 Google Play


Facebook
Facebook, , 1 1 150 2.
( ).
Facebook
. ,
, , , , ,
, Google Play . , Facebook
http://www.facebook.com/DeitelFan.
, , .
.
,
,
.
Twitter
Twitter , 554 .3
140 . Twitter
(
- 40 ).
, ,
( , ,
, ).
, . - (#) . ,
, ,
Twitter @deitel - #AndroidFP2.
-, .
, .

, (YouTube,
Bing Videos, Yahoo! Video), (, Facebook, Twitter,
Google+) .
http://investor.fb.com/releasedetail.cfm?ReleaseID=761090

http://expandedramblings.com/index.php/by-the-numbers-17-amazing-facebook-stats/

http://www.statisticbrain.com/twitter-statistics/

9.13. 379

,
.


. Google Play,
. ,
.

,
(. 9.15), .
(. 9.3). ,
,
.
YouTube (. 9.16).
9.15. , Android

URL

Android Tapp

http://www.androidtapp.com

Appolicious

http://www.androidapps.com

AppBrain

http://www.appbrain.com

AndroidZoom

http://www.androidzoom.com

Appstorm

http://android.appstorm.net

Best Android Apps Review

http://www.bestandroidappsreview.com

Android App Review Source

http://www.androidappreviewsource.com

Androinica

http://www.androinica.com

AndroidLib

http://www.androlib.com

Android and Me

http://www.androidandme.com

AndroidGuys

http://www.androidguys.com/category/reviews

Android Police

http://www.androidpolice.com

AndroidPIT

http://www.androidpit.com

Phandroid

http://www.phandroid.com

380 9 Google Play


9.16. Android

URL

Daily App Show

http://dailyappshow.com

Crazy Mikes Apps

http://crazymikesapps.com

Appolicious

http://www.appvee.com/?device_filter=android

Life of Android

http://www.lifeofandroid.com/video/

Android Video Review

http://www.androidvideoreview.net/

-
,
. ,
Web 2.0, , ,
RSS- PR-. . 9.17
-, , -,
- .
9.17. PR-

URL

PRWeb

http://www.prweb.com

- ( )

ClickPress

http://www.clickpress.com


( ). ClickPress,
.
ClickPress
-

PRLog

http://www.prlog.org/pub/

i-Newswire

http://www.i-newswire.com

openPR

http://www.openpr.com

http://www.prleap.com

PR Leap

9.13. 381

URL

Marketwire

http://www.marketwire.com

-,

: , . .

Mobility PR

http://www.mobilitypr.com

, ,

Press Release
Writing

http://www.press-releasewriting.com

-, : ,
- ..
-


(, , ,
) . (. 9.18)
, Android ( ). , , (, Android, iPhone,
BlackBerry ) . ,
, .
9.18.

URL

AdMob (Google)

http://www.admob.com/

Medialets

http://www.medialets.com

Tapjoy

http://www.tapjoy.com

Nexage

http://www.nexage.com

Jumptap

http://www.jumptap.com

Smaato

http://www.smaato.com

mMedia

http://mmedia.com

InMobi

http://www.inmobi.com

Flurry

http://www.flurry.com

(, ..).

382 9 Google Play


Opera State of Mobile Advertising1, eCPM
(effective cost per 1000 impressions, )
Android $0,88 ( , ..).
Android (CTR, clickthrough rate),
. Jmptap,
CTR 0,65%2,
, ,
.. CTR
, .
, ,
.

9.14.
Google Play Google Wallet, . ,
Google Play,
Android, , AndroidManifest.xml. , Google
Play, ,
.


. ,
, Google Play.

http://www.insidemobileapps.com/2012/12/14/ios-leads-the-pack-in-ecpm-traffic-and-revenueon-operas-mobile-ad-platform-ipad-average-ecpm-of-4-42/

http://paidcontent.org/2012/01/05/419-jumptap-android-the-most-popular-but-ios-still-moreinteractive-for-ads/

. , . , .
Android
.

.
.
.
. , .
.

, 192102, -, . (. ), 3, , . 7.
034-2014, 58.11.12.000
, .
06.03.15. 70100/16. . . . 30,960. 1200. 0000.

142300, , . , . , 1.
: www.chpk.ru. E-mail: marketing@chpk.ru
: 8(496) 726-54-10, : (495) 988-63-87