altosdroid: Toast() requests don't need Bundles
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / AltosDroid.java
index 8abc8a7b9848c3f3977864dd9594e46e84ece617..33da93466ac14406fca341673bdad98ca33d8418 100644 (file)
 
 package org.altusmetrum.AltosDroid;
 
+import java.lang.ref.WeakReference;
 import android.app.Activity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.content.Intent;
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.os.IBinder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TextToSpeech.OnInitListener;
 import android.text.method.ScrollingMovementMethod;
 import android.util.Log;
 //import android.view.KeyEvent;
@@ -48,18 +57,11 @@ public class AltosDroid extends Activity {
        private static final String TAG = "AltosDroid";
        private static final boolean D = true;
 
-    // Message types sent from the BluetoothChatService Handler
-    public static final int MESSAGE_STATE_CHANGE = 1;
-    public static final int MESSAGE_READ = 2;
-    public static final int MESSAGE_WRITE = 3;
-    public static final int MESSAGE_DEVICE_NAME = 4;
-    public static final int MESSAGE_TOAST = 5;
-
-    // Key names received from the BluetoothChatService Handler
-    public static final String DEVICE_NAME = "device_name";
-    public static final String TOAST = "toast";
-
-
+       // Message types sent from the TelemetryService Handler
+       public static final int MSG_STATE_CHANGE    = 1;
+       public static final int MSG_DEVNAME         = 2;
+       public static final int MSG_INCOMING_TELEM  = 3;
+       public static final int MSG_TOAST           = 4;
 
        // Intent request codes
        private static final int REQUEST_CONNECT_DEVICE = 1;
@@ -70,11 +72,88 @@ public class AltosDroid extends Activity {
        private TextView mSerialView;
        //private EditText mOutEditText;
        //private Button mSendButton;
+
+       private boolean mIsBound;
+       Messenger mService = null;
+       final Messenger mMessenger = new Messenger(new IncomingHandler(this));
+
        // Name of the connected device
        private String mConnectedDeviceName = null;
        // Local Bluetooth adapter
        private BluetoothAdapter mBluetoothAdapter = null;
 
+       private TextToSpeech tts;
+       private boolean tts_enabled = false;
+
+       // The Handler that gets information back from the Telemetry Service
+       static class IncomingHandler extends Handler {
+               private final WeakReference<AltosDroid> mAltosDroid;
+               IncomingHandler(AltosDroid ad) { mAltosDroid = new WeakReference<AltosDroid>(ad); }
+
+               @Override
+               public void handleMessage(Message msg) {
+                       AltosDroid ad = mAltosDroid.get();
+                       switch (msg.what) {
+                       case MSG_STATE_CHANGE:
+                               if(D) Log.i(TAG, "MSG_STATE_CHANGE: " + msg.arg1);
+                               switch (msg.arg1) {
+                               case TelemetryService.STATE_CONNECTED:
+                                       ad.mTitle.setText(R.string.title_connected_to);
+                                       ad.mTitle.append(ad.mConnectedDeviceName);
+                                       ad.mSerialView.setText("");
+                                       break;
+                               case TelemetryService.STATE_CONNECTING:
+                                       ad.mTitle.setText(R.string.title_connecting);
+                                       break;
+                               case TelemetryService.STATE_READY:
+                               case TelemetryService.STATE_NONE:
+                                       ad.mTitle.setText(R.string.title_not_connected);
+                                       break;
+                               }
+                               break;
+                       case MSG_INCOMING_TELEM:
+                               byte[] buf = (byte[]) msg.obj;
+                               // construct a string from the buffer
+                               String telem = new String(buf);
+                               ad.mSerialView.append(telem);
+                               break;
+                       case MSG_DEVNAME:
+                               // save the connected device's name
+                               ad.mConnectedDeviceName = (String) msg.obj;
+                               if (ad.mConnectedDeviceName != null)
+                                       Toast.makeText(ad.getApplicationContext(), "Connected to "
+                                                       + ad.mConnectedDeviceName, Toast.LENGTH_SHORT).show();
+                               break;
+                       case MSG_TOAST:
+                               Toast.makeText(
+                                               ad.getApplicationContext(),
+                                               (String) msg.obj,
+                                               Toast.LENGTH_SHORT).show();
+                               break;
+                       }
+               }
+       };
+
+
+       private ServiceConnection mConnection = new ServiceConnection() {
+               public void onServiceConnected(ComponentName className, IBinder service) {
+                       mService = new Messenger(service);
+                       try {
+                               Message msg = Message.obtain(null, TelemetryService.MSG_REGISTER_CLIENT);
+                               msg.replyTo = mMessenger;
+                               mService.send(msg);
+                       } catch (RemoteException e) {
+                               // In this case the service has crashed before we could even do anything with it
+                       }
+               }
+
+               public void onServiceDisconnected(ComponentName className) {
+                       // This is called when the connection with the service has been unexpectedly disconnected - process crashed.
+                       mService = null;
+               }
+       };
+
+
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
@@ -105,6 +184,18 @@ public class AltosDroid extends Activity {
                        return;
                }
 
+               // Enable Text to Speech
+               tts = new TextToSpeech(this, new OnInitListener() {
+                       public void onInit(int status) {
+                               if (status == TextToSpeech.SUCCESS) tts_enabled = true;
+                               if (tts_enabled) tts.speak("AltosDroid ready", TextToSpeech.QUEUE_ADD, null );
+                       }
+               });
+
+               // Start Telemetry Service
+               startService(new Intent(AltosDroid.this, TelemetryService.class));
+
+               doBindService();
        }
 
        @Override
@@ -152,6 +243,11 @@ public class AltosDroid extends Activity {
        @Override
        public void onDestroy() {
                super.onDestroy();
+
+               doUnbindService();
+
+               if (tts != null) tts.shutdown();
+
                if(D) Log.e(TAG, "--- ON DESTROY ---");
        }
 
@@ -242,9 +338,10 @@ public class AltosDroid extends Activity {
                                // User did not enable Bluetooth or an error occured
                                Log.d(TAG, "BT not enabled");
                                stopService(new Intent(AltosDroid.this, TelemetryService.class));
-                               Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
+                               Toast.makeText(this, R.string.bt_not_enabled, Toast.LENGTH_SHORT).show();
                                finish();
                        }
+                       break;
                }
        }
 
@@ -254,9 +351,17 @@ public class AltosDroid extends Activity {
                // Get the BLuetoothDevice object
                BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
                // Attempt to connect to the device
+               try {
+                       //Message msg = Message.obtain(null, TelemetryService.MSG_CONNECT_TELEBT);
+                       //msg.obj = device;
+                       //mService.send(msg);
+                       if (D) Log.i(TAG, "Connecting to " + device.getName());
+                       mService.send(Message.obtain(null, TelemetryService.MSG_CONNECT, device));
+               } catch (RemoteException e) {
+                       e.printStackTrace();
+               }
        }
 
-
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                MenuInflater inflater = getMenuInflater();
@@ -277,4 +382,28 @@ public class AltosDroid extends Activity {
                return false;
        }
 
+
+       void doBindService() {
+               bindService(new Intent(this, TelemetryService.class), mConnection, Context.BIND_AUTO_CREATE);
+               mIsBound = true;
+       }
+
+       void doUnbindService() {
+               if (mIsBound) {
+                       // If we have received the service, and hence registered with it, then now is the time to unregister.
+                       if (mService != null) {
+                               try {
+                                       Message msg = Message.obtain(null, TelemetryService.MSG_UNREGISTER_CLIENT);
+                                       msg.replyTo = mMessenger;
+                                       mService.send(msg);
+                               } catch (RemoteException e) {
+                                       // There is nothing special we need to do if the service has crashed.
+                               }
+                       }
+                       // Detach our existing connection.
+                       unbindService(mConnection);
+                       mIsBound = false;
+               }
+       }
+
 }