diff --git a/app/build.gradle b/app/build.gradle
index 0ae3888..f9c37ac 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,7 +4,7 @@ android {
compileSdkVersion 30
defaultConfig {
applicationId "hendrikschutter.com.externgnss"
- minSdkVersion 14
+ minSdkVersion 17
targetSdkVersion 30
versionCode 1
versionName "1.0"
@@ -27,4 +27,5 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ implementation 'com.github.mik3y:usb-serial-for-android:3.4.3'
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 33ee0cc..3987fa6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,6 +4,7 @@
+
-
+
+
+
+
diff --git a/app/src/main/java/hendrikschutter/com/externgnss/MainActivity.java b/app/src/main/java/hendrikschutter/com/externgnss/MainActivity.java
index 5540ee6..0861c71 100644
--- a/app/src/main/java/hendrikschutter/com/externgnss/MainActivity.java
+++ b/app/src/main/java/hendrikschutter/com/externgnss/MainActivity.java
@@ -2,7 +2,13 @@ package hendrikschutter.com.externgnss;
import android.Manifest;
import android.annotation.SuppressLint;
+import android.app.PendingIntent;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbManager;
import android.location.LocationListener;
import android.location.LocationManager;
import androidx.appcompat.app.AppCompatActivity;
@@ -17,12 +23,20 @@ import pub.devrel.easypermissions.EasyPermissions;
import static java.lang.Thread.sleep;
+import com.hoho.android.usbserial.driver.UsbSerialDriver;
+import com.hoho.android.usbserial.driver.UsbSerialPort;
+import com.hoho.android.usbserial.driver.UsbSerialProber;
+
+import java.io.IOException;
+import java.util.List;
+
public class MainActivity extends AppCompatActivity {
private TextView output;
private LocationManager locationManager;
private boolean doRun = true;
private final Context cntxToastInternGNSSUpdate = this;
- final String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.INTERNET};
+ final String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.INTERNET,};
+ private static final String INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB";
private boolean bChange = true;
@Override
@@ -30,6 +44,15 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startLocationInit();
+
+ SerialUSB serialUSB = new SerialUSB(this);
+
+
+
+
+
+
+
}
// From https://github.com/googlesamples/easypermissions
diff --git a/app/src/main/java/hendrikschutter/com/externgnss/SerialUSB.java b/app/src/main/java/hendrikschutter/com/externgnss/SerialUSB.java
new file mode 100644
index 0000000..eb69739
--- /dev/null
+++ b/app/src/main/java/hendrikschutter/com/externgnss/SerialUSB.java
@@ -0,0 +1,163 @@
+package hendrikschutter.com.externgnss;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbManager;
+import android.util.Log;
+
+import com.hoho.android.usbserial.driver.UsbSerialDriver;
+import com.hoho.android.usbserial.driver.UsbSerialPort;
+import com.hoho.android.usbserial.driver.UsbSerialProber;
+import com.hoho.android.usbserial.util.SerialInputOutputManager;
+
+import java.io.IOException;
+
+public class SerialUSB implements SerialInputOutputManager.Listener{
+
+ private MainActivity mainActivity = null;
+
+ private enum UsbPermission { Unknown, Requested, Granted, Denied }
+
+ private static final String INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB";
+ private static final int WRITE_WAIT_MILLIS = 2000;
+ private static final int READ_WAIT_MILLIS = 2000;
+
+ private int deviceId, portNum, baudRate;
+ private boolean withIoManager;
+
+ private BroadcastReceiver broadcastReceiver = null;
+ //private final Handler mainLooper;
+ //private TextView receiveText;
+ //private ControlLines controlLines;
+
+ private SerialInputOutputManager usbIoManager;
+ private UsbSerialPort usbSerialPort;
+ private UsbPermission usbPermission = UsbPermission.Unknown;
+ private boolean connected = false;
+
+ public SerialUSB(MainActivity mainActivity){
+ this.mainActivity = mainActivity;
+
+ // Find all available drivers from attached devices.
+ UsbManager usbManager = (UsbManager) this.mainActivity.getSystemService(Context.USB_SERVICE);
+ UsbSerialProber usbDefaultProber = UsbSerialProber.getDefaultProber();
+
+ if (usbManager.getDeviceList().values().size() > 0){
+ UsbDevice device = (UsbDevice) usbManager.getDeviceList().values().toArray()[0];
+ UsbSerialDriver driver = usbDefaultProber.probeDevice(device);
+ if(driver == null) {
+ Log.i("SerialUSB", "driver is null");
+ }
+ if(driver != null) {
+ Log.i("SerialUSB", "ExternGNSS: device/driver found!");
+ this.deviceId = device.getDeviceId();
+ this.portNum = 0;
+ this.baudRate = 9600;
+ this.withIoManager = true;
+ }
+ }
+
+
+ broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if(INTENT_ACTION_GRANT_USB.equals(intent.getAction())) {
+ usbPermission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false) ? UsbPermission.Granted : UsbPermission.Denied;
+ connect();
+ } else {
+ Log.i("SerialUSB", "USB permissions are not set");
+ }
+ }
+ };
+ connect();
+ this.mainActivity.registerReceiver(broadcastReceiver, new IntentFilter(INTENT_ACTION_GRANT_USB));
+ }
+
+ private void connect() {
+ Log.i("connect", "starting to connect ...");
+ UsbDevice device = null;
+ UsbManager usbManager = (UsbManager) this.mainActivity.getSystemService(Context.USB_SERVICE);
+ for(UsbDevice v : usbManager.getDeviceList().values())
+ if(v.getDeviceId() == deviceId)
+ device = v;
+ if(device == null) {
+ Log.i("connect", "connection failed: device not found");
+ return;
+ }
+ UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);
+ /*
+ if(driver == null) {
+ driver = CustomProber.getCustomProber().probeDevice(device);
+ }
+ */
+ if(driver == null) {
+ Log.i("connect", "connection failed: no driver for device");
+ return;
+ }
+ if(driver.getPorts().size() < portNum) {
+ Log.i("connect", "connection failed: not enough ports at device");
+ return;
+ }
+ usbSerialPort = driver.getPorts().get(portNum);
+ UsbDeviceConnection usbConnection = usbManager.openDevice(driver.getDevice());
+ if(usbConnection == null && usbPermission == UsbPermission.Unknown && !usbManager.hasPermission(driver.getDevice())) {
+ usbPermission = UsbPermission.Requested;
+ PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this.mainActivity, 0, new Intent(INTENT_ACTION_GRANT_USB), 0);
+ usbManager.requestPermission(driver.getDevice(), usbPermissionIntent);
+ return;
+ }
+ if(usbConnection == null) {
+ if (!usbManager.hasPermission(driver.getDevice()))
+ Log.i("connect", "connection failed: permission denied");
+ else
+ Log.i("connect", "connection failed: open failed");
+ return;
+ }
+
+ try {
+ usbSerialPort.open(usbConnection);
+ usbSerialPort.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
+ if(withIoManager) {
+ usbIoManager = new SerialInputOutputManager(usbSerialPort, this);
+ usbIoManager.start();
+ }
+
+ Log.i("connect", "connected");
+ connected = true;
+ //controlLines.start();
+ } catch (Exception e) {
+ Log.i("connect", "connection failed: " + e.getMessage());
+ disconnect();
+ }
+ }
+
+ private void disconnect() {
+ connected = false;
+ //controlLines.stop();
+ if(usbIoManager != null) {
+ usbIoManager.setListener(null);
+ usbIoManager.stop();
+ }
+ usbIoManager = null;
+ try {
+ usbSerialPort.close();
+ } catch (IOException ignored) {}
+ usbSerialPort = null;
+ }
+
+ @Override
+ public void onNewData(byte[] data) {
+ Log.i("connect", "received data: " + data.length);
+ }
+
+ @Override
+ public void onRunError(Exception e) {
+ Log.e("SerialUSB", "runtime error: " + e.getMessage());
+ this.disconnect();
+ }
+}
diff --git a/app/src/main/res/xml/usb_serial_devices.xml b/app/src/main/res/xml/usb_serial_devices.xml
new file mode 100644
index 0000000..b7bba29
--- /dev/null
+++ b/app/src/main/res/xml/usb_serial_devices.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 30178be..a44dd51 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,8 +6,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.1.2'
-
+ classpath 'com.android.tools.build:gradle:7.1.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -17,6 +16,7 @@ allprojects {
repositories {
google()
mavenCentral()
+ maven { url 'https://jitpack.io' }
}
}