X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=altosdroid%2Fapp%2Fsrc%2Fmain%2Fjava%2Forg%2Faltusmetrum%2FAltosDroid%2FAltosDroid.java;h=bead186362fd57595efa1f7dca4a9a3ed79f2ade;hb=1df1efc7a022597287722dc3a34d3a678fde6d3b;hp=1bcb67ef72e849c56f682a803bc815e1d26dcf90;hpb=8b53f860eb3171cd43e4bd0e440f2889bd810662;p=fw%2Faltos diff --git a/altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroid.java b/altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroid.java index 1bcb67ef..bead1863 100644 --- a/altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroid.java @@ -19,14 +19,12 @@ package org.altusmetrum.AltosDroid; import java.lang.ref.WeakReference; -import java.text.*; import java.util.*; -import java.io.*; +import android.Manifest; import android.app.Activity; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; import android.content.Intent; import android.content.Context; import android.content.ComponentName; @@ -38,10 +36,9 @@ import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; -import android.content.res.Resources; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentManager; -import android.util.DisplayMetrics; +import android.os.Parcelable; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; import android.view.*; import android.widget.*; import android.app.AlertDialog; @@ -49,9 +46,8 @@ import android.location.Location; import android.location.LocationManager; import android.location.LocationListener; import android.hardware.usb.*; -import android.graphics.*; -import android.graphics.drawable.*; - +import android.content.pm.PackageManager; +import androidx.core.app.ActivityCompat; import org.altusmetrum.altoslib_13.*; class SavedState { @@ -77,76 +73,7 @@ class SavedState { } } -class Tracker implements CharSequence, Comparable { - int serial; - String call; - double frequency; - - String display; - - public Tracker(int serial, String call, double frequency) { - if (call == null) - call = "none"; - - this.serial = serial; - this.call = call; - this.frequency = frequency; - if (frequency == 0.0) - display = "Auto"; - else if (frequency == AltosLib.MISSING) { - display = String.format("%-8.8s %6d", call, serial); - } else { - display = String.format("%-8.8s %7.3f %6d", call, frequency, serial); - } - } - - public Tracker(AltosState s) { - this(s == null ? 0 : s.cal_data().serial, - s == null ? null : s.cal_data().callsign, - s == null ? 0.0 : s.frequency); - } - - /* CharSequence */ - public char charAt(int index) { - return display.charAt(index); - } - - public int length() { - return display.length(); - } - - public CharSequence subSequence(int start, int end) throws IndexOutOfBoundsException { - return display.subSequence(start, end); - } - - public String toString() { - return display.toString(); - } - - /* Comparable */ - public int compareTo (Object other) { - Tracker o = (Tracker) other; - if (frequency == 0.0) { - if (o.frequency == 0.0) - return 0; - return -1; - } - if (o.frequency == 0.0) - return 1; - - int a = serial - o.serial; - int b = call.compareTo(o.call); - int c = (int) Math.signum(frequency - o.frequency); - - if (b != 0) - return b; - if (c != 0) - return c; - return a; - } -} - -public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener { +public class AltosDroid extends FragmentActivity implements AltosUnitsListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback { // Actions sent to the telemetry server at startup time @@ -167,16 +94,20 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, 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 int REQUEST_SELECT_TRACKER = 8; public static final String EXTRA_IDLE_MODE = "idle_mode"; public static final String EXTRA_IDLE_RESULT = "idle_result"; + public static final String EXTRA_FREQUENCY = "frequency"; public static final String EXTRA_TELEMETRY_SERVICE = "telemetry_service"; + public static final String EXTRA_TRACKERS = "trackers"; // 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 final int SETUP_FONT_SIZE = 16; public static FragmentManager fm; @@ -222,7 +153,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, TelemetryState telemetry_state; Tracker[] trackers; - UsbDevice pending_usb_device; boolean start_with_usb; @@ -329,7 +259,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, case TelemetryState.CONNECT_CONNECTED: if (telemetry_state.config != null) { String str = String.format("S/N %d %6.3f MHz%s", telemetry_state.config.serial, - telemetry_state.frequency, idle_mode ? " (idle)" : ""); + telemetry_state.frequency, telemetry_state.idle_mode ? " (idle)" : ""); if (telemetry_state.telemetry_rate != AltosLib.ao_telemetry_rate_38400) str = str.concat(String.format(" %d bps", AltosLib.ao_telemetry_rate_values[telemetry_state.telemetry_rate])); @@ -367,7 +297,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } int selected_serial = 0; - int current_serial; long switch_time; void set_switch_time() { @@ -382,11 +311,29 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, if (new_telemetry_state != null) telemetry_state = new_telemetry_state; - if (selected_serial != 0) - current_serial = selected_serial; + if (selected_frequency != AltosLib.MISSING) { + AltosState selected_state = telemetry_state.get(selected_serial); + AltosState latest_state = telemetry_state.get(telemetry_state.latest_serial); + + if (selected_state != null && selected_state.frequency == selected_frequency) { + selected_frequency = AltosLib.MISSING; + } else if ((selected_state == null || selected_state.frequency != selected_frequency) && + (latest_state != null && latest_state.frequency == selected_frequency)) + { + selected_frequency = AltosLib.MISSING; + selected_serial = telemetry_state.latest_serial; + } + } + + if (!telemetry_state.containsKey(selected_serial)) { + selected_serial = telemetry_state.latest_serial; + AltosDebug.debug("selected serial set to %d", selected_serial); + } + + int shown_serial = selected_serial; - if (current_serial == 0) - current_serial = telemetry_state.latest_serial; + if (telemetry_state.idle_mode) + shown_serial = telemetry_state.latest_serial; if (!registered_units_listener) { registered_units_listener = true; @@ -394,7 +341,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } int num_trackers = 0; - for (AltosState s : telemetry_state.states.values()) { + + for (AltosState s : telemetry_state.values()) { num_trackers++; } @@ -403,44 +351,17 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, int n = 0; trackers[n++] = new Tracker(0, "auto", 0.0); - for (AltosState s : telemetry_state.states.values()) + for (AltosState s : telemetry_state.values()) trackers[n++] = new Tracker(s); Arrays.sort(trackers); - update_title(telemetry_state); - - AltosState state = null; - boolean aged = true; - - if (telemetry_state.states.containsKey(current_serial)) { - state = telemetry_state.states.get(current_serial); - int age = state_age(state.received_time); - if (age < 20) - aged = false; - if (current_serial == selected_serial) - aged = false; - else if (switch_time != 0 && (switch_time - state.received_time) > 0) - aged = true; - } - - if (aged) { - AltosState newest_state = null; - int newest_age = 0; - - for (int serial : telemetry_state.states.keySet()) { - AltosState existing = telemetry_state.states.get(serial); - int existing_age = state_age(existing.received_time); + if (telemetry_state.frequency != AltosLib.MISSING) + telem_frequency = telemetry_state.frequency; - if (newest_state == null || existing_age < newest_age) { - newest_state = existing; - newest_age = existing_age; - } - } + update_title(telemetry_state); - if (newest_state != null) - state = newest_state; - } + AltosState state = telemetry_state.get(shown_serial); update_ui(telemetry_state, state, telemetry_state.quiet); @@ -481,6 +402,19 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } + static String age_string(int age) { + String text; + if (age < 60) + text = String.format("%ds", age); + else if (age < 60 * 60) + text = String.format("%dm", age / 60); + else if (age < 60 * 60 * 24) + text = String.format("%dh", age / (60 * 60)); + else + text = String.format("%dd", age / (24 * 60 * 60)); + return text; + } + void update_age() { if (saved_state != null) { int age = state_age(saved_state.received_time); @@ -494,16 +428,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, set_screen_on(age); - String text; - if (age < 60) - text = String.format("%ds", age); - else if (age < 60 * 60) - text = String.format("%dm", age / 60); - else if (age < 60 * 60 * 24) - text = String.format("%dh", age / (60 * 60)); - else - text = String.format("%dd", age / (24 * 60 * 60)); - mAgeView.setText(text); + mAgeView.setText(age_string(age)); } } @@ -601,8 +526,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, for (AltosDroidTab mTab : mTabs) mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem()); - AltosDebug.debug("quiet %b\n", quiet); - if (mAltosVoice != null) + if (mAltosVoice != null && mTabsAdapter.currentItem() != null) mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem(), quiet); } @@ -624,7 +548,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } int deg = (int) Math.floor(p); double min = (p - Math.floor(p)) * 60.0; - return String.format("%d°%9.4f\" %s", deg, min, h); + return String.format("%d° %7.4f\" %s", deg, min, h); } static String number(String format, double value) { @@ -647,14 +571,29 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, return tab_view; } + static public int[] themes = { + R.style.Small, + R.style.Medium, + R.style.Large, + R.style.Extra + }; + + static public int[] dialog_themes = { + R.style.Small_Dialog, + R.style.Medium_Dialog, + R.style.Large_Dialog, + R.style.Extra_Dialog + }; + @Override public void onCreate(Bundle savedInstanceState) { + // Initialise preferences + AltosDroidPreferences.init(this); + setTheme(themes[AltosDroidPreferences.font_size()]); super.onCreate(savedInstanceState); AltosDebug.init(this); AltosDebug.debug("+++ ON CREATE +++"); - // Initialise preferences - AltosDroidPreferences.init(this); fm = getSupportFragmentManager(); @@ -689,7 +628,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, mStateView = (TextView) findViewById(R.id.state_value); mAgeView = (TextView) findViewById(R.id.age_value); mAgeNewColor = mAgeView.getTextColors().getDefaultColor(); - mAgeOldColor = getResources().getColor(R.color.old_color); + mAgeOldColor = getResources().getColor(R.color.old_color, getTheme()); } private void ensureBluetooth() { @@ -798,11 +737,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, noticeIntent(intent); } - @Override - public void onResume() { - super.onResume(); - AltosDebug.debug("+ ON RESUME +"); - + private void enable_location_updates() { // Listen for GPS and Network position updates LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this); @@ -817,12 +752,81 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, update_ui(telemetry_state, state, true); } + static final int MY_PERMISSION_REQUEST = 1001; + + public boolean have_location_permission = false; + public boolean have_storage_permission = false; + public boolean asked_permission = false; + + AltosMapOnline map_online; + + void + tell_map_permission(AltosMapOnline map_online) { + this.map_online = map_online; + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, + int[] grantResults) { + if (requestCode == MY_PERMISSION_REQUEST) { + for (int i = 0; i < grantResults.length; i++) { + if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { + if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)) { + have_location_permission = true; + enable_location_updates(); + if (map_online != null) + map_online.position_permission(); + } + if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + have_storage_permission = true; + } + } + } + } + } + + @Override + public void onResume() { + super.onResume(); + AltosDebug.debug("+ ON RESUME +"); + + if (!asked_permission) { + asked_permission = true; + if (ActivityCompat.checkSelfPermission(this, + Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) + { + have_location_permission = true; + } + if (ActivityCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + == PackageManager.PERMISSION_GRANTED) + { + have_storage_permission = true; + } + int count = (have_location_permission ? 0 : 1) + (have_storage_permission ? 0 : 1); + if (count > 0) + { + String[] permissions = new String[count]; + int i = 0; + if (!have_location_permission) + permissions[i++] = Manifest.permission.ACCESS_FINE_LOCATION; + if (!have_location_permission) + permissions[i++] = Manifest.permission.WRITE_EXTERNAL_STORAGE; + ActivityCompat.requestPermissions(this, permissions, MY_PERMISSION_REQUEST); + } + } + if (have_location_permission) + enable_location_updates(); + } + @Override public void onPause() { super.onPause(); AltosDebug.debug("- ON PAUSE -"); // Stop listening for location updates - ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this); + if (have_location_permission) + ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this); } @Override @@ -845,7 +849,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } protected void onActivityResult(int requestCode, int resultCode, Intent data) { - AltosDebug.debug("onActivityResult " + resultCode); + AltosDebug.debug("onActivityResult request %d result %d", requestCode, resultCode); switch (requestCode) { case REQUEST_CONNECT_DEVICE: // When DeviceListActivity returns with a device to connect to @@ -875,12 +879,18 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, if (resultCode == Activity.RESULT_OK) note_setup_changes(data); break; + case REQUEST_SELECT_TRACKER: + if (resultCode == Activity.RESULT_OK) + select_tracker(data); + break; } } private void note_setup_changes(Intent data) { int changes = data.getIntExtra(SetupActivity.EXTRA_SETUP_CHANGES, 0); + AltosDebug.debug("note_setup_changes changes %d\n", changes); + if ((changes & SETUP_BAUD) != 0) { try { mService.send(Message.obtain(null, TelemetryService.MSG_SETBAUD, @@ -898,6 +908,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, /* nothing to do here */ } set_switch_time(); + if ((changes & SETUP_FONT_SIZE) != 0) { + AltosDebug.debug(" ==== Recreate to switch font sizes ==== "); + finish(); + startActivity(getIntent()); + } } private void connectUsb(UsbDevice device) { @@ -915,10 +930,12 @@ 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"); + if (mService != null) { + try { + mService.send(Message.obtain(null, TelemetryService.MSG_BLUETOOTH_ENABLED, null)); + } catch (RemoteException e) { + AltosDebug.debug("send BT enabled message failed"); + } } } @@ -985,7 +1002,12 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, return true; } + double telem_frequency = 434.550; + double selected_frequency = AltosLib.MISSING; + void setFrequency(double freq) { + telem_frequency = freq; + selected_frequency = AltosLib.MISSING; try { mService.send(Message.obtain(null, TelemetryService.MSG_SETFREQUENCY, freq)); set_switch_time(); @@ -1025,10 +1047,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } } - void select_tracker(int serial) { - int i; + void select_tracker(int serial, double frequency) { - AltosDebug.debug("select tracker %d\n", serial); + AltosDebug.debug("select tracker %d %7.3f\n", serial, frequency); if (serial == selected_serial) { AltosDebug.debug("%d already selected\n", serial); @@ -1036,6 +1057,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } if (serial != 0) { + int i; for (i = 0; i < trackers.length; i++) if (trackers[i].serial == serial) break; @@ -1044,12 +1066,20 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, AltosDebug.debug("attempt to select unknown tracker %d\n", serial); return; } + if (frequency != 0.0 && frequency != AltosLib.MISSING) + setFrequency(frequency); } - current_serial = selected_serial = serial; + selected_serial = serial; update_state(null); } + void select_tracker(Intent data) { + int serial = data.getIntExtra(SelectTrackerActivity.EXTRA_SERIAL_NUMBER, 0); + double frequency = data.getDoubleExtra(SelectTrackerActivity.EXTRA_FREQUENCY, 0.0); + select_tracker(serial, frequency); + } + void touch_trackers(Integer[] serials) { AlertDialog.Builder builder_tracker = new AlertDialog.Builder(this); builder_tracker.setTitle("Select Tracker"); @@ -1059,16 +1089,16 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, my_trackers[0] = new Tracker(null); for (int i = 0; i < serials.length; i++) { - AltosState s = telemetry_state.states.get(serials[i]); + AltosState s = telemetry_state.get(serials[i]); my_trackers[i+1] = new Tracker(s); } builder_tracker.setItems(my_trackers, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { if (item == 0) - select_tracker(0); + select_tracker(0, 0.0); else - select_tracker(my_trackers[item].serial); + select_tracker(my_trackers[item].serial, my_trackers[item].frequency); } }); AlertDialog alert_tracker = builder_tracker.create(); @@ -1120,29 +1150,21 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { setFrequency(frequencies[item]); + selected_frequency = frequencies[item].frequency; } }); AlertDialog alert_freq = builder_freq.create(); alert_freq.show(); return true; case R.id.select_tracker: + serverIntent = new Intent(this, SelectTrackerActivity.class); if (trackers != null) { - AlertDialog.Builder builder_serial = new AlertDialog.Builder(this); - builder_serial.setTitle("Select a tracker"); - builder_serial.setItems(trackers, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - System.out.printf("select item %d %s\n", item, trackers[item].display); - if (item == 0) - select_tracker(0); - else - select_tracker(trackers[item].serial); - } - }); - AlertDialog alert_serial = builder_serial.create(); - alert_serial.show(); - + ArrayList tracker_array = new ArrayList(Arrays.asList(trackers)); + serverIntent.putParcelableArrayListExtra(EXTRA_TRACKERS, tracker_array); + } else { + serverIntent.putExtra(EXTRA_TRACKERS, (Parcelable[]) null); } + startActivityForResult(serverIntent, REQUEST_SELECT_TRACKER); return true; case R.id.delete_track: if (trackers != null) { @@ -1165,6 +1187,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, case R.id.idle_mode: serverIntent = new Intent(this, IdleModeActivity.class); serverIntent.putExtra(EXTRA_IDLE_MODE, idle_mode); + serverIntent.putExtra(EXTRA_FREQUENCY, telem_frequency); startActivityForResult(serverIntent, REQUEST_IDLE_MODE); return true; }