ZOFTINO.COM android and web dev tutorials

Android Sensors Examples

Android supports sensors which provide the measurements of certain properties such as device motion, orientation and rotation, pressure, temperature, light, magnetic field, proximity and humidity. Using android sensor framework, you can implement in your android app the features that use sensors and its raw data.

Sensors

Sensors can be classified into three categories based on the type of the properties they measure, motion sensor, environmental sensors and position sensors. Sensors can be hardware based or software based. Software based sensors use hardware sensors to provide measurement of a parameter.

Motion sensors measure acceleration and rotational forces along three axes. Some of the motion sensors are accelerometer for measuring shake, tilt, etc., proximity sensor for measuring proximity of an object relative to the screen of the device, gyroscope for measuring spin, turn, etc., , gravity sensor for measuring force of gravity and rotational vector for measuring device orientation.

Environmental sensors measure environmental properties such as temperature, pressure, light, humidity. Examples of environmental sensors are thermometer, barometer, photometer used for controlling brightness, and humidity senor.

Position sensors help in calculating device position, for example accelerometer and magneto meters are used to calculate device position. Proximity sensor helps in finding closeness of the device to an object, hand or face.

Available List of Sensors on a Device and Sensor Capabilities

Using android SensorManager, you can get list of all available sensors on a device by calling getSensorList on SensorManager object passing sensor type all argument to it. The method returns list of Sensor objects using that you can get sensor type, name, vendor, power, delay between sensor events and maximum range, etc.

 SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);

String sensorInfo = "";
for (Sensor s : sensorList){
    sensorInfo= sensorInfo + s.getName()+ "\n";
}
textView.setText(sensorInfo);
 

Determining Availability of Specific Sensor

If your app can’t be used without a sensor, you can prevent your app from being shown in play store and installed on the user device by specifying uses-feature element in manifest.

 <uses-feature android:name="android.hardware.accelerometer"
    android:required="true" />
 

But if a sensor is not required for using your app, you can enable or disable the feature which uses sensor depending on the availability of the senor on a device. You can check if there is a default sensor of given sensor type using getDeafultSensor method on SensorManager passing sensor type constants such as Sensor.TYPE_GYROSCOPE, Sensor.TYPE_MAGNETIC_FIELD, Sensor.TYPE_PRESSURE, Sensor.TYPE_GRAVITY, Sensor.TYPE_ORIENTATION, Sensor.TYPE_ACCELEROMETER, and Sensor.TYPE_AMBIENT_TEMPERATURE.

 public boolean checkSensorAvailability(int sensorType){
    SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
    if(sensorManager.getDefaultSensor(sensorType) != null){
        return true;
    }else{
        return false;
    }
}
 

Sensor Event Listener

To listen to sensors events, you need to implement SensorEventListener interface. SensorEventListener has two callback methods, onAccuracyChanged() and onSensorChanged(). Callback method onAccuracyChanged is called when accuracy of measurement changes and is passed sensor object which caused the event and accuracy status. Method onSensorChanged is called when new sensor data is available and it is passed SensorEvent object which contains sensor data.

This listener gets registered to a specific sensor when you get the sensor object by calling getDefaultSensor method on SensorManager passing sensor type that you want to listen to for value changes.

It is important to unregister and reregister the sensor listener in onPuase and onResume callback methods of the activity so that when app is not visible it releases sensors and reuses them on resume or when it comes to foreground.

public class SensorsActivity extends AppCompatActivity 
			implements SensorEventListener {
    private  SensorManager sensorManager;
    private Sensor tempSensor;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
	. . .

        sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
    }
    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
    @Override
    public final void onSensorChanged(SensorEvent event) {

    }
    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, tempSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }
    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

Environment Sensors Example

You can access environment sensors such as temperature, light, pressure, and pressure sensors by calling getDefaultSensor method on SensorManager object passing constants such as Sensor.TYPE_AMBIENT_TEMPERATURE, Sensor.TYPE_LIGHT, Sensor.TYPE_PRESSURE and Sensor.TYPE_RELATIVE_HUMIDITY constant to get respective sensor objects. Then add sensor listener to them to listen to temperature, luminescence, pressure and humidity value changes.

Handling value changes of environmental sensors is easy because in the sensor event listeners you can get the single value of the property that sensors measure and take action based on the value.

The example below shows how to use light sensor and change activity background image depending on luminance value change.

    @Override
    public final void onSensorChanged(SensorEvent event) {
            if(event.sensor.getType() ==  Sensor.TYPE_LIGHT){
                float valueZ = event.values[0];
                Toast.makeText(this, ""+valueZ,Toast.LENGTH_LONG).show();
                if(valueZ > 40){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_three);
                }else{
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_two);
                }
            }
    }

Proximity Sensor Example

To listen to proximity sensor events, your activity should implement sensor event listener and then get proximity sensor object calling getDefaultSensor method on SensorManager passing Sensor.TYPE_PROXIMITY constant to it.

In onSensorChanged method, you can capture proximity value changes and do something with it to provide features in your app. The example below shows different background images when you change proximity of your hand to the device by moving it closer and far.

 public class SensorsActivity extends AppCompatActivity 
			implements SensorEventListener {
    private LinearLayout sensorLayout;
    private  SensorManager sensorManager;
    private Sensor proximitySensor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_sensor);
        sensorLayout = findViewById(R.id.sensors_layout);

        sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
	 if(event.sensor.getType() ==  Sensor.TYPE_PROXIMITY){
                //proximity sensor
                float distance = event.values[0];
                Toast.makeText(this, "proximity "+distance,Toast.LENGTH_LONG).show();
                if(distance > 25){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_three);
                }else{
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_two);
                }
            }
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, proximitySensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    } 

Rotation Sensor Example

Using rotation sensors, you can find values of azimuth, roll and pitch which can be used to determine device rotation. Azimuth is angle between magnetic north and y-axis, roll represents tilt of z-axis toward positive x-axis and pitch represents tilt of z-axis toward positive y-axis. These values can be used to determine device rotation and implement app features based on it.

The example below uses game rotation vector sensor (Sensor.TYPE_GAME_ROTATION_VECTOR) and shows different background images based on the values of azimuth, roll and pitch as device is rotated around each axis. You can use other rotation sensors to determine device rotation such as rotation vector sensor and geo magnetic rotation vector sensor.

 public class SensorsActivity extends AppCompatActivity 
			implements SensorEventListener {
    private LinearLayout sensorLayout;
    private  SensorManager sensorManager;
    private Sensor rotationSensor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_sensor);
        sensorLayout = findViewById(R.id.sensors_layout);

        sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        rotationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
	if(event.sensor.getType() ==  Sensor.TYPE_GAME_ROTATION_VECTOR){
                float[] rotMatrix = new float[9];
                float[] rotVals = new float[3];

                SensorManager.getRotationMatrixFromVector(rotMatrix, event.values);
                SensorManager.remapCoordinateSystem(rotMatrix,
                                SensorManager.AXIS_X, SensorManager.AXIS_Y, rotMatrix);

                SensorManager.getOrientation(rotMatrix, rotVals);
                float azimuth = (float) Math.toDegrees(rotVals[0]);
                float pitch = (float) Math.toDegrees(rotVals[1]);
                float roll = (float) Math.toDegrees(rotVals[2]);

                if(azimuth > 60 && azimuth < 90){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_three);
                }else if(pitch > 10){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_two);
                }else if(roll > 15){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background);
                }else{
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_four);
                }
            }
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, rotationSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
} 

Pedometer or Step Counter Example

You can provide pedometer feature in your app by using step detector sensor. To create pedometer first your activity should implement sensor event listener and then get step counter sensor object by calling getDefaultSensor method on SensorManager passing Sensor.TYPE_STEP_DETECTOR constant to it. In the sensor listener callback method which is called each time user takes a step, you can capture number of steps user has taken.

 public class SensorsActivity extends AppCompatActivity 
			implements SensorEventListener {
    private TextView textView;
    private  SensorManager sensorManager;
    private Sensor stepCounterSensor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_sensor);
        textView = findViewById(R.id.sensors);

        sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
	   if(event.sensor.getType() ==  Sensor.TYPE_STEP_DETECTOR){
                //step counter
                float steps = event.values[0];
                textView.setText("steps : "+steps);
            }
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, stepCounterSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
} 

Example Output

android sensor examples

Activity

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;


public class SensorsActivity extends AppCompatActivity implements SensorEventListener {
    private LinearLayout sensorLayout;
    private TextView textView;
    private int sensorInd;

    private  SensorManager sensorManager;
    private Sensor lightSensor;
    private Sensor proximitySensor;
    private Sensor rotationSensor;
    private Sensor stepCounterSensor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_sensor);
        sensorLayout = findViewById(R.id.sensors_layout);
        textView = findViewById(R.id.sensors);

        sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
        rotationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
        stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
    }

    public void sensorsList(View view){
        List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);

        String sensorInfo = "";
        for (Sensor s : sensorList){
            sensorInfo= sensorInfo + s.getName()+ "\n";
        }
        textView.setText(sensorInfo);
    }
    public boolean checkSensorAvailability(int sensorType){
        boolean isSensor = false;
        if(sensorManager.getDefaultSensor(sensorType) != null){
            isSensor = true;
        }
        Log.d("checkSensorAvailability" ,""+isSensor);
        return  isSensor;
    }
    public void lightSensor(View view){
        if(checkSensorAvailability(Sensor.TYPE_LIGHT)){
            sensorInd = Sensor.TYPE_LIGHT;
        }
    }
    public void proximitySensor(View view){
        if(checkSensorAvailability(Sensor.TYPE_PROXIMITY)){
            sensorInd = Sensor.TYPE_PROXIMITY;
        }
    }
    public void rotationSensor(View view){
         if(checkSensorAvailability(Sensor.TYPE_GAME_ROTATION_VECTOR)){
            sensorInd = Sensor.TYPE_GAME_ROTATION_VECTOR;
        }
    }
    public void stepCounterSensor(View view){
        if(checkSensorAvailability(Sensor.TYPE_GAME_ROTATION_VECTOR)){
            sensorInd = Sensor.TYPE_STEP_DETECTOR;
        }
    }
    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
        //check sensor type matches current sensor type set by button click
        if( event.sensor.getType() == sensorInd){
            //light sensor
            if(event.sensor.getType() ==  Sensor.TYPE_LIGHT){
                float valueZ = event.values[0];
                Toast.makeText(this, "luminescence "+valueZ,Toast.LENGTH_LONG).show();
                if(valueZ > 40){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_three);
                }else{
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_two);
                }
            }else if(event.sensor.getType() ==  Sensor.TYPE_PROXIMITY){
                //proximity sensor
                float distance = event.values[0];
                Toast.makeText(this, "proximity "+distance,Toast.LENGTH_LONG).show();
                if(distance > 25){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_three);
                }else{
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_two);
                }
            }else if(event.sensor.getType() ==  Sensor.TYPE_STEP_DETECTOR){
                //step counter
                float steps = event.values[0];
                textView.setText("steps : "+steps);
            }else if(event.sensor.getType() ==  Sensor.TYPE_GAME_ROTATION_VECTOR){
                //rotation sensor
                float[] rotMatrix = new float[9];
                float[] rotVals = new float[3];

                SensorManager.getRotationMatrixFromVector(rotMatrix, event.values);
                SensorManager.remapCoordinateSystem(rotMatrix,
                                SensorManager.AXIS_X, SensorManager.AXIS_Y, rotMatrix);

                SensorManager.getOrientation(rotMatrix, rotVals);
                float azimuth = (float) Math.toDegrees(rotVals[0]);
                float pitch = (float) Math.toDegrees(rotVals[1]);
                float roll = (float) Math.toDegrees(rotVals[2]);

                if(azimuth > 60 && azimuth < 90){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_three);
                }else if(pitch > 10){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_two);
                }else if(roll > 15){
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background);
                }else{
                    sensorLayout.setBackgroundResource(R.drawable.sensor_background_four);
                }
            }

        }
    }
    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, lightSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, proximitySensor,
                SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, rotationSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, stepCounterSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

Activity Layout

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/sensors_layout"
    android:layout_margin="8dp"
    android:orientation="vertical"
    android:background="@drawable/sensor_background">
    <TextView
        android:id="@+id/sensors"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/holo_red_dark"/>
    <Button
        android:id="@+id/sensors_list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/Widget.AppCompat.Button.Colored"
        android:onClick="sensorsList"
        android:text="Sensors List"/>
    <Button
        android:id="@+id/light_sensor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/Widget.AppCompat.Button.Colored"
        android:onClick="lightSensor"
        android:text="Light Sensor"/>
    <Button
        android:id="@+id/proximity_sensor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/Widget.AppCompat.Button.Colored"
        android:onClick="proximitySensor"
        android:text="Porximity Sensor"/>
    <Button
        android:id="@+id/rotation_sensor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/Widget.AppCompat.Button.Colored"
        android:onClick="rotationSensor"
        android:text="Rotation Sensor"/>
    <Button
        android:id="@+id/steps_sensor"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/Widget.AppCompat.Button.Colored"
        android:onClick="stepCounterSensor"
        android:text="Step Counter Sensor"/>
</LinearLayout></ScrollView>