altosdroid: Run even without Bluetooth
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / AltosDroid.java
index c2a6cb29a972a142b425ccf34eabd39292b3adcf..4f1dcb1a3b441cee951af66fd9728ba060e6eaf8 100644 (file)
@@ -45,13 +45,15 @@ import android.view.*;
 import android.widget.*;
 import android.app.AlertDialog;
 import android.location.Location;
+import android.location.LocationManager;
+import android.location.LocationListener;
 import android.hardware.usb.*;
 import android.graphics.*;
 import android.graphics.drawable.*;
 
-import org.altusmetrum.altoslib_7.*;
+import org.altusmetrum.altoslib_10.*;
 
-public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
+public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener {
 
        // Actions sent to the telemetry server at startup time
 
@@ -98,6 +100,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        private double frequency;
        private int telemetry_rate;
 
+       public Location location = null;
+
        // Tabs
        TabHost         mTabHost;
        AltosViewPager  mViewPager;
@@ -133,7 +137,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
 
                        switch (msg.what) {
                        case MSG_STATE:
-                               AltosDebug.debug("MSG_STATE");
                                if (msg.obj == null) {
                                        AltosDebug.debug("telemetry_state null!");
                                        return;
@@ -141,7 +144,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                                ad.update_state((TelemetryState) msg.obj);
                                break;
                        case MSG_UPDATE_AGE:
-                               AltosDebug.debug("MSG_UPDATE_AGE");
                                ad.update_age();
                                break;
                        }
@@ -316,7 +318,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                                state = newest_state;
                }
 
-               update_ui(telemetry_state, state, telemetry_state.location);
+               update_ui(telemetry_state, state);
 
                start_timer();
        }
@@ -381,19 +383,19 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                }
        }
 
-       void update_ui(TelemetryState telem_state, AltosState state, Location location) {
+       void update_ui(TelemetryState telem_state, AltosState state) {
 
                int prev_state = AltosLib.ao_flight_invalid;
 
                AltosGreatCircle from_receiver = null;
 
                if (saved_state != null)
-                       prev_state = saved_state.state;
+                       prev_state = saved_state.state();
 
                if (state != null) {
                        set_screen_on(state_age(state));
 
-                       if (state.state == AltosLib.ao_flight_stateless) {
+                       if (state.state() == AltosLib.ao_flight_stateless) {
                                boolean prev_locked = false;
                                boolean locked = false;
 
@@ -410,9 +412,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                                        }
                                }
                        } else {
-                               if (prev_state != state.state) {
+                               if (prev_state != state.state()) {
                                        String currentTab = mTabHost.getCurrentTabTag();
-                                       switch (state.state) {
+                                       switch (state.state()) {
                                        case AltosLib.ao_flight_boost:
                                                if (currentTab.equals(tab_pad_name)) mTabHost.setCurrentTabByTag(tab_flight_name);
                                                break;
@@ -450,8 +452,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                                else
                                        mFlightView.setText(String.format("%d", state.flight));
                        }
-                       if (saved_state == null || state.state != saved_state.state) {
-                               if (state.state == AltosLib.ao_flight_stateless) {
+                       if (saved_state == null || state.state() != saved_state.state()) {
+                               if (state.state() == AltosLib.ao_flight_stateless) {
                                        mStateLayout.setVisibility(View.GONE);
                                } else {
                                        mStateView.setText(state.state_name());
@@ -466,8 +468,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                for (AltosDroidTab mTab : mTabs)
                        mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem());
 
-               if (state != null && mAltosVoice != null)
-                       mAltosVoice.tell(state, from_receiver);
+               if (mAltosVoice != null)
+                       mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem());
 
                saved_state = state;
        }
@@ -562,22 +564,15 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                mAgeOldColor   = getResources().getColor(R.color.old_color);
        }
 
-       private boolean ensureBluetooth() {
+       private void ensureBluetooth() {
                // Get local Bluetooth adapter
                mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 
-               // If the adapter is null, then Bluetooth is not supported
-               if (mBluetoothAdapter == null) {
-                       Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
-                       return false;
-               }
-
-               if (!mBluetoothAdapter.isEnabled()) {
+               /* if there is a BT adapter and it isn't turned on, then turn it on */
+               if (mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled()) {
                        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(enableIntent, AltosDroid.REQUEST_ENABLE_BT);
                }
-
-               return true;
        }
 
        private boolean check_usb() {
@@ -643,9 +638,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                                        return;
                        }
                        AltosDebug.debug("Starting by looking for bluetooth devices");
-                       if (ensureBluetooth())
-                               return;
-                       finish();
+                       ensureBluetooth();
                }
        }
 
@@ -654,6 +647,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                super.onStart();
                AltosDebug.debug("++ ON START ++");
 
+               set_switch_time();
+
                noticeIntent(getIntent());
 
                // Start Telemetry Service
@@ -679,24 +674,32 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        public void onResume() {
                super.onResume();
                AltosDebug.debug("+ ON RESUME +");
+
+               // Listen for GPS and Network position updates
+               LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
+               locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this);
+
+               location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+
+               AltosDebug.debug("Resume, location is %f,%f\n",
+                                location.getLatitude(),
+                                location.getLongitude());
+
+               update_ui(telemetry_state, saved_state);
        }
 
        @Override
        public void onPause() {
                super.onPause();
                AltosDebug.debug("- ON PAUSE -");
+               // Stop listening for location updates
+               ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
        }
 
        @Override
        public void onStop() {
                super.onStop();
                AltosDebug.debug("-- ON STOP --");
-
-               doUnbindService();
-               if (mAltosVoice != null) {
-                       mAltosVoice.stop();
-                       mAltosVoice = null;
-               }
        }
 
        @Override
@@ -704,7 +707,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                super.onDestroy();
                AltosDebug.debug("--- ON DESTROY ---");
 
-               if (mAltosVoice != null) mAltosVoice.stop();
+               doUnbindService();
+               if (mAltosVoice != null) {
+                       mAltosVoice.stop();
+                       mAltosVoice = null;
+               }
                stop_timer();
        }
 
@@ -722,12 +729,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                        if (resultCode == Activity.RESULT_OK) {
                                // Bluetooth is now enabled, so set up a chat session
                                //setupChat();
+                               AltosDebug.debug("BT enabled");
+                               bluetoothEnabled(data);
                        } else {
                                // User did not enable Bluetooth or an error occured
-                               AltosDebug.error("BT not enabled");
-                               stopService(new Intent(AltosDroid.this, TelemetryService.class));
-                               Toast.makeText(this, R.string.bt_not_enabled, Toast.LENGTH_SHORT).show();
-                               finish();
+                               AltosDebug.debug("BT not enabled");
                        }
                        break;
                case REQUEST_MAP_TYPE:
@@ -751,6 +757,14 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                }
        }
 
+       private void bluetoothEnabled(Intent data) {
+               try {
+                       mService.send(Message.obtain(null, TelemetryService.MSG_BLUETOOTH_ENABLED, null));
+               } catch (RemoteException e) {
+                       AltosDebug.debug("send BT enabled message failed");
+               }
+       }
+
        private void connectDevice(Intent data) {
                // Attempt to connect to the device
                try {
@@ -859,6 +873,26 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                update_state(null);
        }
 
+       void touch_trackers(Integer[] serials) {
+               AlertDialog.Builder builder_tracker = new AlertDialog.Builder(this);
+               builder_tracker.setTitle("Select Tracker");
+               final String[] trackers = new String[serials.length + 1];
+               trackers[0] = "Auto";
+               for (int i = 0; i < serials.length; i++)
+                       trackers[i+1] = String.format("%d", serials[i]);
+               builder_tracker.setItems(trackers,
+                                        new DialogInterface.OnClickListener() {
+                                                public void onClick(DialogInterface dialog, int item) {
+                                                        if (item == 0)
+                                                                select_tracker(0);
+                                                        else
+                                                                select_tracker(Integer.parseInt(trackers[item]));
+                                                }
+                                        });
+               AlertDialog alert_tracker = builder_tracker.create();
+               alert_tracker.show();
+       }
+
        void delete_track(int serial) {
                try {
                        mService.send(Message.obtain(null, TelemetryService.MSG_DELETE_SERIAL, (Integer) serial));
@@ -871,11 +905,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                Intent serverIntent = null;
                switch (item.getItemId()) {
                case R.id.connect_scan:
-                       if (ensureBluetooth()) {
-                               // Launch the DeviceListActivity to see devices and do scan
-                               serverIntent = new Intent(this, DeviceListActivity.class);
-                               startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
-                       }
+                       ensureBluetooth();
+                       // Launch the DeviceListActivity to see devices and do scan
+                       serverIntent = new Intent(this, DeviceListActivity.class);
+                       startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
                        return true;
                case R.id.disconnect:
                        /* Disconnect the device
@@ -997,7 +1030,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        }
 
        static String direction(AltosGreatCircle from_receiver,
-                            Location receiver) {
+                               Location receiver) {
+               if (from_receiver == null)
+                       return null;
+
+               if (receiver == null)
+                       return null;
+
                if (!receiver.hasBearing())
                        return null;
 
@@ -1016,8 +1055,28 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                else if (iheading < -179 || 179 < iheading)
                        return "backwards";
                else if (iheading < 0)
-                       return String.format("left %d", -iheading);
+                       return String.format("left %d°", -iheading);
                else
-                       return String.format("right %d", iheading);
+                       return String.format("right %d°", iheading);
+       }
+
+       public void onLocationChanged(Location location) {
+               this.location = location;
+               AltosDebug.debug("Location changed to %f,%f",
+                                location.getLatitude(),
+                                location.getLongitude());
+               update_ui(telemetry_state, saved_state);
+       }
+
+       public void onStatusChanged(String provider, int status, Bundle extras) {
+               AltosDebug.debug("Location status now %d\n", status);
+       }
+
+       public void onProviderEnabled(String provider) {
+               AltosDebug.debug("Location provider enabled %s\n", provider);
+       }
+
+       public void onProviderDisabled(String provider) {
+               AltosDebug.debug("Location provider disabled %s\n", provider);
        }
 }