In this lecture, we discuss Android's sensors and accessing them via the SensorManager.
Smartphones have a number of interesting sensors beyond the camera and the microphone, specifically:
In this lecture we will focus mainly on the accelerometer. The Sensor Manager provides access to the 3-axis accelerometer sensor. We use the signals (x, y, and z axis) to infer activity in MyRuns5; specifically, we build an accelerometer pipeline that extracts "features" from the signals and uses these features to infer the activity of the user. More on that in MyRuns5 lab.
We first provide a demo of the accelerometer signals and the Sensor Manager. We will also show you how to access some of the other sensors such as light, barometer.
The demo code used in this lecture include:
Sensor Kinetics is a great app that allows you to quickly check out the sensors on your phone and interact with them. This is a very cool and geeky app.
We will use the DemoShakeSensor.zip app to demonstrate how to read the accelerometer. The empty project can be found here.
Some excellent references.
This simple demo displays the x, y and z axis accelerometer readings in a continuous fashion. If the phone is shaken the background color of the text changes and the phone dials a number, as shown in the example below.
We first get a sensor service and sensor manager before we can access the accelerometer data.
We set the sensor manager to get accelerometer data -- Sensor.TYPE_ACCELEROMETER. But we could have asked for any sensor data that the phone produces -- light, proximity, etc. See the list of sensor types here.
The figure below shows the x, y and z axis of the accelerometer sensor with respect to the phone's orientation.
See developers notes on the definition of the coordination and the SensorEvent object definition which is based to the onSensorChanged() callback when new data is available.
The X axis is horizontal and points to the right, the Y axis is vertical and points up and the Z axis points towards the outside of the front face of the screen. In this system, coordinates behind the screen have negative Z values.
public class MainActivity extends AppCompatActivity implements SensorEventListener {
TextView xLabel, yLabel, zLabel, titleLabel;
SensorManager sensorManager;
double x,y,z;
long lastTime, currentTime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
xLabel = (TextView)findViewById(R.id.xval);
yLabel = (TextView)findViewById(R.id.yval);
zLabel = (TextView)findViewById(R.id.zval);
titleLabel = (TextView)findViewById(R.id.textView);
sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
lastTime = System.currentTimeMillis();
}
The two helper functions display the accelerometer and check to see if the phone has been shaken using a simple test -- if so change the background color of the text and dial a number.
public void onResume(){
super.onResume();
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
public void onPause(){
super.onPause();
sensorManager.unregisterListener(this);
}
public void onSensorChanged(SensorEvent event){
if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
x = event.values[0] / sensorManager.GRAVITY_EARTH;
y = event.values[1] / sensorManager.GRAVITY_EARTH;
z = event.values[2] / sensorManager.GRAVITY_EARTH;
xLabel.setText("X axis: " + x);
yLabel.setText("Y axis: " + y);
zLabel.setText("Z axis: " + z);
checkShake();
}
}
private void checkShake(){
double magnitude = Math.sqrt(x*x + y*y + z*z);
currentTime = System.currentTimeMillis();
if(magnitude > 3 && currentTime - lastTime > 300){
titleLabel.setBackgroundColor(Color.RED);
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel: 123456"));
startActivity(intent);
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy){}
}