[Remark@2015-11-01: getMyLocation() method is deprecated.use com.google.android.gms.location.FusedLocationProviderApi instead. FusedLocationProviderApi provides improved location finding and power usage and is used by the "My Location" blue dot. See the MyLocationDemoActivity in the sample applications folder for example example code, or the Location Developer Guide.]

In this exercise, Google Maps Android API v2 is implemented with MyLocation enabled. When user LongClick on the Map, a marker will be drawn, and a Polyline from touched location to MyLocation will be drawn if MyLocation is available.

To get MyLocation programmatically, you have to enable my-location layer by calling setMyLocationEnabled(true). Then call getMyLocation(), it returns the currently displayed user location, or null if there is no location data available. Please noted that MyLocation may be need long time to available.

Google is launching Google Maps Engine Lite (Beta) helping you create advanced custom maps to share with collaborators and also publish to the web. You can visualize and map more data, import locations from a spreadsheet, use layers to visualize different types of content, or simply draw and add places, lines, and shapes.

To stop a IntentService, call the method stopService (Intent service). It request that a given application service be stopped. If the service is not running, nothing happens. Otherwise it is stopped. Note that calls to startService() are not counted -- this stops the service no matter how many times it was started. So imple? not at all.

In this exercise, buttons are added to start and stop IntentService. It can be noted that:

If you click the "Start IntentService" multi times, only one request will be processed at a time, All requests are handled on a single worker thread. The extra requests will be place in a queue.

If you click the "Start IntentService" multi times, only ONE call of stopService() is need to stop all request.

If you remove the checking on the boolean stopped, in onHandleIntent() of MyIntentService.java; call stopService() will call onDestroy() of MyIntentService, but the code in onHandleIntent() will keep running until finish by itself. Because onHandleIntent() is running on another worker thread.

Refer to the exercise "Example of using NotificationCompat.Builder"; if the statement of new NotificationCompat.Builder...build() modified to remove .setContentIntent(pendingIntent), error of java.lang.IllegalArgumentException: contentIntent requiredMAY be thrown.

It will have no error in compile time, and no error when run on HTC One X (Android 4.1.1) and HTC Fly (Android 3.2.1). But error when run on Nexus One (Android 2.3.6), with error:

But how can main Activity know the status of IntentService before end of job? It's another exercise to send additional Broadcast with another IntentFilter while running, to update main Activity, from IntentService. Such that we can implement additional BroadcastReceiver in main Activity to receive the additional Broadcast , and then update a ProgressBar.

Last exercise demonstrate "Notification.Builder". If your app supports versions of Android as old as API level 4, you can instead use NotificationCompat.Builder, available in the Android Support library.

android.app.Notification.Builder is a builder class for Notification objects. Provides a convenient way to set the various fields of a Notification and generate content views using the platform's notification layout template. If your app supports versions of Android as old as API level 4, you can instead use NotificationCompat.Builder, available in the Android Support library.

Friday, March 22, 2013

The post "Perform background processing with IntentService" demonstrate how to use IntentService in Activity. In this exercise, we are going to modify the exercise of "Yahoo Weather" to demonstrate how to share one IntentService by three Fragments. Here one IntentService means one common IntentService class, not one common IntentService object.

Creater a abstract class MyAbsYWeatherFragment extends Fragment, all our fragments will extend it. All it's sub-class have to override init_country() method to provide the target city of Yahoo Weather, a string of ACTION_RESPONSE for IntentFilter, and boolean retainInst to determine is it need retain instance. It will start our IntentService and handle all job for our fragments.

- Fragment1 call setRetainInstance(flase), so everytime orientation changed, it will re-start and reload new weather.

- Fragment3 call setRetainInstance(true), so it will not reload weather.

- Fragment2 call setRetainInstance(true), it will not reload weather too. But it have the same Action string for IntentFilter of Fragment1, so when IntentService of Fragment1 finished, BroadcastReceiver of Fragment2 will be called also.

Thursday, March 21, 2013

Parcel is a class container for a message (data and object references) that can be sent through an IBinder. A Parcel can contain both flattened data that will be unflattened on the other side of the IPC (using the various methods here for writing specific types, or the general Parcelable interface), and references to live IBinder objects that will result in the other side receiving a proxy IBinder connected with the original IBinder in the Parcel.

Parcelable is Interface for classes whose instances can be written to and restored from a Parcel. Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface.

android.app.IntentService is a subclass of android.app.Service that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

Create our custom IntentService, MyIntentService.java

You have to implement constructor of MyIntentService(). If you only override the default constructor of MyIntentService(String name) from IntentService, RuntimeException of java.lang.InstantiationException with Unable to instantiate service will be thrown.

Main code in MainActivity.java. In order to receive result from IntentService, implement BroadcastReceiver, register in onCreate() and unregister in onDestroy(). To start MyIntentService, call startService() with coresponding intent.