import java.lang.ref.WeakReference;
import java.util.concurrent.TimeoutException;
+import java.io.*;
import java.util.*;
-import android.app.Notification;
-//import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
+import android.app.*;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothAdapter;
+import android.graphics.Color;
import android.hardware.usb.*;
import android.content.Intent;
import android.content.Context;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.os.Looper;
+import android.os.*;
import android.widget.Toast;
-import android.location.Criteria;
+import androidx.core.app.NotificationCompat;
-import org.altusmetrum.altoslib_13.*;
+import org.altusmetrum.altoslib_14.*;
public class TelemetryService extends Service implements AltosIdleMonitorListener {
case MSG_SETFREQUENCY:
AltosDebug.debug("MSG_SETFREQUENCY");
s.telemetry_state.frequency = (Double) msg.obj;
- if (s.telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) {
+ if (s.idle_monitor != null) {
+ s.idle_monitor.set_frequency(s.telemetry_state.frequency);
+ } else if (s.telemetry_state.connect == TelemetryState.CONNECT_CONNECTED) {
try {
s.altos_link.set_radio_frequency(s.telemetry_state.frequency);
s.altos_link.save_frequency();
private void telemetry(AltosTelemetry telem) {
AltosState state;
- if (telemetry_state.states.containsKey(telem.serial()))
- state = telemetry_state.states.get(telem.serial());
- else
+ state = telemetry_state.get(telem.serial());
+ if (state == null)
state = new AltosState(new AltosCalData());
telem.provide_data(state);
- telemetry_state.states.put(telem.serial(), state);
+ telemetry_state.put(telem.serial(), state);
telemetry_state.quiet = false;
if (state != null) {
AltosPreferences.set_state(state,telem.serial());
private Message message() {
if (telemetry_state == null)
AltosDebug.debug("telemetry_state null!");
- if (telemetry_state.states == null)
- AltosDebug.debug("telemetry_state.states null!");
return Message.obtain(null, AltosDroid.MSG_STATE, telemetry_state);
}
send_idle_mode_to_client(client);
}
+ private void send_file_failed_to_client(Messenger client, File f) {
+ Message m = Message.obtain(null, AltosDroid.MSG_FILE_FAILED, f);
+ try {
+ client.send(m);
+ } catch (RemoteException e) {
+ AltosDebug.error("Client %s disappeared", client.toString());
+ remove_client(client);
+ }
+ }
+
+ public void send_file_failed_to_clients(File f) {
+ for (Messenger client : clients)
+ send_file_failed_to_client(client, f);
+ }
+
private void telemetry_start() {
if (telemetry_reader == null && idle_monitor == null && !ignite_running) {
telemetry_reader = new TelemetryReader(altos_link, handler);
}
private void delete_serial(int serial) {
- telemetry_state.states.remove((Integer) serial);
+ telemetry_state.remove(serial);
AltosPreferences.remove_state(serial);
send_to_clients();
}
private void start_altos_bluetooth(DeviceAddress address, boolean pause) {
- if (bluetooth_adapter == null || !bluetooth_adapter.isEnabled())
+ if (bluetooth_adapter == null || !bluetooth_adapter.isEnabled() || address.address == null)
return;
disconnect(false);
telemetry_stop();
idle_monitor = new AltosIdleMonitor(this, altos_link, true, false);
idle_monitor.set_callsign(AltosPreferences.callsign());
+ idle_monitor.set_frequency(telemetry_state.frequency);
+ telemetry_state.idle_mode = true;
idle_monitor.start();
send_idle_mode_to_clients();
}
} catch (InterruptedException ie) {
}
idle_monitor = null;
+ telemetry_state.idle_mode = false;
telemetry_start();
send_idle_mode_to_clients();
}
for (int serial : serials) {
AltosState saved_state = AltosPreferences.state(serial);
if (saved_state != null) {
- if (telemetry_state.latest_serial == 0)
- telemetry_state.latest_serial = serial;
-
AltosDebug.debug("recovered old state serial %d flight %d",
serial,
saved_state.cal_data().flight);
AltosDebug.debug("\tposition %f,%f",
saved_state.gps.lat,
saved_state.gps.lon);
- telemetry_state.states.put(serial, saved_state);
+ telemetry_state.put(serial, saved_state);
} else {
AltosDebug.debug("Failed to recover state for %d", serial);
AltosPreferences.remove_state(serial);
}
}
+
+ private String createNotificationChannel(String channelId, String channelName) {
+ NotificationChannel chan = new NotificationChannel(
+ channelId, channelName, NotificationManager.IMPORTANCE_NONE);
+ chan.setLightColor(Color.BLUE);
+ chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
+ NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ service.createNotificationChannel(chan);
+ return channelId;
+ }
+
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
AltosDebug.debug("Received start id %d: %s", startId, intent);
- CharSequence text = getText(R.string.telemetry_service_started);
-
- // Create notification to be displayed while the service runs
- Notification notification = new Notification(R.drawable.am_status_c, text, 0);
-
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, AltosDroid.class), 0);
- // Set the info for the views that show in the notification panel.
- notification.setLatestEventInfo(this, getText(R.string.telemetry_service_label), text, contentIntent);
+ String channelId =
+ (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+ ? createNotificationChannel("altosdroid_telemetry", "AltosDroid Telemetry Service")
+ : "";
- // Set the notification to be in the "Ongoing" section.
- notification.flags |= Notification.FLAG_ONGOING_EVENT;
+ // Create notification to be displayed while the service runs
+ Notification notification = new NotificationCompat.Builder(this, channelId)
+ .setContentTitle(getText(R.string.telemetry_service_label))
+ .setContentText(getText(R.string.telemetry_service_started))
+ .setContentIntent(contentIntent)
+ .setWhen(System.currentTimeMillis())
+ .setOngoing(true)
+ .setSmallIcon(R.drawable.am_status_c)
+// .setLargeIcon(R.drawable.am_status_c)
+ .build();
// Move us into the foreground.
startForeground(NOTIFICATION, notification);
/* AltosIdleMonitorListener */
public void update(AltosState state, AltosListenerState listener_state) {
- telemetry_state.states.put(state.cal_data().serial, state);
+ if (state != null)
+ AltosDebug.debug("update call %s freq %7.3f", state.cal_data().callsign, state.frequency);
+ telemetry_state.put(state.cal_data().serial, state);
telemetry_state.receiver_battery = listener_state.battery;
send_to_clients();
}