Message sending

pull/43/head
sh123 2022-07-18 20:17:40 +03:00
rodzic 778fd92655
commit f2ad37d825
22 zmienionych plików z 251 dodań i 18 usunięć

Wyświetl plik

@ -475,20 +475,20 @@ public class MainActivity extends AppCompatActivity {
private final BroadcastReceiver onBluetoothDisconnected = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (_appService != null && BluetoothSocketHandler.getSocket() != null && !_isTestMode) {
Toast.makeText(MainActivity.this, R.string.bt_disconnected, Toast.LENGTH_LONG).show();
_appService.stopRunning();
}
if (_appService != null && BluetoothSocketHandler.getSocket() != null && !_isTestMode) {
Toast.makeText(MainActivity.this, R.string.bt_disconnected, Toast.LENGTH_LONG).show();
_appService.stopRunning();
}
}
};
private final BroadcastReceiver onUsbDetached = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (_appService != null && UsbPortHandler.getPort() != null && !_isTestMode) {
Toast.makeText(MainActivity.this, R.string.usb_detached, Toast.LENGTH_LONG).show();
_appService.stopRunning();
}
if (_appService != null && UsbPortHandler.getPort() != null && !_isTestMode) {
Toast.makeText(MainActivity.this, R.string.usb_detached, Toast.LENGTH_LONG).show();
_appService.stopRunning();
}
}
};

Wyświetl plik

@ -23,7 +23,8 @@ public enum AppMessage {
CMD_QUIT(17),
CMD_START_TRACKING(18),
CMD_STOP_TRACKING(19),
CMD_SEND_SINGLE_TRACKING(20);
CMD_SEND_SINGLE_TRACKING(20),
CMD_SEND_MESSAGE(21);
private final int _value;

Wyświetl plik

@ -20,6 +20,7 @@ import android.os.Messenger;
import android.os.PowerManager;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
import android.widget.Toast;
import androidx.annotation.Nullable;
@ -30,6 +31,7 @@ import androidx.preference.PreferenceManager;
import com.radio.codec2talkie.MainActivity;
import com.radio.codec2talkie.R;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.settings.PreferenceKeys;
import com.radio.codec2talkie.tracker.Tracker;
import com.radio.codec2talkie.tracker.TrackerFactory;
@ -51,7 +53,7 @@ public class AppService extends Service {
private Messenger _callbackMessenger;
private Tracker _tracker;
private NotificationManager _notificationManager;
PowerManager.WakeLock _serviceWakeLock;
private PowerManager.WakeLock _serviceWakeLock;
private boolean _voiceNotificationsEnabled = false;
@ -99,6 +101,11 @@ public class AppService extends Service {
_onProcess.sendMessage(msg);
}
public void sendTextMessage(TextMessage textMessage) {
if (_appWorker != null)
_appWorker.sendTextMessage(textMessage);
}
public boolean isTracking() {
if (_tracker == null) return false;
return _tracker.isTracking();

Wyświetl plik

@ -12,6 +12,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.util.Pair;
import androidx.preference.PreferenceManager;
@ -20,6 +21,7 @@ import java.util.Timer;
import java.util.TimerTask;
import com.radio.codec2talkie.R;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.storage.log.LogItem;
import com.radio.codec2talkie.storage.log.LogItemRepository;
import com.radio.codec2talkie.protocol.ProtocolCallback;
@ -170,6 +172,13 @@ public class AppWorker extends Thread {
_onMessageReceived.sendMessage(msg);
}
public void sendTextMessage(TextMessage textMessage) {
Message msg = Message.obtain();
msg.what = AppMessage.CMD_SEND_MESSAGE.toInt();
msg.obj = textMessage;
_onMessageReceived.sendMessage(msg);
}
private void sendStatusUpdate(AppMessage newStatus, String note) {
if (newStatus != _currentStatus) {
@ -416,6 +425,15 @@ public class AppWorker extends Thread {
quitProcessing();
}
break;
case CMD_SEND_MESSAGE:
TextMessage textMessage = (TextMessage) msg.obj;
try {
_protocol.sendTextMessage(textMessage);
} catch (IOException e) {
e.printStackTrace();
quitProcessing();
}
break;
default:
break;
}

Wyświetl plik

@ -10,6 +10,7 @@ import com.radio.codec2talkie.protocol.aprs.AprsCallsign;
import com.radio.codec2talkie.protocol.aprs.AprsData;
import com.radio.codec2talkie.protocol.aprs.AprsDataFactory;
import com.radio.codec2talkie.protocol.aprs.AprsDataType;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.protocol.ax25.AX25Callsign;
import com.radio.codec2talkie.settings.PreferenceKeys;
@ -80,6 +81,20 @@ public class Aprs implements Protocol {
throw new UnsupportedOperationException();
}
@Override
public void sendTextMessage(TextMessage textMessage) throws IOException {
AprsDataType aprsDataType = new AprsDataType(AprsDataType.DataType.MESSAGE);
AprsData aprsData = AprsDataFactory.create(aprsDataType);
assert aprsData != null;
aprsData.fromTextMessage(textMessage);
if (aprsData.isValid()) {
sendData(null, null, aprsData.toBinary());
} else {
Log.e(TAG, "Invalid APRS message");
_parentProtocolCallback.onProtocolTxError();
}
}
@Override
public void sendPcmAudio(String src, String dst, int codec2Mode, short[] pcmFrame) throws IOException {
if (_isVoax25Enabled) {

Wyświetl plik

@ -2,6 +2,7 @@ package com.radio.codec2talkie.protocol;
import android.content.Context;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.transport.Transport;
import com.ustadmobile.codec2.Codec2;
@ -43,6 +44,11 @@ public class AudioCodec2 implements Protocol {
throw new UnsupportedOperationException();
}
@Override
public void sendTextMessage(TextMessage textMessage) {
throw new UnsupportedOperationException();
}
@Override
public void sendPcmAudio(String src, String dst, int codec2Mode, short[] pcmFrame) throws IOException {
_parentProtocolCallback.onTransmitPcmAudio(src, dst, codec2Mode, pcmFrame);

Wyświetl plik

@ -6,6 +6,7 @@ import android.util.Log;
import androidx.preference.PreferenceManager;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.settings.PreferenceKeys;
import com.radio.codec2talkie.transport.Transport;
@ -74,6 +75,11 @@ public class AudioFrameAggregator implements Protocol {
_outputBufferPos += frame.length;
}
@Override
public void sendTextMessage(TextMessage textMessage) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void sendPcmAudio(String src, String dst, int codec, short[] pcmFrame) {
throw new UnsupportedOperationException();

Wyświetl plik

@ -7,6 +7,7 @@ import android.util.Log;
import androidx.preference.PreferenceManager;
import com.radio.codec2talkie.protocol.ax25.AX25Packet;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.settings.PreferenceKeys;
import com.radio.codec2talkie.transport.Transport;
@ -66,6 +67,11 @@ public class Ax25 implements Protocol {
}
}
@Override
public void sendTextMessage(TextMessage textMessage) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void sendPcmAudio(String src, String dst, int codec, short[] pcmFrame) {
throw new UnsupportedOperationException();

Wyświetl plik

@ -11,6 +11,7 @@ import android.widget.Toast;
import androidx.preference.PreferenceManager;
import com.radio.codec2talkie.R;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.settings.PreferenceKeys;
import com.radio.codec2talkie.tools.DebugTools;
@ -208,6 +209,11 @@ public class Kiss implements Protocol {
send(frame);
}
@Override
public void sendTextMessage(TextMessage textMessage) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void sendPcmAudio(String src, String dst, int codec, short[] pcmFrame) {
throw new UnsupportedOperationException();

Wyświetl plik

@ -2,6 +2,7 @@ package com.radio.codec2talkie.protocol;
import android.content.Context;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.transport.Transport;
@ -14,6 +15,8 @@ public interface Protocol {
int getPcmAudioBufferSize();
void sendPcmAudio(String src, String dst, int codec, short[] pcmFrame) throws IOException;
void sendCompressedAudio(String src, String dst, int codec, byte[] frame) throws IOException;
// messaging
void sendTextMessage(TextMessage textMessage) throws IOException;
// data
void sendData(String src, String dst, byte[] dataPacket) throws IOException;
// callback

Wyświetl plik

@ -2,6 +2,7 @@ package com.radio.codec2talkie.protocol;
import android.content.Context;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.transport.Transport;
@ -37,6 +38,11 @@ public class Raw implements Protocol {
_transport.write(Arrays.copyOf(frame, frame.length));
}
@Override
public void sendTextMessage(TextMessage textMessage) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void sendPcmAudio(String src, String dst, int codec, short[] pcmFrame) {
throw new UnsupportedOperationException();

Wyświetl plik

@ -5,6 +5,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.radio.codec2talkie.MainActivity;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.tools.StorageTools;
import com.radio.codec2talkie.transport.Transport;
@ -64,6 +65,11 @@ public class Recorder implements Protocol {
_childProtocol.sendCompressedAudio(src, dst, codec2Mode, frame);
}
@Override
public void sendTextMessage(TextMessage textMessage) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void sendPcmAudio(String src, String dst, int codec, short[] pcmFrame) {
throw new UnsupportedOperationException();

Wyświetl plik

@ -6,6 +6,7 @@ import android.util.Log;
import androidx.preference.PreferenceManager;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.settings.PreferenceKeys;
import com.radio.codec2talkie.tools.ScramblingTools;
@ -59,6 +60,11 @@ public class Scrambler implements Protocol {
}
}
@Override
public void sendTextMessage(TextMessage textMessage) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void sendPcmAudio(String src, String dst, int codec, short[] pcmFrame) {
throw new UnsupportedOperationException();

Wyświetl plik

@ -1,10 +1,13 @@
package com.radio.codec2talkie.protocol.aprs;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
public interface AprsData {
void fromPosition(Position position);
void fromTextMessage(TextMessage textMessage);
Position toPosition();
TextMessage toTextMessage();
void fromBinary(byte[] infoData);
byte[] toBinary();
boolean isValid();

Wyświetl plik

@ -6,7 +6,6 @@ public class AprsDataFactory {
public static AprsData create(AprsDataType aprsDataType) {
switch (aprsDataType.getDataType()) {
case UNKNOWN:
case MESSAGE:
case POSITION_WITH_TIMESTAMP_MSG:
case POSITION_WITH_TIMESTAMP_NO_MSG:
case POSITION_WITHOUT_TIMESTAMP_NO_MSG:
@ -15,6 +14,8 @@ public class AprsDataFactory {
return new AprsDataPositionReportMicE();
case POSITION_WITHOUT_TIMESTAMP_MSG:
return new AprsDataPositionReport();
case MESSAGE:
return new AprsDataTextMessage();
}
return null;
}

Wyświetl plik

@ -3,6 +3,7 @@ package com.radio.codec2talkie.protocol.aprs;
import android.util.Log;
import com.radio.codec2talkie.protocol.aprs.tools.AprsTools;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.tools.DebugTools;
import com.radio.codec2talkie.tools.MathTools;
@ -27,11 +28,21 @@ public class AprsDataPositionReport implements AprsData {
_isValid = true;
}
@Override
public void fromTextMessage(TextMessage textMessage) {
_isValid = false;
}
@Override
public Position toPosition() {
return _position;
}
@Override
public TextMessage toTextMessage() {
return null;
}
@Override
public void fromBinary(byte[] infoData) {
_isValid = false;

Wyświetl plik

@ -1,6 +1,7 @@
package com.radio.codec2talkie.protocol.aprs;
import com.radio.codec2talkie.protocol.aprs.tools.AprsTools;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
import com.radio.codec2talkie.tools.UnitTools;
@ -68,11 +69,21 @@ public class AprsDataPositionReportMicE implements AprsData {
_isValid = true;
}
@Override
public void fromTextMessage(TextMessage textMessage) {
_isValid = false;
}
@Override
public Position toPosition() {
return _position;
}
@Override
public TextMessage toTextMessage() {
return null;
}
@Override
public void fromBinary(byte[] infoData) {
_isValid = false;

Wyświetl plik

@ -0,0 +1,53 @@
package com.radio.codec2talkie.protocol.aprs;
import com.radio.codec2talkie.protocol.message.TextMessage;
import com.radio.codec2talkie.protocol.position.Position;
public class AprsDataTextMessage implements AprsData {
public String dstCallsign;
public String textMessage;
private boolean _isValid;
@Override
public void fromPosition(Position position) {
_isValid = false;
}
@Override
public void fromTextMessage(TextMessage textMessage) {
this.dstCallsign = textMessage.dst;
this.textMessage = textMessage.text;
_isValid = true;
}
@Override
public Position toPosition() {
return null;
}
@Override
public TextMessage toTextMessage() {
TextMessage textMessage = new TextMessage();
textMessage.dst = this.dstCallsign;
textMessage.text = this.textMessage;
return textMessage;
}
@Override
public void fromBinary(byte[] infoData) {
// TODO, implement
_isValid = false;
}
@Override
public byte[] toBinary() {
return String.format(":%-9s:%s", dstCallsign, textMessage).getBytes();
}
@Override
public boolean isValid() {
return _isValid;
}
}

Wyświetl plik

@ -0,0 +1,6 @@
package com.radio.codec2talkie.protocol.message;
public class TextMessage {
public String dst;
public String text;
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.radio.codec2talkie.storage.message.group;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
@ -13,14 +19,20 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.radio.codec2talkie.R;
import com.radio.codec2talkie.app.AppService;
public class MessageGroupActivity extends AppCompatActivity {
private static final String TAG = MessageGroupActivity.class.getSimpleName();
private AppService _appService;
private MessageGroupViewModel _messageGroupViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
setContentView(R.layout.activity_message_groups_view);
setTitle(R.string.messages_group_view_title);
ActionBar actionBar = getSupportActionBar();
@ -38,10 +50,19 @@ public class MessageGroupActivity extends AppCompatActivity {
_messageGroupViewModel = new ViewModelProvider(this).get(MessageGroupViewModel.class);
_messageGroupViewModel.getGroups().observe(this, adapter::submitList);
bindAppService();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
unbindAppService();
}
private final View.OnClickListener _onSendToButtonListener = v -> {
MessageGroupDialogSendTo dialogSendTo = new MessageGroupDialogSendTo(MessageGroupActivity.this);
MessageGroupDialogSendTo dialogSendTo = new MessageGroupDialogSendTo(MessageGroupActivity.this, _appService);
dialogSendTo.show();
};
@ -56,4 +77,29 @@ public class MessageGroupActivity extends AppCompatActivity {
}
return super.onOptionsItemSelected(item);
}
private void bindAppService() {
if (!bindService(new Intent(this, AppService.class), _appServiceConnection, Context.BIND_AUTO_CREATE)) {
Log.e(TAG, "Service does not exists or no access");
}
}
private void unbindAppService() {
unbindService(_appServiceConnection);
}
private final ServiceConnection _appServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
Log.i(TAG, "Connected to app service");
_appService = ((AppService.AppServiceBinder)service).getService();
}
@Override
public void onServiceDisconnected(ComponentName className) {
Log.i(TAG, "Disconnected from app service");
_appService = null;
}
};
}

Wyświetl plik

@ -1,26 +1,30 @@
package com.radio.codec2talkie.storage.message.group;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import com.radio.codec2talkie.R;
import com.radio.codec2talkie.app.AppService;
import com.radio.codec2talkie.protocol.message.TextMessage;
public class MessageGroupDialogSendTo extends AlertDialog implements View.OnClickListener {
public MessageGroupDialogSendTo(@NonNull Context context) {
private final AppService _appService;
public MessageGroupDialogSendTo(@NonNull Context context, AppService appService) {
super(context);
_appService = appService;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(.getString(R.string.activity_send_message_to_title));
setTitle(getContext().getString(R.string.activity_send_message_to_title));
setContentView(R.layout.activity_send_message_to);
Button sendButton = findViewById(R.id.send_message_to_btn_ok);
@ -35,6 +39,15 @@ public class MessageGroupDialogSendTo extends AlertDialog implements View.OnClic
public void onClick(View v) {
int id = v.getId();
if (id == R.id.send_message_to_btn_ok) {
EditText targetEdit = findViewById(R.id.send_message_to_target_edit);
EditText messageEdit = findViewById(R.id.send_message_to_message_edit);
assert targetEdit != null;
assert messageEdit != null;
TextMessage textMessage = new TextMessage();
textMessage.dst = targetEdit.getText().toString();
textMessage.text = messageEdit.getText().toString();
_appService.sendTextMessage(textMessage);
dismiss();
} else if (id == R.id.send_message_to_btn_cancel) {
dismiss();
}

Wyświetl plik

@ -23,10 +23,13 @@
android:id="@+id/messages_send_to"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="@string/message_groups_send_to_btn_title"
android:textAllCaps="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:text="@string/message_groups_send_to_btn_title"/>
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>