Geocoding and Reverse Geocoding in Android

Download source code of the article.

Geocoding is the process of finding geographic location from location name, zip codes, etc… Reverse Geocoding is the process of finding location name and other information from geographic location. In Android there is a class Geocoder which handles Geocoding and Reverse Geocoding. This class has three methods: getFromLocation, getFromLocationName and a variant of getFromLocationName.

The method getFromLocation is used to reverse geocode and the method getFromLocationName is used to geocode. The getFromLocation method accepts 3 parameters: latitude, longitude and maximum number of results to return.

There are 2 variants of the method getFromLocationName. Both accept location name and maximum number of results to return. The first variant accepts additional four parameters. These are the longitude and latitude of the bounding rectangle for the search results. If you specify these parameters, the Geocoder will only search within the bounding rectangle, i.e. the results outside the bounding rectangle will not be included in the results.

These functions return a list of Address class which represents the result of the query.

The sample provided is a simple one to demonstrate the use of this class, hope this will help you to start geocoding.

Vibrating the phone in Android

To vibrate the phone we use Vibrator class. This is a system service so we don’t instantiate but use getSystemService to get the instance of the class. The following code snippet vibrates the phone for a period of time.

Vibrator vibrator = (Vibrator)getSystemService(VIBRATOR_SERVICE);
long[] pattern = {0,1000,2000,3000};

vibrator.vibrate(pattern, -1);

The vibrate method accepts the pattern to vibrate and an index of the pattern to start repeating. If we don’t want to repeat pass -1. If we just want to vibrate for a period of time with default pattern then we can use the following variant of the vibrate method which vibrate for 1 second.

vibrator.vibrate(1000);

Using Status Bar Notification in Android

Download source code of the article.

This is an example of using Status Bar Notification in Android. Notifications are using in Android to notify the user of events. The classes Notification and NotificationManager is used create notification. NotificationManager is a system service. We get the instance using getSystemService. The following code snippet creates a default notification:

NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

int icon = R.drawable.icon;
CharSequence text = "Notification Text";
CharSequence contentTitle = "Notification Title";
CharSequence contentText = "Sample notification text.";
long when = System.currentTimeMillis();

Intent intent = new Intent(this, NotificationViewer.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);

Notification notification = new Notification(icon,text,when);

notification.setLatestEventInfo(this, contentTitle, contentText, contentIntent);

notificationManager.notify(Constants.NOTIFICATION_ID, notification);

For creating a status bar notification, we create an instance of Notification class and uses notify method of NotificationManager to add the trigger the notification. Here the Notification class is created with three parameters, icon to display, notification text to ticker and the time at which the notification is displayed. Then we set the notification title, notification text and the Pending Intent to launch when the user clicks on the notification.

The notify method of the NotificationManager is used to trigger the notification. This will add the notification to the status bar area. When the use pulls down the status bar the notification title, text and icon will be shown.

Vibrating the phone

If we want to vibrate the phone when the notification is displayed, then we can set the vibration pattern or use the flag to use the default vibration. Following code snippet sets the default vibration.

notification.defaults |= Notification.DEFAULT_VIBRATE;

To vibrate we set the vibrate member of the notification class. This is an array of long values; first element is the millisecond to wait before start, second is the length of the first vibration, third is the next millisecond to stay off and forth is the next millisecond to stay on and so on. The pattern can be as long as we like. Following code snippet sets the vibration:

long[] vibrate = {0,100,200,300};
notification.vibrate = vibrate;
Flashing the LED If we want to flash the LED then we can use the defaults flag to DEFAULT_LIGHTS. Following code snippets adds the default LED flash.
notification.defaults |= Notification.DEFAULT_LIGHTS;

To use our own color pattern, set the ledARGB, ledOffMS, and ledOnMS and add the FLAG_SHOW_LIGHTS to the flag field. Following code snippets add a custom color pattern.

notification.ledARGB = Color.RED;
notification.ledOffMS = 300;
notification.ledOnMS = 300; 

Using a custom view to display notification.

In the above example the notification is displayed in a default view. If we want to use our own custom view to display notification, then we can define the custom layout using the RemoteView. For this we create an instance of RemoteView and set the contentView field of the Notification class.

Note: If we are setting the contentView then we should set the contentIntent field also, otherwise an exception will occur.

The RemoteView provides helper methods to set the values of the layout items like setTextViewText, setProgressBar, setImageViewResource, etc…

The example provided here is a simple one to display default and custom view notifications. The custom view defines an image view, text view and a progress bar. Once the custom notification is triggered, the application creates a thread to start the progress bar update. This is a simple method display the progress indicator. Real world scenarios require more complicated method.

Using PhoneStateListener to listen to state change in Android

Download source code of this article.

My previous article explains how to use the TelephonyManager. One of the important functionality of TelephonyManager is listening to different phone state events. The method listen(PhoneStateListener listener, int events) is used to add a phone state listener. The first parameter is the PhoneStateListener class and the second parameter is the int value contains various phone state to listen. We can listen for following events:

PhoneStateListener.LISTEN_SIGNAL_STRENGTH
PhoneStateListener.LISTEN_DATA_ACTIVITY
PhoneStateListener.LISTEN_CELL_LOCATION
PhoneStateListener.LISTEN_CALL_STATE
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
PhoneStateListener.LISTEN_SERVICE_STATE

The PhoneStateListener has following methods:

void onCallForwardingIndicatorChanged(boolean cfi)
void onCallStateChanged(int state, String incomingNumber)
void onCellLocationChanged(CellLocation location)
void onDataActivity(int direction)
void onDataConnectionStateChanged(int state)
void onDataConnectionStateChanged(int state, int networkType)
void onMessageWaitingIndicatorChanged(boolean mwi)
void onServiceStateChanged(ServiceState serviceState)
void onSignalStrengthChanged(int asu)
void onSignalStrengthsChanged(SignalStrength signalStrength)

The PhoneStateListener.LISTEN_SIGNAL_STRENGTH events invoke the onSignalStrengthChanged(int asu) method. This method requires the permission READ_PHONE_STATE. The method has one integer parameter which is the signal strength value. This value can be in the range 0-31. This function is deprecated in Android Version 2.0 and above. Above 2.0 we should use the onSignalStrengthsChanged(SignalStrength signalStrength) method. Only one parameter is there and it SignalStrenth class. The SignalStrength class has different following methods:

int describeContents()
boolean equals(Object o)
int getCdmaDbm()
int getCdmaEcio()
int getEvdoDbm()
int getEvdoEcio()
int getEvdoSnr()
int getGsmBitErrorRate()
int getGsmSignalStrength()

The function names describes its purpose.

The PhoneStateListener.LISTEN_DATA_CONNECTION_STATE event invokes the methods onDataConnectionStateChanged(int state) and onDataConnectionStateChanged(int state, int networkType). Both these are invoked. The first parameter is the connection state and can be one of the following values:

TelephonyManager.DATA_DISCONNECTED
TelephonyManager.DATA_CONNECTING
TelephonyManager.DATA_CONNECTED
TelephonyManager.DATA_SUSPENDED

The PhoneStateListener.LISTEN_DATA_ACTIVITY event invokes the method onDataActivity(int direction). This method requires the permission READ_PHONE_STATE. The direction parameter can be one of the following values:

TelephonyManager.DATA_ACTIVITY_IN
TelephonyManager.DATA_ACTIVITY_OUT
TelephonyManager.DATA_ACTIVITY_INOUT
TelephonyManager.DATA_ACTIVITY_NONE

The PhoneStateListener.LISTEN_CALL_STATE event invokes the method onCallStateChanged(int state, String incomingNumber). This method requires the permission READ_PHONE_STATE. The state parameter can be one of the following values:

TelephonyManager.CALL_STATE_IDLE
TelephonyManager.CALL_STATE_RINGING
TelephonyManager.CALL_STATE_OFFHOOK

The incomingNumber parameter contains the incoming number if the state is TelephonyManager.CALL_STATE_RINGING.

The PhoneStateListener.LISTEN_CELL_LOCATION event invokes the method onCellLocationChanged(CellLocation location) method. This method requires the permission ACCESS_COARSE_LOCATION. This will be an instance of GsmCellLocation class. GsmCellLocation class is explained in my previous article.

The PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR event invokes the method onCallForwardingIndicatorChanged(boolean cfi) method. This method requires the permission READ_PHONE_STATE. The boolean parameter cgi indicates whether the current call is forwarding or not.

The PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR event invokes the method onMessageWaitingIndicatorChanged(boolean mwi). This method requires the permission READ_PHONE_STATE. The boolean parameter mwi indicates whether an incoming message is waiting for user attention or not.

The PhoneStateListener.LISTEN_SERVICE_STATE event invokes the method onServiceStateChanged(ServiceState serviceState). The parameter is an instance of ServiceState class. The ServiceState class has methods to retrieve operator name in short alphanumeric format, operator name in short long format, operator id, etc…

To un-register a listener we use the method listen with event parameter set to LISTEN_NONE.

The sample provided is same for this and the previous article. Hope this article helps to to get started with PhoneStateListener.

Using Android TelephonyManager

Download source code of this article.

Android TelephonyManager provides information about the android telephony system. To use the TelephonyManager first get the instance of the Telephony Service by calling Context.getSystemService(TELEPHONY_SERVICE). This telephony service can be used to retrieve Call State, Cell Location, Operator Name, etc… as well as to listen to the various telephony events. Following are some of the important information we can get from TelephonyManager:

Cell Location

The getCellLocation method is used to get the Cell Location of the device. This method returns an instance of GsmCellLocation class. The getCid() and getLac() methods of this class can used to retrieve the Cell ID and LAC of the device. This method requires the permission ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION. Following code snippet shows how to retrieve the Cell ID and LAC.

TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
GsmCellLocation loc = (GsmCellLocation) tm.getCellLocation();

int cellid = loc.getCid();
int lac = loc.getLac();

IMEI/MEID

The getDeviceId() method is used to get the IMEI/MEID of the device. If the device is a GSM device then IMEI will be returned and if the device is a CDMA device then MEID will be returned. This device id can be used to uniquely identify the device. This method requires the permission READ_PHONE_STATE. Following code snippet retrieve the device id.

String deviceid = tm.getDeviceId();

Device Phone Number

The getLine1Number() method returns the device phone number (MSISDN). This method requires the permission READ_PHONE_STATE. Following code retrieve the device phone number:

String phonenumber = tm.getLine1Number();

Note: This function name not work prior to Android Version 2.0.

Network Name

The getNetworkOperatorName() method returns the registered network operator’s name, getNetworkOperator() method returns the MCC + MNC of the registered network operator and getNetworkCountryIso() returns the registered network operator’s country code. This information may not be available on CDMA devices. Following code snippets retrieves these details:

String operatorname = tm.getNetworkOperatorName();
String operatorcode = tm.getNetworkOperator();
String operatoriso = tm.getNetworkCountryIso();

SIM Card Infomarion

The getSimCountryIso() returns the SIM operator’s country code, getSimOperator() returns the SIM operator’s MNC + MCC number, getSimOperatorName() returns the SIM operator’s name and getSimSerialNumber() returns the SIM Serial Number. This method requires the permission READ_PHONE_STATE. Following code snippets reads the SIM Card information:

String simcountrycode = tm.getSimCountryIso();
String simoperator = tm.getSimOperatorName();
String simserialno = tm.getSimSerialNumber();

Network Type

The getNetworkType() returns the type of the network available in the device. This method returns one of the following values:

TelephonyManager.NETWORK_TYPE_UNKNOWN
TelephonyManager.NETWORK_TYPE_GPRS
TelephonyManager.NETWORK_TYPE_EDGE
TelephonyManager.NETWORK_TYPE_UMTS

Phone Type

The getPhoneType() returns the device type. This method returns one of the following values:

TelephonyManager.PHONE_TYPE_NONE
TelephonyManager.PHONE_TYPE_GSM
TelephonyManager.PHONE_TYPE_CDMA

Subscriber ID

getSubscriberId() return the subscriber id of the device. This is IMSI if the device is a GSM device. If unavailable the function returns null. This function requires the permission READ_PHONE_STATE.

Neighboring Cell Information

The getNeighboringCellInfo() function returns a list of NeighboringCellInfo class which represents the neighboring cell information if available otherwise the function returns null. This function returns the permission ACCESS_COARSE_UPDATES. Following code snippet returns the this information:

List cellinfo = tm.getNeighboringCellInfo();

for(NeighboringCellInfo info: cellinfo){
    cellid = info.getCid();
    rssi = info.getRssi();
}
Note: I never got this working. I search a lot but I didn't get any useful information why it is not returning value. Also when I ran this on a Android Version 1.6 Developer Phone I got a Unknown permission android.permission.ACCESS_COARSE_UPDATES. Please let me know if you get this working. Listening to Phone State Change
The listen() method is used to register a phone state listener. It accepts a PhoneStateListener instance and an int value specifying what are the events to listen. Following are the events we can listen:
PhoneStateListener.LISTEN_SIGNAL_STRENGTH
PhoneStateListener.LISTEN_DATA_ACTIVITY
PhoneStateListener.LISTEN_CELL_LOCATION
PhoneStateListener.LISTEN_CALL_STATE
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
PhoneStateListener.LISTEN_SERVICE_STATE

PhoneStateListener class has following method:

void onCallForwardingIndicatorChanged(boolean cfi)
void onCallStateChanged(int state, String incomingNumber)
void onCellLocationChanged(CellLocation location)
void onDataActivity(int direction)
void onDataConnectionStateChanged(int state)
void onDataConnectionStateChanged(int state, int networkType)
void onMessageWaitingIndicatorChanged(boolean mwi)
void onServiceStateChanged(ServiceState serviceState)
void onSignalStrengthChanged(int asu)
void onSignalStrengthsChanged(SignalStrength signalStrength)

Listening to phone state requires a separate article to describe, so this will be explained in my next post.

Following table describes important functions and its permission:

Function Description
getCellLocation() Returns the the Cell Location of the device
ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION
getDeviceId() Returns the IMEI/MEID of the device. If the device is a GSM device
then IMEI will be returned and if the device is a CDMA device then MEID
will be returned
READ_PHONE_STATE
getLine1Number() Returns the device phone number (MSISDN)
READ_PHONE_STATE
getNetworkOperatorName() Returns the registered network operator's name
getNetworkOperator() Returns the MCC + MNC of the registered network operator
getNetworkCountryIso() Returns the registered network operator's country code
getSimCountryIso() Returns the SIM operator's country code
READ_PHONE_STATE
getSimOperator() Returns the SIM operator's MNC + MCC number
READ_PHONE_STATE
getSimOperatorName() Returns the SIM operator's name
READ_PHONE_STATE
getSimSerialNumber() Returns the SIM Serial Number
READ_PHONE_STATE
getNetworkType() Returns the type of the network available in the device. This will be
one of the following values:

TelephonyManager.NETWORK_TYPE_UNKNOWN

TelephonyManager.NETWORK_TYPE_GPRS

TelephonyManager.NETWORK_TYPE_EDGE

TelephonyManager.NETWORK_TYPE_UMTS


READ_PHONE_STATE

getPhoneType() Returns the device type. This will be one of the following values:

TelephonyManager.PHONE_TYPE_NONE

TelephonyManager.PHONE_TYPE_GSM

TelephonyManager.PHONE_TYPE_CDMA


READ_PHONE_STATE

getSubscriberId() Return the subscriber id (IMSI) of the device
READ_PHONE_STATE
getNeighboringCellInfo() Returns a list of NeighboringCellInfo class which represents the
neighboring cell information if available otherwise the function
returns null
ACCESS_COARSE_UPDATES

Programming GPS on Android and calculating distance between two geographic locations

Download source code of the article.

Programming GPS on Android is fairly simple. In Android to get GPS updates you simply initiate LocationManager class, find a GPS provider and request for updates. To initiate LocationManager manager class you call getSystemService method of the Activity class. LocationManager class provides the location service and periodic updates of the geo location. Once you get the LocationManager class next step is to find out the best GPS provider available on the system which satisfies your criteria.

To get the provider you specify different criteria you need like accuracy, altitude, bearing, etc… For this we use the Criteria class. Following is a sample criterion:

final Criteria criteria = new Criteria();

criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);

To find out whether a GPS provider best matches the given criteria we use the getBestProvider method of the LocationManager class. This manager will return name of the location provider if it is available. Otherwise the criteria are modified/loosened in the following order:

    Power requirement
    Accuracy
    Bearing
    Speed and
    Altitude

Once we get the provider, we request updates using requestLocationUpdates method. If you only need current location and not need to receive continuous location update you can use getLastKnownLocation method to get the last known location of the device.

To request continuous location we device a variable of LocationListener class and override onLocationChanged method. LocationManager will call this method and pass a Location class whenever there is a change in the device geographic location.

To calculate the distance between two geographic locations, the Location class provides a static method distanceBetween. This method calculates the distance between two geographic locations in meters and returns the result in a float array you pass. You can pass an array of length 1, 2 or 3.

The first element (array[0]) will be the distance in meter. If the array has 2 or more elements the second element (array[1]) will hold the initial bearing value. If the array has 3 or more elements then the third element (array[2]) will hold the final bearing value.

To stop receiving the location updates you call the removeUpdates method of the LocationManager class.

The given sample initializes the LocationManager and requests for periodic location updates. When you press the “Start Measuring” button it calculates the distance between that position and your current position. Hope this will help you to start GPS programming on Android.