Android SDK with Java Basics: 09


Backwards Compatibility Strategies

If you wish to conditionally execute some lines of code based on what version of Android the device is running, you can check the value of Build.VERSION,

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { 
 	// do something only on API Level 9 and higher
}

Project: DownloadNotify

Suppose we want to download a file. That may take some time. If we are having a service download the file, there is the possibility that our UI is no longer in the foreground at the time the download is done, so we cannot necessarily update the UI.

On API Level 11 and higher, there is a Notification.Builder class that you can use. But, you may prefer to use NotificationCompat.Builder, this will work back to API Level 4.

setAutoCancel(true): When the user slides open the notification drawer and taps on our entry, the Notification is automatically canceled and goes away.

setDefaults(Notification.DEFAULT_ALL): Playing the device’s standard notification tone, LED light flash, and vibration to occur when the Notification is displayed.

if the user taps on our notification, we will attempt to bring up a PDF viewer on the downloaded PDF file.

locally-unique integer NOTIFY_ID can later be used with a cancel() method to remove the Notification from the screen.

Run the app in wear devices too.

Project: Big Notifications (BigNotify)

This sample application wrapped a regular Notification in a NotificationCompat.InboxStyle “big” Notification, one with both a regular action and a separate “Play” action button.

setPriority() to set the priority of the Notification means that this Notification may be displayed higher in the notification drawer than it might ordinarily appear.

addAction() adds an action button to the Notification, to be shown in the expanded form.

Project: Foreground Services (Foreground)

If you have a service that will run for a substantial period of time, there is a risk that your process will still be terminated.

But, what about services that are delivering value to the user for a long period? For example, a music player. For those sorts of situations, you can flag a service as being a “foreground service”.

setOngoing(true), to indicate that this is an “ongoing” operation. This precludes the user from removing the Notification manually, as doing that would drop our process out of foreground priority.

Run the app in wear devices too.

Project: Notification-Stacked

An email client won’t raise a separate Notification for each email. Rather, the vision is that you update an existing Notification with new content. For example, after a regular Notification for the first time, you replace that Notification with one that has a simple summary (“2 messages are in your inbox!”)

setGroup() associates the Notification with a group, identified by a String key.

Project: Notification-BigLocal

Sometimes, you will want to raise a Notification that does not make sense to show on a Wear device, only on the primary device. In that case, you will need to call setLocalOnly()

Project: Notification-Pages

With a Wear device, app raising Notification involves pulling out the primary device. It might be nice to provide some additional information to the Wear user, so that perhaps they can make a more informed decision as to whether it is worthwhile to open up their primary device. In Wear terms, this involves adding more “pages” to a Notification.

Project: Notification-WearActions

To set up Wear-only actions, use addAction() on WearableExtender, as opposed to (or in addition to) addAction() on NotificationCompat.Builder.

setGroup() associates the Notification with a group, identified by a String key.

Project: Notification-VoiceInput

Voice input can be very handy responding to a text message without pulling out one’s phone.

The key for retrieving the response in our VoiceReceiver (VoiceReceiver.EXTRA_SPEECH)

Project: Notification-RemoteInput

Starting with Android 7.0, RemoteInput is also available for standard device as well as wear device. Rather than using voice input, you get a small EditText into which the user can type something and submit it.

Project: Notification-Lollipop

The default behavior is a “private” Notification. Basic information appears on the lockscreen, but not the whole Notification.

You could flag your main Notification as having public visibility. This is suitable for notifications where there is little to no privacy implications.

Secret notifications only appear once the user has gotten past the lockscreen.

From Android 5.0, you can show high-priority notifications in a “headsup” style, popping up a small dialog-like window over the main screen, with the same basic content as would appear for the Notification in its title.

Project: Notification-FullScreen

Sometimes we need to be somewhat more “in the user’s face”, such as for a calendar event reminder, or for an incoming phone call from our VOIP app.

You could launch and activity and some apps actually do launch an activity.

A “middle ground” between showing a Notification and launching an activity is to use a full-screen Notification. However, on Android 5.0+, the behavior has changed, where a full-screen Notification actually just triggers a heads-up notification.

Project: Http-OkHttpProgress

Use setProgress() on the NotificationCompat.Builder, periodically updating the Notification to reflect the now-current amount of progress.

ProgressSource does two things:

  1. It tracks the total number of bytes that have been read so far
  2. Every time that we read more data, we call a ProgressResponseBody.Listener with the number of bytes that have been read so far

Project: Notification-CustomView

Project: Notification-Messaging

Notification.MessagingStyle is part of Android 7.0’s SDK, so this project demonstrates the use of NotificationCompat.MessagingStyle, from the Android Support libraries for backwards compatibility.

Project: GridLayout-Sampler

GridLayout works a bit like TableLayout, insofar as it sets things up in a grid, with rows and columns, where the row and column sizes are computed based upon what is placed into those rows and columns.

However, unlike TableLayout, which relies upon a separate TableRow container to manage the rows, GridLayout takes the RelativeLayout approach of putting rules on the individual widgets (or containers) in the grid, where those rules steer the layout processing.

GridLayout’s columns and rows will have a size of 0 by default. Hence, to ensure that each row and column has a minimum size, this layout uses Space elements to establish those minimums.

Project: Dialogs-Chrono

Project: Dialogs-DialogFragment

One challenge with dialogs comes with configuration changes. If user rotates screen, presumably the dialog should remain on the screen after the change. However, since Android wants to destroy and recreate the activity, that would have dire impacts on your dialog.

DialogFragment handles the configuration change process. You have two ways of supplying the dialog to the DialogFragment:

  1. You can override onCreateDialog() and return a Dialog, such as AlertDialog created via an AlertDialog.Builder
  2. You can override onCreateView(), as you would with an ordinary fragment,
    and the View that you return will be placed inside of a dialog

onCancel() is called if the user presses the BACK button to exit the dialog.

onDismiss() is called whenever the dialog goes away for any reason (BACK or a button click).

Project: HeaderDetailList

Project: ActionBar

Project: NavDrawer-Simple

One thought on “Android SDK with Java Basics: 09

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.