Creating Android Apps in Java and XML
http://markmeretzky.com/android/
mark.meretzky@gmail.com

In Fall 2018 at NYU SPS, this course is INFO1-CE9416. The iOS course has the same format. The one-day version of this course consists of the 16 examples marked with an orange sun.

Getting Started

  1. Installation. Instructions for installing Android Studio, VirtualBox, and Genymotion on your Mac, PC, or Linux.
  2. XML. Part of an Android app is written in the Extensible Markup Language (XML), part in Java.
  3. Hello. Create a “Hello, World!” app and run it on the Android emulator, the Genymotion emulator, or your phone.
    1. Create one activity object. The <activity> element in the app’s AndroidManifest.xml file specifies which subclass of class Activity will be instantiated.
    2. Call the onCreate method of the activity object when the app is launched.
    3. onCreate is one of the methods in one of the three pairs of Activity lifecycle methods. Don’t call them directly. For example, call finish to trigger a call to onDestroy. Permanent data should be saved in onPause, not in onDestroy.
    4. activity_main.xml contains a RelativeLayout which contains a TextView. The items inside a RelativeLayout can have positioning attributes such as android:layout_below and android:layout_toRightOf.
    5. Drag in the TextClock (exercise #11).
  4. Layouts. A layout is a big view that contains smaller views and positions them on the screen.
    1. RelativeLayout.
    2. LinearLayout.
    3. Classes FrameLayout and FrameLayout.LayoutParams. A FrameLayout usually holds only one child. See exercise 12 in LinearLayout; exercise 1 in GridView; Sqlite.
  5. Bed. This app is a testbed for playing with Java variables, statements, loops, if statements, and objects. Input and output are performed by dialog boxes that pop up and are dismissed.
  6. The Java language.
    1. Before Objects. Data types, values, variables, control structure, arrays.
    2. Class. Create a class and an object of the class. Create a variable that contains a reference to the object. Create a subclass that overrides a method of the superclass. Create the subclass as an anonymous inner class. The anonymous inner class will be needed when we create a listener such as the View.OnClickListener in Listener.
  7. Text. Instead of printing a predefined string, compose the text as the app runs.
    1. Pop up a piece of Toast on the Android screen.
    2. Pop up a dialog box on the Android screen.
    3. Write to a TextView on the Android screen.
    4. Write to the standard output of the adb logcat command on your Mac or PC. Direct the standard output into a pipe or a file.
    5. Change of orientation (portrait vs. landscape) is an example of a configuration change that will destroy and re-create the Activity object.
  8. Copy your app from Android Studio to one of three destinations.
    1. Zip file.
      1. Save the project as a .zip file.
      2. Reopen the project from the .zip file.
    2. GitHub. Upload the source code of your app to the GitHub website. Links to accounts:
      1. Spring 2015 Section 2 (Saturday)
      2. Summer 2015 Section 2 (Saturday)
      3. Fall 2015 Section 1 (Saturday)
    3. Download. Download the app to an Android device (a phone or tablet).
  9. Screenshot. Capture a screenshot of your app as it runs on an emulator or on an Android device.
  10. Sample apps.
    1. Contemporary samples. Try UI → BorderlessButtons for example. The left panel lets you see the source code files.
    2. ApiDemos: Lots of small, self-contained activities. Although it’s been relegated to the legacy folder, it’s still my favorite set of demonstrations, and is still bundled with every Android emulator. Try
      Views → Buttons
      Graphics → OpenGL ES → OpenGL ES 2.0
  11. Busybox lets you run classic Unix utilities (grep, awk, find, etc.) on your Android emulator or device.

Controls and Listeners

Install an event listener into a View. This is the most important topic of the course.

  1. Click Listener. A View.OnClickListener can be installed into a Button or into any other type of View. The View.OnClickListener has a method named onClick. Composition vs. inheritance.
  2. Key Listener. A View.OnKeyListener can be installed into an EditText. The View.OnKeyListener has a method named onKey.
  3. Change Listener. A SeekBar.OnSeekBarChangeListener can be installed into a SeekBar (slider). The SeekBar.OnSeekBarChangeListener has a method named onProgressChanged.
  4. Crawl. Move the Star Wars crawl with a SeekBar.
  5. Date Picker. A DatePicker.OnDateChangedListener can be installed into a DatePicker. The DatePicker.OnDateChangedListener has a method named onDateChanged.

Create the user interface programmatically

If you want the same interface each time you run the app, create it with an activity_main.xml file. If the interface might be different during each run, create it with executable Java code containing if statements and other conditionals.

  1. Programmatic. Create exactly the same RelativeLayout and Button as the activity_main.xml file of the Click Listener example.

Still-life graphics

Draw the graphics in a subclass of class View containing a constructor and an onDraw method.

  1. Japan. Create a new subclass of class View, and an object of that class.
    1. Call methods of the Canvas argument passed to onDraw: drawColor, drawCircle, drawRect, drawPoint, drawLine.
    2. Create a Path containing a series of points connected by straight lines: moveTo and lineTo. Needed because Canvas has no methods for drawing triangles, pentagons, houses, etc.
    3. Transformations: translate, scale, rotate, skew.
  2. Drawable. Create a new shape (a triangle) that can be drawn as easily as the built-in shapes such as circle and rectangle.
  3. Manhattan. Apply transformations to coördinates drawn from a Google map.
  4. America. Draw an image file on the screen.
  5. HTML5. Draw the graphics in HTML5 instead of in Android. Display them in a WebView object.

Graphics that respond to touch and gravity

The following pictures redraw themselves when you touch the screen. See the invalidate method of class View.

  1. Touch. Move a drawable shape in response to a tap or drag.
  2. Etch. An Etch A Sketch that uses the interface View.OnTouchListener and its method onTouch. Uses the Path we saw in the triangle in Japan. Erases itself when the activity’s configuration (e.g., orientation) changes; see Configuration Changes.
  3. Face. Is the Android device lying face up or face down? The accelerometer registers the force of gravity.
  4. Plumb. The accelerometer tells the plumb bob which way is down.
  5. Where. Where on the tabletop has the Android device been pushed to?

Built-in animations

Make the graphics move under their own power, without having to be dragged with a finger. See Animation and Graphics.

  1. Animation. An Animation object such as TranslateAnimation (added in API 1) can smoothly change the position at which a View is displayed, but it has no effect on the View itself and its fields. This type of animation has been superseded by ViewPropertyAnimator, is applicable only to an object of class View and only to certain of its properties: alpha, translate, scale, and rotate. See View Animation.
  2. ViewPropertyAnimator. A ViewPropertyAnimator (added in API 12) is the fastest and simplest way to smoothly change a field of a View object. This type of animation is applicable only to an object of class View and only to certain of its properties: alpha, translate, scale, rotate, x, y, and z. See Animating with ViewPropertyAnimator.
  3. Puzzle. The tiles of this classic 3 × 3 puzzle move with a ViewPropertyAnimator.
  4. 8 Ball. The answer to your question floats to the surface with a ViewPropertyAnimator.
  5. Collective. This app is one of several apps that can launch each other’s Activitys. The Activity in this app uses two ViewPropertyAnimators.
  6. ObjectAnimator. An ObjectAnimator (added in API 11) can smoothly change any field of any object, including objects that are not Views and fields of any data type. Unlike an Animation, a ObjectAnimator actually changes the object’s fields, not merely its appearance on the screen. See Animating with ObjectAnimator.
  7. Crawler. Use an ObjectAnimator to animate the top padding property of a View.
  8. Phase. A motion picture made of a series of images.

A second thread

  1. Anr: the user interface freezes when the main thread attempts a task that takes more than five seconds. This causes an Application Not Responding error message.
  2. Thread: create a second thread.
  3. DownloadFile. Download a file in a worker thread. Then call post to update the user interface in the main thread.

Custom animations

Implement an animation by having a separate thread call postInvalidate (instead of plain old invalidate) over and over to trigger calls to the the onDraw method of the View.

  1. Pong. Respond to two fingers simultaneously (multi-touch).
  2. Pearl. Give a graphic heft by endowing it with mass and momentum. Get accelerometer input.

Gesture recognition

A View is touch-sensitive because we plugged a touch listener into it. The touch listener can store information about each touch into a gesture detector object. When the gesture detector feels it has received all the information necessary to constitute a gesture, it calls one of the methods of the gesture listener plugged into the gesture detector. See Gestures and Detecting Common Gestures.

  1. Tap. Recognize a single vs. double tap.
  2. Fling. Recognize a horizontal vs. vertical swipe.
  3. Pinch. Recognize a pinch vs. spread (two fingers).
  4. Gesture. Create your own gestures with the Gestures Builder app.

Plug an adapter into an adapter view

A data item is a number, string, image, etc. We can display one or more data items in a View by calling the drawText or drawBitmap methods of the Canvas passed to the onDraw method of the View; see America for an example. In this section, however, we will display each data item in its own View.

An Adapter takes a series of data items and encases each one in a View. The simplest example of an Adapter is an ArrayAdapter, which gets its data items from a Java array.

An Adapter creates Views, but does not actually display them on the screen. To display the Views we plug the Adapter into an AdapterView, which is a big View that can display smaller Views inside it. In other words, an AdapterView is an example of ViewGroup. In more other words, class AdapterView is a subclass of class ViewGroup. See Building Layouts with an Adapter.

  1. Spinner. The simplest example of an AdapterView is a Spinner (dropdown menu). The Adapter we plug into this Spinner is an ArrayAdapter.
  2. ListView. A ListView is another example of an AdapterView.
  3. Adapter. We can’t use class ArrayAdapter here, so we’ll have to build our own implementation of interface Adapter.
  4. GridView of images. A GridView is another type of AdapterView. We’ll have to make our own implementation of the Adapter interface.

Plug a cursor into an adapter

  1. Images. A SimpleCursorAdapter can write an image into an ImageView as easily as it can write text into a TextView.
  2. Play with SQLite (the Structured Query Language for databases) using the sqlite3 command line shell.
  3. Stroker. This app creates an SQLite database and reads and writes it using graphics and touches.
  4. Sqlite. This app creates an SQLite database and reads and writes it using a ListView and Dialogs.
  5. Assets. This gets a pre-written SQLite database from the assets folder and reads and writes it.

Content providers

  1. Cursor. Read the contacts list with a Cursor. The Cursor comes from a CursorLoader running under the control of the LoaderManager.
  2. CursorAdapter. Plug a Cursor into an Adapter; plug the Adapter into an AdapterView. Our AdapterView is a SimpleCursorAdapter and our AdapterView is a ListView.
  3. President. Create a content provider, and a client that will read and write the data stored by the content provider.

Read from a remote database

  1. Offer. A GridView of real estate offers read from an SQLite database.
  2. Restaurant. The New York City Restaurant Inspection Database in CSV format. P means “padlocked”.
  3. JSON. Parse a string written in JSON format. Another example:
    https://maps.googleapis.com/maps/api/geocode/json?address=7+East+12th+Street,+New+York,+NY+10003
  4. Weather. Read one record, not an entire database, from a server. The record arrives in JSON format.
  5. Top Stories from the New York Times API.
  6. WeatherGrid. Display seven records in a GridView.
  7. Client. Read and write records in a database on a server. The Android app is the client.
  8. Near. Get records for restaurants in one zipcode from a server.

Read and write a database in the cloud

  1. Parse.com: host a database at Parse.com.

Launch an Activity

Use an Intent object to launch an Activity belonging to another app. See Starting Another Activity.

  1. Dial. Dial the telephone.
  2. Speech recognition. Get a result back from the other activity.

Multi-threaded Activity

The main thread must never attempt a job that takes more than five seconds. For longer jobs, the main thread must create a worker thread. But only the main thread can access the user interface. See Threads-threaded. See Offer for threads with Runnable, Thread, Handler, and AsyncTask. See MediaPlayer for AsyncTask with publishProgress and onPublishProgress.

  1. Rocket: create several threads running simultaneously with classes Runnable and Thread.
  2. postDelayed
  3. Class Handler. Examples: animation, time picker.
  4. Class AsyncTask. See How to Avoid ANRs. Example.

Still photos, video, audio

  1. Photo: take a still photo and store it in the Gallery app.
  2. VideoView: play a video file using a VideoView object.
  3. PhotoByIntent: Android’s sample app to take thumbnails, full-size photos, and videos.
  4. Record: record audio using a MediaRecorder and save the file in the Music folder.

Services vs. Activities.

  1. MediaPlayer. Have an Activity play music using a MediaPlayer. The music starts playing from the beginning when the Activity is destroyed and recreated by a change of orientation.
  2. MediaPlayerService. The same MediaPlayer, but now run by a Service instead of by the Activity. The music reliably keeps playing even after the Activity is destroyed.
  3. Binder. The Activity and the Service share and communicate via a binder object.
  4. AudioService. The Service is executed by a separate thread.

GPS, Google Maps, Geocoding

  1. Location. Get your latitude and longitude from the GPS.
  2. MapView. Display a Google map in a MapView using the Google Maps Android API version 2.
  3. Map. Display a Google map in a WebView using the Google Maps Android JavaScript API v3.
  4. Address. Convert a latitude and longitude into a street address and zipcode.
  5. Marker. Convert a street address into a latitude and longitude. Put a Marker there with a label and Infowindow.
  6. Violation. Display each restaurant’s violation description when you touch its marker.

Broadcast Receivers

OpenGL ES three dimensional graphics

User interface topics

  1. Menu.
  2. Dialog.
  3. Action bar and status bar.
  4. Notification. See MediaPlayerService.
  5. Fragment.