Android Sensor Programming by Example - Sample Chapter
Android Sensor Programming by Example - Sample Chapter
ee
$ 39.99 US
25.99 UK
P U B L I S H I N G
Varun Nagpal
pl
C o m m u n i t y
E x p e r i e n c e
D i s t i l l e d
Sa
m
Varun Nagpal
Preface
Welcome to Android Sensor Programming By Example. This book will provide you the skills
required to use sensors in your Android applications. It will walk you through all the
fundamentals of sensors and will provide a thorough understanding of the Android Sensor
Framework. This book will cover a wide variety of sensors available on the Android
Platform. You will learn how to write code for the infrastructure (service, threads, database)
required to process high volumes of sensor data. This book will also teach you how to
connect and use sensors in external devices (such as Android Wear) from the Android app
using the Google Fit platform.
You will learn from many real-world sensor-based applications such, as the Pedometer app
to detect daily steps, the Weather app to detect temperature, altitude, absolute and
humidity, the Driving app to detect risky driving behavior, and the Fitness tracker app to
track heart rate, weight, daily steps, and calories burned.
fundamentals and framework of Android sensors. It walks you through the different types
of sensors and the sensor coordinate system in detail.
Chapter 2, Playing with Sensors, guides you through various classes, callbacks, and APIs of
the Android Sensor framework. It walks you through a sample application, which provides
a list of available sensors and their values and individual capabilities, such as the range of
values, power consumption, minimum time interval, and so on.
Chapter 3, The Environmental Sensors The Weather Utility App, explains the usage of
sensors. It explains the difference between wakeup and non-wakeup sensors and explains
the concept of the hardware FIFO sensor queue. As a learning exercise, we develop a small
application that turns on/off a flashlight using a proximity sensor, and it also adjusts screen
brightness using a light sensor.
Preface
Chapter 5, The Motion, Position, and Fingerprint Sensors, explains the working principle of
Chapter 6, The Step Counter and Detector Sensors The Pedometer App, explains how to use
the step detector and step counter sensors. Through a real-world pedometer application, we
learn how to analyze and process the accelerometer and step detector sensor data to
develop an algorithm for detecting the type of step (walking, jogging, sprinting). We also
look at how to drive the pedometer data matrix (total steps, distance, duration, average
speed, average step frequency, calories burned, and type of step) from the sensor data.
Chapter 7, The Google Fit Platform and APIs The Fitness Tracker App, introduces you to the
new Google Fit platform. It walks you through the different APIs provided by the Google
Fit platform and explains how to request automated collection and storage of sensor data in
a battery-efficient manner without the app being alive in the background all the time. As a
learning exercise, we develop a fitness tracker application that collects and processes the
fitness sensor data, including the sensor data obtained from remotely connected Android
Wear devices.
Bonus Chapter, Sensor Fusion and Sensor Based APIs (the Driving Events Detection App),
guides you through the working principle of sensor-based Android APIs (activity
recognition, geo-fence, and fused location) and teaches you various aspects of sensor fusion.
Through a real-world application, you will learn how to use multiple sensors along with
input from sensor-based APIs to detect risky driving behavior. Through the same
application, you will also learn how to develop the infrastructure (service, threads, and
database) required to process high volumes of sensor data in the background for a longer
duration of time. This chapter is available online at the link https://www.packtpub.com/
sites/default/files/downloads/SensorFusionandSensorBasedAPIs_TheDriving
EventDetectionApp_OnlineChapter.pdf
[ 72 ]
Chapter 4
Most Android devices have the same hardware, which works for both light and proximity
sensors, but Android still treats them as logically separate sensors. It depends on whether
the individual OEMs (Original Equipment Manufactures) have a single hardware or two
separate hardware to support both the logical sensors.
The light and proximity sensor is generally located on the top right-hand section of the
phone, a few millimetres to the right of the earpiece. You have to look very carefully to spot
the sensor as it's barely visible because of its small size. Generally, it's a pair of small black
holes covered under the screen. Some OEMs might choose a different location for the light
and proximity sensor, but mostly it will be on the top edge of the phone. For example,
Samsung Galaxy S devices have them on the right-hand side of the earpiece, while HTC
Android devices have them on the left-hand side of the earpiece.
[ 73 ]
SensorManager mSensorManager;
Sensor mSensor;
boolean isSensorPresent;
float distanceFromPhone;
Camera mCamera;
SurfaceTexture mPreviewTexture;
Camera.Parameters mParameters;
boolean isFlashLightOn = false;
[ 74 ]
Chapter 4
!= null) {
mSensor = mSensorManager.getDefaultSensor
(Sensor.TYPE_PROXIMITY);
isSensorPresent = true;
} else {
isSensorPresent = false;
}
initCameraFlashLight();
}
2. As a best practice, we registered the listener in the onResume() method and unregistered it in the onPause() method. Inside the
custom initCameraFlashlight() method, we initialized
the Camera, SurfaceTexture, and Paramters objects required for turning on
the flashlight. In the onDestroy() method of the activity, we released
the Camera object and set all the initialized object references to null:
@Override
protected void onResume() {
super.onResume();
if(isSensorPresent) {
mSensorManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
@Override
protected void onPause() {
super.onPause();
if(isSensorPresent) {
mSensorManager.unregisterListener(this);
}
}
public void initCameraFlashLight()
{
mCamera = Camera.open();
mParameters = mCamera.getParameters();
mPreviewTexture = new SurfaceTexture(0);
try {
mCamera.setPreviewTexture(mPreviewTexture);
} catch (IOException ex) {
Log.e(TAG, ex.getLocalizedMessage());
Toast.makeText(getApplicationContext(),
getResources().getText(R.string.error_message),
Toast.LENGTH_SHORT).show();
[ 75 ]
3. After initiating SurfaceTexture, camera, and sensors, we will now write our
core logic for the app. In our custom turnTorchLightOn() method, we start the
flash light by setting the flash mode to FLASH_MODE_TORCH for the camera
parameters and starting the camera preview. Similarly, in the
custom turnTorchLightOff() method, we stop the flash light by setting the
flash mode to FLASH_MODE_OFF for the camera parameters and stopping the
camera preview. Now, we call these methods from the onSensorChanged()
method, depending on the distance of any object from the proximity sensor. If the
distance of any object from the phone's proximity sensor is less than the
maximum range of the proximity sensor, then we consider the object to be near
and call the custom turnTorchLighOn() method; however, if the distance is
equal to or greater than the range of the proximity sensor, we consider the object
is far and call the turnTorchLightOff() method. We use the isFlashLightOn
Boolean variable to maintain the on/off states of the flashlight:
public void turnTorchLightOn()
{
mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(mParameters);
mCamera.startPreview();
isFlashLightOn = true;
}
public void turnTorchLightOff()
{
mParameters.setFlashMode(mParameters.FLASH_MODE_OFF);
mCamera.setParameters(mParameters);
mCamera.stopPreview();
isFlashLightOn = false;
}
public void onSensorChanged(SensorEvent event) {
distanceFromPhone = event.values[0];
[ 76 ]
Chapter 4
if(distanceFromPhone < mSensor.getMaximumRange()) {
if(!isFlashLightOn) {
turnTorchLightOn();
}
} else {
if(isFlashLightOn) {
turnTorchLightOff();
}
}
}
[ 77 ]
SensorManager mSensorManager;
Sensor mSensor;
boolean isSensorPresent;
ContentResolver mContentResolver;
Window mWindow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lightsensor_layout);
mSensorManager = (SensorManager)this.getSystemService
(Context.SENSOR_SERVICE);
if(mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) != null)
{
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
isSensorPresent = true;
} else {
isSensorPresent = false;
}
initScreenBrightness();
}
[ 78 ]
Chapter 4
public void initScreenBrightness()
{
mContentResolver = getContentResolver();
mWindow = getWindow();
}
@Override
protected void onDestroy() {
super.onDestroy();
mSensorManager = null;
mSensor = null;
mContentResolver = null;
mWindow = null;
}
3. As discussed earlier, we will use a light range from 0 to 100 lux for our example.
We will be adjusting the brightness for two objects: one for the current visible
window (for which the brightness value lies between 0 and 1), and the second for
the system preference (for which the brightness value lies between 0 and 255). In
order to use the common brightness value for both the objects, we will stick to a
value between 0 and 1, and for system brightness we will scale up by multiplying
it by 255. Since we have to increase the screen brightness, as the outside
lightening goes low and vice versa, we take the inverse of the light sensor values.
Also to keep the range of the brightness value between 0 and 1, we use only light
values between 0 and 100. We pass on the inverse of light values obtained from
the light sensor in the onSensorChanged() method, as an argument to our
custom changeScreenBrightness() method to update the current window
and system screen brightness:
public void changeScreenBrightness(float brightness)
{
//system setting brightness values ranges between 0-255
//We scale up by multiplying by 255
//This change brightness for over all system settings
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, (int)
(brightness*255));
//screen brightness values ranges between 0 - 1
//This only changes brightness for the current window
LayoutParams mLayoutParams = mWindow.getAttributes();
mLayoutParams.screenBrightness = brightness;
mWindow.setAttributes(mLayoutParams);
}
@Override
public void onSensorChanged(SensorEvent event) {
[ 79 ]
The app needs to have following three permissions to run the previous two examples:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT"
/>
<uses-permission
android:name="android.permission.WRITE_SETTINGS" />
The camera permission is required to access the camera object, flashlight permission is
required to turn on and turn off the flashlight, and the write settings permission is required
to change any system settings.
[ 80 ]
Chapter 4
[ 81 ]
Summary
In this chapter, we looked at the two new proximity and light sensors and developed a
small app using them. We also learned how to turn on and turn off the flashlight using the
proximity sensor and adjust the screen brightness using the light sensor. We understood
how to wake up the application processor when it's in suspended mode using wake locks.
We looked at the wakeup and non-wake up sensors and their FIFO queues.
In the next chapter, we will learn about motion sensors (accelerometer, gyroscope, linear
acceleration, gravity, and significant motion) and position sensors (magnetometer and
orientation). We will also explore the newly introduced fingerprint sensor.
[ 82 ]
www.PacktPub.com
Stay Connected: