diff options
18 files changed, 722 insertions, 117 deletions
| diff --git a/altosdroid/.gitignore b/altosdroid/.gitignore index 7f0858ea..cf7ad5a8 100644 --- a/altosdroid/.gitignore +++ b/altosdroid/.gitignore @@ -5,3 +5,4 @@ libs  google-play-services_lib  src/org/altusmetrum/AltosDroid/BuildInfo.java  res/drawable/*led.png +AndroidManifest.xml diff --git a/altosdroid/AndroidManifest.xml.in b/altosdroid/AndroidManifest.xml.in index 15b04445..488a6766 100644 --- a/altosdroid/AndroidManifest.xml.in +++ b/altosdroid/AndroidManifest.xml.in @@ -92,6 +92,11 @@                    android:theme="@android:style/Theme.Dialog"                    android:configChanges="orientation|keyboardHidden" /> +	<activity android:name=".SetupActivity" +		  android:label="@string/setup" +                  android:theme="@android:style/Theme.Dialog" +                  android:configChanges="orientation|keyboardHidden" /> +		            <service android:name=".TelemetryService" />          <meta-data android:name="com.google.android.maps.v2.API_KEY" diff --git a/altosdroid/res/layout/setup.xml b/altosdroid/res/layout/setup.xml new file mode 100644 index 00000000..73ba2ad1 --- /dev/null +++ b/altosdroid/res/layout/setup.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + Copyright © 2016 Keith Packard <keithp@keithp.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +    android:orientation="vertical" +    android:layout_width="match_parent" +    android:layout_height="match_parent" +    > +  <TableLayout +      xmlns:android="http://schemas.android.com/apk/res/android" +      android:stretchColumns="2,3" +      android:layout_weight="0" +      android:layout_width="fill_parent" +      android:layout_height="wrap_content"> + +    <TableRow +	android:layout_gravity="center" +	android:layout_weight="1" +	android:padding="2dip" +	android:layout_width="wrap_content" +	android:layout_height="wrap_content"> +      <TextView +	  android:id="@+id/select_rate_label" +	  android:layout_width="wrap_content" +	  android:layout_height="wrap_content" +	  android:text="@string/telemetry_rate" +	  /> +      <Spinner android:id="@+id/select_rate" +	       android:layout_width="fill_parent" +	       android:layout_height="wrap_content" +	       android:prompt="@string/telemetry_rate" +	       android:spinnerMode="dropdown" +	       /> +    </TableRow> +    <TableRow +	android:layout_gravity="center" +	android:layout_weight="1" +	android:padding="2dip" +	android:layout_width="wrap_content" +	android:layout_height="wrap_content"> +      <TextView +	  android:id="@+id/set_units_label" +	  android:layout_width="wrap_content" +	  android:layout_height="wrap_content" +	  android:text="@string/set_units" +	  /> +      <Spinner android:id="@+id/set_units" +	       android:layout_width="fill_parent" +	       android:layout_height="wrap_content" +	       android:prompt="@string/set_units" +	       android:spinnerMode="dropdown" +	       /> +    </TableRow> +    <TableRow +	android:layout_gravity="center" +	android:layout_weight="1" +	android:padding="2dip" +	android:layout_width="wrap_content" +	android:layout_height="wrap_content"> +      <TextView +	  android:id="@+id/map_type_label" +	  android:layout_width="wrap_content" +	  android:layout_height="wrap_content" +	  android:text="@string/map_type" +	  /> +      <Spinner android:id="@+id/map_type" +	       android:layout_width="fill_parent" +	       android:layout_height="wrap_content" +	       android:prompt="@string/map_type" +	       android:spinnerMode="dropdown" +	       /> +    </TableRow> +    <TableRow +	android:layout_gravity="center" +	android:layout_weight="1" +	android:padding="2dip" +	android:layout_width="wrap_content" +	android:layout_height="wrap_content"> +      <TextView +	  android:id="@+id/map_source_label" +	  android:layout_width="wrap_content" +	  android:layout_height="wrap_content" +	  android:text="@string/map_source" +	  /> +      <Spinner android:id="@+id/map_source" +	       android:layout_width="fill_parent" +	       android:layout_height="wrap_content" +	       android:prompt="@string/map_source" +	       android:spinnerMode="dropdown" +	       /> +    </TableRow> +  </TableLayout> +  <Button android:id="@+id/preload_maps" +          android:layout_width="match_parent" +          android:layout_height="wrap_content" +	  android:text="@string/preload_maps" +	  /> +  <Button android:id="@+id/done" +          android:layout_width="match_parent" +          android:layout_height="wrap_content" +	  android:text="@string/done" +	  /> +</LinearLayout> diff --git a/altosdroid/res/menu/option_menu.xml b/altosdroid/res/menu/option_menu.xml index 4de4a16e..b2ca01a4 100644 --- a/altosdroid/res/menu/option_menu.xml +++ b/altosdroid/res/menu/option_menu.xml @@ -25,30 +25,21 @@      <item android:id="@+id/select_freq"            android:icon="@android:drawable/ic_menu_preferences"            android:title="@string/select_freq" /> -    <item android:id="@+id/select_rate" -          android:icon="@android:drawable/ic_menu_preferences" -          android:title="@string/select_rate" /> -    <item android:id="@+id/change_units" -	  android:icon="@android:drawable/ic_menu_view" -	  android:title="@string/change_units" /> -    <item android:id="@+id/preload_maps" -	  android:icon="@android:drawable/ic_menu_mapmode" -	  android:title="@string/preload_maps" /> -    <item android:id="@+id/map_type" -	  android:icon="@android:drawable/ic_menu_mapmode" -	  android:title="@string/map_type" /> -    <item android:id="@+id/map_source" -	  android:icon="@android:drawable/ic_menu_mapmode" -	  android:title="@string/map_source" /> +      <item android:id="@+id/select_tracker"  	  android:icon="@android:drawable/ic_menu_view"  	  android:title="@string/select_tracker"/>      <item android:id="@+id/delete_track"  	  android:icon="@android:drawable/ic_notification_clear_all"  	  android:title="@string/delete_track"/> + +    <item android:id="@+id/setup" +          android:icon="@android:drawable/ic_menu_preferences" +          android:title="@string/setup" />      <item android:id="@+id/idle_mode"            android:icon="@android:drawable/ic_menu_preferences"            android:title="@string/idle_mode" /> +      <item android:id="@+id/quit"            android:icon="@android:drawable/ic_menu_close_clear_cancel"            android:title="@string/quit" /> diff --git a/altosdroid/res/values/strings.xml b/altosdroid/res/values/strings.xml index 6f761a58..7538f7b5 100644 --- a/altosdroid/res/values/strings.xml +++ b/altosdroid/res/values/strings.xml @@ -29,6 +29,7 @@  	<string name="connect_device">Connect a device</string>  	<string name="disconnect_device">Disconnect device</string>  	<string name="quit">Quit</string> +	<string name="setup">Setup</string>  	<string name="select_freq">Select radio frequency</string>  	<string name="select_rate">Select data rate</string>  	<string name="change_units">Change units</string> @@ -126,4 +127,12 @@  	<string name="igniter_armed">Armed</string>  	<string name="igniter_fire">Fire</string> +	<!-- setup --> +	<string name="telemetry_rate">Telemetry Rate</string> +	<string name="set_units">Units</string> +	<string name="map_type">Map Type</string> +	<string name="map_source">Map Source</string> +	<string name="preload_maps">Preload Maps</string> +	<string name="done">Done</string> +	  </resources> diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java index e5f56a5a..ea3bbae6 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroid.java @@ -71,15 +71,19 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,  	public static final int REQUEST_CONNECT_DEVICE = 1;  	public static final int REQUEST_ENABLE_BT      = 2;  	public static final int REQUEST_PRELOAD_MAPS   = 3; -	public static final int REQUEST_MAP_TYPE       = 4;  	public static final int REQUEST_IDLE_MODE      = 5;  	public static final int REQUEST_IGNITERS       = 6; +	public static final int REQUEST_SETUP	       = 7;  	public static final String EXTRA_IDLE_MODE = "idle_mode";  	public static final String EXTRA_IDLE_RESULT = "idle_result";  	public static final String EXTRA_TELEMETRY_SERVICE = "telemetry_service"; -	public int map_type = AltosMap.maptype_hybrid; +	// Setup result bits +	public static final int SETUP_BAUD = 1; +	public static final int SETUP_UNITS = 2; +	public static final int SETUP_MAP_SOURCE = 4; +	public static final int SETUP_MAP_TYPE = 8;  	public static FragmentManager	fm; @@ -534,11 +538,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,  		return tab_view;  	} -	public void set_map_source(int source) { -		for (AltosDroidTab mTab : mTabs) -			mTab.set_map_source(source); -	} -  	@Override  	public void onCreate(Bundle savedInstanceState) {  		super.onCreate(savedInstanceState); @@ -757,17 +756,39 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,  				AltosDebug.debug("BT not enabled");  			}  			break; -		case REQUEST_MAP_TYPE: -			if (resultCode == Activity.RESULT_OK) -				set_map_type(data); -			break;  		case REQUEST_IDLE_MODE:  			if (resultCode == Activity.RESULT_OK)  				idle_mode(data);  			break;  		case REQUEST_IGNITERS:  			break; +		case REQUEST_SETUP: +			if (resultCode == Activity.RESULT_OK) +				note_setup_changes(data); +			break; +		} +	} + +	private void note_setup_changes(Intent data) { +		int changes = data.getIntExtra(SetupActivity.EXTRA_SETUP_CHANGES, 0); + +		if ((changes & SETUP_BAUD) != 0) { +			try { +				mService.send(Message.obtain(null, TelemetryService.MSG_SETBAUD, +							     AltosPreferences.telemetry_rate(1))); +			} catch (RemoteException re) { +			}  		} +		if ((changes & SETUP_UNITS) != 0) { +			/* nothing to do here */ +		} +		if ((changes & SETUP_MAP_SOURCE) != 0) { +			/* nothing to do here */ +		} +		if ((changes & SETUP_MAP_TYPE) != 0) { +			/* nothing to do here */ +		} +		set_switch_time();  	}  	private void connectUsb(UsbDevice device) { @@ -814,17 +835,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,  		}  	} -	private void set_map_type(Intent data) { -		int type = data.getIntExtra(MapTypeActivity.EXTRA_MAP_TYPE, -1); - -		AltosDebug.debug("intent set_map_type %d\n", type); -		if (type != -1) { -			map_type = type; -			for (AltosDroidTab mTab : mTabs) -				mTab.set_map_type(map_type); -		} -	} -  	private void idle_mode(Intent data) {  		int type = data.getIntExtra(IdleModeActivity.EXTRA_IDLE_RESULT, -1);  		Message msg; @@ -981,6 +991,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,  			disconnectDevice();  			finish();  			return true; +		case R.id.setup: +			serverIntent = new Intent(this, SetupActivity.class); +			startActivityForResult(serverIntent, REQUEST_SETUP); +			return true;  		case R.id.select_freq:  			// Set the TBT radio frequency @@ -1008,44 +1022,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener,  			AlertDialog alert_freq = builder_freq.create();  			alert_freq.show();  			return true; -		case R.id.select_rate: -			// Set the TBT baud rate - -			final String[] rates = { -				"38400", -				"9600", -				"2400", -			}; - -			AlertDialog.Builder builder_rate = new AlertDialog.Builder(this); -			builder_rate.setTitle("Pick a baud rate"); -			builder_rate.setItems(rates, -					 new DialogInterface.OnClickListener() { -						 public void onClick(DialogInterface dialog, int item) { -							 setBaud(rates[item]); -						 } -					 }); -			AlertDialog alert_rate = builder_rate.create(); -			alert_rate.show(); -			return true; -		case R.id.change_units: -			boolean	imperial = AltosPreferences.imperial_units(); -			AltosPreferences.set_imperial_units(!imperial); -			return true; -		case R.id.preload_maps: -			serverIntent = new Intent(this, PreloadMapActivity.class); -			startActivityForResult(serverIntent, REQUEST_PRELOAD_MAPS); -			return true; -		case R.id.map_type: -			serverIntent = new Intent(this, MapTypeActivity.class); -			startActivityForResult(serverIntent, REQUEST_MAP_TYPE); -			return true; -		case R.id.map_source: -			int source = AltosDroidPreferences.map_source(); -			int new_source = source == AltosDroidPreferences.MAP_SOURCE_ONLINE ? AltosDroidPreferences.MAP_SOURCE_OFFLINE : AltosDroidPreferences.MAP_SOURCE_ONLINE; -			AltosDroidPreferences.set_map_source(new_source); -			set_map_source(new_source); -			return true;  		case R.id.select_tracker:  			if (serials != null) {  				String[] trackers = new String[serials.length+1]; diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapInterface.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapInterface.java index 944f4b51..43abef0f 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapInterface.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapInterface.java @@ -25,6 +25,8 @@ import org.altusmetrum.altoslib_10.*;  public interface AltosDroidMapInterface {  	public void onCreateView(AltosDroid altos_droid); +	public void onDestroyView(); +  	public void set_visible(boolean visible);  	public void center(double lat, double lon, double accuracy); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapSourceListener.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapSourceListener.java new file mode 100644 index 00000000..e2775ef5 --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidMapSourceListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosDroid; + +public interface AltosDroidMapSourceListener { +	public void map_source_changed(int map_source); +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java index bd3bd942..dd86c818 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidPreferences.java @@ -16,6 +16,10 @@   */  package org.altusmetrum.AltosDroid; +import java.io.*; +import java.util.*; +import java.text.*; +  import android.content.Context;  import org.altusmetrum.altoslib_10.*; @@ -65,12 +69,19 @@ public class AltosDroidPreferences extends AltosPreferences {  		}  	} +	static LinkedList<AltosDroidMapSourceListener> map_source_listeners; +  	public static void set_map_source(int map_source) {  		synchronized(backend) {  			AltosDroidPreferences.map_source = map_source;  			backend.putInt(mapSourcePreference, map_source);  			flush_preferences();  		} +		if (map_source_listeners != null) { +			for (AltosDroidMapSourceListener l : map_source_listeners) { +				l.map_source_changed(map_source); +			} +		}  	}  	public static int map_source() { @@ -78,4 +89,18 @@ public class AltosDroidPreferences extends AltosPreferences {  			return map_source;  		}  	} + +	public static void register_map_source_listener(AltosDroidMapSourceListener l) { +		synchronized(backend) { +			if (map_source_listeners == null) +				map_source_listeners = new LinkedList<AltosDroidMapSourceListener>(); +			map_source_listeners.add(l); +		} +	} + +	public static void unregister_map_source_listener(AltosDroidMapSourceListener l) { +		synchronized(backend) { +			map_source_listeners.remove(l); +		} +	}  } diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java index d01bd33c..77dbbcb1 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosDroidTab.java @@ -39,12 +39,6 @@ public abstract class AltosDroidTab extends Fragment implements AltosUnitsListen  	public abstract String tab_name(); -	public void set_map_type(int map_type) { -	} - -	public void set_map_source(int map_source) { -	} -  	public void units_changed(boolean imperial_units) {  		if (!isHidden())  			show(last_telem_state, last_state, last_from_receiver, last_receiver); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOffline.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOffline.java index 6edc87a5..bde80cfc 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOffline.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOffline.java @@ -79,7 +79,7 @@ class Rocket implements Comparable {  	}  } -public class AltosMapOffline extends View implements ScaleGestureDetector.OnScaleGestureListener, AltosMapInterface, AltosDroidMapInterface { +public class AltosMapOffline extends View implements ScaleGestureDetector.OnScaleGestureListener, AltosMapInterface, AltosDroidMapInterface, AltosMapTypeListener {  	ScaleGestureDetector	scale_detector;  	boolean			scaling;  	AltosMap		map; @@ -493,7 +493,8 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal  	public void onCreateView(AltosDroid altos_droid) {  		this.altos_droid = altos_droid;  		map = new AltosMap(this); -		map.set_maptype(altos_droid.map_type); +		AltosPreferences.register_map_type_listener(this); +		map.set_maptype(AltosPreferences.map_type());  		pad_bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pad);  		/* arrow at the bottom of the launchpad image */ @@ -511,7 +512,11 @@ public class AltosMapOffline extends View implements ScaleGestureDetector.OnScal  		here_off_y = here_bitmap.getHeight() / 2;  	} -	public void set_map_type(int map_type) { +	public void onDestroyView() { +		AltosPreferences.unregister_map_type_listener(this); +	} + +	public void map_type_changed(int map_type) {  		if (map != null)  			map.set_maptype(map_type);  	} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOnline.java b/altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOnline.java index fd4dc98a..fcdb930b 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOnline.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/AltosMapOnline.java @@ -102,7 +102,7 @@ class RocketOnline implements Comparable {  	}  } -public class AltosMapOnline implements AltosDroidMapInterface, GoogleMap.OnMarkerClickListener, GoogleMap.OnMapClickListener { +public class AltosMapOnline implements AltosDroidMapInterface, GoogleMap.OnMarkerClickListener, GoogleMap.OnMapClickListener, AltosMapTypeListener {  	public SupportMapFragment mMapFragment;  	private GoogleMap mMap;  	private boolean mapLoaded = false; @@ -124,7 +124,8 @@ public class AltosMapOnline implements AltosDroidMapInterface, GoogleMap.OnMarke  	public void onCreateView(AltosDroid altos_droid) {  		this.altos_droid = altos_droid; -		final int map_type = altos_droid.map_type; +		final int map_type = AltosPreferences.map_type(); +		AltosPreferences.register_map_type_listener(this);  		mMapFragment = new SupportMapFragment() {  			@Override  			public void onActivityCreated(Bundle savedInstanceState) { @@ -144,9 +145,9 @@ public class AltosMapOnline implements AltosDroidMapInterface, GoogleMap.OnMarke  		};  	} -//	public void onActivityCreated() { -//		getChildFragmentManager().beginTransaction().add(R.id.map, mMapFragment).commit(); -//	} +	public void onDestroyView() { +		AltosPreferences.unregister_map_type_listener(this); +	}  	private double pixel_distance(LatLng a, LatLng b) {  		Projection projection = mMap.getProjection(); @@ -190,7 +191,7 @@ public class AltosMapOnline implements AltosDroidMapInterface, GoogleMap.OnMarke  	public void setupMap(int map_type) {  		mMap = mMapFragment.getMap();  		if (mMap != null) { -			set_map_type(map_type); +			map_type_changed(map_type);  			mMap.setMyLocationEnabled(true);  			mMap.getUiSettings().setTiltGesturesEnabled(false);  			mMap.getUiSettings().setZoomControlsEnabled(false); @@ -308,7 +309,7 @@ public class AltosMapOnline implements AltosDroidMapInterface, GoogleMap.OnMarke  	} -	public void set_map_type(int map_type) { +	public void map_type_changed(int map_type) {  		if (mMap != null) {  			if (map_type == AltosMap.maptype_hybrid)  				mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java b/altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java index a608bba0..9e3dac67 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/IgniterActivity.java @@ -36,36 +36,41 @@ import org.altusmetrum.altoslib_10.*;  class IgniterItem {  	public String name; +	public String pretty;  	public String status;  	public LinearLayout igniter_view = null; -	public TextView	name_view = null; +	public TextView	pretty_view = null;  	public TextView	status_view = null;  	private void update() { -		AltosDebug.debug("update item %s %s", name, status); -		if (name_view != null) -			name_view.setText(name); +		AltosDebug.debug("update item %s %s", pretty, status); +		if (pretty_view != null) +			pretty_view.setText(pretty);  		if (status_view != null)  			status_view.setText(status);  	} -	public void set(String name, String status) { -		if (!name.equals(this.name) || !status.equals(this.status)) { +	public void set(String name, String pretty, String status) { +		if (!name.equals(this.name) || +		    !pretty.equals(this.pretty) || +		    !status.equals(this.status)) +		{  			this.name = name; +			this.pretty = pretty;  			this.status = status;  			update();  		}  	}  	public void realize(LinearLayout igniter_view, -			    TextView name_view, +			    TextView pretty_view,  			    TextView status_view) {  		if (igniter_view != this.igniter_view || -		    name_view != this.name_view || +		    pretty_view != this.pretty_view ||  		    status_view != this.status_view)  		{  			this.igniter_view = igniter_view; -			this.name_view = name_view; +			this.pretty_view = pretty_view;  			this.status_view = status_view;  			update();  		} @@ -124,6 +129,9 @@ public class IgniterActivity extends Activity {  	private Timer timer; +	private Timer arm_timer; +	private int arm_remaining; +  	public static final int IGNITER_QUERY = 1;  	public static final int IGNITER_FIRE = 2; @@ -175,10 +183,44 @@ public class IgniterActivity extends Activity {  		finish();  	} +	class FireThread extends Thread { +		private final String igniter; + +		@Override +		public void run() { +			Message msg = Message.obtain(null, TelemetryService.MSG_IGNITER_FIRE, igniter); +			try { +				service.send(msg); +			} catch (RemoteException re) { +			} +		} + +		public FireThread(String igniter) { +			this.igniter = igniter; +		} +	} +  	private void fire_igniter() { +		if (igniters_adapter.selected_item >= 0) { +			IgniterItem	item = igniters_adapter.getItem(igniters_adapter.selected_item); +			FireThread	ft = new FireThread(item.name); +			ft.run(); +		}  	}  	private void arm_igniter(boolean is_checked) { +		if (is_checked) { +			arm_timer = new Timer(); +			fire.setEnabled(true); +			arm_timer.scheduleAtFixedRate(new TimerTask() { +					public void run() { +						arm_timer_tick(); +					}}, +				1000L, 1000L); +		} else { +			arm_timer.cancel(); +			fire.setEnabled(false); +		}  	}  	private synchronized void timer_tick() { @@ -190,6 +232,7 @@ public class IgniterActivity extends Activity {  			msg.replyTo = messenger;  			service.send(msg);  		} catch (RemoteException re) { +			timer_running = false;  		}  	} @@ -205,7 +248,7 @@ public class IgniterActivity extends Activity {  		} else  			item = igniters.get(name); -		item.set(pretty, AltosIgnite.status_string(status.get(name))); +		item.set(name, pretty, AltosIgnite.status_string(status.get(name)));  		return true;  	} @@ -227,16 +270,44 @@ public class IgniterActivity extends Activity {  //			igniters_view.setSelection(selected_item);  	} -	private class IgniterItemClickListener implements ListView.OnItemClickListener { -		@Override -		public void onItemClick(AdapterView<?> av, View v, int position, long id) { +	private void arm_set_text() { +		String	text = String.format("Armed %d", arm_remaining); + +		arm.setTextOn(text); +	} + +	private void arm_timer_tick() { +		--arm_remaining; +		if (arm_remaining <= 0) { +			timer.cancel(); +			arm.setChecked(false); +			fire.setEnabled(false); +		} else +			arm_set_text(); +	} + +	private void select_item(int position) { +		if (position != igniters_adapter.selected_item) {  			if (igniters_adapter.selected_item >= 0)  				igniters_view.setItemChecked(igniters_adapter.selected_item, false); -			igniters_view.setItemChecked(position, true); +			if (position >= 0) { +				igniters_view.setItemChecked(position, true); +				arm.setEnabled(true); +				arm_remaining = 10; +				arm_set_text(); +			} else +				arm.setEnabled(false);  			igniters_adapter.selected_item = position;  		}  	} +	private class IgniterItemClickListener implements ListView.OnItemClickListener { +		@Override +		public void onItemClick(AdapterView<?> av, View v, int position, long id) { +			select_item(position); +		} +	} +  	@Override  	protected void onCreate(Bundle savedInstanceState) {  		super.onCreate(savedInstanceState); @@ -261,6 +332,7 @@ public class IgniterActivity extends Activity {  			});  		arm = (ToggleButton) findViewById(R.id.igniter_arm); +		arm.setEnabled(false);  		arm.setOnCheckedChangeListener(new ToggleButton.OnCheckedChangeListener() {  				public void onCheckedChanged(CompoundButton v, boolean is_checked) {  					arm_igniter(is_checked); diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/SetupActivity.java b/altosdroid/src/org/altusmetrum/AltosDroid/SetupActivity.java new file mode 100644 index 00000000..ef802f0f --- /dev/null +++ b/altosdroid/src/org/altusmetrum/AltosDroid/SetupActivity.java @@ -0,0 +1,326 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.AltosDroid; + +import java.lang.ref.WeakReference; +import java.util.*; +import org.altusmetrum.AltosDroid.R; + +import android.app.Activity; +import android.bluetooth.*; +import android.content.*; +import android.os.*; +import android.view.*; +import android.view.View.*; +import android.widget.*; +import android.widget.AdapterView.*; + +import org.altusmetrum.altoslib_10.*; + +public class SetupActivity extends Activity { +	private Spinner select_rate; +	private Spinner set_units; +	private Spinner map_type; +	private Spinner map_source; +	private Button preload_maps; +	private Button done; + +	private boolean is_bound; +	private Messenger service = null; + +	public final static String EXTRA_SETUP_CHANGES = "setup_changes"; + +	private ServiceConnection connection = new ServiceConnection() { +		public void onServiceConnected(ComponentName className, IBinder binder) { +			service = new Messenger(binder); +		} + +		public void onServiceDisconnected(ComponentName className) { +			// This is called when the connection with the service has been unexpectedly disconnected - process crashed. +			service = null; +		} +	}; + +	void doBindService() { +		bindService(new Intent(this, TelemetryService.class), connection, Context.BIND_AUTO_CREATE); +		is_bound = true; +	} + +	void doUnbindService() { +		if (is_bound) { +			// If we have received the service, and hence registered with it, then now is the time to unregister. +			unbindService(connection); +			is_bound = false; +		} +	} + +	static final String[] rates = { +		"38400", +		"9600", +		"2400", +	}; + +	static final String[] map_types = { +		"Hybrid", +		"Satellite", +		"Roadmap", +		"Terrain" +	}; + +	static final int[] map_type_values = { +		AltosMap.maptype_hybrid, +		AltosMap.maptype_satellite, +		AltosMap.maptype_roadmap, +		AltosMap.maptype_terrain, +	}; + +	static final String[] map_sources = { +		"Online", +		"Offline" +	}; + +	private int	set_telemetry_rate; +	private int	set_map_source; +	private int	set_map_type; +	private boolean	set_imperial_units; + +	private int	changes = 0; + +	private void add_change(int change) { +		changes |= change; +	} + +	private void done() { +		Intent intent = new Intent(); +		if ((changes & AltosDroid.SETUP_BAUD) != 0) +			AltosPreferences.set_telemetry_rate(1, set_telemetry_rate); +		if ((changes & AltosDroid.SETUP_UNITS) != 0) +			AltosPreferences.set_imperial_units(set_imperial_units); +		if ((changes & AltosDroid.SETUP_MAP_SOURCE) != 0) +			AltosDroidPreferences.set_map_source(set_map_source); +		if ((changes & AltosDroid.SETUP_MAP_TYPE) != 0) +			AltosPreferences.set_map_type(set_map_type); +		intent.putExtra(EXTRA_SETUP_CHANGES, changes); +		setResult(Activity.RESULT_OK, intent); +		finish(); +	} + +	private void add_strings(Spinner spinner, String[] strings, int def) { +		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item); + +		for (int i = 0; i < strings.length; i++) +			adapter.add(strings[i]); + +		spinner.setAdapter(adapter); +		if (def >= 0) +			spinner.setSelection(def); +	} + +	private int default_rate_pos() { +		int	default_rate = AltosPreferences.telemetry_rate(1); + +		for (int pos = 0; pos < rates.length; pos++) { +			if (string_to_rate(rates[pos]) == default_rate) +				return pos; +		} +		return -1; +	} + +	private void setBaud(int baud) { +		try { +			service.send(Message.obtain(null, TelemetryService.MSG_SETBAUD, baud)); +			set_telemetry_rate = baud; +			add_change(AltosDroid.SETUP_BAUD); +		} catch (RemoteException e) { +		} +	} + +	private int string_to_rate(String baud) { +		int	rate = AltosLib.ao_telemetry_rate_38400; +		try { +			int	value = Integer.parseInt(baud); +			switch (value) { +			case 2400: +				rate = AltosLib.ao_telemetry_rate_2400; +				break; +			case 9600: +				rate = AltosLib.ao_telemetry_rate_9600; +				break; +			case 38400: +				rate = AltosLib.ao_telemetry_rate_38400; +				break; +			} +		} catch (NumberFormatException e) { +		} +		return rate; +	} + +	private void setBaud(String baud) { +		setBaud(string_to_rate(baud)); +	} + +	private void select_rate(int pos) { +		setBaud(rates[pos]); +	} + +	static final String[] units = { +		"Metric", +		"Imperial" +	}; + +	private int default_units_pos() { +		boolean	imperial = AltosPreferences.imperial_units(); + +		if (imperial) +			return 1; +		return 0; +	} + +	private void set_units(int pos) { +		switch (pos) { +		default: +			set_imperial_units = false; +			break; +		case 1: +			set_imperial_units = true; +			break; +		} +		add_change(AltosDroid.SETUP_UNITS); +	} + +	private int default_map_type_pos() { +		int	default_map_type = AltosPreferences.map_type(); + +		for (int pos = 0; pos < map_types.length; pos++) +			if (map_type_values[pos] == default_map_type) +				return pos; +		return 0; +	} + +	private void select_map_type(int pos) { +		set_map_type = map_type_values[pos]; +		add_change(AltosDroid.SETUP_MAP_TYPE); +	} + +	private int default_map_source_pos() { +		int	default_source = AltosDroidPreferences.map_source(); + +		switch (default_source) { +		case AltosDroidPreferences.MAP_SOURCE_OFFLINE: +			return 1; +		default: +			return 0; +		} +	} + +	private void select_map_source(int pos) { +		switch (pos) { +		default: +			set_map_source = AltosDroidPreferences.MAP_SOURCE_ONLINE; +			break; +		case 1: +			set_map_source = AltosDroidPreferences.MAP_SOURCE_OFFLINE; +			break; +		} +		add_change(AltosDroid.SETUP_MAP_SOURCE); +	} + +	private void preload_maps(){ +		Intent intent = new Intent(this, PreloadMapActivity.class); +		startActivity(intent); +	} + +	@Override +	protected void onCreate(Bundle savedInstanceState) { +		super.onCreate(savedInstanceState); + +		// Setup the window +		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); +		setContentView(R.layout.setup); + +		select_rate = (Spinner) findViewById(R.id.select_rate); +		add_strings(select_rate, rates, default_rate_pos()); +		select_rate.setOnItemSelectedListener(new OnItemSelectedListener() { +				public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { +					select_rate(pos); +				} +				public void onNothingSelected(AdapterView<?> parent) { +				} +			}); + +		set_units = (Spinner) findViewById(R.id.set_units); +		add_strings(set_units, units, default_units_pos()); +		set_units.setOnItemSelectedListener(new OnItemSelectedListener() { +				public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { +					set_units(pos); +				} +				public void onNothingSelected(AdapterView<?> parent) { +				} +			}); + +		map_type = (Spinner) findViewById(R.id.map_type); +		add_strings(map_type, map_types, default_map_type_pos()); +		map_type.setOnItemSelectedListener(new OnItemSelectedListener() { +				public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { +					select_map_type(pos); +				} +				public void onNothingSelected(AdapterView<?> parent) { +				} +			}); + +		map_source = (Spinner) findViewById(R.id.map_source); +		add_strings(map_source, map_sources, default_map_source_pos()); +		map_source.setOnItemSelectedListener(new OnItemSelectedListener() { +				public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { +					select_map_source(pos); +				} +				public void onNothingSelected(AdapterView<?> parent) { +				} +			}); + + +		preload_maps = (Button) findViewById(R.id.preload_maps); +		preload_maps.setOnClickListener(new OnClickListener() { +				public void onClick(View v) { +					preload_maps(); +				} +			}); + +		done = (Button) findViewById(R.id.done); +		done.setOnClickListener(new OnClickListener() { +				public void onClick(View v) { +					done(); +				} +			}); + +		// Set result for when the user backs out +		setResult(Activity.RESULT_CANCELED); +	} + +	@Override +	protected void onStart() { +		super.onStart(); +		doBindService(); +	} + +	@Override +	protected void onStop() { +		super.onStop(); +		doUnbindService(); +	} +} diff --git a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java index de74420f..19ce86c9 100644 --- a/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java +++ b/altosdroid/src/org/altusmetrum/AltosDroid/TabMap.java @@ -32,7 +32,7 @@ import android.widget.*;  import android.location.Location;  import android.content.*; -public class TabMap extends AltosDroidTab { +public class TabMap extends AltosDroidTab implements AltosDroidMapSourceListener {  	AltosLatLon	here; @@ -74,7 +74,8 @@ public class TabMap extends AltosDroidTab {  		map_offline.onCreateView(altos_droid);  		map_online = new AltosMapOnline(view.getContext());  		map_online.onCreateView(altos_droid); -		set_map_source(AltosDroidPreferences.map_source()); +		map_source_changed(AltosDroidPreferences.map_source()); +		AltosDroidPreferences.register_map_source_listener(this);  		return view;  	} @@ -88,6 +89,9 @@ public class TabMap extends AltosDroidTab {  	@Override  	public void onDestroyView() {  		super.onDestroyView(); +		map_offline.onDestroyView(); +		map_online.onDestroyView(); +		AltosDroidPreferences.unregister_map_source_listener(this);  	}  	public String tab_name() { return AltosDroid.tab_map_name; } @@ -144,16 +148,7 @@ public class TabMap extends AltosDroidTab {  		}  	} -	@Override -	public void set_map_type(int map_type) { -		if (map_offline != null) -			map_offline.set_map_type(map_type); -		if (map_online != null) -			map_online.set_map_type(map_type); -	} - -	@Override -	public void set_map_source(int map_source) { +	public void map_source_changed(int map_source) {  		this.map_source = map_source;  		if (map_source == AltosDroidPreferences.MAP_SOURCE_OFFLINE) {  			if (map_online != null) diff --git a/altoslib/AltosMapTypeListener.java b/altoslib/AltosMapTypeListener.java new file mode 100644 index 00000000..b82bda3f --- /dev/null +++ b/altoslib/AltosMapTypeListener.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +package org.altusmetrum.altoslib_10; + +public interface AltosMapTypeListener { +	public void map_type_changed(int map_type); +} diff --git a/altoslib/AltosPreferences.java b/altoslib/AltosPreferences.java index 43fc9f22..4bf48f6d 100644 --- a/altoslib/AltosPreferences.java +++ b/altoslib/AltosPreferences.java @@ -128,6 +128,9 @@ public class AltosPreferences {  	public static int map_cache = 9; +	final static String mapTypePreference = "MAP-TYPE"; +	static int	map_type; +  	public static AltosFrequency[] load_common_frequencies() {  		AltosFrequency[] frequencies = null;  		boolean	existing = false; @@ -221,6 +224,7 @@ public class AltosPreferences {  		map_cache = backend.getInt(mapCachePreference, 9);  		map_cache_listeners = new LinkedList<AltosMapCacheListener>(); +		map_type = backend.getInt(mapTypePreference, AltosMap.maptype_hybrid);  	}  	public static void flush_preferences() { @@ -638,4 +642,39 @@ public class AltosPreferences {  			return map_cache;  		}  	} + +	static LinkedList<AltosMapTypeListener> map_type_listeners; + +	public static void set_map_type(int map_type) { +		synchronized(backend) { +			AltosPreferences.map_type = map_type; +			backend.putInt(mapTypePreference, map_type); +			flush_preferences(); +		} +		if (map_type_listeners != null) { +			for (AltosMapTypeListener l : map_type_listeners) { +				l.map_type_changed(map_type); +			} +		} +	} + +	public static int map_type() { +		synchronized(backend) { +			return map_type; +		} +	} + +	public static void register_map_type_listener(AltosMapTypeListener l) { +		synchronized(backend) { +			if (map_type_listeners == null) +				map_type_listeners = new LinkedList<AltosMapTypeListener>(); +			map_type_listeners.add(l); +		} +	} + +	public static void unregister_map_type_listener(AltosMapTypeListener l) { +		synchronized(backend) { +			map_type_listeners.remove(l); +		} +	}  } diff --git a/altoslib/Makefile.am b/altoslib/Makefile.am index e5d8c964..73638782 100644 --- a/altoslib/Makefile.am +++ b/altoslib/Makefile.am @@ -157,6 +157,7 @@ altoslib_JAVA = \  	AltosLaunchSites.java \  	AltosMapLoaderListener.java \  	AltosMapLoader.java \ +	AltosMapTypeListener.java \  	AltosVersion.java  JAR=altoslib_$(ALTOSLIB_VERSION).jar | 
