I am going to teach you. How can you create an apps that displays all the sensors in the phone reporting the following characteristics:
3. Now create the file res/values/types.xml
You have created all xml files required to display contents . Now its time to play with Java coding to make this apps live.
6. Open your MainActivity.java page (Check in src\YOUR PACKAGE\) and replace all content with following content except first line (indicating import your package)
Check this line: public class MainActivity extends ListActivity implements SensorEventListener
Here MainActivity is extended by ListActivity. Because it's easy to show contents in list view using ListActivity.
I display and set the text views related to “Min Delay” only if the API level is equal to or greater than Gingerbread
some strings are displayed using the method Html.fromHtml(String source) because they contain special characters (µ or ²).
9. Create a class MySensor.java on same package where MainActivity.java class stored. Copy following content and paste into MySensor.java class.
the annotation @TargetApi avoids a compilation error
the variables MICRO e SQUARE define some special characters in the method Html.fromHtml(String source) of the class SensorAdapte.
- Name: Name of the sensor
- Version: Version of the sensor’s module
- Vendor: Vendor of this sensor
- Type: Type of this sensor
- Max Range: maximum range of the sensor
- Resolution: resolution of the sensor
- Min Delay: minimum delay allowed between two events (equals to zero if this sensor only returns a value when the data it’s measuring changes)
- Power: the power of the sensor
- Create a project.
- Open file res/values/strings.xml and replace all content with following:
<resources>These string name, we will use in entire project.
<string name="app_name">Sensor List</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string name="name_label">Name</string>
<string name="vendor_label">Vendor</string>
<string name="default_text">not found</string>
<string name="type_label">Type</string>
<string name="version_label">Version</string>
<string name="maximum_range_label">Max Range</string>
<string name="min_delay_label">Min Delay</string>
<string name="resolution_label">Resolution</string>
<string name="power_label">Power</string>
</resources>
3. Now create the file res/values/types.xml
<?xml version="1.0" encoding="utf-8"?>4. Open the file res/values/styles.xml and replace with following code:
<resources>
<string name="accelerometer">accelerometer sensor</string>
<string name="ambient_temperature">ambient temperature sensor</string>
<string name="gravity">gravity sensor</string>
<string name="gyroscope">gyroscope sensor</string>
<string name="light">light sensor</string>
<string name="linear_acceleration">linear acceleration sensor</string>
<string name="magnetic_field">magnetic field sensor</string>
<string name="orientation">orientation sensor (deprecated)</string>
<string name="pressure">pressure sensor</string>
<string name="proximity">proximity sensor</string>
<string name="relative_humidity">relative humidity sensor</string>
<string name="rotation_vector">rotation vector sensor</string>
<string name="temperature">temperature sensor (deprecated)</string>
<string name="unknown">unknown sensor</string>
</resources>
5. There are many sensors using in your mobile. To view all sensors in a list. Create the resource res/layout/list_item.xml
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <style name="AppTheme" parent="android:Theme.Light" /> <style name="TitleLabel" parent="@android:style/Widget.TextView"> <item name="android:textStyle">italic</item> <item name="android:textSize">14sp</item> </style> <style name="BodyLabel" parent="@android:style/Widget.TextView"> <item name="android:textStyle">italic</item> <item name="android:textSize">12sp</item> </style> <style name="TitleView" parent="@android:style/Widget.TextView"> <item name="android:textStyle">bold</item> <item name="android:textSize">14sp</item> </style> <style name="BodyView" parent="@android:style/Widget.TextView"> <item name="android:textSize">12sp</item> </style> </resources>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="10sp" android:paddingBottom="10sp" > <TextView android:id="@+id/nameLabel" style="@style/TitleLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="10dp" android:text="@string/name_label" /> <TextView android:id="@+id/vendorLabel" style="@style/TitleLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/nameLabel" android:layout_below="@id/nameLabel" android:text="@string/vendor_label" /> <TextView android:id="@+id/typeLabel" style="@style/BodyLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/vendorLabel" android:layout_below="@id/vendorLabel" android:text="@string/type_label" /> <TextView android:id="@+id/maximumRangeLabel" style="@style/BodyLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/typeLabel" android:layout_below="@id/typeLabel" android:text="@string/maximum_range_label" /> <TextView android:id="@+id/resolutionLabel" style="@style/BodyLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/maximumRangeLabel" android:layout_below="@id/maximumRangeLabel" android:text="@string/resolution_label" /> <TextView android:id="@+id/minDelayLabel" style="@style/BodyLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/resolutionLabel" android:layout_below="@id/resolutionLabel" android:text="@string/min_delay_label" /> <TextView android:id="@+id/powerLabel" style="@style/BodyLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/minDelayLabel" android:layout_below="@id/minDelayLabel" android:text="@string/power_label" /> <TextView android:id="@+id/nameView" style="@style/TitleView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/nameLabel" android:layout_alignBottom="@id/nameLabel" android:layout_marginLeft="40dp" android:layout_toRightOf="@id/nameLabel" android:singleLine="true" android:text="@string/default_text" /> <TextView android:id="@+id/versionLabel" style="@style/BodyLabel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/nameView" android:layout_alignBottom="@id/nameView" android:layout_marginLeft="10dp" android:layout_toRightOf="@id/nameView" android:text="@string/version_label" /> <TextView android:id="@+id/vendorView" style="@style/TitleView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/vendorLabel" android:layout_alignBottom="@id/vendorLabel" android:layout_alignLeft="@id/nameView" android:singleLine="true" android:text="@string/default_text" /> <TextView android:id="@+id/typeView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/typeLabel" android:layout_alignBottom="@id/typeLabel" android:layout_alignLeft="@id/nameView" android:text="@string/default_text" /> <TextView android:id="@+id/versionView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/versionLabel" android:layout_alignBottom="@id/versionLabel" android:layout_marginLeft="10dp" android:layout_toRightOf="@id/versionLabel" android:text="@string/default_text" /> <TextView android:id="@+id/maximumRangeView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/maximumRangeLabel" android:layout_alignBottom="@id/maximumRangeLabel" android:layout_alignLeft="@id/nameView" android:text="@string/default_text" /> <TextView android:id="@+id/unitsRangeView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/maximumRangeView" android:layout_alignBottom="@id/maximumRangeView" android:layout_marginLeft="2dp" android:layout_toRightOf="@id/maximumRangeView" android:text="" /> <TextView android:id="@+id/minDelayView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/minDelayLabel" android:layout_alignBottom="@id/minDelayLabel" android:layout_alignLeft="@id/nameView" android:text="@string/default_text" /> <TextView android:id="@+id/unitsDelayView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/minDelayView" android:layout_alignBottom="@id/minDelayView" android:layout_marginLeft="2dp" android:layout_toRightOf="@id/minDelayView" android:text="" /> <TextView android:id="@+id/powerView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/powerLabel" android:layout_alignBottom="@id/powerLabel" android:layout_alignLeft="@id/nameView" android:text="@string/default_text" /> <TextView android:id="@+id/unitsPowerView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/powerView" android:layout_alignBottom="@id/powerView" android:layout_marginLeft="2dp" android:layout_toRightOf="@id/powerView" android:text="" /> <TextView android:id="@+id/resolutionView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/resolutionLabel" android:layout_alignBottom="@id/resolutionLabel" android:layout_alignLeft="@id/nameView" android:text="@string/default_text" /> <TextView android:id="@+id/unitsResolutionView" style="@style/BodyView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@id/resolutionView" android:layout_alignBottom="@id/resolutionView" android:layout_marginLeft="2dp" android:layout_toRightOf="@id/resolutionView" android:text="" /> </RelativeLayout> </HorizontalScrollView>
You have created all xml files required to display contents . Now its time to play with Java coding to make this apps live.
6. Open your MainActivity.java page (Check in src\YOUR PACKAGE\) and replace all content with following content except first line (indicating import your package)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import android.app.ListActivity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class MainActivity extends ListActivity implements SensorEventListener {
private SensorAdapter adapter;
private List<MySensor> sensorList;
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sensorList = new ArrayList<MySensor>(); /* It is an array containing the Sensor objects that are the sensors of the phone */
sensorList = getSensors();
adapter = new SensorAdapter(this, R.layout.list_item, sensorList);
setListAdapter(adapter);
}
public void onSensorChanged(SensorEvent event) {
}
private List<MySensor> getSensors() { /*I find all the sensors of the phone and I add them as objects of the class MySensor to a List that I set to ArrayList<MySensor> in the onCreate event*/
List<MySensor> list = new ArrayList<MySensor>();
SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
List<Sensor> phoneSensor = sm.getSensorList(Sensor.TYPE_ALL);
Iterator<Sensor> it = phoneSensor.iterator();
while (it.hasNext()) {
Sensor s = it.next();
list.add(new MySensor(s, getApplicationContext()));
}
return list;
}
}
Check this line: public class MainActivity extends ListActivity implements SensorEventListener
Here MainActivity is extended by ListActivity. Because it's easy to show contents in list view using ListActivity.
7. Create SensorAdapter.java class on same folder where your MainActivity.java file stored.
8. Open this page. Copy following content and paste it.
import java.util.List;When you extend an ArrayAdapter, you override the method getView to set the layout (res/layout/list_item.xml)
import android.content.Context;
import android.os.Build;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class SensorAdapter extends ArrayAdapter<MySensor> {
private static final int SDK = Build.VERSION.SDK_INT;
private int resource;
public SensorAdapter(Context context, int resource, List<MySensor> items) {
super(context, resource, items);
this.resource = resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout newView;
if (convertView == null) {
newView = new LinearLayout(getContext());
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li;
li = (LayoutInflater) getContext().getSystemService(inflater);
li.inflate(resource, newView, true);
} else {
newView = (LinearLayout) convertView;
}
TextView nameView = (TextView) newView.findViewById(R.id.nameView);
TextView vendorView = (TextView) newView.findViewById(R.id.vendorView);
TextView typeView = (TextView) newView.findViewById(R.id.typeView);
TextView versionView = (TextView) newView
.findViewById(R.id.versionView);
TextView maximumRangeView = (TextView) newView
.findViewById(R.id.maximumRangeView);
TextView minDelayView = (TextView) newView
.findViewById(R.id.minDelayView);
TextView powerView = (TextView) newView.findViewById(R.id.powerView);
TextView resolutionView = (TextView) newView
.findViewById(R.id.resolutionView);
TextView unitsRangeView = (TextView) newView
.findViewById(R.id.unitsRangeView);
TextView unitsResolutionView = (TextView) newView
.findViewById(R.id.unitsResolutionView);
TextView unitsDelayView = (TextView) newView
.findViewById(R.id.unitsDelayView);
TextView unitsPowerView = (TextView) newView
.findViewById(R.id.unitsPowerView);
if (SDK < Build.VERSION_CODES.GINGERBREAD) {
TextView minDelayLabel = (TextView) newView
.findViewById(R.id.minDelayLabel);
minDelayLabel.setVisibility(View.GONE);
minDelayView.setVisibility(View.GONE);
unitsDelayView.setVisibility(View.GONE);
}
MySensor mySensor = getItem(position);
nameView.setText(mySensor.getName());
vendorView.setText(mySensor.getVendor());
typeView.setText(mySensor.getTypeDescription());
versionView.setText(String.valueOf(mySensor.getVersion()));
maximumRangeView.setText(String.valueOf(mySensor.getMaximumRange()));
if (SDK >= Build.VERSION_CODES.GINGERBREAD)
minDelayView.setText(String.valueOf(mySensor.getMinDelay()));
powerView.setText(String.valueOf(mySensor.getPower()));
resolutionView.setText(String.format("%f", mySensor.getResolution()));
unitsRangeView.setText(Html.fromHtml(mySensor.getUnits()));
unitsResolutionView.setText(Html.fromHtml(mySensor.getUnits()));
if (SDK >= Build.VERSION_CODES.GINGERBREAD)
unitsDelayView.setText(Html.fromHtml(mySensor.getDelayUnits()));
unitsPowerView.setText(Html.fromHtml(mySensor.getPowerUnits()));
return newView;
}
}
I display and set the text views related to “Min Delay” only if the API level is equal to or greater than Gingerbread
some strings are displayed using the method Html.fromHtml(String source) because they contain special characters (µ or ²).
9. Create a class MySensor.java on same package where MainActivity.java class stored. Copy following content and paste into MySensor.java class.
import android.annotation.TargetApi;The method getMinDelay of the class Sensor is new with GingerBread (API 9, Android 2.3), then you can use it only after the condition that the API level of the device is equal to or greater than 9
import android.content.Context;
import android.hardware.Sensor;
import android.os.Build;
public class MySensor {
private final static String MICRO = "&#x3BC;";
private static final int SDK = Build.VERSION.SDK_INT;
private final static String SQUARE = "&#xB2;";
private Context context;
private float maximumRange, minDelay, power, resolution;
private String name, vendor;
private int type, version;
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public MySensor(Sensor sensor, Context context) {
this.name = sensor.getName();
this.vendor = sensor.getVendor();
this.type = sensor.getType();
this.version = sensor.getVersion();
this.maximumRange = sensor.getMaximumRange();
if (SDK >= Build.VERSION_CODES.GINGERBREAD)
this.minDelay = sensor.getMinDelay();
this.power = sensor.getPower();
this.resolution = sensor.getResolution();
this.context = context;
}
public String getDelayUnits() {
return MICRO + "s";
}
public float getMaximumRange() {
return maximumRange;
}
public float getMinDelay() {
return minDelay;
}
public String getName() {
return name;
}
public float getPower() {
return power;
}
public String getPowerUnits() {
return "mA";
}
public float getResolution() {
return resolution;
}
public int getType() {
return type;
}
public String getTypeDescription() {
String description = null;
switch (type) {
case Sensor.TYPE_ACCELEROMETER:
description = context.getResources().getString(
R.string.accelerometer);
break;
case Sensor.TYPE_AMBIENT_TEMPERATURE:
description = context.getResources().getString(
R.string.ambient_temperature);
break;
case Sensor.TYPE_GRAVITY:
description = context.getResources().getString(R.string.gravity);
break;
case Sensor.TYPE_GYROSCOPE:
description = context.getResources().getString(R.string.gyroscope);
break;
case Sensor.TYPE_LIGHT:
description = context.getResources().getString(R.string.light);
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
description = context.getResources().getString(
R.string.linear_acceleration);
break;
case Sensor.TYPE_MAGNETIC_FIELD:
description = context.getResources().getString(
R.string.magnetic_field);
break;
case Sensor.TYPE_ORIENTATION:
description = context.getResources()
.getString(R.string.orientation);
break;
case Sensor.TYPE_PRESSURE:
description = context.getResources().getString(R.string.pressure);
break;
case Sensor.TYPE_PROXIMITY:
description = context.getResources().getString(R.string.proximity);
break;
case Sensor.TYPE_RELATIVE_HUMIDITY:
description = context.getResources().getString(
R.string.relative_humidity);
break;
case Sensor.TYPE_ROTATION_VECTOR:
description = context.getResources().getString(
R.string.rotation_vector);
break;
case Sensor.TYPE_TEMPERATURE:
description = context.getResources()
.getString(R.string.temperature);
break;
default:
description = context.getResources().getString(R.string.unknown);
break;
}
return description;
}
public String getUnits() {
String units = null;
switch (type) {
case Sensor.TYPE_ACCELEROMETER:
units = "m/s" + SQUARE;
break;
case Sensor.TYPE_AMBIENT_TEMPERATURE:
units = "°C";
break;
case Sensor.TYPE_GRAVITY:
units = "m/s" + SQUARE;
break;
case Sensor.TYPE_GYROSCOPE:
units = "rad/s";
break;
case Sensor.TYPE_LIGHT:
units = "SI lux";
break;
case Sensor.TYPE_LINEAR_ACCELERATION:
units = "m/s" + SQUARE;
break;
case Sensor.TYPE_MAGNETIC_FIELD:
units = MICRO + "T";
break;
case Sensor.TYPE_ORIENTATION:
units = "°";
break;
case Sensor.TYPE_PRESSURE:
units = "hPa";
break;
case Sensor.TYPE_PROXIMITY:
units = "cm";
break;
case Sensor.TYPE_RELATIVE_HUMIDITY:
units = "";
break;
case Sensor.TYPE_ROTATION_VECTOR:
units = "";
break;
case Sensor.TYPE_TEMPERATURE:
units = "°C";
break;
default:
units = "unknown";
break;
}
return units;
}
public String getVendor() {
return vendor;
}
public int getVersion() {
return version;
}
public void setMaximumRange(float maximumRange) {
this.maximumRange = maximumRange;
}
public void setMinDelay(float minDelay) {
this.minDelay = minDelay;
}
public void setName(String name) {
this.name = name;
}
public void setPower(float power) {
this.power = power;
}
public void setResolution(float resolution) {
this.resolution = resolution;
}
public void setType(int type) {
this.type = type;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public void setVersion(int version) {
this.version = version;
}
@Override
public String toString() {
return name;
}
}
the annotation @TargetApi avoids a compilation error
the variables MICRO e SQUARE define some special characters in the method Html.fromHtml(String source) of the class SensorAdapte.