X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=altosdroid%2Fapp%2Fsrc%2Fmain%2Fjava%2Forg%2Faltusmetrum%2FAltosDroid%2FAltosDroid.java;h=6d70872123954b1a88ba3fc3b897529e9b4da9f8;hb=HEAD;hp=bead186362fd57595efa1f7dca4a9a3ed79f2ade;hpb=1df1efc7a022597287722dc3a34d3a678fde6d3b;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 bead1863..6d708721 100644 --- a/altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroid.java +++ b/altosdroid/app/src/main/java/org/altusmetrum/AltosDroid/AltosDroid.java @@ -20,6 +20,7 @@ package org.altusmetrum.AltosDroid; import java.lang.ref.WeakReference; import java.util.*; +import java.io.*; import android.Manifest; import android.app.Activity; @@ -48,7 +49,7 @@ import android.location.LocationListener; import android.hardware.usb.*; import android.content.pm.PackageManager; import androidx.core.app.ActivityCompat; -import org.altusmetrum.altoslib_13.*; +import org.altusmetrum.altoslib_14.*; class SavedState { long received_time; @@ -86,6 +87,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, public static final int MSG_UPDATE_AGE = 2; public static final int MSG_IDLE_MODE = 3; public static final int MSG_IGNITER_STATUS = 4; + public static final int MSG_FILE_FAILED = 5; // Intent request codes public static final int REQUEST_CONNECT_DEVICE = 1; @@ -95,12 +97,14 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, 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 int REQUEST_DELETE_TRACKER = 9; 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"; + public static final String EXTRA_TRACKERS_TITLE = "trackers_title"; // Setup result bits public static final int SETUP_BAUD = 1; @@ -188,19 +192,23 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, ad.idle_mode = (Boolean) msg.obj; ad.update_state(null); break; + case MSG_FILE_FAILED: + ad.file_failed((File) msg.obj); + break; } } }; - private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { + AltosDebug.debug("onServiceConnected\n"); mService = new Messenger(service); try { Message msg = Message.obtain(null, TelemetryService.MSG_REGISTER_CLIENT); msg.replyTo = mMessenger; mService.send(msg); } catch (RemoteException e) { + AltosDebug.debug("attempt to register telemetry service client failed\n"); // In this case the service has crashed before we could even do anything with it } if (pending_usb_device != null) { @@ -213,17 +221,20 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } public void onServiceDisconnected(ComponentName className) { + AltosDebug.debug("onServiceDisconnected\n"); // This is called when the connection with the service has been unexpectedly disconnected - process crashed. mService = null; } }; void doBindService() { + AltosDebug.debug("doBindService\n"); bindService(new Intent(this, TelemetryService.class), mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; } void doUnbindService() { + AltosDebug.debug("doUnbindService\n"); if (mIsBound) { // If we have received the service, and hence registered with it, then now is the time to unregister. if (mService != null) { @@ -241,6 +252,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } } + public AltosDroidTab findTab(String name) { + for (AltosDroidTab mTab : mTabs) + if (name.equals(mTab.tab_name())) + return mTab; + return null; + } + public void registerTab(AltosDroidTab mTab) { mTabs.add(mTab); } @@ -434,6 +452,12 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, void update_ui(TelemetryState telem_state, AltosState state, boolean quiet) { + AltosDebug.debug("update_ui telem %b state %b quiet %b saved_state %b\n", + telem_state != null, + state != null, + quiet, + saved_state != null); + this.state = state; int prev_state = AltosLib.ao_flight_invalid; @@ -523,8 +547,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, saved_state = new SavedState(state); } - for (AltosDroidTab mTab : mTabs) + for (AltosDroidTab mTab : mTabs) { + AltosDebug.debug("mTab %s current %s\n", + mTab, mTabsAdapter.currentItem()); mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem()); + } if (mAltosVoice != null && mTabsAdapter.currentItem() != null) mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem(), quiet); @@ -587,13 +614,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, @Override public void onCreate(Bundle savedInstanceState) { + AltosDebug.init(this); + AltosDebug.debug("+++ ON CREATE +++"); + // Initialise preferences AltosDroidPreferences.init(this); setTheme(themes[AltosDroidPreferences.font_size()]); super.onCreate(savedInstanceState); - AltosDebug.init(this); - AltosDebug.debug("+++ ON CREATE +++"); - fm = getSupportFragmentManager(); @@ -609,10 +636,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager); - mTabsAdapter.addTab(mTabHost.newTabSpec(tab_pad_name).setIndicator(create_tab_view("Pad")), TabPad.class, null); - mTabsAdapter.addTab(mTabHost.newTabSpec(tab_flight_name).setIndicator(create_tab_view("Flight")), TabFlight.class, null); - mTabsAdapter.addTab(mTabHost.newTabSpec(tab_recover_name).setIndicator(create_tab_view("Recover")), TabRecover.class, null); - mTabsAdapter.addTab(mTabHost.newTabSpec(tab_map_name).setIndicator(create_tab_view("Map")), TabMap.class, null); + mTabsAdapter.addTab(mTabHost.newTabSpec(tab_pad_name).setIndicator(create_tab_view("Pad")), TabPad.class, null, findTab(tab_pad_name)); + mTabsAdapter.addTab(mTabHost.newTabSpec(tab_flight_name).setIndicator(create_tab_view("Flight")), TabFlight.class, null, findTab(tab_flight_name)); + mTabsAdapter.addTab(mTabHost.newTabSpec(tab_recover_name).setIndicator(create_tab_view("Recover")), TabRecover.class, null, findTab(tab_recover_name)); + mTabsAdapter.addTab(mTabHost.newTabSpec(tab_map_name).setIndicator(create_tab_view("Map")), TabMap.class, null, findTab(tab_map_name)); // Display the Version mVersion = (TextView) findViewById(R.id.version); @@ -628,7 +655,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, getTheme()); + mAgeOldColor = getResources().getColor(R.color.old_color); } private void ensureBluetooth() { @@ -647,7 +674,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, if (device != null) { Intent i = new Intent(this, AltosDroid.class); - PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent("hello world", null, this, AltosDroid.class), 0); + int flag; + + if (android.os.Build.VERSION.SDK_INT >= 31) // android.os.Build.VERSION_CODES.S + flag = 33554432; // PendingIntent.FLAG_MUTABLE + else + flag = 0; + PendingIntent pi = PendingIntent.getActivity(this, 0, new Intent("hello world", null, this, AltosDroid.class), flag); if (AltosUsb.request_permission(this, device, pi)) { connectUsb(device); @@ -733,31 +766,47 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); - AltosDebug.debug("onNewIntent"); + AltosDebug.debug("+ ON NEW INTENT +"); noticeIntent(intent); } - private void enable_location_updates() { + private void enable_location_updates(boolean do_update) { // 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); + if (locationManager != null) + { + try { + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this); + location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + } catch (Exception e) { + locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 1, this); + location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + } - if (location != null) - AltosDebug.debug("Resume, location is %f,%f\n", - location.getLatitude(), - location.getLongitude()); + if (location != null) + AltosDebug.debug("Resume, location is %f,%f\n", + location.getLatitude(), + location.getLongitude()); + AltosDebug.debug("Failed to get GPS updates\n"); + } - update_ui(telemetry_state, state, true); + if (do_update) + 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 have_bluetooth_permission = false; + public boolean have_bluetooth_connect_permission = false; + public boolean have_bluetooth_scan_permission = false; public boolean asked_permission = false; + static final String BLUETOOTH_CONNECT = "android.permission.BLUETOOTH_CONNECT"; + static final String BLUETOOTH_SCAN = "android.permission.BLUETOOTH_SCAN"; + AltosMapOnline map_online; void @@ -773,13 +822,22 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { if (permissions[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)) { have_location_permission = true; - enable_location_updates(); + enable_location_updates(true); if (map_online != null) map_online.position_permission(); } if (permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) { have_storage_permission = true; } + if (permissions[i].equals(Manifest.permission.BLUETOOTH)) { + have_bluetooth_permission = true; + } + if (permissions[i].equals(BLUETOOTH_CONNECT)) { + have_bluetooth_connect_permission = true; + } + if (permissions[i].equals(BLUETOOTH_SCAN)) { + have_bluetooth_scan_permission = true; + } } } } @@ -787,9 +845,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, @Override public void onResume() { - super.onResume(); AltosDebug.debug("+ ON RESUME +"); + super.onResume(); + if (!asked_permission) { asked_permission = true; if (ActivityCompat.checkSelfPermission(this, @@ -804,26 +863,62 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, { have_storage_permission = true; } - int count = (have_location_permission ? 0 : 1) + (have_storage_permission ? 0 : 1); + if (ActivityCompat.checkSelfPermission(this, + Manifest.permission.BLUETOOTH) + == PackageManager.PERMISSION_GRANTED) + { + have_bluetooth_permission = true; + } + if (ActivityCompat.checkSelfPermission(this, + BLUETOOTH_CONNECT) + == PackageManager.PERMISSION_GRANTED) + { + have_bluetooth_connect_permission = true; + } + if (ActivityCompat.checkSelfPermission(this, + BLUETOOTH_SCAN) + == PackageManager.PERMISSION_GRANTED) + { + have_bluetooth_scan_permission = true; + } + int count = 0; + if (!have_location_permission) + count += 1; + if (!have_storage_permission) + count += 1; + if (!have_bluetooth_permission) + count += 1; + if (!have_bluetooth_connect_permission) + count += 1; + if (!have_bluetooth_scan_permission) + count += 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) + if (!have_storage_permission) permissions[i++] = Manifest.permission.WRITE_EXTERNAL_STORAGE; + if (!have_bluetooth_permission) + permissions[i++] = Manifest.permission.BLUETOOTH; + if (!have_bluetooth_connect_permission) + permissions[i++] = BLUETOOTH_CONNECT; + if (!have_bluetooth_scan_permission) + permissions[i++] = BLUETOOTH_SCAN; ActivityCompat.requestPermissions(this, permissions, MY_PERMISSION_REQUEST); } } if (have_location_permission) - enable_location_updates(); + enable_location_updates(false); } @Override public void onPause() { - super.onPause(); AltosDebug.debug("- ON PAUSE -"); + + super.onPause(); + // Stop listening for location updates if (have_location_permission) ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this); @@ -831,15 +926,19 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, @Override public void onStop() { - super.onStop(); AltosDebug.debug("-- ON STOP --"); + + super.onStop(); } @Override public void onDestroy() { - super.onDestroy(); AltosDebug.debug("--- ON DESTROY ---"); + super.onDestroy(); + + saved_state = null; + doUnbindService(); if (mAltosVoice != null) { mAltosVoice.stop(); @@ -883,6 +982,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, if (resultCode == Activity.RESULT_OK) select_tracker(data); break; + case REQUEST_DELETE_TRACKER: + if (resultCode == Activity.RESULT_OK) + delete_track(data); + break; } } @@ -995,6 +1098,24 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, } } + boolean fail_shown; + + private void file_failed(File file) { + if (!fail_shown) { + fail_shown = true; + AlertDialog fail = new AlertDialog.Builder(this).create(); + fail.setTitle("Failed to Create Log File"); + fail.setMessage(file.getPath()); + fail.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + fail.show(); + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); @@ -1080,36 +1201,44 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, select_tracker(serial, frequency); } - void touch_trackers(Integer[] serials) { - AlertDialog.Builder builder_tracker = new AlertDialog.Builder(this); - builder_tracker.setTitle("Select Tracker"); - - final Tracker[] my_trackers = new Tracker[serials.length + 1]; + void delete_track(int serial) { + try { + mService.send(Message.obtain(null, TelemetryService.MSG_DELETE_SERIAL, (Integer) serial)); + } catch (Exception ex) { + } + } - my_trackers[0] = new Tracker(null); + void delete_track(Intent data) { + int serial = data.getIntExtra(SelectTrackerActivity.EXTRA_SERIAL_NUMBER, 0); + if (serial != 0) + delete_track(serial); + } - for (int i = 0; i < serials.length; i++) { - AltosState s = telemetry_state.get(serials[i]); - my_trackers[i+1] = new Tracker(s); + void start_select_tracker(Tracker[] select_trackers, int title_id, int request) { + Intent intent = new Intent(this, SelectTrackerActivity.class); + AltosDebug.debug("put title id 0x%x %s", title_id, getResources().getString(title_id)); + intent.putExtra(EXTRA_TRACKERS_TITLE, title_id); + if (select_trackers != null) { + ArrayList tracker_array = new ArrayList(Arrays.asList(select_trackers)); + intent.putParcelableArrayListExtra(EXTRA_TRACKERS, tracker_array); + } else { + intent.putExtra(EXTRA_TRACKERS, (Parcelable[]) null); } - builder_tracker.setItems(my_trackers, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - if (item == 0) - select_tracker(0, 0.0); - else - select_tracker(my_trackers[item].serial, my_trackers[item].frequency); - } - }); - AlertDialog alert_tracker = builder_tracker.create(); - alert_tracker.show(); + startActivityForResult(intent, request); } - void delete_track(int serial) { - try { - mService.send(Message.obtain(null, TelemetryService.MSG_DELETE_SERIAL, (Integer) serial)); - } catch (Exception ex) { + void start_select_tracker(Tracker[] select_trackers) { + start_select_tracker(select_trackers, R.string.select_tracker, REQUEST_SELECT_TRACKER); + } + + void touch_trackers(Integer[] serials) { + Tracker[] my_trackers = new Tracker[serials.length]; + + for (int i = 0; i < serials.length; i++) { + AltosState s = telemetry_state.get(serials[i]); + my_trackers[i] = new Tracker(s); } + start_select_tracker(my_trackers); } @Override @@ -1145,7 +1274,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, frequency_strings[i] = frequencies[i].toString(); AlertDialog.Builder builder_freq = new AlertDialog.Builder(this); - builder_freq.setTitle("Pick a frequency"); + builder_freq.setTitle("Select Frequency"); builder_freq.setItems(frequency_strings, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { @@ -1157,32 +1286,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener, alert_freq.show(); return true; case R.id.select_tracker: - serverIntent = new Intent(this, SelectTrackerActivity.class); - if (trackers != null) { - 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); + start_select_tracker(trackers); return true; case R.id.delete_track: - if (trackers != null) { - AlertDialog.Builder builder_serial = new AlertDialog.Builder(this); - builder_serial.setTitle("Delete a track"); - final Tracker[] my_trackers = new Tracker[trackers.length - 1]; - for (int i = 0; i < trackers.length - 1; i++) - my_trackers[i] = trackers[i+1]; - builder_serial.setItems(my_trackers, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - delete_track(my_trackers[item].serial); - } - }); - AlertDialog alert_serial = builder_serial.create(); - alert_serial.show(); - - } + if (trackers != null && trackers.length > 0) + start_select_tracker(trackers, R.string.delete_track, REQUEST_DELETE_TRACKER); return true; case R.id.idle_mode: serverIntent = new Intent(this, IdleModeActivity.class);