1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package com.android.tests.testsensors;
18 
19 import java.util.ArrayList;
20 import java.util.List;
21 
22 import android.app.Activity;
23 import android.hardware.Sensor;
24 import android.hardware.SensorEvent;
25 import android.hardware.SensorEventListener;
26 import android.hardware.SensorManager;
27 import android.os.Bundle;
28 import android.view.LayoutInflater;
29 import android.widget.TableLayout;
30 import android.widget.TableRow;
31 import android.widget.TextView;
32 
33 public class TestSensorsActivity extends Activity {
34     private static final String TAG = "testSensors";
35     /** Array containing monitored sensors. */
36     private List<MonitoredSensor> mSensors;
37     /** Controls displayed list of sensors. */
38     private TableLayout mTableLayout;
39 
40     /**
41      * Encapsulates a sensor.
42      */
43     private class MonitoredSensor implements SensorEventListener {
44         /** Sensor to monitor. */
45         private final Sensor mSensor;
46         /** Check box representing the sensor on the screen. */
47         private final TextView mName;
48         /** Text view displaying the value of the sensor. */
49         private final TextView mVal;
50         /** Formats string to show in the TextView. */
51         private String mTextFmt;
52 
53         /**
54          * Constructs MonitoredSensor instance, and register the listeners.
55          *
56          * @param sensor Sensor to monitor.
57          */
MonitoredSensor(Sensor sensor)58         MonitoredSensor(Sensor sensor) {
59             mSensor = sensor;
60 
61             // Add a row representing this sensor on the display
62             final LayoutInflater inflater = getLayoutInflater();
63             final TableRow row = (TableRow) inflater.inflate(R.layout.one_row, mTableLayout, false);
64             mTableLayout.addView(row);
65 
66             // Initialize displayed checkbox for this sensor, and register
67             // checked state listener for it.
68             mName = (TextView) row.findViewById(R.id.row_textview_name);
69 
70             // Initialize displayed text box for this sensor.
71             mVal = (TextView) row.findViewById(R.id.row_textview_value);
72             mVal.setText("");
73 
74             // Set appropriate sensor name depending on the type. Unfortunately,
75             // we can't really use sensor.getName() here, since the value it
76             // returns (although resembles the purpose) is a bit vaguer than it
77             // should be. Also choose an appropriate format for the strings that
78             // display sensor's value, and strings that are sent to the
79             // emulator.
80             switch (sensor.getType()) {
81                 case Sensor.TYPE_ACCELEROMETER:
82                     mName.setText("Accelerometer");
83                     // 3 floats.
84                     mTextFmt = "%+.2f %+.2f %+.2f";
85                     break;
86                 case 9: // Sensor.TYPE_GRAVITY is missing in API 7
87                     // 3 floats.
88                     mName.setText("Gravity");
89                     mTextFmt = "%+.2f %+.2f %+.2f";
90                     break;
91                 case Sensor.TYPE_GYROSCOPE:
92                     mName.setText("Gyroscope");
93                     // 3 floats.
94                     mTextFmt = "%+.2f %+.2f %+.2f";
95                     break;
96                 case Sensor.TYPE_LIGHT:
97                     mName.setText("Light");
98                     // 1 integer.
99                     mTextFmt = "%.0f";
100                     break;
101                 case 10: // Sensor.TYPE_LINEAR_ACCELERATION is missing in API 7
102                     mName.setText("Linear acceleration");
103                     // 3 floats.
104                     mTextFmt = "%+.2f %+.2f %+.2f";
105                     break;
106                 case Sensor.TYPE_MAGNETIC_FIELD:
107                     mName.setText("Magnetic field");
108                     // 3 floats.
109                     mTextFmt = "%+.2f %+.2f %+.2f";
110                     break;
111                 case Sensor.TYPE_ORIENTATION:
112                     mName.setText("Orientation");
113                     // 3 integers.
114                     mTextFmt = "%+03.0f %+03.0f %+03.0f";
115                     break;
116                 case Sensor.TYPE_PRESSURE:
117                     mName.setText("Pressure");
118                     // 1 integer.
119                     mTextFmt = "%.0f";
120                     break;
121                 case Sensor.TYPE_PROXIMITY:
122                     mName.setText("Proximity");
123                     // 1 integer.
124                     mTextFmt = "%.0f";
125                     break;
126                 case 11: // Sensor.TYPE_ROTATION_VECTOR is missing in API 7
127                     mName.setText("Rotation");
128                     // 3 floats.
129                     mTextFmt = "%+.2f %+.2f %+.2f";
130                     break;
131                 case Sensor.TYPE_TEMPERATURE:
132                     mName.setText("Temperature");
133                     // 1 integer.
134                     mTextFmt = "%.0f";
135                     break;
136                 default:
137                     mName.setText("<Unknown>");
138                     mTextFmt = "N/A";
139                     break;
140             }
141         }
142 
143         /**
144          * Gets sensor type.
145          *
146          * @return Sensor type as one of the Sensor.TYPE_XXX constants.
147          */
getType()148         private int getType() {
149             return mSensor.getType();
150         }
151 
152         /**
153          * Starts monitoring the sensor. NOTE: This method is called from
154          * outside of the UI thread.
155          */
startListening()156         private void startListening() {
157             SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
158             sm.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI);
159         }
160 
161         /**
162          * Stops monitoring the sensor. NOTE: This method is called from outside
163          * of the UI thread.
164          */
stopListening()165         private void stopListening() {
166             SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
167             sm.unregisterListener(this);
168         }
169 
170         /**
171          * Handles "sensor changed" event. This is an implementation of the
172          * SensorEventListener interface.
173          */
174         @Override
onSensorChanged(SensorEvent event)175         public void onSensorChanged(SensorEvent event) {
176             // Display current sensor value, and format message that will be
177             // sent to the emulator.
178             final int nArgs = event.values.length;
179             String val;
180             if (nArgs == 3) {
181                 val = String.format(mTextFmt, event.values[0], event.values[1], event.values[2]);
182             } else if (nArgs == 2) {
183                 val = String.format(mTextFmt, event.values[0], event.values[1]);
184             } else if (nArgs == 1) {
185                 val = String.format(mTextFmt, event.values[0]);
186             } else {
187                 return;
188             }
189             mVal.setText(val);
190         }
191 
192         /**
193          * Handles "sensor accuracy changed" event. This is an implementation of
194          * the SensorEventListener interface.
195          */
196         @Override
onAccuracyChanged(Sensor sensor, int accuracy)197         public void onAccuracyChanged(Sensor sensor, int accuracy) {
198         }
199     } // MonitoredSensor
200 
201     /** Called when the activity is first created. */
202     @Override
onCreate(Bundle savedInstanceState)203     public void onCreate(Bundle savedInstanceState) {
204         super.onCreate(savedInstanceState);
205         setContentView(R.layout.main);
206 
207         mTableLayout = (TableLayout) findViewById(R.id.tableLayout);
208 
209         // Iterate through the available sensors, adding them to the array.
210         mSensors = new ArrayList<MonitoredSensor>();
211         SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
212         List<Sensor> sensors = sm.getSensorList(Sensor.TYPE_ALL);
213         int cur_index = 0;
214         for (int n = 0; n < sensors.size(); n++) {
215             Sensor avail_sensor = sensors.get(n);
216 
217             // There can be multiple sensors of the same type. We need only one.
218             if (!isSensorTypeAlreadyMonitored(avail_sensor.getType())) {
219                 // The first sensor we've got for the given type is not
220                 // necessarily the right one. So, use the default sensor
221                 // for the given type.
222                 Sensor def_sens = sm.getDefaultSensor(avail_sensor.getType());
223                 MonitoredSensor to_add = new MonitoredSensor(def_sens);
224                 cur_index++;
225                 mSensors.add(to_add);
226                 to_add.startListening();
227             }
228         }
229     }
230 
231     /**
232      * Checks if a sensor for the given type is already monitored.
233      *
234      * @param type Sensor type (one of the Sensor.TYPE_XXX constants)
235      * @return true if a sensor for the given type is already monitored, or
236      *         false if the sensor is not monitored.
237      */
isSensorTypeAlreadyMonitored(int type)238     private boolean isSensorTypeAlreadyMonitored(int type) {
239         for (int n = 0; n < mSensors.size(); n++) {
240             if (mSensors.get(n).getType() == type) {
241                 return true;
242             }
243         }
244         return false;
245     }
246 }
247