Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/usb-serial-telnet-server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2023-08-14 22:51:16 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2023-08-14 22:51:16 +0300
commitb200abb7e3318683881ef955c0cfe095bf5a9798 (patch)
tree4a9ea1120ff3ccaa79fdcaddae2f2332d215e3d4
parentaa8aa784f89929cd615771bc3f61307fc3631c4a (diff)
Autostart (issues #4 and #6)
-rw-r--r--app/src/main/AndroidManifest.xml21
-rw-r--r--app/src/main/java/com/clusterrr/usbserialtelnetserver/BootCompletedReceiver.java9
-rw-r--r--app/src/main/java/com/clusterrr/usbserialtelnetserver/ConnectedReceiver.java26
-rw-r--r--app/src/main/java/com/clusterrr/usbserialtelnetserver/MainActivity.java122
-rw-r--r--app/src/main/java/com/clusterrr/usbserialtelnetserver/UsbSerialTelnetService.java18
-rw-r--r--app/src/main/res/layout/activity_main.xml21
-rw-r--r--app/src/main/res/values/strings.xml6
7 files changed, 168 insertions, 55 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index facc8b0..90ea25d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-feature android:name="android.hardware.usb.host" />
@@ -15,11 +16,24 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.USBSerialTelnetServer">
+ <receiver
+ android:name=".ConnectedReceiver"
+ android:enabled="true"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
+ android:resource="@xml/usb_device_filter" />
+ </receiver>
<service
android:name=".UsbSerialTelnetService"
android:enabled="true"
- android:exported="true" />
+ android:exported="true"
+ android:foregroundServiceType="connectedDevice" />
<activity
android:name=".MainActivity"
@@ -27,6 +41,7 @@
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
+
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
@@ -38,7 +53,9 @@
android:resource="@xml/usb_device_filter" />
</activity>
- <receiver android:name=".BootCompletedReceiver" android:exported="true">
+ <receiver
+ android:name=".BootCompletedReceiver"
+ android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
diff --git a/app/src/main/java/com/clusterrr/usbserialtelnetserver/BootCompletedReceiver.java b/app/src/main/java/com/clusterrr/usbserialtelnetserver/BootCompletedReceiver.java
index 3a80fba..23cda8b 100644
--- a/app/src/main/java/com/clusterrr/usbserialtelnetserver/BootCompletedReceiver.java
+++ b/app/src/main/java/com/clusterrr/usbserialtelnetserver/BootCompletedReceiver.java
@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
+import android.util.Log;
import com.hoho.android.usbserial.driver.UsbSerialPort;
@@ -12,11 +13,13 @@ public class BootCompletedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- // App was started before shutdown
SharedPreferences prefs = context.getApplicationContext().getSharedPreferences(context.getString(R.string.app_name), Context.MODE_PRIVATE);
- boolean needToStart = prefs.getBoolean(UsbSerialTelnetService.KEY_LAST_STATE, false);
- if (needToStart) {
+ if ((prefs.getInt(MainActivity.SETTING_AUTOSTART, MainActivity.AUTOSTART_DISABLED) != MainActivity.AUTOSTART_DISABLED)
+ && MainActivity.isDevicePresent(context))
+ {
Intent mainActivityStartIntent = new Intent(context, MainActivity.class);
+ mainActivityStartIntent.setAction(intent.getAction());
+ mainActivityStartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainActivityStartIntent);
}
}
diff --git a/app/src/main/java/com/clusterrr/usbserialtelnetserver/ConnectedReceiver.java b/app/src/main/java/com/clusterrr/usbserialtelnetserver/ConnectedReceiver.java
new file mode 100644
index 0000000..e75c038
--- /dev/null
+++ b/app/src/main/java/com/clusterrr/usbserialtelnetserver/ConnectedReceiver.java
@@ -0,0 +1,26 @@
+package com.clusterrr.usbserialtelnetserver;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.widget.Toast;
+
+public class ConnectedReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(UsbSerialTelnetService.TAG, "Connected device detected");
+ SharedPreferences prefs = context.getApplicationContext().getSharedPreferences(context.getString(R.string.app_name), Context.MODE_PRIVATE);
+ if (prefs.getInt(MainActivity.SETTING_AUTOSTART, MainActivity.AUTOSTART_DISABLED) != MainActivity.AUTOSTART_DISABLED)
+ {
+ Intent mainActivityStartIntent = new Intent(context, MainActivity.class);
+ mainActivityStartIntent.setAction(intent.getAction());
+ mainActivityStartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(mainActivityStartIntent);
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/com/clusterrr/usbserialtelnetserver/MainActivity.java b/app/src/main/java/com/clusterrr/usbserialtelnetserver/MainActivity.java
index 6d539ee..2776a64 100644
--- a/app/src/main/java/com/clusterrr/usbserialtelnetserver/MainActivity.java
+++ b/app/src/main/java/com/clusterrr/usbserialtelnetserver/MainActivity.java
@@ -21,6 +21,7 @@ import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
+import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
@@ -33,7 +34,7 @@ import com.hoho.android.usbserial.driver.UsbSerialProber;
import java.util.List;
-public class MainActivity extends AppCompatActivity implements View.OnClickListener, UsbSerialTelnetService.IOnStopListener {
+public class MainActivity extends AppCompatActivity implements View.OnClickListener, UsbSerialTelnetService.IOnStartStopListener, AdapterView.OnItemSelectedListener {
final static String SETTING_TCP_PORT = "tcp_port";
final static String SETTING_BAUD_RATE = "baud_rate";
final static String SETTING_DATA_BITS = "data_bits";
@@ -41,9 +42,15 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
final static String SETTING_PARITY = "parity";
final static String SETTING_NO_LOCAL_ECHO = "no_local_echo";
final static String SETTING_REMOVE_LF = "remove_lf";
+ final static String SETTING_AUTOSTART = "autostart";
+
+ final static int AUTOSTART_DISABLED = 0;
+ final static int AUTOSTART_ENABLED = 1;
+ final static int AUTOSTART_CLOSE = 2;
private UsbSerialTelnetService.ServiceBinder mServiceBinder = null;
- private Handler mHandler;
+ private Handler mHandler = new Handler();
+ private boolean mNeedClose = false;
private Button mStartButton;
private Button mStopButton;
private EditText mTcpPort;
@@ -54,18 +61,18 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private TextView mStatus;
private Switch mNoLocalEcho;
private Switch mRemoveLF;
+ private Spinner mAutostart;
- private boolean isStarted() {
+ public boolean isStarted() {
return mServiceBinder != null && mServiceBinder.isStarted();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ Log.d(UsbSerialTelnetService.TAG, "Creating activity");
setContentView(R.layout.activity_main);
- mHandler = new Handler();
-
mStartButton = findViewById(R.id.buttonStart);
mStopButton = findViewById(R.id.buttonStop);
mTcpPort = findViewById(R.id.editTextTcpPort);
@@ -76,44 +83,53 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
mStatus = findViewById(R.id.textViewStatus);
mNoLocalEcho = findViewById(R.id.switchNoLocalEcho);
mRemoveLF = findViewById(R.id.switchRemoveLf);
+ mAutostart = findViewById(R.id.spinnerAutostart);
+ mAutostart.setOnItemSelectedListener(this);
mStartButton.setOnClickListener(this);
mStopButton.setOnClickListener(this);
Intent serviceIntent = new Intent(this, UsbSerialTelnetService.class);
- bindService(serviceIntent, serviceConnection, 0); // in case if service already started
+ bindService(serviceIntent, mServiceConnection, 0); // in case if service already started
updateSettings();
+ }
+ @Override
+ protected void onNewIntent(Intent intent) {
+ // Start service if need
+ super.onNewIntent(intent);
+ if (intent == null) return;
SharedPreferences prefs = getApplicationContext().getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
- boolean needToStart = prefs.getBoolean(UsbSerialTelnetService.KEY_LAST_STATE, false);
- if (needToStart) {
- mHandler.postDelayed(() -> {
- boolean started = mServiceBinder != null && mServiceBinder.isStarted();
- if (!started) {
+ String action = intent.getAction();
+ Log.d(UsbSerialTelnetService.TAG, "Received intent: " + action);
+ switch(action)
+ {
+ case UsbSerialTelnetService.ACTION_NEED_TO_START:
+ if (mServiceBinder == null || !mServiceBinder.isStarted())
+ start();
+ break;
+ case Intent.ACTION_BOOT_COMPLETED:
+ case UsbManager.ACTION_USB_DEVICE_ATTACHED:
+ if (!isStarted() && prefs.getInt(SETTING_AUTOSTART, AUTOSTART_DISABLED) != AUTOSTART_DISABLED)
+ {
+ mNeedClose = prefs.getInt(SETTING_AUTOSTART, AUTOSTART_DISABLED) == AUTOSTART_CLOSE;
start();
}
- }, 5000);
+ break;
}
}
- @Override
- protected void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- if (intent != null) {
- // Start service if need
- if ((intent.getAction() == UsbSerialTelnetService.ACTION_NEED_TO_START) &&
- (!(mServiceBinder != null && mServiceBinder.isStarted()))) {
- // Test that permission is granted
- UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
- List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
- if (!availableDrivers.isEmpty()) {
- UsbSerialDriver driver = availableDrivers.get(0);
- UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
- if (connection != null) start();
- }
- }
+ public static boolean isDevicePresent(Context context)
+ {
+ UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+ List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
+ if (!availableDrivers.isEmpty()) {
+ UsbSerialDriver driver = availableDrivers.get(0);
+ UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
+ return connection != null;
}
+ return false;
}
@Override
@@ -128,6 +144,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
switch(view.getId())
{
case R.id.buttonStart:
+ mNeedClose = false;
start();
break;
case R.id.buttonStop:
@@ -136,6 +153,20 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
}
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ if (parent.getId() != R.id.spinnerAutostart) return;
+ SharedPreferences prefs = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
+ prefs.edit()
+ .putInt(SETTING_AUTOSTART, position)
+ .commit();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Unused
+ }
+
private void start() {
saveSettings();
@@ -144,7 +175,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
if (ignoreOptimization != null) startActivity(ignoreOptimization);
Intent serviceIntent = new Intent(this, UsbSerialTelnetService.class);
- SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
+ SharedPreferences prefs = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
serviceIntent.putExtra(UsbSerialTelnetService.KEY_TCP_PORT, prefs.getInt(SETTING_TCP_PORT, 2323));
serviceIntent.putExtra(UsbSerialTelnetService.KEY_BAUD_RATE, prefs.getInt(SETTING_BAUD_RATE, 115200));
serviceIntent.putExtra(UsbSerialTelnetService.KEY_DATA_BITS, prefs.getInt(SETTING_DATA_BITS, 3) + 5);
@@ -167,15 +198,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
} else {
startService(serviceIntent);
}
- bindService(serviceIntent, serviceConnection, 0);
-
- // Save last state
- mHandler.postDelayed(() -> {
- boolean started = mServiceBinder != null && mServiceBinder.isStarted();
- SharedPreferences prefsShared = getApplicationContext().getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
- prefsShared.edit().putBoolean(UsbSerialTelnetService.KEY_LAST_STATE, started).commit();
- Log.d(UsbSerialTelnetService.TAG, "Last state saved: " + started);
- }, 500);
+ bindService(serviceIntent, mServiceConnection, 0);
}
private void stop() {
@@ -187,16 +210,23 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
updateSettings();
}
- private ServiceConnection serviceConnection = new ServiceConnection() {
+ private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
mServiceBinder = (UsbSerialTelnetService.ServiceBinder) service;
- mServiceBinder.setOnStopListener(MainActivity.this);
+ mServiceBinder.setOnStartStopListener(MainActivity.this);
updateSettings();
SharedPreferences prefs = getApplicationContext().getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
prefs.edit().putBoolean(UsbSerialTelnetService.KEY_LAST_STATE, isStarted()).commit();
Log.d(UsbSerialTelnetService.TAG, "Service connected");
+ // Close if autoclose enabled
+ if (isStarted() && mNeedClose) {
+ // Delay to prevent race condition
+ mHandler.postDelayed(() -> {
+ if (mNeedClose) finish();
+ }, 1000);
+ }
}
@Override
@@ -207,11 +237,16 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
};
@Override
+ public void usbSerialServiceStarted() {
+ }
+
+ @Override
public void usbSerialServiceStopped() {
updateSettings();
}
+
private void saveSettings() {
- SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
+ SharedPreferences prefs = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
int tcpPort;
try {
tcpPort = Integer.parseInt(mTcpPort.getText().toString());
@@ -238,8 +273,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
private void updateSettings() {
- SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
- boolean started = mServiceBinder != null && mServiceBinder.isStarted();
+ SharedPreferences prefs = getSharedPreferences(getString(R.string.app_name), Context.MODE_PRIVATE);
+ boolean started = isStarted();
mStartButton.setEnabled(!started);
mStopButton.setEnabled(started);
mTcpPort.setEnabled(!started);
@@ -256,6 +291,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
mParity.setSelection(prefs.getInt(SETTING_PARITY, 0));
mNoLocalEcho.setChecked(prefs.getBoolean(SETTING_NO_LOCAL_ECHO, true));
mRemoveLF.setChecked(prefs.getBoolean(SETTING_REMOVE_LF, true));
+ mAutostart.setSelection(prefs.getInt(SETTING_AUTOSTART, AUTOSTART_DISABLED));
if (started)
mStatus.setText(getString(R.string.started_please_connect) + " telnet://" + UsbSerialTelnetService.getIPAddress() + ":"+ mTcpPort.getText());
else
diff --git a/app/src/main/java/com/clusterrr/usbserialtelnetserver/UsbSerialTelnetService.java b/app/src/main/java/com/clusterrr/usbserialtelnetserver/UsbSerialTelnetService.java
index b90d445..3c53739 100644
--- a/app/src/main/java/com/clusterrr/usbserialtelnetserver/UsbSerialTelnetService.java
+++ b/app/src/main/java/com/clusterrr/usbserialtelnetserver/UsbSerialTelnetService.java
@@ -7,7 +7,6 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
@@ -65,7 +64,7 @@ public class UsbSerialTelnetService extends Service {
{
if (mStarted) {
// Already started
- new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(UsbSerialTelnetService.this.getApplicationContext(), getString(R.string.already_started), Toast.LENGTH_LONG).show());
+ //new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(UsbSerialTelnetService.this.getApplicationContext(), getString(R.string.already_started), Toast.LENGTH_LONG).show());
return START_STICKY;
}
@@ -86,10 +85,11 @@ public class UsbSerialTelnetService extends Service {
.setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher))
.setContentTitle(message)
- .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(Notification.CATEGORY_SERVICE)
.setShowWhen(false)
.setContentIntent(mainActivityPendingIntent)
+ .setSound(null)
.build();
startForeground(1, notification);
@@ -145,12 +145,14 @@ public class UsbSerialTelnetService extends Service {
if (message != null)
Log.i(TAG, message);
mStarted = true;
+ mBinder.started();
} else {
if (message != null)
Log.e(TAG, message);
stopSelf();
mStarted = false;
}
+
return START_STICKY;
}
@@ -201,16 +203,18 @@ public class UsbSerialTelnetService extends Service {
private final ServiceBinder mBinder = new ServiceBinder();
public class ServiceBinder extends Binder {
- private IOnStopListener onStopListener = null;
+ private IOnStartStopListener onStartStopListener = null;
public boolean isStarted()
{
return mStarted;
}
- public void setOnStopListener(IOnStopListener listener) { onStopListener = listener; }
- public void stopped() { if (onStopListener != null) onStopListener.usbSerialServiceStopped(); }
+ public void setOnStartStopListener(IOnStartStopListener listener) { onStartStopListener = listener; }
+ public void started() { if (onStartStopListener != null) onStartStopListener.usbSerialServiceStarted(); }
+ public void stopped() { if (onStartStopListener != null) onStartStopListener.usbSerialServiceStopped(); }
}
- public interface IOnStopListener
+ public interface IOnStartStopListener
{
+ public void usbSerialServiceStarted();
public void usbSerialServiceStopped();
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 467c010..e074ce3 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -209,6 +209,27 @@
app:layout_constraintStart_toEndOf="@+id/textRemoveLf"
app:layout_constraintTop_toBottomOf="@+id/switchNoLocalEcho" />
+ <TextView
+ android:id="@+id/textAutostart"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="24dp"
+ android:text="@string/autostart_on_device_connect"
+ app:layout_constraintBottom_toBottomOf="@+id/spinnerAutostart"
+ app:layout_constraintEnd_toStartOf="@+id/spinnerAutostart"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/spinnerAutostart" />
+
+ <Spinner
+ android:id="@+id/spinnerAutostart"
+ android:layout_width="0dp"
+ android:layout_height="48dp"
+ android:layout_marginEnd="24dp"
+ android:entries="@array/autostart"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/textAutostart"
+ app:layout_constraintTop_toBottomOf="@+id/switchRemoveLf" />
+
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index cc4d268..4269713 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -16,6 +16,7 @@
<string name="already_started">Already started</string>
<string name="no_local_echo">Forced local echo off</string>
<string name="remove_lf">Convert client\'s CR-LF to CR</string>
+ <string name="autostart_on_device_connect">Autostart on device attach</string>
<string-array name="data_bits">
<item>5</item>
<item>6</item>
@@ -35,4 +36,9 @@
<item>Mark</item>
<item>Space</item>
</string-array>
+ <string-array name="autostart">
+ <item>Disabled</item>
+ <item>Enabled</item>
+ <item>+Autoclose</item>
+ </string-array>
</resources> \ No newline at end of file