Custom CAR DOCK application in Android

by Krishnaraj Varma on October 31, 2010

Download source code of this article.

Car mode in Android is a UI mode that is invoked when the device is connected to the car dock. An application can programmatically switch to this mode by using UiModeManager.enterCarMode() method with UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME parameter. This a safer way to access the applications while driving. Android has introduced a new application “Car Home” from 2.2 onwards. This is a default car mode application. Car Home application provides you a quick access to selected applications and supports customization also. You can add shortcuts of the application that supports car mode. To support car mode an application has to specify the category “android.intent.category.CAR_MODE” in AndroidManifest.xml file. By specifying this category we can tell the system that our application supports car mode and a user will be able to create shortcut of the application.

We can create our own custom car mode application by specifying the category “android.intent.category.CAR_DOCK” in AndroidManifest.xml file and thereby override the default “Car Home” application. But we have to take extra care to make it usable and safer while driving.

The sample application is a very simple and minimal that just shows information text and does nothing. If you press the BACK key the application will exit from the car mode by using UiModeManager.disableCarMode() with passing UiModeManager.DISABLE_CAR_MODE_GO_HOME as parameter.

{ 2 comments }

Multi-touch in Android

by Krishnaraj Varma on October 17, 2010

Download source code of this article.

Multi-touch is the ability to detect touch events with 2 or more fingers. Android supports multi-touch from version 2.0 onwards. Most common multi-touch gesture is pinch zoom. With Pinch zoom, you can zoom in or out the content by squeezing or pull apart the fingers. We can implement multi-touch in Android using either onTouch events or ScaleGestureDetector.

To View.onTouchEvent is called when we touch the screen. This method has one MotionEvent parameter. This represents the touch event that occurred. The MotionEvent.getAction() method returns the event action. There are different event actions like ACTION_DOWN, ACTION_MOVE, ACTION_UP, ACTION_POINTER_DOWN, ACTION_POINTER_UP, etc. MotionEvent.getX() and MotionEvent.getY() returns x and y position of the event respectively.

ACTION_TOUCH will be generated whenever we touch the screen with one finger (primary pointer). ACTION_UP is generated when the finger has left the screen. This is for single touch. When we touch the screen with two fingers, the first touch detected is considered as the primary pointer and all others are considered as non-primary pointer. For the primary pointer (first touch detected) ACTION_TOUCH is generated and for the non-primary pointers (second touch onwards) ACTION_POINTER_DOWN is generated. When we move the fingers ACTION_MOVE will be generated. When the non-primary pointer left the screen, ACTION_POINTER_UP is generated.

To find now many pointers are there for an event, we can use MotionEvent.getPointerCount() method. This will return how many pointers are there for the event. The getX() and getY() methods has another variant which accepts a pointer id, i.e. MotionEvent.getX(pointerid) and MotionEvent.getY(pointerid) which returns the X and Y coordinates of the pointer with given pointerid. Note that we are passing pointer id not pointer index. The method MotionEvent.getPointerId(index) returns the pointer id of the pointer at the specified index. The index ranges from 0 to getPointerCount() – 1. Now we have X and Y coordinates of the different pointers involved in the multi-touch gesture and we can use this to implement actions like zoom-in, zoom-out, etc.

Using ScaleGestureDetector

ScaleGestureDetector class detects gestures with more than two fingers. We use this class the same way we use the GestureDetector class, i.e. we create and instance of the class and on View.onTouchEvent we call the ScaleGestureDetector.onTouchEvent method. The ScaleGestureDetector uses callback interface ScaleGestureDetector.OnScaleGestureListener to report the events occurred. This interface has following three methods:

boolean onScaleBegin(ScaleGestureDetector detector)
boolean onScale(ScaleGestureDetector detector)
void onScaleEnd(ScaleGestureDetector detector)

The onScaleBegin method is called when two-finger gesture is detected. We have to return true to indicate we have handled this event and all the other methods should be called. If we return false then the ScaleGestureDetector will not call other methods.

The onScale method is called when we move the fingers. Note that this event will not be called when you return false from onScaleBegin callback method.

The onScaleEnd is called when the gesture is finished, i.e. then the fingers left the screen.

All these methods have one parameter ScaleGestureDetector which is instance of the ScaleGestureDetector reported the event.

The ScaleGestureDetector has different methods like, getCurrentSpan(), getFocusX(), getFocusY(), etc. The getCurrentSpan() method returns the current distance between the fingers. The getFocusX() and getFocusY() methods returns the focal point’s (middle point) X and Y coordinates respectively. Using this information we can implement the pinch-zoom gesture. Refer the reference links for more details.

Sample Application

The sample application is a simple one which draws a line between different pointers when you touch the screen with two fingers. The pinch-zoom is not implemented in this application but can be done with minimal effort. See the reference links for an example of pinch-zoom.

Reference links

How to use Multi-touch in Android 2
MotionEvent documentation
ScaleGestureDetector documentation

{ 3 comments }

Using hardware sensors in Android, part 1

by Krishnaraj Varma on October 11, 2010

Download source code of this article.

Hardware sensors are present in almost all the modern mobile phone devices. Different types of sensors like accelerometer sensor, magnetic field sensor, orientation sensor, proximity sensor, etc. are present in these devices. Sensors that are present vary from device to device.

In Android different types of sensors are supported. SensorManager class is used to access these sensors. Sensor Manager is a system service running in Android. We get an instance of this service by calling Context.getSystemService() method with SENSOR_MANAGER as the argument. Android supports different types of sensors, some of them are:

Sensor.TYPE_ACCELEROMETER - accelerometer sensor
Sensor.TYPE_GYROSCOPE - gyroscope sensor
Sensor.TYPE_LIGHT - light sensor
Sensor.TYPE_MAGNETIC_FIELD - magnetic field sensor
Sensor.TYPE_ORIENTATION - orientation sensor
Sensor.TYPE_PRESSURE - pressure sensor
Sensor.TYPE_PROXIMITY - proximity sensor
Sensor.TYPE_TEMPERATURE - temperature sensor

Not all these will present in the target device, so before start using a particular type of sensor, we need to check whether the desired sensor is present in the device or not. We can check the presence using either SensorManager.getDefaultSensor() or ServiceManager.getSensorList(). Both methods accept sensor type parameter as an argument. In case of ServiceManager.getSensorList() method we can pass the Sensor. TYPE_ALL to get all the sensors present in the system. Once we confirm the desired sensor is present in the device, we can start getting the event updates from the sensor using SensorManager.registerListener() method. This method accepts one SensorEventListener callback interface. This is the interface that SensorManager uses to report the calling application whenever a sensor event occurred. This callback interface has following methods:

abstract void onAccuracyChanged(Sensor sensor, int accuracy)
abstract void onSensorChanged(SensorEvent event)

The onAccuractChanged method is called when there is a change in the sensor accuracy. First parameter is the Sensor registered and second one is the accuracy value. This can be one of the following:

SensorManager.SENSOR_STATUS_ACCURACY_HIGH - high accuracy
SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM - medium accuracy
SensorManager.SENSOR_STATUS_ACCURACY_LOW - low accuracy
SensorManager.SENSOR_STATUS_UNRELIABLE - accuracy is unreliable and cannot be trusted

The onSensorChanged is called when the sensor values are changed. The only argument SensorEvent is the sensor event occurred. This class holds the sensor values, accuracy of the sensor values, Sensor itself and a timestamp at which the event occurred.

SensorEvent.values contains the sensor values. This is an array of float values representing the sensor values. The length and content of this array depends on the type of sensor used. For example if the sensor is an accelerometer then it will be having three elements representing Azimuth angle, Pitch and Roll. Other sensors have different values. Sensor values are described in this link.

Sample application

Sample application for this article lists all the sensors present in the device and when you select a particular sensor, the application registers for sensor events and update the values on the screen. This application does not do anything with the values but just prints it on the screen. A real application should use these values to do something more meaning such as drawing a compass, counting steps while walking, etc. In the coming parts of this article I will try to explain different type of sensors in more detail.

{ 2 comments }

Gesture detection in Android, part 2 of 2

by Krishnaraj Varma on October 10, 2010

Download source code of this article.

In my previous article I tried to explain simple gesture detection in Android using GestureDetector. In this article I will explain complex gesture detection using GestureOverlayView.

From Android 1.6 onwards includes a new package android.gesture which is used to for complex gesture recognition. This package includes APIs to store, load, draw and recognize gestures. We can define our own pre-defined patterns in our application and store these gestures in a file and later on use this file to recognize the gesture.

Gestures Builder application

There is a handy sample application, Gestures Builder, which comes with the Android 1.6 and higher. This application is pre-installed in 1.6 and higher emulators. Here is a screenshot of the application:

Gesture Builder Sample application

Gesture Builder Sample application

Using this application we can create our gesture library and save it to SD card. Once the file is created we can include this file in our application in /res/raw folder.

Loading a gesture library

To load the gesture file, we use the class GestureLibraries class. This class has functions to load from resource, SD card file or private file. GestureLibraries class has following methods:

static GestureLibrary fromFile(String path)
static GestureLibrary fromFile(File path)
static GestureLibrary fromPrivateFile(Context context, String name)
static GestureLibrary fromRawResource(Context context, int resourceId)

All these methods return a class GestureLibrary. This class is used to read gestures entries from file, save gestures entries to file, recognize the gestures, etc. Once the GestureLibraries return a GestureLibrary class that corresponds to the file specified, we read all the gesture entries using GestureLibrary.load method.

Drawing and recognize a gesture

To draw and recognize gestures, we use the class GestureOverlayView. This view extends the FrameLayout, i.e. we can use it inside any other layout or use it as a parent layout to include other child views. This view acts as an overlay view and the user can draw gestures on it. This view uses three callback interfaces to report the actions performed, they are:

interface GestureOverlayView.OnGestureListener
interface GestureOverlayView.OnGesturePerformedListener
interface GestureOverlayView.OnGesturingListener

The GestureOverlayView.OnGestureListener callback interface is used to handle the gesture operations in low-level. This interface has following methods:

void onGestureStarted(GestureOverlayView overlay, MotionEvent event)
void onGesture(GestureOverlayView overlay, MotionEvent event)
void onGestureEnded(GestureOverlayView overlay, MotionEvent event)
void onGestureCancelled(GestureOverlayView overlay, MotionEvent event)


All these methods have two parameters GestureOverlayView
and MotionEvent and represent the overlay view and the event that occurred.

The GestureOverlayView.OnGesturingListener callback interface is used to find when the gesture is started and ended. The interface has following methods:

void onGesturingStarted(GestureOverlayView overlay)
void onGesturingEnded(GestureOverlayView overlay)

The onGestuingStarted will be called when gesture action is started and onGesturingEnded will be called when the gesture action ended. Both these methods contain the GestureOverlayView that is used.

Most important is the GestureOverlayView.OnGesturePerformedListener interface. This interface has only one method:

void onGesturePerformed(GestureOverlayView overlay, Gesture gesture)

This method is called when the user performed the gesture and is processed by the GestureOverlayView. The first parameter is the overlay view that is used and the second is a class Gesture that represents the user performed gesture. Gesture class represents a hand drawn shape. This representation has one or more strokes; each stroke is a series of points. The GestureLibrary class uses this class to recognize gestures.

To recognize a gesture, we use GestureLibrary.recognize method. This method accepts a Gesture class. This method recognizes the gestures using internal recognizers and returns a list of predictions. The prediction is represented by Prediction class and contains two member variables name and score. The name variable represents the name of the gesture and score variable represents the score given by the gesture recognizer. This score member is used to choose the best matching prediction from the list. One of the common methods is to choose the first value that has score greater that one. Another method used is to choose the value that is inside a minimum and maximum threshold limit. Choosing this threshold limit is entirely depends on the implementation ranging from simple limits based on trial and error methods and more complex methods that may include leaning the user inputs and improve the recognition based on that.

Sample application

The sample application that accompanies this article includes 5 pre-defined gestures A, B, C, D and E. When the user draws these patterns the application lists the names and scores of all the predictions.

Hope this article helps you to understand complex gesture recognition in Android.

{ 0 comments }

Gesture detection in Android, part 1 of 2

by Krishnaraj Varma on October 10, 2010

Download the source code of this article.

Gesture detection is one of the great features of all touch based mobile devices. Gestures are patterns drawn by the user on the screen. Simple gestures include tap, scroll, swipe, etc. Complex gestures are more complex patterns drawn on the screen. In Android we can detect simple gestures using GestureDetector class and complex gestures using GestureOverlayView class.

In part 1 of this 2 part article series, I will try to explain the simple gesture detection using GestureDetector class and in next part I will try to explain complex gesture detection using GestureOverlayView class.

GestureDetector is a class which is used to detect simple gestures like tap, scroll, swipe or fling, etc. This class detects gestures using the supplied MotionEvent class. We use this class along with the onTouchEvent, inside this method we call the GestureDetector.onTouchEvent. GestureDetector identify the gestures or events that occurred and report back to us using GestureDetector.OnGestureListener callback interface. We create an instance of the GestureDetector class by passing Context and GestureDetector.OnGestureListener listener.

The GestureDetector.OnGestureListener interface has following abstract methods:

abstract boolean onDown(MotionEvent e)
abstract void onLongPress(MotionEvent e)
abstract boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
abstract void onShowPress(MotionEvent e)
abstract boolean onSingleTapUp(MotionEvent e)
abstract boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)

The onDown method is called when the user first touch the screen, the MotionEvent parameter represents the event that corresponds to the touch event.

The onLongPress method is called when user touches the screen and holds it for a period of time. The MotionEvent parameter represents the event that corresponds to the touch event.

The onScroll method is called when the user touches the screen and moves to another location on the screen. This method has 4 parameters; first MotionEvent corresponds to the first touch event that occurred, second MotionEvent corresponds to the scroll that occurred, the distanceX parameter represents the scrolled distance along the X axis since the last call to onScroll and the forth parameter distanceY is the distance occurred along Y axis since the last call to onScroll. The third and forth parameters are little bit confusing and are not the distance between MotionEvent 1 and MotionEvent 2.

The onShowPress method is called when the user touches the phone and not moved yet. This event is mostly used for giving visual feedback to the user to show their action.

The onSingleTapUp method is called when a tap occurred, i.e. use taps the screen.

The onFling method is called whenever the user swipes the screen in any direction, i.e. the user touches the screen and immediately moves the finger in any direction. The first parameter is the MotionEvent corresponds to the touch event that started the fling, second parameter is the MotionEvent that corresponds to the movement that triggered the fling, the third one corresponds to the velocity along X axis measured and the forth one corresponds to the velocity along Y axis measured. The use of this gesture depends on application to application. Some application starts the movement of some objects in the screens with velocity based on the X and Y velocity measured and gradually slows down the movement and settled the objects somewhere on the screen. Another use of this method is to move from one page to another within the application.

Double-tap

You should be noticed that the double-tap event is not present in the GestureDetector.onGestureListener callback interface. For some reason this event is reported using another callback interface GestureDetector.onDoubleTapListener. To use this callback interface we have to register for these events using GestureDetector.setOnDoubleTapListener passing the above listener. This interface has the following methods:

abstract boolean onDoubleTap(MotionEvent e)
abstract boolean onDoubleTapEvent(MotionEvent e)
abstract boolean onSingleTapConfirmed(MotionEvent e)

The onDoubleTap method is called when there is a double-tap event occurred. The only parameter MotionEvent corresponds to the double-tap event that occurred.

The onDoubleTapEvent is called for all events that occurred within the double-tap, i.e. down, move and up events.

The onSingleTapConfirmed
method is called when there is a single tap occurred and confirmed, but this is not same as the single-tap event in the GestureDetector.onGestureListener. This is called when the GestureDetector detects and confirms that this tap does not lead to a double-tap.

The MotionEvent class

The MotionEvent class contains all the values correspond to a movement and touch event. This class holds values such as X and Y position at which the event occurred, timestamp at which the event occurred, mouse pointer index, etc. This class also contains the multi-touch information. Another interesting member is the pressure variable, which reports the pressure of the touch and movement events. I am experimenting with multi-touch and pressure and will be posting an article soon.

Example application

The example application accompanies this article is a simple one to show the use of these gestures. The application has 4 views and each view has different color. It has and 2 modes, SCROLL mode and FLIP mode. The application starts in FLIP mode. In this mode when you perform the swipe/fling gesture in left right, up and down direction, the view changes back and forth. When a long-press is detected, the application changes to SCROLL mode, in this mode you scroll the displayed view. While in this mode, you can double-tap on the screen to bring back the screen to its original position. Again when a long-press is detected the application changes to FLIP mode.

I hope this will give you an introduction to the simple gesture detection in Android. In the next part of this article I will try to explain complex gesture detection using GestureOverlayView class.

Happy gesture coding! :)

{ 6 comments }

Security Permissions in Android

by Krishnaraj Varma on October 3, 2010

As we all know whenever we use a particular feature or API we need to request the permission in AndroidManifest.xml file with uses-permission element. If we don’t specify any permissions, then the application will not have any permission and application can do anything that does not require a permission. This link explains the permissions in android in more detail and this link lists the permissions in Android.

Permissions are granted to the application by package installer while installing. But not all the permissions will be granted to the system. There are some system permission which will not be granted to the user applications, but only to the system applications. Following are some of the permissions that may NOT be granted to the user application.

android.permission.ACCESS_CHECKIN_PROPERTIES
android.permission.ACCESS_SURFACE_FLINGER
android.permission.ACCOUNT_MANAGER
android.permission.BIND_APPWIDGET
android.permission.BIND_DEVICE_ADMIN
android.permission.BIND_INPUT_METHOD
android.permission.BIND_WALLPAPER
android.permission.BRICK
android.permission.BROADCAST_PACKAGE_REMOVED
android.permission.BROADCAST_SMS
android.permission.BROADCAST_WAP_PUSH
android.permission.CALL_PRIVILEGED
android.permission.CHANGE_COMPONENT_ENABLED_STATE
android.permission.CLEAR_APP_USER_DATA
android.permission.CONTROL_LOCATION_UPDATES
android.permission.DELETE_CACHE_FILES
android.permission.DELETE_PACKAGES
android.permission.DEVICE_POWER
android.permission.DIAGNOSTIC
android.permission.FACTORY_TEST
android.permission.FORCE_BACK
android.permission.GLOBAL_SEARCH
android.permission.HARDWARE_TEST
android.permission.INJECT_EVENTS
android.permission.INSTALL_LOCATION_PROVIDER
android.permission.INSTALL_PACKAGES
android.permission.INTERNAL_SYSTEM_WINDOW
android.permission.MANAGE_APP_TOKENS
android.permission.MASTER_CLEAR
android.permission.READ_FRAME_BUFFER
android.permission.READ_INPUT_STATE
android.permission.REBOOT
android.permission.SET_ACTIVITY_WATCHER
android.permission.SET_ORIENTATION
android.permission.SET_PREFERRED_APPLICATIONS
android.permission.SET_TIME
android.permission.STATUS_BAR
android.permission.UPDATE_DEVICE_STATS
android.permission.WRITE_GSERVICES
android.permission.WRITE_SECURE_SETTINGS

To get these permissions, the application must be signed with the key which used to sign the platform. This may be different for manufacturers. So it practically not possible to get these permissions granted to a user application.

Note: While playing with PowerManager.reboot I was so stupid I thought my application will be granted the permission android.permission.REBOOT, but it was not granted. Then I created an application requesting all the permissions and above list of permissions are not granted. Hope this will help you when you request a permission next time.

{ 2 comments }

Network Traffic Statistics in Android 2.2

by Krishnaraj Varma on September 19, 2010

Download source code of this article

Android API version 8 (Version 2.2) includes a convenient class, TrafficStats, to retrieve the traffic statistics of the device. This class provides traffic statistics of both Mobile Interface and All Network Interface. This class has following methods:

static long getMobileRxBytes()
static long getMobileRxPackets()
static long getMobileTxBytes()
static long getMobileTxPackets()
static long getTotalRxBytes()
static long getTotalRxPackets()
static long getTotalTxBytes()
static long getTotalTxPackets()
static long getUidRxBytes(int uid)
static long getUidTxBytes(int uid)

The function names explains its purpose. For more detailed documentation visit this link. Note that this class is only available from API version 8 onwards.

{ 0 comments }

Detecting incoming and outgoing calls in Android

by Krishnaraj Varma on August 29, 2010

Download source code of this article

In one of my project, I wanted to detect incoming and outgoing calls. I used BroadcastReceiver with action android.intent.action.NEW_OUTGOING_CALL and android.intent.action.PHONE_STATE.

The android.intent.action.NEW_OUTGOING_CALL will be broadcasted when an outgoing call is initiated. The receiving intent will have an extra string variable Intent.EXTRA_PHONE_NUMBER which contains the outgoing number. This requires the permission android.permission.PROCESS_OUTGOING_CALLS.

To detect the incoming call, we register a BroadcastReceiver for the action android.intent.action.PHONE_STATE. This will be broadcasted when there is a change in phone state. The receiving intent will have an extra string variable TelephonyManager.EXTRA_STATE which describes the phone state. If this state is TelephonyManager.EXTRA_STATE_RINGING then there will be another extra string variable TelephonyManager.EXTRA_INCOMING_NUMBER. This variable contains the incoming phone number. Note that this variable will not be present when the state is not TelephonyManager.EXTRA_STATE_RINGING.

The sample application is a simple one just for demonstration. The application registers for these actions and when the calls are detected it just displays a toast.

{ 12 comments }

Android network connectivity BroadcastReceiver

by Krishnaraj Varma on August 24, 2010

Download source code of this article.

Most of the time we need to connect to internet to download or upload data. If the downloading or uploading is a lengthy process, we need to know when the network connected or gone, so that we can temporarily pause the uploading or downloading and resume once the connection is established. In Android we can register a BroadcastReciver with action ConnectivityManager.CONNECTIVITY_ACTION. System will broadcast this whenever a change in the network connectivity occurs.

Information regarding the connection will be there in the receiving intent. Some of them are:

ConnectivityManager.EXTRA_EXTRA_INFO
A string value indicating the network state.

ConnectivityManager.EXTRA_IS_FAILOVER
A boolean value indicates whether the connection manager is failing over or not.

ConnectivityManager.EXTRA_NETWORK_INFO
A NetworkInfo class with network information.

ConnectivityManager.EXTRA_NO_CONNECTIVITY
A boolean value indicating there is no internet connectivity.

ConnectivityManager.EXTRA_OTHER_NETWORK_INFO
A NetworkInfo class with network information of another network that may be connected.

ConnectivityManager.EXTRA_REASON
A String value about the reason of the connection failure.

You can check either ConnectivityManager.EXTRA_EXTRA_INFO or NetworkInfo.State from the ConnectivityManager.EXTRA_NETWORK_INFO key.

{ 3 comments }

Android sample application: Simple logcat viewer

by Krishnaraj Varma on August 24, 2010

Download source code of this article.

Here is a sample application to view logcat messages on device. The application runs the command “logcat” using Runtime class, reads each log string and adds the string to a list view. Whenever you click on an item, an alert box is displayed with the corresponding log message.

{ 0 comments }