diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/MainActivity.java b/codec2talkie/src/main/java/com/radio/codec2talkie/MainActivity.java index e40611d..ef7d9fa 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/MainActivity.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/MainActivity.java @@ -39,7 +39,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; -import com.radio.codec2talkie.audio.AudioProcessor; +import com.radio.codec2talkie.app.AppWorker; import com.radio.codec2talkie.connect.BleConnectActivity; import com.radio.codec2talkie.connect.BluetoothConnectActivity; import com.radio.codec2talkie.connect.BluetoothSocketHandler; @@ -84,7 +84,7 @@ public class MainActivity extends AppCompatActivity { Manifest.permission.ACCESS_FINE_LOCATION }; - private AudioProcessor _audioProcessor; + private AppWorker _appWorker; private SharedPreferences _sharedPreferences; @@ -121,11 +121,11 @@ public class MainActivity extends AppCompatActivity { _textRssi = findViewById(R.id.textRssi); // UV bar - int barMaxValue = AudioProcessor.getAudioMaxLevel() - AudioProcessor.getAudioMinLevel(); + int barMaxValue = AppWorker.getAudioMaxLevel() - AppWorker.getAudioMinLevel(); _progressAudioLevel = findViewById(R.id.progressAudioLevel); _progressAudioLevel.setMax(barMaxValue); _progressAudioLevel.getProgressDrawable().setColorFilter( - new PorterDuffColorFilter(AudioTools.colorFromAudioLevel(AudioProcessor.getAudioMinLevel()), PorterDuff.Mode.SRC_IN)); + new PorterDuffColorFilter(AudioTools.colorFromAudioLevel(AppWorker.getAudioMinLevel()), PorterDuff.Mode.SRC_IN)); // S-meter _progressRssi = findViewById(R.id.progressRssi); @@ -174,8 +174,8 @@ public class MainActivity extends AppCompatActivity { } private void stopRunning() { - if (_audioProcessor != null) { - _audioProcessor.stopRunning(); + if (_appWorker != null) { + _appWorker.stopRunning(); } finish(); } @@ -240,9 +240,9 @@ public class MainActivity extends AppCompatActivity { private final BroadcastReceiver onBluetoothDisconnected = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (_audioProcessor != null && BluetoothSocketHandler.getSocket() != null && !_isTestMode) { + if (_appWorker != null && BluetoothSocketHandler.getSocket() != null && !_isTestMode) { Toast.makeText(MainActivity.this, R.string.bt_disconnected, Toast.LENGTH_LONG).show(); - _audioProcessor.stopRunning(); + _appWorker.stopRunning(); } } }; @@ -250,9 +250,9 @@ public class MainActivity extends AppCompatActivity { private final BroadcastReceiver onUsbDetached = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (_audioProcessor != null && UsbPortHandler.getPort() != null && !_isTestMode) { + if (_appWorker != null && UsbPortHandler.getPort() != null && !_isTestMode) { Toast.makeText(MainActivity.this, R.string.usb_detached, Toast.LENGTH_LONG).show(); - _audioProcessor.stopRunning(); + _appWorker.stopRunning(); } } }; @@ -286,8 +286,8 @@ public class MainActivity extends AppCompatActivity { return true; } if (itemId == R.id.reconnect) { - if (_audioProcessor != null) { - _audioProcessor.stopRunning(); + if (_appWorker != null) { + _appWorker.stopRunning(); } return true; } @@ -379,13 +379,13 @@ public class MainActivity extends AppCompatActivity { public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: - if (_audioProcessor != null) - _audioProcessor.startRecording(); + if (_appWorker != null) + _appWorker.startRecording(); break; case MotionEvent.ACTION_UP: v.performClick(); - if (_audioProcessor != null) - _audioProcessor.startPlayback(); + if (_appWorker != null) + _appWorker.startPlayback(); break; } return false; @@ -417,34 +417,34 @@ public class MainActivity extends AppCompatActivity { @Override public void handleMessage(Message msg) { switch (msg.what) { - case AudioProcessor.PROCESSOR_CONNECTED: + case AppWorker.PROCESSOR_CONNECTED: Toast.makeText(getBaseContext(), R.string.processor_connected, Toast.LENGTH_SHORT).show(); break; - case AudioProcessor.PROCESSOR_DISCONNECTED: + case AppWorker.PROCESSOR_DISCONNECTED: _btnPtt.setText(R.string.main_status_stop); Toast.makeText(getBaseContext(), R.string.processor_disconnected, Toast.LENGTH_SHORT).show(); startTransportConnection(); break; - case AudioProcessor.PROCESSOR_LISTENING: + case AppWorker.PROCESSOR_LISTENING: _btnPtt.setText(R.string.push_to_talk); _textStatus.setText(""); break; - case AudioProcessor.PROCESSOR_TRANSMITTING: + case AppWorker.PROCESSOR_TRANSMITTING: if (msg.obj != null) { _textStatus.setText((String) msg.obj); } _btnPtt.setText(R.string.main_status_tx); break; - case AudioProcessor.PROCESSOR_RECEIVING: + case AppWorker.PROCESSOR_RECEIVING: _btnPtt.setText(R.string.main_status_rx); break; - case AudioProcessor.PROCESSOR_PLAYING: + case AppWorker.PROCESSOR_PLAYING: if (msg.obj != null) { _textStatus.setText((String) msg.obj); } _btnPtt.setText(R.string.main_status_play); break; - case AudioProcessor.PROCESSOR_RX_RADIO_LEVEL: + case AppWorker.PROCESSOR_RX_RADIO_LEVEL: if (msg.arg1 == 0) { _textRssi.setText(""); _progressRssi.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN)); @@ -456,15 +456,15 @@ public class MainActivity extends AppCompatActivity { } break; // same progress bar is reused for rx and tx levels - case AudioProcessor.PROCESSOR_RX_LEVEL: - case AudioProcessor.PROCESSOR_TX_LEVEL: + case AppWorker.PROCESSOR_RX_LEVEL: + case AppWorker.PROCESSOR_TX_LEVEL: _progressAudioLevel.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(AudioTools.colorFromAudioLevel(msg.arg1), PorterDuff.Mode.SRC_IN)); - _progressAudioLevel.setProgress(msg.arg1 - AudioProcessor.getAudioMinLevel()); + _progressAudioLevel.setProgress(msg.arg1 - AppWorker.getAudioMinLevel()); break; - case AudioProcessor.PROCESSOR_RX_ERROR: + case AppWorker.PROCESSOR_RX_ERROR: _btnPtt.setText(R.string.main_status_rx_error); break; - case AudioProcessor.PROCESSOR_TX_ERROR: + case AppWorker.PROCESSOR_TX_ERROR: _btnPtt.setText(R.string.main_status_tx_error); break; } @@ -502,12 +502,12 @@ public class MainActivity extends AppCompatActivity { String statusLine = getSpeedStatusText(codec2ModeName) + ", " + getFeatureStatusText(protocolType); _textCodecMode.setText(statusLine); - _audioProcessor = new AudioProcessor(transportType, + _appWorker = new AppWorker(transportType, protocolType, AudioTools.extractCodec2ModeId(codec2ModeName), onAudioProcessorStateChanged, getApplicationContext()); - _audioProcessor.start(); + _appWorker.start(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, R.string.audio_failed_to_start_processing, Toast.LENGTH_LONG).show(); diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/audio/AudioProcessor.java b/codec2talkie/src/main/java/com/radio/codec2talkie/app/AppWorker.java similarity index 91% rename from codec2talkie/src/main/java/com/radio/codec2talkie/audio/AudioProcessor.java rename to codec2talkie/src/main/java/com/radio/codec2talkie/app/AppWorker.java index 82fd614..e74062b 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/audio/AudioProcessor.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/app/AppWorker.java @@ -1,7 +1,8 @@ -package com.radio.codec2talkie.audio; +package com.radio.codec2talkie.app; import android.content.Context; import android.content.SharedPreferences; +import android.location.Location; import android.media.AudioAttributes; import android.media.AudioFormat; import android.media.AudioRecord; @@ -27,9 +28,9 @@ import com.radio.codec2talkie.tools.AudioTools; import com.radio.codec2talkie.transport.Transport; import com.radio.codec2talkie.transport.TransportFactory; -public class AudioProcessor extends Thread { +public class AppWorker extends Thread { - private static final String TAG = AudioProcessor.class.getSimpleName(); + private static final String TAG = AppWorker.class.getSimpleName(); public static final int PROCESSOR_DISCONNECTED = 1; public static final int PROCESSOR_CONNECTED = 2; @@ -45,6 +46,7 @@ public class AudioProcessor extends Thread { public static final int PROCESSOR_PROCESS = 12; public static final int PROCESSOR_QUIT = 13; + public static final int PROCESSOR_SEND_LOCATION = 14; private static final int AUDIO_MIN_LEVEL = -70; private static final int AUDIO_MAX_LEVEL = 0; @@ -79,8 +81,8 @@ public class AudioProcessor extends Thread { private final Context _context; private final SharedPreferences _sharedPreferences; - public AudioProcessor(TransportFactory.TransportType transportType, ProtocolFactory.ProtocolType protocolType, int codec2Mode, - Handler onPlayerStateChanged, Context context) throws IOException { + public AppWorker(TransportFactory.TransportType transportType, ProtocolFactory.ProtocolType protocolType, int codec2Mode, + Handler onPlayerStateChanged, Context context) throws IOException { _onPlayerStateChanged = onPlayerStateChanged; _context = context; @@ -156,12 +158,19 @@ public class AudioProcessor extends Thread { } public void stopRunning() { - if (_currentStatus != PROCESSOR_DISCONNECTED) { - Log.i(TAG, "stopRunning()"); - Message msg = new Message(); - msg.what = PROCESSOR_QUIT; - _onMessageReceived.sendMessage(msg); - } + if (_currentStatus == PROCESSOR_DISCONNECTED) return; + Log.i(TAG, "stopRunning()"); + Message msg = new Message(); + msg.what = PROCESSOR_QUIT; + _onMessageReceived.sendMessage(msg); + } + + private void sendLocation(Location location) { + if (_currentStatus == PROCESSOR_DISCONNECTED) return; + Message msg = new Message(); + msg.what = PROCESSOR_SEND_LOCATION; + msg.obj = location; + _onMessageReceived.sendMessage(msg); } private void sendStatusUpdate(int newStatus, String note) { @@ -384,6 +393,14 @@ public class AudioProcessor extends Thread { case PROCESSOR_QUIT: quitProcessing(); break; + case PROCESSOR_SEND_LOCATION: + try { + _protocol.sendPosition(Position.fromLocation((Location) msg.obj)); + } catch (IOException e) { + e.printStackTrace(); + quitProcessing(); + } + break; default: break; } diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/Aprs.java b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/Aprs.java index a991356..df3b412 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/Aprs.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/Aprs.java @@ -6,7 +6,6 @@ import android.util.Log; import androidx.preference.PreferenceManager; -import com.radio.codec2talkie.audio.AudioProcessor; import com.radio.codec2talkie.protocol.aprs.AprsCallsign; import com.radio.codec2talkie.protocol.aprs.AprsData; import com.radio.codec2talkie.protocol.aprs.AprsDataFactory; diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/position/Position.java b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/position/Position.java index 16143dc..fa4c2d5 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/position/Position.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/position/Position.java @@ -1,5 +1,7 @@ package com.radio.codec2talkie.protocol.position; +import android.location.Location; + public class Position { public String timestamp; public String srcCallsign; @@ -17,4 +19,14 @@ public class Position { public int extDigipathSsid; public boolean isSpeedBearingEnabled; public boolean isAltitudeEnabled; + + public static Position fromLocation(Location location) { + Position position = new Position(); + position.latitude = location.getLatitude(); + position.longitude = location.getLongitude(); + position.bearingDegrees = location.getBearing(); + position.altitudeMeters = location.getAltitude(); + position.speedMetersPerSecond = location.getSpeed(); + return position; + } } diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/tools/AudioTools.java b/codec2talkie/src/main/java/com/radio/codec2talkie/tools/AudioTools.java index 51b1901..189a7c8 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/tools/AudioTools.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/tools/AudioTools.java @@ -1,12 +1,8 @@ package com.radio.codec2talkie.tools; -import android.content.SharedPreferences; import android.graphics.Color; -import com.radio.codec2talkie.R; -import com.radio.codec2talkie.audio.AudioProcessor; -import com.radio.codec2talkie.protocol.ProtocolFactory; -import com.radio.codec2talkie.settings.PreferenceKeys; +import com.radio.codec2talkie.app.AppWorker; public class AudioTools { @@ -28,9 +24,9 @@ public class AudioTools { public static int colorFromAudioLevel(int audioLevel) { int color = Color.GREEN; - if (audioLevel > AudioProcessor.getAudioMaxLevel() + UV_METER_MAX_DELTA) + if (audioLevel > AppWorker.getAudioMaxLevel() + UV_METER_MAX_DELTA) color = Color.RED; - else if (audioLevel < AudioProcessor.getAudioMinLevel() + UV_METER_MIN_DELTA) + else if (audioLevel < AppWorker.getAudioMinLevel() + UV_METER_MIN_DELTA) color = Color.LTGRAY; return color; }