Android
|
Modified: 11/14/2014 10:16:27 |
Resources
http://webhole.net/2011/08/20/android-sdk-accelerometer-example-tutorial/ - Very basic accelerometer example.
http://www.vogella.de/articles/AndroidSensor/article.html - Accelerometer tutorial.
http://www.vogella.de/articles/AndroidLocationAPI/article.html - Location and map example.
http://android-er.blogspot.com/2011/02/get-list-of-available-sensors.html - Sensor list example.
Overview
Android devices have a variety of sensors and timers, including:
- accelerometers
- temperature
- orientation (gyroscope)
- light
- proximity
- location
- etc.
Android Timer Example
System.currentTimeMillis() gives the current wall-clock time in milliseconds.
mHandler.postDelayed(this, 1000) re-executes the mUpdateElapsedTimeTask Runnable object after a 1000 ms. delay.
mHandler.removeCallbacks(mUpdateElapsedTimeTask) removes any existing callbacks for mUpdateElapsedTimeTask.
package edu.ius.rwisman.TimerUpdating; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.TextView; public class TimerUpdatingActivity extends Activity { private Handler mHandler = new Handler(); long mStartTime; TextView mTimeLabel; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTimeLabel = (TextView) findViewById(R.id.time); } private Runnable mUpdateElapsedTimeTask = new Runnable() { public void run() { final long start = mStartTime; long millis = System.currentTimeMillis() - start; mTimeLabel.setText("" + millis); // Re-execute after 1000 ms. mHandler.postDelayed(this, 1000); } }; public void Start(View v) { mStartTime = System.currentTimeMillis(); mHandler.removeCallbacks(mUpdateElapsedTimeTask); mHandler.postDelayed(mUpdateElapsedTimeTask, 0); } public void Stop(View v) { mHandler.removeCallbacks(mUpdateElapsedTimeTask); } } |
Android Sensors
List all sensors
The following list all available sensors on the Xoom device.
package edu.ius.rwisman.SensorList; import java.util.ArrayList; import java.util.List; import android.app.ListActivity; import android.content.Context; import android.hardware.Sensor; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.ArrayAdapter; public class SensorListActivity extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); List |
Sensors are accessed in a generic way by implementing SensorEventListener and registering as a listener to a specific Sensor type.
A ServiceManager is acquired via getSystemService(SENSOR_SERVICE) which can register a SensorEventListener.
As a SensorEventListener two methods must be implemented that receive callbacks:
public void onAccuracyChanged(Sensor sensor, int accuracy)
public void onSensorChanged(SensorEvent event)
public class SensorActivity extends Activity implements SensorEventListener { private final SensorManager mSensorManager; private final Sensor mGenericSensor; public SensorActivity() { mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); mGenericSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GENERIC); } protected void onResume() { super.onResume(); mSensorManager.registerListener(this, mGenericSensor, SensorManager.SENSOR_DELAY_NORMAL); } protected void onPause() { super.onPause(); mSensorManager.unregisterListener(this); } public void onAccuracyChanged(Sensor sensor, int accuracy) { } public void onSensorChanged(SensorEvent event) { } } |
To avoid the unnecessary usage of battery, register the listener in the onResume method and de-register on the onPause method.
Android Temperature Example
For devices with a temperature sensor, specified by Sensor.TYPE_TEMPERATURE, the following displays the current temperature as changes occur.
package edu.ius.rwisman.Temperature; import android.app.Activity; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.widget.TextView; public class TemperatureActivity extends Activity implements SensorEventListener { private SensorManager mSensorManager; private Sensor mTemperature; private TextView mTemperatureLabel; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTemperatureLabel = (TextView) findViewById(R.id.temperature); mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); mTemperature = mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE); } protected void onResume() { super.onResume(); mSensorManager.registerListener(this, mTemperature, SensorManager.SENSOR_DELAY_NORMAL); } protected void onPause() { // Turn off sensor when not in use. super.onPause(); mSensorManager.unregisterListener(this); } public void onAccuracyChanged(Sensor sensor, int accuracy) {} public void onSensorChanged(SensorEvent event) { // Check for temperature sensor callback if (event.sensor.getType() != Sensor.TYPE_TEMPERATURE) return; mTemperatureLabel.setText(""+mTemperature.getPower()); } } |
Android Accelerometer Example
The accelerometer values are represented in SI units (m/s2). The device at right has the bottom of the device screen pointing toward the center of gravity. Gravity on Earth is 9.80665 m/s2.
package edu.ius.rwisman.AccelerometerSimpleExample; import android.app.Activity; import android.graphics.Color; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; public class AccelerometerSimpleExampleActivity extends Activity implements SensorEventListener { private SensorManager sensorManager; private boolean color = false; private View view; private long lastUpdate; TextView xCoor; TextView yCoor; TextView zCoor; @Override public void onCreate(Bundle savedInstanceState){ requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); setContentView(R.layout.main); view = findViewById(R.id.textView); view.setBackgroundColor(Color.GREEN); xCoor=(TextView)findViewById(R.id.xcoor); yCoor=(TextView)findViewById(R.id.ycoor); zCoor=(TextView)findViewById(R.id.zcoor); sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); sensorManager.registerListener( this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); lastUpdate = System.currentTimeMillis(); } @Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { float[] values = event.values; float x = values[0]; float y = values[1]; float z = values[2]; xCoor.setText("X: "+x); yCoor.setText("Y: "+y); zCoor.setText("Z: "+z); float accelerationSquareRoot = (x * x + y * y + z * z) / (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH); long actualTime = System.currentTimeMillis(); if (accelerationSquareRoot >= 2) { if (actualTime - lastUpdate < 200) return; lastUpdate = actualTime; Toast.makeText(this, "Device was shaken", Toast.LENGTH_SHORT).show(); if (color) view.setBackgroundColor(Color.GREEN); else view.setBackgroundColor(Color.RED); color = !color; } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override protected void onResume() { super.onResume(); // register as a listener for orientation and // accelerometer sensors sensorManager.registerListener( this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { // unregister listener sensorManager.unregisterListener( this ); super.onStop(); } } |
main.xml supplies the plot area parameters.
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TableRow> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="match_parent" android:text="Shake to get a toast message and to switch color" /> </TableRow> <TableRow> <TextView android:id="@+id/xcoor" android:text="X Coordinate: " android:layout_width="wrap_content" android:layout_height="wrap_content" /> </TableRow> <TableRow> <TextView android:id="@+id/ycoor" android:text="Y Coordinate: " android:layout_width="wrap_content" android:layout_height="wrap_content" /> </TableRow> <TableRow> <TextView android:id="@+id/zcoor" android:text="Z Coordinate: " android:layout_width="wrap_content" android:layout_height="wrap_content" /> </TableRow> </TableLayout> |
Location
A LocationManager is acquired via getSystemService(Context.LOCATION_SERVICE) to access location.
A location (longitude, latitude) can be entered for the emulator by (at the command line):
telnet localhost 5554
geo fix -85.819 38.343
package edu.ius.rwisman.Location; import android.app.Activity; import android.content.Context; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.widget.TextView; import android.widget.Toast; public class LocationActivity extends Activity implements LocationListener { private TextView latitudeField; private TextView longitudeField; private LocationManager locationManager; private String provider; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); latitudeField = (TextView) findViewById(R.id.latitude); longitudeField = (TextView) findViewById(R.id.longitude); // Get the location manager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); // Criteria to select location provider Criteria criteria = new Criteria(); provider = locationManager.getBestProvider(criteria, false); Location location = locationManager.getLastKnownLocation(provider); if (location != null) { System.out.println("Provider " + provider + " has been selected."); latitudeField.setText(location.getLatitude()+""); longitudeField.setText(location.getLongitude()+""); } else { latitudeField.setText("Provider not available"); longitudeField.setText("Provider not available"); } } // Request updates at startup @Override protected void onResume() { super.onResume(); locationManager.requestLocationUpdates(provider, 400, 1, this); } // Remove LocationListener updates @Override protected void onPause() { super.onPause(); locationManager.removeUpdates(this); } @Override public void onLocationChanged(Location location) { latitudeField.setText(location.getLatitude()+""); longitudeField.setText(location.getLongitude()+""); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { Toast.makeText(this, "Enabled provider " + provider, Toast.LENGTH_SHORT).show(); } @Override public void onProviderDisabled(String provider) { Toast.makeText(this, "Disabled provider " + provider, Toast.LENGTH_SHORT).show(); } } |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:id="@+id/linearLayout1" android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal" android:layout_marginTop="40dip"> <TextView android:text="Latitude: " android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/TextView01" android:layout_marginLeft="10dip" android:layout_marginRight="5dip" android:textSize="20dip"></TextView> <TextView android:text="unknown" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/latitude" android:textSize="20dip"></TextView> </LinearLayout> <LinearLayout android:id="@+id/linearLayout2" android:layout_height="wrap_content" android:layout_width="match_parent"> <TextView android:text="Longitude: " android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/TextView03" android:layout_marginLeft="10dip" android:layout_marginRight="5dip" android:textSize="20dip"></TextView> <TextView android:text="unknown" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/longitude" android:textSize="20dip"></TextView> </LinearLayout> </LinearLayout> |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="edu.ius.rwisman.Location" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="13" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".LocationActivity" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest> |