- Flinging a URL
- Sending KeyEvents to the TV
- Sending Mouse Events to the TV
- Summary
- Q&A
- Workshop
- Exercises
Sending Mouse Events to the TV
Using the Anymote protocol we have the capability to send messages to the TV that appear to the TV as mouse events. That is, the messages are equivalent to using the mousepad or trackpad on the remote that comes with the TV. We do this using the Anymote Library sendMoveRelative method.
Using the Accelerometer
For this remote app, we will use the phone’s Accelerometer to create the values to send to the TV. Android phones have sensors that can detect a number of values from the real world. The Accelerometer detects how the phone is accelerating through space. It detects three values as the phone moves. The x, y, and z values represent a three-dimensional coordinate system, as shown in Figure 23.2.
Figure 23.2. The coordinate system. Image from Google.
If you move the phone to the right, the x value increases. If you push the phone straight away from you, the y value increases. If you move the phone upward, the z value increases.
We will do a simple mapping of the returned x and y values to create mouselike movements to send to the TV. The effect is to use the phone as a mouse where tilting and moving results in the mouse cursor moving in a reasonable way on the TV.
We implement one Button in the app. It is a Click Button that sends the equivalent of a mouse click to the TV. This makes our remote useful as a mouse, but does not provide for D-Pad navigation, a back button, or any other keyboard input.
Listing 23.9 shows the onCreate method for the Accelerometer remote app. This handles the Click Button by sending mouse down and mouse up keys to the TV.
Listing 23.9. Accelerometer App onCreate
1: Button click = (Button) findViewById(R.id.button1); 2: click.setOnClickListener(new OnClickListener() { 3: @Override 4: public void onClick(View v) { 5: anymoteSender.sendKey (Code.BTN_MOUSE, Action.DOWN); 6: anymoteSender.sendKey (Code.BTN_MOUSE, Action.UP); 7: } 8: });
Detecting Changes Using SensorEventListener
To use the Accelerometer, we must implement a SensorEventListener for the Activity:
public class Hour23AccelerometerRemote extends Activity implements ClientListener, SensorEventListener
A SensorManager field is defined for the class:
private SensorManager sensorManager;
The logic for the Accelerometer remote app is the following:
- Pair with the TV.
- Begin listening for Accelerometer events.
- Send those events to the TV as mouse movements.
To accomplish this, we create the SensorManager after the connection is made between the TV and the remote, so we do it in the onConnected method. The onConnected method for the example is shown in Listing 23.10.
Listing 23.10. Defining SensorManager in onConnected Method
1: @Override 2: public void onConnected(final AnymoteSender anymoteSender) { 3: this.anymoteSender = anymoteSender; 4: sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE); 5: sensorManager.registerListener(this, 6: sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 7: SensorManager.SENSOR_DELAY_FASTEST); 8: handler.post(new Runnable() { 9: public void run() { 10: progressBar.setVisibility(View.INVISIBLE); 11: } 12: }); 13: }
The sensorManager is defined in line 4 of Listing 23.10. In lines 5 to 8, the sensorManager is set up to listen for Accelerometer events. We use the flag SensorManager.SENSOR_DELAY_FASTEST to capture all values from the sensor.
For the SensorEventListener we must implement two methods: onAccuracyChanged and onSensorChanged. To demonstrate sending a mouse movement to the TV, the work will be done in the onSensorChanged method.
Listing 23.11 shows both methods. Line 6 checks to see if the sensor is an Accelerometer. If it is, the values for x, y, and z are populated. Line 10 sends the mouse movement to the TV. In this implementation, 1 is subtracted from y as a simple way to compensate for gravity. Each value is multiplied by -1 to set the proper direction on the TV screen.
This is a very simple movement detection and translation scheme that handles gravity and shows how to make the connection between a sensor on the phone and an action on the TV.
Listing 23.11. Detecting Sensor Changes
1: @Override 2: public void onAccuracyChanged(Sensor Sensor, int accuracy) { 3: } 4: @Override 5: public void onSensorChanged(SensorEvent event) { 6: if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){ 7: float x=event.values[0]; 8: float y=event.values[1]; 9: float z=event.values[2]; 10: anymoteSender.sendMoveRelative((int)x*-1,(int) ((y-1)*-1)); 11: } 12: }
Using the Accelerometer, we can detect motion of a phone and successfully translate that motion into mouse events on a Google TV. There are a number of other sensors available in most Android phones. Sensors can detect things like temperature, light, and proximity. Using phone sensors and Google TV creates new opportunities for detecting information using a phone and displaying it on a TV.