3. Februar 2013

Android: Lagesensordaten verwenden

Jedes aktuelle Smartphone besitzt heute einen internen Lagesensor, der Daten über die Lage und Ausrichtung des Geräts im Raum erfasst. Wie alle Sensordaten des Geräts, lassen sich auch die Daten dieses so genannten "Accelerometers" auswerten und von Apps verwenden. Das folgende Beispiel soll beispielhaft zeigen, wie so etwas aussehen kann.

Die generelle Vorgehensweise im Umgang mit Sensoren bei der Android-Programmierung ist es, einen entsprechenden Listener, der das Interface android.hardware.SensorEventListener implementiert an einem sogenannten SensorManager zu registrieren. Dieser SensorManager ist ein SystemService, über den alle Sensoren des Geräts angesprochen werden können. Über folgenden Methodenaufruf erhält man eine Instanz auf den SensorManager innerhalb einer Activity:
 SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);  
Um einen SensorEventListener an dieser SensorManager-Instanz zu registrieren reicht folgender Methodenaufruf:
 sensorManager.registerListener(listener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);  
Der Parameter "listener" entspricht dabei dem SensorEventListener, der zum Empfang der Sensordaten registriert werden soll und dessen Implementierung weiter unten noch folgen wird. Die Konstante Sensor.TYPE_ACCELEROMETER bezeichnet den Lagesensor, der in diesem Beispiel verwendet werden soll. Analog dazu funktioniert auch die Verwendung anderer Sensoren. Außerdem lässt sich über den dritten Parameter das Intervall steuern, in dem die Sensordaten aktualisiert werden. Folgende Werte sind hierbei möglich:
  • SENSOR_DELAY_FASTEST: Hierbei werden die Daten so schnell wie technisch möglich aktualisiert. 
  • SENSOR_DELAY_GAME: Das Intervall, das für die Verwendung in Spielen gedacht ist. 
  • SENSOR_DELAY_NORMAL: Entspricht der Standard-Einstellung, die beispielsweise für das Umschalten zwischen vertikaler Ausrichtung und Landscape-Modus genutz wird. 
  • SENSOR_DELAY_UI: Das langsamste Intervall, das für für die Verwendung zur Gestaltung von Benutzeroberflächen gedacht ist.
Der Code für die gesamte Activity, inklusive der Implementierung des SensorEventListeners könnte in etwa wie folgt aussehen:
     public class ExampleActivity extends Activity {  
       
         private SensorManager sensorManager;  
       
         private SensorEventListener accelerometerListener = new SensorEventListener {  
    
             public void onAccuracyChanged(Sensor sensor, int accuracy) {
                 return;
             }
    
             public void onSensorChanged(SensorEvent event) {
                 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                     float x = event.values[0];
                     float y = event.values[1];
                     float z = event.values[2];
    
                     TextView xCoor = (TextView) activity.findViewById(R.id.xcoor);
                     TextView yCoor = (TextView) activity.findViewById(R.id.ycoor);
                     TextView zCoor = (TextView) activity.findViewById(R.id.zcoor);
    
                     xCoor.setText("X: " + x);
                     yCoor.setText("Y: " + y);
                     zCoor.setText("Z: " + z);
                 }
             }
    
         };  
       
         @Override  
         public void onCreate(Bundle savedInstanceState) {  
             super.onCreate(savedInstanceState);  
       
             sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);  
             sensorManager.registerListener(accelerometerListener,  
                     sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),  
                     SensorManager.SENSOR_DELAY_UI);  
         }  
       
         @Override  
         public void onDestroy() {  
             super.onDestroy();  
             sensorManager.unregisterListener(accelerometerListener);  
         }  
       
     }  
    Zu beachten ist hierbei, dass die Registrierung am SensorManager beim Beenden der Activity wieder rückgängig gemacht werden muss, da ansonsten weiterhin Sensordaten empfangen werden und die Anwendung niemals komplett beendet werden würde. Dies geschieht über einen entsprechenden Methodenaufruf indem die onDestroy()-Methode der Activity überschrieben wird.

    Die Sensordaten des Lagesensors umfassen drei Werte, die den drei Achsen des dreidimensionalen Raumes entsprechen. In diesem Beispiel werden die erfassten Werte durch den SensorEventListener lediglich auf drei TextViews ausgegeben. Hierfür müssen die TextViews mit den entsprechenden IDs natürlich definiert sein, was über folgendes XML Layout File geschieht:
     <?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/xcoor"  
           android:layout_width="wrap_content"  
           android:layout_height="wrap_content"  
           android:text="X Coordinate: " />  
       </TableRow>  
       
       <TableRow>  
       
         <TextView  
           android:id="@+id/ycoor"  
           android:layout_width="wrap_content"  
           android:layout_height="wrap_content"  
           android:text="Y Coordinate: " />  
       </TableRow>  
       
       <TableRow>  
       
         <TextView  
           android:id="@+id/zcoor"  
           android:layout_width="wrap_content"  
           android:layout_height="wrap_content"  
           android:text="Z Coordinate: " />  
       </TableRow>  
       
     </TableLayout>  

    Keine Kommentare:

    Kommentar veröffentlichen