Google TV

Building Second-screen Applications

Google TV has a Anymote service that can receive and respond to Anymote Protocol messages. You can write remote Android applications or Chrome extensions that communicate with Google TV using the Anymote protocol.

For information on how to build Chrome extensions to communicate with Google TV please see google-tv-chrome-extensions project. The rest of this section focuses on building Android applications that communicate with Google TV.

Use the Google TV Android Remote sample app as the starting point for your own client application. The app is open source, and is available from the google-tv-remote project site.

OR

Use the Anymote library, which handles connecting and communicating with Google TV using Anymote protocol. The BlackJackGTV and BlackJackGTVRemote sample apps demonstrate how to use the Anymote library.

The following is a step-by-step guide to using the Anymote library to create a second-screen application. It assumes you are using Eclipse as your development environment, and you've already set up Eclipse for Android development.

  1. Checkout the Anymote library source and import it into Eclipse as a project.
  2. Include it in your application's Eclipse project following the instructions in Referencing a library project.
  3. Include the third party library jar files provided in the Anymote library's lib folder in your application's build path.
  4. In the AndroidManifest.xml file of your application, declare the following elements (from the Anymote library's AndroidManifest.xml):
    <manifest>
    <application>
        ...
        <service android:name = "com.example.google.tv.anymotelibrary.client.AnymoteClientService">
        </service>
        <activity
            android:name="com.example.google.tv.anymotelibrary.connection.PairingActivity"
            android:configChanges="orientation"
            android:label="Pairing with TV"
            android:launchMode="singleTop" />
        ...
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    <uses-feature android:name="android.hardware.touchscreen" android:required="true" />
    <uses-feature android:name="android.hardware.wifi" android:required="true" />
    </manifest>
    
    
  5. Implement the AnymoteClientService.ClientListener interface to listen for the Google TV connection state and then display the status to the user:
    @Override
    public void onConnected(final AnymoteSender anymoteSender) {
        if (anymoteSender != null) {
            // Send events to Google TV using anymoteSender.
            // save handle to the anymoteSender instance.
            this.anymoteSender = anymoteSender;
        } else {
            // Show message to tell the user that the connection failed.
    	// Try to connect again if needed.
        }
    }
    
    @Override
    public void onDisconnected() {
        // show message to tell the user about disconnection.
        // Try to connect again if needed.
        this.anymoteSender = null;
    }
    
    @Override
    public void onConnectionError() {
        // show message to tell the user about disconnection.
        // Try to connect again if needed.
    
        this.anymoteSender = null;
    }
    
  6. Bind to the library's AnymoteClientService service. This service will initiate the pairing process to connect to the Google TV devices on local network.

    Attach the AnymoteClientService.ClientListener listener implementation to this service. This service continuously monitors the connection to Google TV device and calls back to the onDisconnected() or onConnectionError() methods when the connection fails. When this happens try establishing the connection again and continue.

    // Bind to the AnymoteClientService
    Intent intent = new Intent(mContext, AnymoteClientService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    
    
    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {
        /*
         * ServiceConnection listener methods.
         */
        public void onServiceConnected(ComponentName name, IBinder service) {
    
            mAnymoteClientService = ((AnymoteClientService.AnymoteClientServiceBinder) service)
                    .getService();
            mAnymoteClientService.attachClientListener(BlackJackRemoteActivity.this);
        }
    
        public void onServiceDisconnected(ComponentName name) {
            mAnymoteClientService.detachClientListener(BlackJackRemoteActivity.this);
            mAnymoteClientService = null;
        }
    };
    
  7. The onConnected() callback from the ClientListener gives you a handle to the AnymoteSender class to send messages to the connected Google TV using the Anymote protocol.

    Send key presses to Google TV:

    private void sendKeyEvent(final int keyEvent) {
        // create new Thread to avoid network operations on UI Thread
        new Thread(new Runnable() {
            public void run() {
                anymoteSender.sendKeyPress(keyEvent);
            }
        }).start();
    }
    

    Send Intent to launch a Google TV app:

    final Intent intent = new Intent();
    intent.setAction ("com.example.googletv.blackjack.VIEW_ACTION");
    anymoteSender.sendUrl (intent.toUri(Intent.URI_INTENT_SCHEME));
    

    Send Intent to view a webpage on Google TV:

    final Intent intent = new Intent(Intent.ACTION_VIEW,
            Uri.parse("http://<webpage_url>");
    anymoteSender.sendUrl (intent.toUri(Intent.URI_INTENT_SCHEME));
    

  8. To send touch events to the connected Google TV using the Anymote protocol, instantiate the TouchHandler and pass in the View whose touch events need to be sent and a handle to AnymoteSender.

    // Attach touch handler to the touchpad view
    new TouchHandler(
            findViewById(R.id.touch_pad), Mode.POINTER_MULTITOUCH, anymoteSender);
    
    
  9. To send trackball events to the connected Google TV using the Anymote protocol, instantiate the TrackballHandler as shown below:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // To play sound on trackball event
        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        trackballHandler = createTrackballHandler();
        trackballHandler.setAudioManager(am);
    }
    
    /**
     * Returns an object handling trackball events.
     */
    private TrackballHandler createTrackballHandler() {
        TrackballHandler handler = new TrackballHandler(new Listener() {
            public void onClick() {
                anymoteSender.sendKeyPress(Code.KEYCODE_DPAD_CENTER);
            }
    
            public void onDirectionalEvent(Direction direction) {
                switch (direction) {
                    case DOWN:
                        anymoteSender.sendKeyPress(Code.KEYCODE_DPAD_DOWN);;
                        break;
    
                    case LEFT:
                        Action.DPAD_LEFT.execute(anymoteSender);
                        break;
    
                    case RIGHT:
                        Action.DPAD_RIGHT.execute(anymoteSender);
                        break;
    
                    case UP:
                        Action.DPAD_UP.execute(anymoteSender);
                        break;
    
                   default:
                        break;
                }
          }
    
          public void onScrollEvent(int dx, int dy) {
               anymoteSender.scroll(dx, dy);
          }
        }, this);
        handler.setEnabled(true);
        handler.setMode(Mode.DPAD);
        return handler;
    }
    

    Next, override the onTrackballEvent() callback method for your application's Activity, and pass the MotionEvent to TrackballHandler. The TrackballHandler will pass that event to the connected Google TV using Anymote.

    @Override
    public boolean onTrackballEvent(MotionEvent event) {
      return trackballHandler.onTrackballEvent(event);
    }
    

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.