Responding to Sensor Data

Android provides a simple way to acquire touch events, but sensors are a more complicated matter. This isn’t to say that getting the data is tricky or difficult, but working with the input in a meaningful way can be a real challenge. You concentrate on accelerometer data here because it’s the most commonly used sensor, and the other sensors (such as the gyroscope) are akin to it.

The data that tablet sensors deliver is very precise and usually of the Java long floating-point data type. This is a mixed blessing because long floating-point data is convoluted and complicated to figure out. Making things more difficult is the fact that tablets can be held in a variety of orientations. Holding the tablet in portrait mode completely alters the axis of rotation. To solve this temporarily, you can assume that the tablet is held in landscape mode. Later, you learn a way to detect the orientation of the tablet and instruct the user about the correct position for your particular game.

Let’s add some code to the project and see what this sensor data is all about:

  1. You need to import another Android library. To do so, add the code in Listing 3-13 to the MainActivity.java file.

    Listing 3-13. Getting Access to Sensor Data

    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
  2. You may notice with these imports that you’re talking about hardware-specific information. It’s possible that the device that runs your game lacks the correct sensors.
  3. Implement the SensorEventListener class in your MainActivity class. To do so, add implements SensorEventListener directly after the extends Activity line. When an error message appears, double-click it to create the two events shown in Listing 3-14.

    Listing 3-14. Autogenerated Sensor Methods

    @Override
    public void onAccuracyChanged(Sensor arg0, int arg1) {
            // TODO Auto-generated method stub

    }
    @Override
    public void onSensorChanged(SensorEvent arg0) {
            // TODO Auto-generated method stub

    }        
  4. This is fairly self-explanatory: the creation of a SensorEventListener and then two methods that register when a sensor changes accuracy or its values change. You concentrate most on onSensorChanged() because you’re looking for the data. There are many other functions besides these that you can use when you want very specific information from your sensors.
  5. Place the lines in Listing 3-15 above the onCreate() method in MainActivity.

    Listing 3-15. Creating Sensor Objects

    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
  6. Initialize these sensor objects in the onCreate() method, as shown in Listing 3-16.

    Listing 3-16. Initializing Sensor Objects

    mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
    mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  7. To handle sensors, you add two basic methods that are already available with every activity: onPause() and onResume(). You need them here because you don’t want to continue searching for sensor input when the device is already in some sort of sleep mode. The code in Listing 3-17 handles this issue.

    Listing 3-17. onPause() and onResume()

    protected void onResume() {
    super.onResume();
    mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    protected void onPause() {
    super.onPause();
    mSensorManager.unregisterListener(this);
    }
  8. You can look at a modified onSensorChanged() to determine the values of the pitch, roll, and azimuth. For reference, azimuth is rotation around the z-axis, pitch is around the x-axis, and roll is around the y-axis. To express the values of the accelerometer, you introduce a debugging technique for Eclipse and Android. At the top, import Android.util.Log. Then change onSensorChanged() to the code shown in Listing 3-18.

    Listing 3-18. onSensorChanged (add import android.util.Log)

    @Override
    public void onSensorChanged(SensorEvent event) {


            float R[] = new float[9];
            float orientation[] = new float[3];
            SensorManager.getOrientation(R, orientation);

            Log.d("azimuth",Float.toString(orientation[0]));
            Log.d("pitch",Float.toString(orientation[1]));
            Log.d("role",Float.toString(orientation[2]));

    }
  9. Basically, you create two arrays to store values. Then you call on sensor manager to get the orientation of the device. Finally, you take the orientation array and print out the values. The Log.d function may look novel to you, but it’s simply a way to send data to your debugger. Before you run the program, you can set up the view for reading these values by choosing Window images Show View images Other images Android images LogCat.

Now, instead of seeing the output of the console, you see tons of data points flashing by as the emulator starts up. When the application begins running, you see the accelerometer values. Figure 3-7 shows what happens when you use the emulator on a computer and it doesn’t get any changes in motion.

images

Figure 3-7. Noting the azimuth, pitch, and roll of a device

When I want to work with sensor data, I always test it on my actual tablet device because it’s so simple to hold the device in different positions. If you haven’t looked at it already, Appendix A has information about setting up your tablet for testing. If you’re more adventurous or don’t have a device, Android has a sensor simulator that can help you when you’re writing code.

You can see the Google code project here: http://code.google.com/p/openintents/wiki/SensorSimulator. It’s actually a fairly easy proposition to set up the entire system, but I won’t go into it here. At some point, only a real device can provide immediacy of response and show you what its processing capabilities are.

The Sensor Simulator does have some advantages over a real device. By correlating the exact movement values to the way the device responds, you can get a better feel for how well your program is working. For most developers, it’s difficult to measure a perfect 37-degree rotation just by holding a tablet.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.53.32