");
}
}
-
+
// then display streams status
displayText.append("
");
for (SOSTClient client: sostClients)
{
- Map dataStreams = client.getDataStreams();
+ Map dataStreams = client.getDataStreams();
long now = System.currentTimeMillis();
-
+
for (Entry stream : dataStreams.entrySet())
{
displayText.append("" + stream.getKey().getName() + " : ");
@@ -1169,7 +1210,7 @@ else if (dt > stream.getValue().measPeriodMs)
displayText.append(stream.getValue().errorCount);
displayText.append(")");
}
-
+
displayText.append(" ");
}
}
@@ -1178,15 +1219,15 @@ else if (dt > stream.getValue().measPeriodMs)
displayText.setLength(displayText.length()-5); // remove last
displayText.append("
");
}
-
-
+
+
protected synchronized void newStatusMessage(String msg)
{
displayText.setLength(0);
appendStatusMessage(msg);
}
-
-
+
+
protected synchronized void appendStatusMessage(String msg)
{
displayText.append(msg);
@@ -1199,17 +1240,17 @@ public void run()
}
});
}
-
-
+
+
protected void startListeningForEvents()
{
if (boundService == null || boundService.getSensorHub() == null)
return;
-
+
boundService.getSensorHub().getModuleRegistry().registerListener(this);
}
-
-
+
+
protected void stopListeningForEvents()
{
if (boundService == null || boundService.getSensorHub() == null)
From 25588db9d8552d259090918f5538087f515ed062 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 27 Jun 2019 15:49:42 -0500
Subject: [PATCH 071/207] Update Config in Place
---
.../src/org/sensorhub/android/MainActivity.java | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 0961ad59..34ef0553 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -937,11 +937,15 @@ public void onReceive(Context context, Intent intent)
// mr.startModule(proxySensorConfig.id);
// reload SOS?
+ mr.updateModuleConfigAsync(sosConf);
// mr.stopModule(sosConf.id);
+// Thread.sleep(2000);
+// sensorhubConfig.update(sosConf);
// mr.loadModule(sosConf);
// mr.startModule(sosConf.id);
- boundService.stopSensorHub();
+ // Stop and Restart SensorHub
+ /*boundService.stopSensorHub();
Thread.sleep(2000);
Log.d("OSHApp", "Starting Sensorhub Again");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
@@ -949,9 +953,9 @@ public void onReceive(Context context, Intent intent)
sostClients.clear();
boundService.startSensorHub(sensorhubConfig, showVideo, MainActivity.this);
if (boundService.hasVideo())
- textArea.setBackgroundColor(0x80FFFFFF);
+ textArea.setBackgroundColor(0x80FFFFFF);*/
// showRunNamePopup();
- } catch (SensorHubException | InterruptedException e) {
+ } catch (SensorHubException e) {
Log.e("OSHApp", "Error Loading Proxy Sensor", e);
}
From d203c2ba76c08c81e2a12d1e1c4dfc33fb243c75 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Wed, 10 Jul 2019 14:46:55 -0500
Subject: [PATCH 072/207] Start Proxy Sensor Stream on GetResult
---
.../org/sensorhub/android/MainActivity.java | 11 +-----
.../sensor/swe/ProxySensor/ProxySensor.java | 38 +++++++++----------
.../swe/ProxySensor/ProxySensorConfig.java | 1 +
.../swe/ProxySensor/ProxySensorOutput.java | 25 +++++++-----
4 files changed, 35 insertions(+), 40 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 0961ad59..ce4a5dd8 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -933,14 +933,6 @@ public void onReceive(Context context, Intent intent)
SOSServiceWithIPCConfig sosConf = (SOSServiceWithIPCConfig) mr.getModuleById("SOS_SERVICE").getConfiguration();
sosConf.dataProviders.add(dataProviderConfig);
-// mr.loadModule(proxySensorConfig);
-// mr.startModule(proxySensorConfig.id);
-
- // reload SOS?
-// mr.stopModule(sosConf.id);
-// mr.loadModule(sosConf);
-// mr.startModule(sosConf.id);
-
boundService.stopSensorHub();
Thread.sleep(2000);
Log.d("OSHApp", "Starting Sensorhub Again");
@@ -950,7 +942,6 @@ public void onReceive(Context context, Intent intent)
boundService.startSensorHub(sensorhubConfig, showVideo, MainActivity.this);
if (boundService.hasVideo())
textArea.setBackgroundColor(0x80FFFFFF);
-// showRunNamePopup();
} catch (SensorHubException | InterruptedException e) {
Log.e("OSHApp", "Error Loading Proxy Sensor", e);
}
@@ -1090,7 +1081,7 @@ protected void testProxyBroadcast()
Intent testIntent = new Intent();
testIntent.setAction(ACTION_BROADCAST_RECEIVER);
- testIntent.putExtra("sosEndpointUrl", "http://192.168.1.195:8585/sensorhub/sos?service=SOS&version=2.0&request=GetCapabilities");
+ testIntent.putExtra("sosEndpointUrl", "http://192.168.0.46:8585/sensorhub/sos?service=SOS&version=2.0&request=GetCapabilities");
testIntent.putExtra("name", "Android Sensors [S9]");
testIntent.putExtra("sensorId", "urn:android:device:aa3de549fc5ae2c3");
testIntent.putStringArrayListExtra("properties", testProperties);
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
index 1c5d309e..495c27e1 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
@@ -1,18 +1,25 @@
package org.sensorhub.impl.sensor.swe.ProxySensor;
import android.util.Log;
+
import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.api.sensor.ISensorDataInterface;
import org.sensorhub.impl.sensor.swe.SWEVirtualSensor;
+
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
+import java.util.Set;
import net.opengis.gml.v32.AbstractFeature;
import net.opengis.sensorml.v20.AbstractPhysicalProcess;
import net.opengis.swe.v20.DataBlock;
import net.opengis.swe.v20.DataChoice;
import net.opengis.swe.v20.DataComponent;
+
import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.impl.client.sos.SOSClient;
import org.sensorhub.impl.client.sos.SOSClient.SOSRecordListener;
@@ -30,7 +37,7 @@
import org.vast.util.TimeExtent;
public class ProxySensor extends SWEVirtualSensor {
-// protected static final Logger log = LoggerFactory.getLogger(ProxySensor.class);
+ // protected static final Logger log = LoggerFactory.getLogger(ProxySensor.class);
private static final String TAG = "OSHProxySensor";
private static final String SOS_VERSION = "2.0";
private static final String SPS_VERSION = "2.0";
@@ -39,7 +46,6 @@ public class ProxySensor extends SWEVirtualSensor {
AbstractFeature currentFoi;
List sosClients;
SPSClient spsClient;
- Map recordListeners;
public ProxySensor() {
super();
@@ -99,7 +105,6 @@ public void start() throws SensorHubException {
if (outputNum == 1 && config.sensorML == null)
this.sensorDescription = (AbstractPhysicalProcess) sos.getSensorDescription(config.sensorUID);
} catch (SensorHubException e) {
-// log.warn("Cannot get remote sensor description", e);
Log.d(TAG, "Cannot get remote sensor description.", e);
}
@@ -107,21 +112,6 @@ public void start() throws SensorHubException {
final ProxySensorOutput output = new ProxySensorOutput(this, recordDef, sos.getRecommendedEncoding());
this.addOutput(output, false);
- recordListeners.put(sos.toString(), new SOSRecordListener() {
- @Override
- public void newRecord(DataBlock data) {
- output.publishNewRecord(data);
- }
- });
-
-// // TODO: Move to event based start
-// sos.startStream(new SOSRecordListener() {
-// @Override
-// public void newRecord(DataBlock data) {
-// output.publishNewRecord(data);
-// }
-// });
-
outputNum++;
}
}
@@ -136,8 +126,16 @@ public void newRecord(DataBlock data) {
}
public void startSOSStreams() throws SensorHubException {
- for (SOSClient client: sosClients){
- client.startStream(recordListeners.get(client.toString()));
+ for (int i = 0; i < sosClients.size(); i++) {
+ String name = sosClients.get(i).getRecordDescription().getName();
+ SOSRecordListener rl = new SOSRecordListener() {
+ @Override
+ public void newRecord(DataBlock data) {
+ ProxySensorOutput output = (ProxySensorOutput)getObservationOutputs().get(name);
+ output.publishNewRecord(data);
+ }
+ };
+ sosClients.get(i).startStream(rl);
}
}
}
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java
index 26108c1a..9bf47b25 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java
@@ -7,5 +7,6 @@ public class ProxySensorConfig extends SWEVirtualSensorConfig
public ProxySensorConfig()
{
super();
+ this.moduleClass = ProxySensor.class.getCanonicalName();
}
}
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
index 191564f4..7c515bda 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
@@ -19,25 +19,30 @@ public class ProxySensorOutput extends SWEVirtualSensorOutput
DataComponent recordStructure;
DataEncoding recordEncoding;
- public ProxySensorOutput(SWEVirtualSensor sensor, DataComponent recordStructure, DataEncoding recordEncoding) {
+ public ProxySensorOutput(ProxySensor sensor, DataComponent recordStructure, DataEncoding recordEncoding) {
super(sensor, recordStructure, recordEncoding);
- }
-
- @Override
- public void publishNewRecord(DataBlock dataBlock) {
- Log.d(TAG, "publishNewRecord");
+ this.parentSensor = sensor;
+ this.recordStructure = recordStructure;
+ this.recordEncoding = recordEncoding;
}
@Override
public void registerListener(IEventListener listener)
{
+// super.registerListener(listener);
Log.d(TAG, "Registering Proxy Sensor Listener");
//TODO: How to start the SOS stream at this point?
try {
- this.parentSensor.startSOSStreams();
- } catch (SensorHubException e) {
- Log.d(TAG, "Error Starting Stream while registering Proxy Sensor", e);
- }
+ this.parentSensor.startSOSStreams();
+ } catch (SensorHubException e) {
+ Log.d(TAG, "Error Starting Stream while registering Proxy Sensor", e);
+ }
eventHandler.registerListener(listener);
}
+
+ @Override
+ public void publishNewRecord(DataBlock dataBlock) {
+ super.publishNewRecord(dataBlock);
+ Log.d(TAG, "publishNewRecord: ");
+ }
}
From 4510ec62c8814a046ccd5556d028221890e1e628 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Wed, 10 Jul 2019 15:29:33 -0500
Subject: [PATCH 073/207] Stop Proxy Sensor stream manually
---
sensorhub-android-app/res/menu/main.xml | 8 +++-
sensorhub-android-app/res/values/strings.xml | 3 +-
.../org/sensorhub/android/MainActivity.java | 12 ++++++
.../sensor/swe/ProxySensor/ProxySensor.java | 40 +++++++++++++++++++
.../swe/ProxySensor/ProxySensorConfig.java | 11 +++++
5 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/sensorhub-android-app/res/menu/main.xml b/sensorhub-android-app/res/menu/main.xml
index 5d9d37aa..a3a51dca 100644
--- a/sensorhub-android-app/res/menu/main.xml
+++ b/sensorhub-android-app/res/menu/main.xml
@@ -26,9 +26,15 @@
android:showAsAction="never"
android:title="@string/action_proxy"/>
+
+
diff --git a/sensorhub-android-app/res/values/strings.xml b/sensorhub-android-app/res/values/strings.xml
index 24776d0c..d018250d 100644
--- a/sensorhub-android-app/res/values/strings.xml
+++ b/sensorhub-android-app/res/values/strings.xml
@@ -6,7 +6,8 @@
Start SensorHubStop SensorHubAbout
- Test Proxy
+ Start Proxy
+ Stop ProxySOS Settings (Required)SOS-T Settings (Optional)Android Sensor
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index ce4a5dd8..e6cebc10 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -62,6 +62,7 @@
import org.sensorhub.impl.persistence.h2.MVStorageConfig;
import org.sensorhub.impl.sensor.android.AndroidSensorsConfig;
import org.sensorhub.impl.sensor.angel.AngelSensorConfig;
+import org.sensorhub.impl.sensor.swe.ProxySensor.ProxySensor;
import org.sensorhub.impl.sensor.swe.ProxySensor.ProxySensorConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
import org.sensorhub.impl.service.sos.SOSServiceConfig;
@@ -311,6 +312,7 @@ protected void updateConfig(SharedPreferences prefs, String runName)
// SOS Data Providers
for (ProxySensorConfig proxySensorConfig : proxySensorConfigs) {
+// proxySensorConfig.androidContext = this.getApplicationContext();
sensorhubConfig.add(proxySensorConfig);
SensorDataProviderConfig dataProviderConfig = new SensorDataProviderConfig();
@@ -905,6 +907,7 @@ public void onReceive(Context context, Intent intent)
}
ProxySensorConfig proxySensorConfig = (ProxySensorConfig) createSensorConfig(Sensors.ProxySensor);
+ proxySensorConfig.androidContext = getApplicationContext();
proxySensorConfig.sosEndpointUrl = sosEndpointUrl;
proxySensorConfig.name = name;
proxySensorConfig.id = sensorId;
@@ -1003,6 +1006,9 @@ else if (id == R.id.action_proxy)
{
testProxyBroadcast();
}
+ else if(id == R.id.action_stop_proxy){
+ testStopProxyBroadcast();
+ }
return super.onOptionsItemSelected(item);
}
@@ -1088,6 +1094,12 @@ protected void testProxyBroadcast()
sendBroadcast(testIntent);
}
+ protected void testStopProxyBroadcast(){
+ Intent testIntent = new Intent();
+ testIntent.setAction("org.sofwerx.ogc.ACTION_PROXY");
+ sendBroadcast(testIntent);
+ }
+
@Override
public void handleEvent(Event> e)
{
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
index 495c27e1..dfff50ee 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
@@ -1,7 +1,12 @@
package org.sensorhub.impl.sensor.swe.ProxySensor;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.util.Log;
+import org.sensorhub.android.SOSServiceWithIPCConfig;
import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.api.sensor.ISensorDataInterface;
import org.sensorhub.impl.sensor.swe.SWEVirtualSensor;
@@ -47,12 +52,41 @@ public class ProxySensor extends SWEVirtualSensor {
List sosClients;
SPSClient spsClient;
+ public static final String ACTION_PROXY = "org.sofwerx.ogc.ACTION_PROXY";
+ private static final String EXTRA_PAYLOAD = "PROXY";
+ private static final String EXTRA_ORIGIN = "src";
+ private Context androidContext;
+
public ProxySensor() {
super();
}
@Override
public void start() throws SensorHubException {
+ androidContext = ((ProxySensorConfig) config).androidContext;
+
+ BroadcastReceiver receiver = new BroadcastReceiver()
+ {
+ @Override
+ public void onReceive(Context context, Intent intent)
+ {
+ String origin = intent.getStringExtra(EXTRA_ORIGIN);
+ if (!context.getPackageName().equalsIgnoreCase(origin))
+ {
+ String requestPayload = intent.getStringExtra(EXTRA_PAYLOAD); // TODO: Can be observable property string
+ try {
+ stopSOSStreams();
+ } catch (SensorHubException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_PROXY);
+
+ androidContext.registerReceiver(receiver, filter);
+
Log.d(TAG, "Starting Proxy Sensor");
checkConfig();
@@ -138,4 +172,10 @@ public void newRecord(DataBlock data) {
sosClients.get(i).startStream(rl);
}
}
+
+ public void stopSOSStreams() throws SensorHubException {
+ for (int i = 0; i < sosClients.size(); i++) {
+ sosClients.get(i).stopStream();
+ }
+ }
}
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java
index 9bf47b25..5737b520 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java
@@ -1,12 +1,23 @@
package org.sensorhub.impl.sensor.swe.ProxySensor;
+import android.content.Context;
+
+import org.sensorhub.api.module.ModuleConfig;
import org.sensorhub.impl.sensor.swe.SWEVirtualSensorConfig;
public class ProxySensorConfig extends SWEVirtualSensorConfig
{
+ public transient Context androidContext;
+
public ProxySensorConfig()
{
super();
this.moduleClass = ProxySensor.class.getCanonicalName();
}
+
+ @Override
+ public ModuleConfig clone()
+ {
+ return this; // disable clone for now as it crashes Android app
+ }
}
From 38a9f91c5dfe73b76c92efb89a40170760400b00 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Wed, 10 Jul 2019 16:01:44 -0500
Subject: [PATCH 074/207] Fix proxy sensor time error, remove autorestart
---
.../org/sensorhub/android/MainActivity.java | 56 +++++++++----------
.../sensor/swe/ProxySensor/ProxySensor.java | 9 +++
2 files changed, 37 insertions(+), 28 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index e6cebc10..40b01b8f 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -312,7 +312,6 @@ protected void updateConfig(SharedPreferences prefs, String runName)
// SOS Data Providers
for (ProxySensorConfig proxySensorConfig : proxySensorConfigs) {
-// proxySensorConfig.androidContext = this.getApplicationContext();
sensorhubConfig.add(proxySensorConfig);
SensorDataProviderConfig dataProviderConfig = new SensorDataProviderConfig();
@@ -920,34 +919,35 @@ public void onReceive(Context context, Intent intent)
proxySensorConfig.autoStart = true;
proxySensorConfigs.add(proxySensorConfig);
+ // TODO: clean up later to fix restarting the hub on proxy sensor insert
// register and "start" new sensor, data stream doesn't begin until someone requests data
- ModuleRegistry mr = boundService.sensorhub.getInstance().getModuleRegistry();
-
- try {
- mr.loadModule(proxySensorConfig);
- Log.d("OSHApp", "Loading Proxy Sensor " + proxySensorConfig.name);
- sensorhubConfig.add(proxySensorConfig);
- SensorDataProviderConfig dataProviderConfig = new SensorDataProviderConfig();
- dataProviderConfig.name = proxySensorConfig.name;
- dataProviderConfig.sensorID = proxySensorConfig.id;
- dataProviderConfig.offeringID = proxySensorConfig.id + "-sos";
- dataProviderConfig.enabled = true;
-
- SOSServiceWithIPCConfig sosConf = (SOSServiceWithIPCConfig) mr.getModuleById("SOS_SERVICE").getConfiguration();
- sosConf.dataProviders.add(dataProviderConfig);
-
- boundService.stopSensorHub();
- Thread.sleep(2000);
- Log.d("OSHApp", "Starting Sensorhub Again");
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- updateConfig(PreferenceManager.getDefaultSharedPreferences(MainActivity.this), runName);
- sostClients.clear();
- boundService.startSensorHub(sensorhubConfig, showVideo, MainActivity.this);
- if (boundService.hasVideo())
- textArea.setBackgroundColor(0x80FFFFFF);
- } catch (SensorHubException | InterruptedException e) {
- Log.e("OSHApp", "Error Loading Proxy Sensor", e);
- }
+// ModuleRegistry mr = boundService.sensorhub.getInstance().getModuleRegistry();
+
+// try {
+// mr.loadModule(proxySensorConfig);
+// Log.d("OSHApp", "Loading Proxy Sensor " + proxySensorConfig.name);
+// sensorhubConfig.add(proxySensorConfig);
+// SensorDataProviderConfig dataProviderConfig = new SensorDataProviderConfig();
+// dataProviderConfig.name = proxySensorConfig.name;
+// dataProviderConfig.sensorID = proxySensorConfig.id;
+// dataProviderConfig.offeringID = proxySensorConfig.id + "-sos";
+// dataProviderConfig.enabled = true;
+//
+// SOSServiceWithIPCConfig sosConf = (SOSServiceWithIPCConfig) mr.getModuleById("SOS_SERVICE").getConfiguration();
+// sosConf.dataProviders.add(dataProviderConfig);
+//
+// boundService.stopSensorHub();
+// Thread.sleep(2000);
+// Log.d("OSHApp", "Starting Sensorhub Again");
+// getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+// updateConfig(PreferenceManager.getDefaultSharedPreferences(MainActivity.this), runName);
+// sostClients.clear();
+// boundService.startSensorHub(sensorhubConfig, showVideo, MainActivity.this);
+// if (boundService.hasVideo())
+// textArea.setBackgroundColor(0x80FFFFFF);
+// } catch (SensorHubException | InterruptedException e) {
+// Log.e("OSHApp", "Error Loading Proxy Sensor", e);
+// }
}
}
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
index dfff50ee..295e0f9a 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
@@ -146,6 +146,15 @@ public void onReceive(Context context, Intent intent)
final ProxySensorOutput output = new ProxySensorOutput(this, recordDef, sos.getRecommendedEncoding());
this.addOutput(output, false);
+ // HACK TO PREVENT GETRESULT TIME ERROR
+ sos.startStream((data) -> output.publishNewRecord(data));
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ sos.stopStream();
+
outputNum++;
}
}
From 53353a3f3a98ad3a7da56c43a10a898fb77091bd Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 11 Jul 2019 19:06:50 -0500
Subject: [PATCH 075/207] Fix PhenomTime error.
---
.../org/sensorhub/android/MainActivity.java | 3 +-
.../sensor/swe/ProxySensor/ProxySensor.java | 14 ++++-----
.../swe/ProxySensor/ProxySensorOutput.java | 29 ++++++++++++++-----
3 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 40b01b8f..2add7b15 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -1087,7 +1087,8 @@ protected void testProxyBroadcast()
Intent testIntent = new Intent();
testIntent.setAction(ACTION_BROADCAST_RECEIVER);
- testIntent.putExtra("sosEndpointUrl", "http://192.168.0.46:8585/sensorhub/sos?service=SOS&version=2.0&request=GetCapabilities");
+// testIntent.putExtra("sosEndpointUrl", "http://192.168.0.46:8585/sensorhub/sos?service=SOS&version=2.0&request=GetCapabilities");
+ testIntent.putExtra("sosEndpointUrl", "http://192.168.1.195:8585/sensorhub/sos?service=SOS&version=2.0&request=GetCapabilities");
testIntent.putExtra("name", "Android Sensors [S9]");
testIntent.putExtra("sensorId", "urn:android:device:aa3de549fc5ae2c3");
testIntent.putStringArrayListExtra("properties", testProperties);
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
index 295e0f9a..cec78848 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
@@ -147,13 +147,13 @@ public void onReceive(Context context, Intent intent)
this.addOutput(output, false);
// HACK TO PREVENT GETRESULT TIME ERROR
- sos.startStream((data) -> output.publishNewRecord(data));
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- sos.stopStream();
+// sos.startStream((data) -> output.publishNewRecord(data));
+// try {
+// Thread.sleep(1000);
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// sos.stopStream();
outputNum++;
}
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
index 7c515bda..f2bee0b2 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
@@ -26,6 +26,17 @@ public ProxySensorOutput(ProxySensor sensor, DataComponent recordStructure, Data
this.recordEncoding = recordEncoding;
}
+ @Override
+ public void publishNewRecord(DataBlock dataBlock) {
+ super.publishNewRecord(dataBlock);
+ Log.d(TAG, "publishNewRecord: ");
+ }
+
+ @Override
+ public long getLatestRecordTime() {
+ return System.currentTimeMillis();
+ }
+
@Override
public void registerListener(IEventListener listener)
{
@@ -33,16 +44,20 @@ public void registerListener(IEventListener listener)
Log.d(TAG, "Registering Proxy Sensor Listener");
//TODO: How to start the SOS stream at this point?
try {
- this.parentSensor.startSOSStreams();
- } catch (SensorHubException e) {
- Log.d(TAG, "Error Starting Stream while registering Proxy Sensor", e);
- }
+ this.parentSensor.startSOSStreams();
+ } catch (SensorHubException e) {
+ Log.d(TAG, "Error Starting Stream while registering Proxy Sensor", e);
+ }
eventHandler.registerListener(listener);
}
@Override
- public void publishNewRecord(DataBlock dataBlock) {
- super.publishNewRecord(dataBlock);
- Log.d(TAG, "publishNewRecord: ");
+ public void unregisterListener(IEventListener listener) {
+ try {
+ this.parentSensor.stopSOSStreams();
+ Log.d(TAG, "unregisterListener: Stopping streams");
+ } catch (SensorHubException e) {
+ e.printStackTrace();
+ }
}
}
From 70d59124d999f470d4f62ed7e77072705fdd9080 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 11 Jul 2019 19:18:19 -0500
Subject: [PATCH 076/207] Reinstate Auto Restart + small refactoring
---
.../org/sensorhub/android/MainActivity.java | 48 ++++++-------------
.../swe/ProxySensor/ProxySensorOutput.java | 3 +-
2 files changed, 16 insertions(+), 35 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 2add7b15..8cebce91 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -911,43 +911,25 @@ public void onReceive(Context context, Intent intent)
proxySensorConfig.name = name;
proxySensorConfig.id = sensorId;
proxySensorConfig.sensorUID = sensorId;
- for (String property : properties)
- {
- proxySensorConfig.observedProperties.add(property);
- }
+ proxySensorConfig.observedProperties.addAll(properties);
proxySensorConfig.sosUseWebsockets = true;
proxySensorConfig.autoStart = true;
proxySensorConfigs.add(proxySensorConfig);
- // TODO: clean up later to fix restarting the hub on proxy sensor insert
- // register and "start" new sensor, data stream doesn't begin until someone requests data
-// ModuleRegistry mr = boundService.sensorhub.getInstance().getModuleRegistry();
-
-// try {
-// mr.loadModule(proxySensorConfig);
-// Log.d("OSHApp", "Loading Proxy Sensor " + proxySensorConfig.name);
-// sensorhubConfig.add(proxySensorConfig);
-// SensorDataProviderConfig dataProviderConfig = new SensorDataProviderConfig();
-// dataProviderConfig.name = proxySensorConfig.name;
-// dataProviderConfig.sensorID = proxySensorConfig.id;
-// dataProviderConfig.offeringID = proxySensorConfig.id + "-sos";
-// dataProviderConfig.enabled = true;
-//
-// SOSServiceWithIPCConfig sosConf = (SOSServiceWithIPCConfig) mr.getModuleById("SOS_SERVICE").getConfiguration();
-// sosConf.dataProviders.add(dataProviderConfig);
-//
-// boundService.stopSensorHub();
-// Thread.sleep(2000);
-// Log.d("OSHApp", "Starting Sensorhub Again");
-// getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-// updateConfig(PreferenceManager.getDefaultSharedPreferences(MainActivity.this), runName);
-// sostClients.clear();
-// boundService.startSensorHub(sensorhubConfig, showVideo, MainActivity.this);
-// if (boundService.hasVideo())
-// textArea.setBackgroundColor(0x80FFFFFF);
-// } catch (SensorHubException | InterruptedException e) {
-// Log.e("OSHApp", "Error Loading Proxy Sensor", e);
-// }
+ // register and "start" new sensor, data stream doesn't begin until someone requests data;
+ try {
+ boundService.stopSensorHub();
+ Thread.sleep(2000);
+ Log.d("OSHApp", "Starting Sensorhub Again");
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ updateConfig(PreferenceManager.getDefaultSharedPreferences(MainActivity.this), runName);
+ sostClients.clear();
+ boundService.startSensorHub(sensorhubConfig, showVideo, MainActivity.this);
+ if (boundService.hasVideo())
+ textArea.setBackgroundColor(0x80FFFFFF);
+ } catch (InterruptedException e) {
+ Log.e("OSHApp", "Error Loading Proxy Sensor", e);
+ }
}
}
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
index f2bee0b2..0bd52860 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
@@ -40,9 +40,8 @@ public long getLatestRecordTime() {
@Override
public void registerListener(IEventListener listener)
{
-// super.registerListener(listener);
+ // TODO: Start the SOS Stream of only requested data
Log.d(TAG, "Registering Proxy Sensor Listener");
- //TODO: How to start the SOS stream at this point?
try {
this.parentSensor.startSOSStreams();
} catch (SensorHubException e) {
From b73bf6bbc71ed42eec13255516abfc5d0edd09ea Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 11 Jul 2019 22:09:22 -0500
Subject: [PATCH 077/207] Stop streams on unregisterListener
---
.../org/sensorhub/android/MainActivity.java | 2 +-
.../sensor/swe/ProxySensor/ProxySensor.java | 36 +++++++++++++++----
.../swe/ProxySensor/ProxySensorOutput.java | 9 +++--
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 8cebce91..ffd97ac2 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -1064,7 +1064,7 @@ protected void testProxyBroadcast()
{
ArrayList testProperties = new ArrayList();
testProperties.add("http://sensorml.com/ont/swe/property/Acceleration");
-// testProperties.add("http://sensorml.com/ont/swe/property/MagneticField");
+ testProperties.add("http://sensorml.com/ont/swe/property/MagneticField");
// testProperties.add("http://sensorml.com/ont/swe/property/AngularRate");
Intent testIntent = new Intent();
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
index cec78848..6e0b9e20 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
@@ -65,14 +65,11 @@ public ProxySensor() {
public void start() throws SensorHubException {
androidContext = ((ProxySensorConfig) config).androidContext;
- BroadcastReceiver receiver = new BroadcastReceiver()
- {
+ BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
- public void onReceive(Context context, Intent intent)
- {
+ public void onReceive(Context context, Intent intent) {
String origin = intent.getStringExtra(EXTRA_ORIGIN);
- if (!context.getPackageName().equalsIgnoreCase(origin))
- {
+ if (!context.getPackageName().equalsIgnoreCase(origin)) {
String requestPayload = intent.getStringExtra(EXTRA_PAYLOAD); // TODO: Can be observable property string
try {
stopSOSStreams();
@@ -174,7 +171,7 @@ public void startSOSStreams() throws SensorHubException {
SOSRecordListener rl = new SOSRecordListener() {
@Override
public void newRecord(DataBlock data) {
- ProxySensorOutput output = (ProxySensorOutput)getObservationOutputs().get(name);
+ ProxySensorOutput output = (ProxySensorOutput) getObservationOutputs().get(name);
output.publishNewRecord(data);
}
};
@@ -182,9 +179,34 @@ public void newRecord(DataBlock data) {
}
}
+ public void startSOSStream(String outputName) throws SensorHubException {
+ for (SOSClient client : sosClients) {
+ if (client.getRecordDescription().getName().equals(outputName)) {
+ SOSRecordListener recordListener = new SOSRecordListener() {
+ @Override
+ public void newRecord(DataBlock data) {
+ ProxySensorOutput output = (ProxySensorOutput) getObservationOutputs().get(outputName);
+ output.publishNewRecord(data);
+ }
+ };
+ client.startStream(recordListener);
+ break;
+ }
+ }
+ }
+
public void stopSOSStreams() throws SensorHubException {
for (int i = 0; i < sosClients.size(); i++) {
sosClients.get(i).stopStream();
}
}
+
+ public void stopSOSStream(String outputName) throws SensorHubException {
+ for (SOSClient client : sosClients) {
+ if (client.getRecordDescription().getName().equals(outputName)) {
+ client.stopStream();
+ break;
+ }
+ }
+ }
}
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
index 0bd52860..36397598 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
+++ b/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
@@ -40,10 +40,9 @@ public long getLatestRecordTime() {
@Override
public void registerListener(IEventListener listener)
{
- // TODO: Start the SOS Stream of only requested data
- Log.d(TAG, "Registering Proxy Sensor Listener");
+ Log.d(TAG, "Registering Proxy Sensor Listener for: " + this.name);
try {
- this.parentSensor.startSOSStreams();
+ this.parentSensor.startSOSStream(this.name);
} catch (SensorHubException e) {
Log.d(TAG, "Error Starting Stream while registering Proxy Sensor", e);
}
@@ -53,8 +52,8 @@ public void registerListener(IEventListener listener)
@Override
public void unregisterListener(IEventListener listener) {
try {
- this.parentSensor.stopSOSStreams();
- Log.d(TAG, "unregisterListener: Stopping streams");
+ this.parentSensor.stopSOSStream(this.name);
+ Log.d(TAG, "unregisterListener: Stopping stream: " + this.name);
} catch (SensorHubException e) {
e.printStackTrace();
}
From d2ded8555a93eff18842731e96d8d6120b8cb8f6 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Mon, 23 Sep 2019 19:18:41 -0500
Subject: [PATCH 078/207] Testing BLE Beacon Usage
---
sensorhub-android-app/AndroidManifest.xml | 1 +
.../org/sensorhub/android/MainActivity.java | 547 +++++++++---------
sensorhub-android-blebeacon/.gitignore | 1 +
sensorhub-android-blebeacon/build.gradle | 34 ++
.../consumer-rules.pro | 0
sensorhub-android-blebeacon/docs/BLEDoc.txt | 12 +
.../proguard-rules.pro | 21 +
.../blebeacon/ExampleInstrumentedTest.java | 26 +
.../src/main/AndroidManifest.xml | 2 +
.../sensor/blebeacon/BLEBeaconConfig.java | 6 +
.../impl/sensor/blebeacon/BLETest.java | 4 +
.../src/main/res/values/strings.xml | 3 +
.../sensor/blebeacon/ExampleUnitTest.java | 17 +
settings.gradle | 1 +
14 files changed, 401 insertions(+), 274 deletions(-)
create mode 100644 sensorhub-android-blebeacon/.gitignore
create mode 100644 sensorhub-android-blebeacon/build.gradle
create mode 100644 sensorhub-android-blebeacon/consumer-rules.pro
create mode 100644 sensorhub-android-blebeacon/docs/BLEDoc.txt
create mode 100644 sensorhub-android-blebeacon/proguard-rules.pro
create mode 100644 sensorhub-android-blebeacon/src/androidTest/java/org/sensorhub/impl/sensor/blebeacon/ExampleInstrumentedTest.java
create mode 100644 sensorhub-android-blebeacon/src/main/AndroidManifest.xml
create mode 100644 sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconConfig.java
create mode 100644 sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLETest.java
create mode 100644 sensorhub-android-blebeacon/src/main/res/values/strings.xml
create mode 100644 sensorhub-android-blebeacon/src/test/java/org/sensorhub/impl/sensor/blebeacon/ExampleUnitTest.java
diff --git a/sensorhub-android-app/AndroidManifest.xml b/sensorhub-android-app/AndroidManifest.xml
index bf4cff68..d61bc395 100644
--- a/sensorhub-android-app/AndroidManifest.xml
+++ b/sensorhub-android-app/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index ffd97ac2..693adf17 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -1,19 +1,25 @@
/*************************** BEGIN LICENSE BLOCK ***************************
-The contents of this file are subject to the Mozilla Public License, v. 2.0.
-If a copy of the MPL was not distributed with this file, You can obtain one
-at http://mozilla.org/MPL/2.0/.
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the License.
-
-Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
-
-******************************* END LICENSE BLOCK ***************************/
+ The contents of this file are subject to the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one
+ at http://mozilla.org/MPL/2.0/.
+
+ Software distributed under the License is distributed on an "AS IS" basis,
+ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ for the specific language governing rights and limitations under the License.
+
+ Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+ ******************************* END LICENSE BLOCK ***************************/
package org.sensorhub.android;
+import android.app.ListActivity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanResult;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
@@ -86,13 +92,13 @@
import android.preference.PreferenceManager;
import android.provider.Settings.Secure;
import android.text.Html;
+import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.TextView;
import static android.content.ContentValues.TAG;
-public class MainActivity extends Activity implements TextureView.SurfaceTextureListener, IEventListener
-{
+public class MainActivity extends Activity implements TextureView.SurfaceTextureListener, IEventListener {
public static final String ACTION_BROADCAST_RECEIVER = "org.sensorhub.android.BROADCAST_RECEIVER";
String deviceID;
@@ -122,22 +128,18 @@ enum Sensors {
URL sostUrl = null;
boolean showVideo;
- private ServiceConnection sConn = new ServiceConnection()
- {
- public void onServiceConnected(ComponentName className, IBinder service)
- {
+ private ServiceConnection sConn = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
boundService = ((SensorHubService.LocalBinder) service).getService();
}
- public void onServiceDisconnected(ComponentName className)
- {
+ public void onServiceDisconnected(ComponentName className) {
boundService = null;
}
};
- protected void updateConfig(SharedPreferences prefs, String runName)
- {
+ protected void updateConfig(SharedPreferences prefs, String runName) {
// get device name
deviceID = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
deviceName = prefs.getString("device_name", null);
@@ -151,14 +153,10 @@ protected void updateConfig(SharedPreferences prefs, String runName)
String sosUriConfig = prefs.getString("sos_uri", "http://127.0.0.1:8585/sensorhub/sos");
String sosUser = prefs.getString("sos_username", "");
String sosPwd = prefs.getString("sos_password", "");
- if (sosUriConfig != null && sosUriConfig.trim().length() > 0)
- {
- try
- {
+ if (sosUriConfig != null && sosUriConfig.trim().length() > 0) {
+ try {
sosUrl = new URL(sosUriConfig);
- }
- catch (MalformedURLException e)
- {
+ } catch (MalformedURLException e) {
e.printStackTrace();
}
}
@@ -179,7 +177,7 @@ protected void updateConfig(SharedPreferences prefs, String runName)
sosConfig.autoStart = true;
sosConfig.enableTransactional = true;
- File dbFile = new File(getApplicationContext().getFilesDir()+"/db/");
+ File dbFile = new File(getApplicationContext().getFilesDir() + "/db/");
dbFile.mkdirs();
MVStorageConfig basicStorageConfig = new MVStorageConfig();
basicStorageConfig.moduleClass = "org.sensorhub.impl.persistence.h2.MVObsStorageImpl";
@@ -190,8 +188,7 @@ protected void updateConfig(SharedPreferences prefs, String runName)
// Push Sensors Config
AndroidSensorsConfig androidSensorsConfig = (AndroidSensorsConfig) createSensorConfig(Sensors.Android);
sensorhubConfig.add(androidSensorsConfig);
- if (isPushingSensor(Sensors.Android))
- {
+ if (isPushingSensor(Sensors.Android)) {
addSosTConfig(androidSensorsConfig, sosUser, sosPwd);
}
@@ -203,23 +200,20 @@ protected void updateConfig(SharedPreferences prefs, String runName)
// TruPulse sensor
boolean enabled = prefs.getBoolean("trupulse_enable", false);
- if (enabled)
- {
+ if (enabled) {
String truPulseDevice = prefs.getString("trupulse_datasource", "SIMULATED");
TruPulseConfig truPulseConfig = truPulseDevice == "SIMULATED"
? (TruPulseConfig) createSensorConfig(Sensors.TruPulseSim)
: (TruPulseConfig) createSensorConfig(Sensors.TruPulse);
sensorhubConfig.add(truPulseConfig);
- if (isPushingSensor(Sensors.TruPulse))
- {
+ if (isPushingSensor(Sensors.TruPulse)) {
addSosTConfig(truPulseConfig, sosUser, sosPwd);
}
}
// AngelSensor
enabled = prefs.getBoolean("angel_enabled", false);
- if (enabled)
- {
+ if (enabled) {
AngelSensorConfig angelConfig = (AngelSensorConfig) createSensorConfig(Sensors.Angel);
//angelConfig.btAddress = "00:07:80:79:04:AF"; // mike
//angelConfig.btAddress = "00:07:80:03:0E:0A"; // alex
@@ -230,8 +224,7 @@ protected void updateConfig(SharedPreferences prefs, String runName)
// FLIR One sensor
enabled = prefs.getBoolean("flirone_enabled", false);
- if (enabled)
- {
+ if (enabled) {
showVideo = true;
FlirOneCameraConfig flironeConfig = (FlirOneCameraConfig) createSensorConfig(Sensors.FlirOne);
@@ -317,7 +310,7 @@ protected void updateConfig(SharedPreferences prefs, String runName)
SensorDataProviderConfig dataProviderConfig = new SensorDataProviderConfig();
dataProviderConfig.name = proxySensorConfig.id;
dataProviderConfig.sensorID = proxySensorConfig.id;
- dataProviderConfig.offeringID = proxySensorConfig.id+"-sos";
+ dataProviderConfig.offeringID = proxySensorConfig.id + "-sos";
dataProviderConfig.enabled = true;
sosConfig.dataProviders.add(dataProviderConfig);
@@ -326,12 +319,10 @@ protected void updateConfig(SharedPreferences prefs, String runName)
sensorhubConfig.add(sosConfig);
}
- private boolean isPushingSensor(Sensors sensor)
- {
+ private boolean isPushingSensor(Sensors sensor) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
- if (Sensors.Android.equals(sensor))
- {
+ if (Sensors.Android.equals(sensor)) {
if (prefs.getBoolean("accelerometer_enable", false)
&& prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
@@ -350,9 +341,7 @@ private boolean isPushingSensor(Sensors sensor)
if (prefs.getBoolean("video_enable", false)
&& prefs.getStringSet("video_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
- }
- else if (Sensors.TruPulse.equals(sensor) || Sensors.TruPulseSim.equals(sensor))
- {
+ } else if (Sensors.TruPulse.equals(sensor) || Sensors.TruPulseSim.equals(sensor)) {
if (prefs.getBoolean("trupulse_enable", false)
&& prefs.getStringSet("trupulse_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
@@ -361,8 +350,7 @@ else if (Sensors.TruPulse.equals(sensor) || Sensors.TruPulseSim.equals(sensor))
return false;
}
- private SensorDataProviderConfig createDataProviderConfig(AndroidSensorsConfig sensorConfig)
- {
+ private SensorDataProviderConfig createDataProviderConfig(AndroidSensorsConfig sensorConfig) {
SensorDataProviderConfig dataProviderConfig = new SensorDataProviderConfig();
dataProviderConfig.sensorID = sensorConfig.id;
dataProviderConfig.offeringID = sensorConfig.id + ":offering";
@@ -374,19 +362,14 @@ private SensorDataProviderConfig createDataProviderConfig(AndroidSensorsConfig s
return dataProviderConfig;
}
- private StreamStorageConfig createStreamStorageConfig(AndroidSensorsConfig sensorConfig)
- {
+ private StreamStorageConfig createStreamStorageConfig(AndroidSensorsConfig sensorConfig) {
// H2 Storage Config
- File dbFile = new File(getApplicationContext().getFilesDir()+"/db/", deviceID+"_h2.dat");
+ File dbFile = new File(getApplicationContext().getFilesDir() + "/db/", deviceID + "_h2.dat");
dbFile.getParentFile().mkdirs();
- if(!dbFile.exists())
- {
- try
- {
+ if (!dbFile.exists()) {
+ try {
dbFile.createNewFile();
- }
- catch (IOException e)
- {
+ } catch (IOException e) {
e.printStackTrace();
}
}
@@ -418,12 +401,10 @@ private StreamStorageConfig createStreamStorageConfig(AndroidSensorsConfig senso
return streamStorageConfig;
}
- private SensorConfig createSensorConfig(Sensors sensor)
- {
+ private SensorConfig createSensorConfig(Sensors sensor) {
SensorConfig sensorConfig;
- if (Sensors.Android.equals(sensor))
- {
+ if (Sensors.Android.equals(sensor)) {
sensorConfig = new AndroidSensorsConfig();
sensorConfig.id = "urn:android:device:" + deviceID;
sensorConfig.name = "Android Sensors [" + deviceName + "]";
@@ -434,18 +415,15 @@ private SensorConfig createSensorConfig(Sensors sensor)
((AndroidSensorsConfig) sensorConfig).activateAccelerometer = prefs.getBoolean("accelerometer_enable", false);
((AndroidSensorsConfig) sensorConfig).activateGyrometer = prefs.getBoolean("gyroscope_enable", false);
((AndroidSensorsConfig) sensorConfig).activateMagnetometer = prefs.getBoolean("magnetometer_enable", false);
- if (prefs.getBoolean("orientation_enable", false))
- {
+ if (prefs.getBoolean("orientation_enable", false)) {
((AndroidSensorsConfig) sensorConfig).activateOrientationQuat = prefs.getStringSet("orientation_angles", Collections.emptySet()).contains("QUATERNION");
((AndroidSensorsConfig) sensorConfig).activateOrientationEuler = prefs.getStringSet("orientation_angles", Collections.emptySet()).contains("EULER");
}
- if (prefs.getBoolean("location_enable", false))
- {
+ if (prefs.getBoolean("location_enable", false)) {
((AndroidSensorsConfig) sensorConfig).activateGpsLocation = prefs.getStringSet("location_type", Collections.emptySet()).contains("GPS");
((AndroidSensorsConfig) sensorConfig).activateNetworkLocation = prefs.getStringSet("location_type", Collections.emptySet()).contains("NETWORK");
}
- if (prefs.getBoolean("video_enable", false))
- {
+ if (prefs.getBoolean("video_enable", false)) {
showVideo = true;
((AndroidSensorsConfig) sensorConfig).activateBackCamera = true;
@@ -455,9 +433,7 @@ private SensorConfig createSensorConfig(Sensors sensor)
((AndroidSensorsConfig) sensorConfig).androidContext = this.getApplicationContext();
((AndroidSensorsConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
((AndroidSensorsConfig) sensorConfig).runName = runName;
- }
- else if (Sensors.TruPulse.equals(sensor))
- {
+ } else if (Sensors.TruPulse.equals(sensor)) {
sensorConfig = new TruPulseConfig();
sensorConfig.id = "TRUPULSE_SENSOR";
sensorConfig.name = "TruPulse Range Finder [" + deviceName + "]";
@@ -468,9 +444,7 @@ else if (Sensors.TruPulse.equals(sensor))
btConf.moduleClass = BluetoothCommProvider.class.getCanonicalName();
((TruPulseConfig) sensorConfig).commSettings = btConf;
((TruPulseConfig) sensorConfig).serialNumber = deviceID;
- }
- else if (Sensors.TruPulseSim.equals(sensor))
- {
+ } else if (Sensors.TruPulseSim.equals(sensor)) {
sensorConfig = new TruPulseConfig();
sensorConfig.id = "TRUPULSE_SENSOR_SIMULATED";
sensorConfig.name = "Simulated TruPulse Range Finder [" + deviceName + "]";
@@ -481,9 +455,7 @@ else if (Sensors.TruPulseSim.equals(sensor))
btConf.moduleClass = SimulatedDataStream.class.getCanonicalName();
((TruPulseConfig) sensorConfig).commSettings = btConf;
((TruPulseConfig) sensorConfig).serialNumber = deviceID;
- }
- else if (Sensors.Angel.equals(sensor))
- {
+ } else if (Sensors.Angel.equals(sensor)) {
sensorConfig = new AngelSensorConfig();
sensorConfig.id = "ANGEL_SENSOR";
sensorConfig.name = "Angel Sensor [" + deviceName + "]";
@@ -497,9 +469,7 @@ else if (Sensors.Angel.equals(sensor))
sensorhubConfig.add(bleConf);
((AngelSensorConfig) sensorConfig).networkID = bleConf.id;
- }
- else if (Sensors.FlirOne.equals(sensor))
- {
+ } else if (Sensors.FlirOne.equals(sensor)) {
sensorConfig = new FlirOneCameraConfig();
sensorConfig.id = "FLIRONE_SENSOR";
sensorConfig.name = "FLIR One Camera [" + deviceName + "]";
@@ -507,43 +477,33 @@ else if (Sensors.FlirOne.equals(sensor))
((FlirOneCameraConfig) sensorConfig).androidContext = this.getApplicationContext();
((FlirOneCameraConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
- }
- else if (Sensors.ProxySensor.equals(sensor))
- {
+ } else if (Sensors.ProxySensor.equals(sensor)) {
sensorConfig = new ProxySensorConfig();
- }
- else
- {
+ } else {
sensorConfig = new SensorConfig();
}
return sensorConfig;
}
- protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig storageConf)
- {
- if (sensorConf instanceof AndroidSensorsConfig)
- {
+ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig storageConf) {
+ if (sensorConf instanceof AndroidSensorsConfig) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
- SensorManager sensorManager = (SensorManager)getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
+ SensorManager sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
List deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
String sensorName;
- for (Sensor sensor: deviceSensors)
- {
- if (sensor.isWakeUpSensor())
- {
+ for (Sensor sensor : deviceSensors) {
+ if (sensor.isWakeUpSensor()) {
continue;
}
Log.d(TAG, "addStorageConfig: sensor: " + sensor.getName());
- switch (sensor.getType())
- {
+ switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
if (!prefs.getBoolean("accelerometer_enable", false)
- || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding accelerometer");
@@ -555,8 +515,7 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
break;
case Sensor.TYPE_GYROSCOPE:
if (!prefs.getBoolean("gyroscope_enable", false)
- || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding gyroscope");
@@ -568,8 +527,7 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
break;
case Sensor.TYPE_MAGNETIC_FIELD:
if (!prefs.getBoolean("magnetometer_enable", false)
- || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding magnetometer");
@@ -581,8 +539,7 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
break;
case Sensor.TYPE_ROTATION_VECTOR:
if (!prefs.getBoolean("orientation_enable", false)
- || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding orientation");
@@ -599,8 +556,7 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
}
}
if (!prefs.getBoolean("location_enable", false)
- || !prefs.getStringSet("location_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding location");
@@ -612,8 +568,7 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
Log.d(TAG, "addStorageConfig: NOT excluding location");
}
if (!prefs.getBoolean("video_enable", false)
- || !prefs.getStringSet("video_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("video_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding video");
@@ -629,28 +584,23 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
sensorhubConfig.add(storageConf);
}
- protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderConfig dataProviderConf)
- {
+ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderConfig dataProviderConf) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
- SensorManager sensorManager = (SensorManager)getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
+ SensorManager sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
List deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
String sensorName;
- for (Sensor sensor: deviceSensors)
- {
- if (sensor.isWakeUpSensor())
- {
+ for (Sensor sensor : deviceSensors) {
+ if (sensor.isWakeUpSensor()) {
continue;
}
Log.d(TAG, "addSosServerConfig: sensor: " + sensor.getName());
- switch (sensor.getType())
- {
+ switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
if (!prefs.getBoolean("accelerometer_enable", false)
- || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding accelerometer");
@@ -662,8 +612,7 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
break;
case Sensor.TYPE_GYROSCOPE:
if (!prefs.getBoolean("gyroscope_enable", false)
- || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding gyroscope");
@@ -675,8 +624,7 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
break;
case Sensor.TYPE_MAGNETIC_FIELD:
if (!prefs.getBoolean("magnetometer_enable", false)
- || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding magnetometer");
@@ -688,8 +636,7 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
break;
case Sensor.TYPE_ROTATION_VECTOR:
if (!prefs.getBoolean("orientation_enable", false)
- || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding orientation");
@@ -706,8 +653,7 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
}
}
if (!prefs.getBoolean("location_enable", false)
- || !prefs.getStringSet("location_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding location");
@@ -719,8 +665,7 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
Log.d(TAG, "addSosServerConfig: NOT excluding location");
}
if (!prefs.getBoolean("video_enable", false)
- || !prefs.getStringSet("video_options", Collections.emptySet()).contains("STORE_LOCAL"))
- {
+ || !prefs.getStringSet("video_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding video");
@@ -735,8 +680,7 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
sosConf.dataProviders.add(dataProviderConf);
}
- protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sosPwd)
- {
+ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sosPwd) {
if (sosUrl == null)
return;
@@ -755,28 +699,23 @@ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sos
sosConfig.connection.usePersistentConnection = true;
sosConfig.connection.reconnectAttempts = 9;
- if (sensorConf instanceof AndroidSensorsConfig)
- {
+ if (sensorConf instanceof AndroidSensorsConfig) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
- SensorManager sensorManager = (SensorManager)getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
+ SensorManager sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
List deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
String sensorName;
- for (Sensor sensor: deviceSensors)
- {
- if (sensor.isWakeUpSensor())
- {
+ for (Sensor sensor : deviceSensors) {
+ if (sensor.isWakeUpSensor()) {
continue;
}
Log.d(TAG, "addSosTConfig: sensor: " + sensor.getName());
- switch (sensor.getType())
- {
+ switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
if (!prefs.getBoolean("accelerometer_enable", false)
- || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("PUSH_REMOTE"))
- {
+ || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("PUSH_REMOTE")) {
Log.d(TAG, "addSosTConfig: excluding accelerometer");
@@ -788,8 +727,7 @@ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sos
break;
case Sensor.TYPE_GYROSCOPE:
if (!prefs.getBoolean("gyroscope_enable", false)
- || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("PUSH_REMOTE"))
- {
+ || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("PUSH_REMOTE")) {
Log.d(TAG, "addSosTConfig: excluding gyroscope");
@@ -801,8 +739,7 @@ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sos
break;
case Sensor.TYPE_MAGNETIC_FIELD:
if (!prefs.getBoolean("magnetometer_enable", false)
- || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("PUSH_REMOTE"))
- {
+ || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("PUSH_REMOTE")) {
Log.d(TAG, "addSosTConfig: excluding magnetometer");
@@ -814,8 +751,7 @@ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sos
break;
case Sensor.TYPE_ROTATION_VECTOR:
if (!prefs.getBoolean("orientation_enable", false)
- || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("PUSH_REMOTE"))
- {
+ || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("PUSH_REMOTE")) {
Log.d(TAG, "addSosTConfig: excluding orientation");
@@ -832,8 +768,7 @@ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sos
}
}
if (!prefs.getBoolean("location_enable", false)
- || !prefs.getStringSet("location_options", Collections.emptySet()).contains("PUSH_REMOTE"))
- {
+ || !prefs.getStringSet("location_options", Collections.emptySet()).contains("PUSH_REMOTE")) {
Log.d(TAG, "addSosTConfig: excluding location");
@@ -845,8 +780,7 @@ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sos
Log.d(TAG, "addSosTConfig: NOT excluding location");
}
if (!prefs.getBoolean("video_enable", false)
- || !prefs.getStringSet("video_options", Collections.emptySet()).contains("PUSH_REMOTE"))
- {
+ || !prefs.getStringSet("video_options", Collections.emptySet()).contains("PUSH_REMOTE")) {
Log.d(TAG, "addSosTConfig: excluding video");
@@ -865,8 +799,7 @@ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sos
@SuppressLint("HandlerLeak")
@Override
- protected void onCreate(Bundle savedInstanceState)
- {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textArea = (TextView) findViewById(R.id.text);
@@ -883,25 +816,78 @@ protected void onCreate(Bundle savedInstanceState)
displayHandler = new Handler(Looper.getMainLooper());
setupBroadcastReceivers();
+
+ // TODO: Integrate into BLEBeacon Sensor after POC
+ BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ Log.d(TAG, bluetoothAdapter.getName());
+ BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner();
+ ScanCallback scb = new ScanCallback() {
+ @Override
+ public void onScanResult(int callbackType, ScanResult result) {
+ super.onScanResult(callbackType, result);
+ Log.d(TAG, result.toString());
+ }
+ };
+ bleScanner.startScan(scb);
+
+
+ // Listen to and Log from nearby BLE beacons
+ /*int REQUEST_ENABLE_BT = 1; // Make sure this is the correct usage
+
+ BluetoothAdapter bluetoothAdapter;
+ // Initializes Bluetooth adapter.
+ final BluetoothManager bluetoothManager =
+ (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+ bluetoothAdapter = bluetoothManager.getAdapter();
+
+ // Ensures Bluetooth is available on the device and it is enabled. If not,
+ // displays a dialog requesting user permission to enable Bluetooth.
+ if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
+ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
+ }
+
+ final boolean[] mScanning = new boolean[1];
+ Handler handler = new Handler();
+ LeDeviceListAdapter leDeviceListAdapter;
+ BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
+ @Override
+ public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ leDe
+ }
+ });
+ }
+ };
+
+ final long SCAN_PERIOD = 10000;
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mScanning[0] = false;
+ bluetoothAdapter.stopLeScan(leScanCallback);
+ }
+ }, SCAN_PERIOD);
+
+ mScanning[0] = true;
+ bluetoothAdapter.startLeScan(leScanCallback);*/
}
private void setupBroadcastReceivers() {
- BroadcastReceiver receiver = new BroadcastReceiver()
- {
+ BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
- public void onReceive(Context context, Intent intent)
- {
+ public void onReceive(Context context, Intent intent) {
String origin = intent.getStringExtra("src");
- if (!context.getPackageName().equalsIgnoreCase(origin))
- {
+ if (!context.getPackageName().equalsIgnoreCase(origin)) {
String sosEndpointUrl = intent.getStringExtra("sosEndpointUrl");
String name = intent.getStringExtra("name");
String sensorId = intent.getStringExtra("sensorId");
ArrayList properties = intent.getStringArrayListExtra("properties");
- if (sosEndpointUrl== null || name == null || sensorId == null || properties.size() == 0)
- {
+ if (sosEndpointUrl == null || name == null || sensorId == null || properties.size() == 0) {
return;
}
@@ -942,33 +928,26 @@ public void onReceive(Context context, Intent intent)
@Override
- public boolean onCreateOptionsMenu(Menu menu)
- {
+ public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
- public boolean onOptionsItemSelected(MenuItem item)
- {
+ public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
- if (id == R.id.action_settings)
- {
+ if (id == R.id.action_settings) {
startActivity(new Intent(this, UserSettingsActivity.class));
return true;
- }
- else if (id == R.id.action_start)
- {
+ } else if (id == R.id.action_start) {
if (boundService != null && boundService.getSensorHub() == null)
showRunNamePopup();
return true;
- }
- else if (id == R.id.action_stop)
- {
+ } else if (id == R.id.action_stop) {
stopListeningForEvents();
stopRefreshingStatus();
sostClients.clear();
@@ -979,16 +958,11 @@ else if (id == R.id.action_stop)
newStatusMessage("SensorHub Stopped");
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
return true;
- }
- else if (id == R.id.action_about)
- {
+ } else if (id == R.id.action_about) {
showAboutPopup();
- }
- else if (id == R.id.action_proxy)
- {
+ } else if (id == R.id.action_proxy) {
testProxyBroadcast();
- }
- else if(id == R.id.action_stop_proxy){
+ } else if (id == R.id.action_stop_proxy) {
testStopProxyBroadcast();
}
@@ -996,8 +970,7 @@ else if(id == R.id.action_stop_proxy){
}
- protected void showRunNamePopup()
- {
+ protected void showRunNamePopup() {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("Run Name");
@@ -1010,10 +983,8 @@ protected void showRunNamePopup()
input.getText().append(formatter.format(new Date()));
alert.setView(input);
- alert.setPositiveButton("Ok", new DialogInterface.OnClickListener()
- {
- public void onClick(DialogInterface dialog, int whichButton)
- {
+ alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
runName = input.getText().toString();
newStatusMessage("Starting SensorHub...");
@@ -1036,17 +1007,13 @@ public void onClick(DialogInterface dialog, int whichButton) {
}
- protected void showAboutPopup()
- {
+ protected void showAboutPopup() {
String version = "?";
- try
- {
+ try {
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
version = pInfo.versionName;
- }
- catch (PackageManager.NameNotFoundException e)
- {
+ } catch (PackageManager.NameNotFoundException e) {
}
String message = "A software platform for building smart sensor networks and the Internet of Things\n\n";
@@ -1060,8 +1027,7 @@ protected void showAboutPopup()
}
- protected void testProxyBroadcast()
- {
+ protected void testProxyBroadcast() {
ArrayList testProperties = new ArrayList();
testProperties.add("http://sensorml.com/ont/swe/property/Acceleration");
testProperties.add("http://sensorml.com/ont/swe/property/MagneticField");
@@ -1077,32 +1043,27 @@ protected void testProxyBroadcast()
sendBroadcast(testIntent);
}
- protected void testStopProxyBroadcast(){
+ protected void testStopProxyBroadcast() {
Intent testIntent = new Intent();
testIntent.setAction("org.sofwerx.ogc.ACTION_PROXY");
sendBroadcast(testIntent);
}
@Override
- public void handleEvent(Event> e)
- {
- if (e instanceof ModuleEvent)
- {
+ public void handleEvent(Event> e) {
+ if (e instanceof ModuleEvent) {
// start refreshing status on first module loaded
- if (!oshStarted && ((ModuleEvent) e).getType() == ModuleEvent.Type.LOADED)
- {
+ if (!oshStarted && ((ModuleEvent) e).getType() == ModuleEvent.Type.LOADED) {
oshStarted = true;
startRefreshingStatus();
return;
}
// detect when SOS-T modules are connected
- else if (e.getSource() instanceof SOSTClient && ((ModuleEvent)e).getType() == ModuleEvent.Type.STATE_CHANGED)
- {
- switch (((ModuleEvent)e).getNewState())
- {
+ else if (e.getSource() instanceof SOSTClient && ((ModuleEvent) e).getType() == ModuleEvent.Type.STATE_CHANGED) {
+ switch (((ModuleEvent) e).getNewState()) {
case INITIALIZING:
- sostClients.add((SOSTClient)e.getSource());
+ sostClients.add((SOSTClient) e.getSource());
break;
}
}
@@ -1110,16 +1071,13 @@ else if (e.getSource() instanceof SOSTClient && ((ModuleEvent)e).getType() == Mo
}
- protected void startRefreshingStatus()
- {
+ protected void startRefreshingStatus() {
if (displayCallback != null)
return;
// handler to display async messages in UI
- displayCallback = new Runnable()
- {
- public void run()
- {
+ displayCallback = new Runnable() {
+ public void run() {
displayStatus();
textArea.setText(Html.fromHtml(displayText.toString()));
displayHandler.postDelayed(this, 1000);
@@ -1130,34 +1088,28 @@ public void run()
}
- protected void stopRefreshingStatus()
- {
- if (displayCallback != null)
- {
+ protected void stopRefreshingStatus() {
+ if (displayCallback != null) {
displayHandler.removeCallbacks(displayCallback);
displayCallback = null;
}
}
- protected synchronized void displayStatus()
- {
+ protected synchronized void displayStatus() {
displayText.setLength(0);
// first display error messages if any
- for (SOSTClient client: sostClients)
- {
+ for (SOSTClient client : sostClients) {
Map dataStreams = client.getDataStreams();
boolean showError = (client.getCurrentError() != null);
boolean showMsg = (dataStreams.size() == 0) && (client.getStatusMessage() != null);
- if (showError || showMsg)
- {
+ if (showError || showMsg) {
displayText.append("
" + client.getName() + ": ");
if (showMsg)
displayText.append(client.getStatusMessage() + " ");
- if (showError)
- {
+ if (showError) {
Throwable errorObj = client.getCurrentError();
String errorMsg = errorObj.getMessage().trim();
if (!errorMsg.endsWith("."))
@@ -1172,13 +1124,11 @@ protected synchronized void displayStatus()
// then display streams status
displayText.append("
");
- for (SOSTClient client: sostClients)
- {
+ for (SOSTClient client : sostClients) {
Map dataStreams = client.getDataStreams();
long now = System.currentTimeMillis();
- for (Entry stream : dataStreams.entrySet())
- {
+ for (Entry stream : dataStreams.entrySet()) {
displayText.append("" + stream.getKey().getName() + " : ");
long lastEventTime = stream.getValue().lastEventTime;
@@ -1190,8 +1140,7 @@ else if (dt > stream.getValue().measPeriodMs)
else
displayText.append("OK (" + dt + "ms ago)");
- if (stream.getValue().errorCount > 0)
- {
+ if (stream.getValue().errorCount > 0) {
displayText.append(" (");
displayText.append(stream.getValue().errorCount);
displayText.append(")");
@@ -1202,34 +1151,29 @@ else if (dt > stream.getValue().measPeriodMs)
}
if (displayText.length() > 5)
- displayText.setLength(displayText.length()-5); // remove last
+ displayText.setLength(displayText.length() - 5); // remove last
displayText.append("
");
}
- protected synchronized void newStatusMessage(String msg)
- {
+ protected synchronized void newStatusMessage(String msg) {
displayText.setLength(0);
appendStatusMessage(msg);
}
- protected synchronized void appendStatusMessage(String msg)
- {
+ protected synchronized void appendStatusMessage(String msg) {
displayText.append(msg);
- displayHandler.post(new Runnable()
- {
- public void run()
- {
+ displayHandler.post(new Runnable() {
+ public void run() {
textArea.setText(displayText.toString());
}
});
}
- protected void startListeningForEvents()
- {
+ protected void startListeningForEvents() {
if (boundService == null || boundService.getSensorHub() == null)
return;
@@ -1237,8 +1181,7 @@ protected void startListeningForEvents()
}
- protected void stopListeningForEvents()
- {
+ protected void stopListeningForEvents() {
if (boundService == null || boundService.getSensorHub() == null)
return;
@@ -1246,10 +1189,8 @@ protected void stopListeningForEvents()
}
- protected void showVideo()
- {
- if (boundService.getVideoTexture() != null)
- {
+ protected void showVideo() {
+ if (boundService.getVideoTexture() != null) {
TextureView textureView = (TextureView) findViewById(R.id.video);
if (textureView.getSurfaceTexture() != boundService.getVideoTexture())
textureView.setSurfaceTexture(boundService.getVideoTexture());
@@ -1257,28 +1198,24 @@ protected void showVideo()
}
- protected void hideVideo()
- {
+ protected void hideVideo() {
}
@Override
- protected void onStart()
- {
+ protected void onStart() {
super.onStart();
}
@Override
- protected void onResume()
- {
+ protected void onResume() {
super.onResume();
TextureView textureView = (TextureView) findViewById(R.id.video);
textureView.setSurfaceTextureListener(this);
- if (oshStarted)
- {
+ if (oshStarted) {
startListeningForEvents();
startRefreshingStatus();
@@ -1289,8 +1226,7 @@ protected void onResume()
@Override
- protected void onPause()
- {
+ protected void onPause() {
stopListeningForEvents();
stopRefreshingStatus();
hideVideo();
@@ -1299,8 +1235,7 @@ protected void onPause()
@Override
- protected void onStop()
- {
+ protected void onStop() {
stopListeningForEvents();
stopRefreshingStatus();
super.onStop();
@@ -1308,35 +1243,99 @@ protected void onStop()
@Override
- protected void onDestroy()
- {
+ protected void onDestroy() {
stopService(new Intent(this, SensorHubService.class));
super.onDestroy();
}
@Override
- public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1)
- {
+ public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
showVideo();
}
@Override
- public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1)
- {
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture)
- {
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
- public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture)
- {
+ public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
}
+
+
+// TODO: Deal with this in BLEBeacon's own module later
+
+
+/*
+public class LeDeviceListAdapter extends BaseAdapter {
+ private ArrayList mLeDevices;
+ private LayoutInflater mInflator;
+
+
+ public LeDeviceListAdapter() {
+ super();
+ mLeDevices = new ArrayList();
+ mInflator = this.getLayoutInflater();
+ }
+
+ public void addDevice(BluetoothDevice device) {
+ if (!mLeDevices.contains(device)) {
+ mLeDevices.add(device);
+ }
+ }
+
+ public BluetoothDevice getDevice(int position) {
+ return mLeDevices.get(position);
+ }
+
+ public void clear() {
+ mLeDevices.clear();
+ }
+
+ @Override
+ public int getCount() {
+ return mLeDevices.size();
+ }
+
+ @Override
+ public Object getItem(int i) {
+ return mLeDevices.get(i);
+ }
+
+ @Override
+ public long getItemId(int i) {
+ return i;
+ }
+
+ @Override
+ public View getView(int i, View view, ViewGroup viewGroup) {
+ ViewHolder viewHolder;
+ // General ListView optimization code.
+ if (view == null) {
+ view = mInflator.inflate(R.layout.listitem_device, null);
+ viewHolder = new ViewHolder();
+ viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
+ viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
+ view.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) view.getTag();
+ }
+ BluetoothDevice device = mLeDevices.get(i);
+ final String deviceName = device.getName();
+ if (deviceName != null && deviceName.length() > 0)
+ viewHolder.deviceName.setText(deviceName);
+ else
+ viewHolder.deviceName.setText(R.string.unknown_device);
+ viewHolder.deviceAddress.setText(device.getAddress());
+ return view;
+ }
+}*/
diff --git a/sensorhub-android-blebeacon/.gitignore b/sensorhub-android-blebeacon/.gitignore
new file mode 100644
index 00000000..796b96d1
--- /dev/null
+++ b/sensorhub-android-blebeacon/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/sensorhub-android-blebeacon/build.gradle b/sensorhub-android-blebeacon/build.gradle
new file mode 100644
index 00000000..6ccfe595
--- /dev/null
+++ b/sensorhub-android-blebeacon/build.gradle
@@ -0,0 +1,34 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 28
+
+
+ defaultConfig {
+ minSdkVersion 22
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles 'consumer-rules.pro'
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+ compile project(path: ':sensorhub-core')
+}
diff --git a/sensorhub-android-blebeacon/consumer-rules.pro b/sensorhub-android-blebeacon/consumer-rules.pro
new file mode 100644
index 00000000..e69de29b
diff --git a/sensorhub-android-blebeacon/docs/BLEDoc.txt b/sensorhub-android-blebeacon/docs/BLEDoc.txt
new file mode 100644
index 00000000..32ebfb29
--- /dev/null
+++ b/sensorhub-android-blebeacon/docs/BLEDoc.txt
@@ -0,0 +1,12 @@
+The BLE Beacon Sensor is a work in progress module designed to use the URL String gathered from
+BLE Beacons using the Eddystone URL protocol with known locations to give an approximate location of
+the phone when indoors.
+
+MODULE MUST:
+1. Have a constellation of registered Beacons with UIDs that have known locations
+2. Be able to triangulate based on the three strongest signals
+3. Have the ability to add a new registered beacon through the App
+4. Have the ability to remove a registered beacon through the app
+
+OPTIONAL:
+1. Notify that a beacon has low battery life
\ No newline at end of file
diff --git a/sensorhub-android-blebeacon/proguard-rules.pro b/sensorhub-android-blebeacon/proguard-rules.pro
new file mode 100644
index 00000000..f1b42451
--- /dev/null
+++ b/sensorhub-android-blebeacon/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/sensorhub-android-blebeacon/src/androidTest/java/org/sensorhub/impl/sensor/blebeacon/ExampleInstrumentedTest.java b/sensorhub-android-blebeacon/src/androidTest/java/org/sensorhub/impl/sensor/blebeacon/ExampleInstrumentedTest.java
new file mode 100644
index 00000000..50c2ab2d
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/androidTest/java/org/sensorhub/impl/sensor/blebeacon/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package org.sensorhub.impl.sensor.blebeacon;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+ assertEquals("org.sensorhub.impl.sensor.blebeacon.test", appContext.getPackageName());
+ }
+}
diff --git a/sensorhub-android-blebeacon/src/main/AndroidManifest.xml b/sensorhub-android-blebeacon/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..0a6f2047
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconConfig.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconConfig.java
new file mode 100644
index 00000000..fdca8b59
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconConfig.java
@@ -0,0 +1,6 @@
+package org.sensorhub.impl.sensor.blebeacon;
+
+import org.sensorhub.api.sensor.SensorConfig;
+
+public class BLEBeaconConfig extends SensorConfig {
+}
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLETest.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLETest.java
new file mode 100644
index 00000000..55a44d33
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLETest.java
@@ -0,0 +1,4 @@
+package org.sensorhub.impl.sensor.blebeacon;
+
+public class BLETest {
+}
diff --git a/sensorhub-android-blebeacon/src/main/res/values/strings.xml b/sensorhub-android-blebeacon/src/main/res/values/strings.xml
new file mode 100644
index 00000000..78b089d9
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ sensorhub-android-blebeacon
+
diff --git a/sensorhub-android-blebeacon/src/test/java/org/sensorhub/impl/sensor/blebeacon/ExampleUnitTest.java b/sensorhub-android-blebeacon/src/test/java/org/sensorhub/impl/sensor/blebeacon/ExampleUnitTest.java
new file mode 100644
index 00000000..5ee2a7eb
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/test/java/org/sensorhub/impl/sensor/blebeacon/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package org.sensorhub.impl.sensor.blebeacon;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 3c0d243b..707c30e5 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,3 +1,4 @@
+include ':sensorhub-android-blebeacon'
rootProject.name = 'osh-android'
def oshMainDir = "$rootDir/.."
From 9e419e36062b475bd99683ed5823d243c2daba9b Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 3 Oct 2019 14:55:50 -0500
Subject: [PATCH 079/207] Implementing BLE Beacon Sensor Driver
---
sensorhub-android-blebeacon/build.gradle | 1 +
.../impl/sensor/blebeacon/BLEBeacon.java | 96 +++++++++++++++++
.../sensor/blebeacon/BLEBeaconConfig.java | 20 ++++
.../sensor/blebeacon/BLEBeaconDriver.java | 70 ++++++++++++
.../sensor/blebeacon/BLEBeaconRawOutput.java | 100 ++++++++++++++++++
.../impl/sensor/blebeacon/BLETest.java | 4 -
6 files changed, 287 insertions(+), 4 deletions(-)
create mode 100644 sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeacon.java
create mode 100644 sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconDriver.java
create mode 100644 sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconRawOutput.java
delete mode 100644 sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLETest.java
diff --git a/sensorhub-android-blebeacon/build.gradle b/sensorhub-android-blebeacon/build.gradle
index 6ccfe595..e4e35ea8 100644
--- a/sensorhub-android-blebeacon/build.gradle
+++ b/sensorhub-android-blebeacon/build.gradle
@@ -31,4 +31,5 @@ dependencies {
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
compile project(path: ':sensorhub-core')
+ compile 'org.altbeacon:android-beacon-library:2.16.2'
}
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeacon.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeacon.java
new file mode 100644
index 00000000..1d65ee3b
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeacon.java
@@ -0,0 +1,96 @@
+package org.sensorhub.impl.sensor.blebeacon;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.RemoteException;
+import android.util.Log;
+
+import org.altbeacon.beacon.Beacon;
+import org.altbeacon.beacon.BeaconConsumer;
+import org.altbeacon.beacon.BeaconManager;
+import org.altbeacon.beacon.BeaconParser;
+import org.altbeacon.beacon.Identifier;
+import org.altbeacon.beacon.RangeNotifier;
+import org.altbeacon.beacon.Region;
+import org.altbeacon.beacon.utils.UrlBeaconUrlCompressor;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class BLEBeacon implements BeaconConsumer, RangeNotifier {
+ private Context parentContext;
+ private String TAG = "BLEBeacon-DeafultTAG";
+ private BeaconManager mBeaconManager;
+ private Map beacons;
+
+ public BLEBeacon(Context context){
+ this.parentContext = context;
+ this.beacons = new HashMap();
+ }
+
+ public void BeaconManagerSetup(){
+ mBeaconManager = BeaconManager.getInstanceForApplication(parentContext);
+ // Detect the URL frame:
+ mBeaconManager.getBeaconParsers().add(new BeaconParser().
+ setBeaconLayout(BeaconParser.EDDYSTONE_URL_LAYOUT));
+ mBeaconManager.bind(this);
+ }
+
+ public void unbind(){
+ try {
+ mBeaconManager.stopRangingBeaconsInRegion(new Region("all-beacons-region", null, null, null));
+ } catch (RemoteException e){
+ Log.d(TAG, "unbind: " + e);
+ }
+
+ mBeaconManager.unbind(this);
+ }
+
+ @Override
+ public void onBeaconServiceConnect() {
+ Region region = new Region("all-beacons-region", null, null, null);
+ try {
+ mBeaconManager.startRangingBeaconsInRegion(region);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ mBeaconManager.setRangeNotifier(this);
+ }
+
+ @Override
+ public Context getApplicationContext() {
+ return this.parentContext;
+ }
+
+ @Override
+ public void unbindService(ServiceConnection serviceConnection) {
+
+ }
+
+ @Override
+ public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
+ return false;
+ }
+
+ @Override
+ public void didRangeBeaconsInRegion(Collection beacons, Region region) {
+ for (Beacon beacon: beacons) {
+ if (beacon.getServiceUuid() == 0xfeaa && beacon.getBeaconTypeCode() == 0x10) {
+ // This is an Eddystone-URL frame
+ String url = UrlBeaconUrlCompressor.uncompress(beacon.getId1().toByteArray());
+ Log.d(TAG, "Beacon ID: "+ beacon.getId1() + "Beacon URL: " + url +
+ " approximately " + beacon.getDistance() + " meters away.");
+ // TODO: Need to improve this to handle non-EsURL beacons that have info in the other ID slots
+ this.beacons.put(beacon.getId1(), beacon);
+ }
+ }
+ }
+
+ public void printBeaconList(){
+ Log.d(TAG, "printBeaconList: " + this.beacons);
+ }
+
+
+}
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconConfig.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconConfig.java
index fdca8b59..a898bdf1 100644
--- a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconConfig.java
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconConfig.java
@@ -1,6 +1,26 @@
package org.sensorhub.impl.sensor.blebeacon;
+import android.content.Context;
+
+import org.sensorhub.api.module.ModuleConfig;
import org.sensorhub.api.sensor.SensorConfig;
public class BLEBeaconConfig extends SensorConfig {
+ public boolean activateBLEBeacon = false;
+
+ public String deviceName;
+ public String runName;
+ public String runDescription;
+
+ public transient Context androidContext;
+
+ public BLEBeaconConfig(){
+ this.moduleClass = BLEBeaconDriver.class.getCanonicalName();
+ }
+
+ // clone disabled as it causes crashes for now
+ @Override
+ public ModuleConfig clone(){
+ return this;
+ }
}
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconDriver.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconDriver.java
new file mode 100644
index 00000000..8e735d49
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconDriver.java
@@ -0,0 +1,70 @@
+package org.sensorhub.impl.sensor.blebeacon;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.location.LocationManager;
+import android.os.Build;
+import android.os.HandlerThread;
+import android.provider.Settings;
+
+import net.opengis.sensorml.v20.PhysicalComponent;
+
+import org.sensorhub.api.common.SensorHubException;
+import org.sensorhub.api.sensor.ISensorDataInterface;
+import org.sensorhub.impl.sensor.AbstractSensorModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+public class BLEBeaconDriver extends AbstractSensorModule {
+ private static final Logger log = LoggerFactory.getLogger(BLEBeaconDriver.class.getSimpleName());
+ public static final String LOCAL_REF_FRAME = "LOCAL_FRAME";
+
+ String localFrameURI;
+ HandlerThread eventThread;
+ SensorManager sensorManager;
+ LocationManager locationManager;
+// SensorMLBuilder sensorMLBuilder;
+ List smlComponents;
+ BLEBeaconRawOutput rawOutput;
+
+ public BLEBeaconDriver(){}
+
+ @Override
+ public synchronized void init() throws SensorHubException{
+ Context androidContext = config.androidContext;
+
+ String deviceID = Settings.Secure.getString(androidContext.getContentResolver(), Settings.Secure.ANDROID_ID);
+ this.xmlID = "ANDROID_SENSORS_" + Build.SERIAL; // Deprecated in API level 26
+ this.uniqueID = "urn:android:device:" + deviceID;
+ this.localFrameURI = this.uniqueID + "#" + LOCAL_REF_FRAME;
+
+ rawOutput = new BLEBeaconRawOutput(this);
+ addOutput(rawOutput, false);
+ }
+
+ @Override
+ public void start() throws SensorHubException {
+ // start the BLEBeacon Manager scanning
+
+ }
+
+ @Override
+ public void stop() throws SensorHubException {
+
+ }
+
+ protected void useSensor(ISensorDataInterface output, Sensor sensor){
+ addOutput(output, false);
+ }
+
+ @Override
+ public boolean isConnected() {
+ return true;
+ }
+
+ @Override
+ public Logger getLogger(){return log;}
+}
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconRawOutput.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconRawOutput.java
new file mode 100644
index 00000000..bfa8c7fe
--- /dev/null
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconRawOutput.java
@@ -0,0 +1,100 @@
+package org.sensorhub.impl.sensor.blebeacon;
+
+import android.hardware.SensorEventListener;
+import android.os.Handler;
+
+import net.opengis.swe.v20.DataBlock;
+import net.opengis.swe.v20.DataComponent;
+import net.opengis.swe.v20.DataEncoding;
+
+import org.sensorhub.api.sensor.SensorDataEvent;
+import org.sensorhub.impl.sensor.AbstractSensorOutput;
+import org.vast.swe.SWEHelper;
+
+public class BLEBeaconRawOutput extends AbstractSensorOutput implements {
+ private static final String BLE_BEACON_DEF = "http://sensorml.com/ont/swe/property/BLEBeacon";
+ private static final String URL_DEF = "http://sensorml.com/ont/swe/property/";
+
+ String name = "BLE Beacon Raw Data";
+ boolean enabled;
+ DataComponent bleData;
+ DataEncoding dataEncoding;
+ double samplingPeriod;
+ long systemTimeOffset = -1L;
+ BLEBeacon bleBeacon;
+
+
+ protected BLEBeaconRawOutput(BLEBeaconDriver parent) {
+ super(parent);
+
+ // create output structure
+ SWEHelper fac = new SWEHelper();
+ bleData = fac.newDataRecord();
+ bleData.setName(getName());
+ bleData.setDefinition(BLE_BEACON_DEF);
+ bleData.setDescription("Bluetooth Low Energy Beacon readings for commonly available data");
+
+ // add fields
+ bleData.addComponent("time", fac.newTimeStampIsoUTC());
+ bleData.addComponent("id", fac.newCategory("http://sensorml.com/ont/swe/property/SensorID", null, null, null));
+ bleData.addComponent("name", fac.newText(URL_DEF + "name", null, null));
+ bleData.addComponent("ID1", fac.newText(URL_DEF + "Identifier_1", null, "First of the three ids used by most BLE beacons, in ES-URL, the only id"));
+ bleData.addComponent("ID2", fac.newText(URL_DEF + "Identifier_2", null, null));
+ bleData.addComponent("ID3", fac.newText(URL_DEF + "Identifier_3", null, null));
+ bleData.addComponent("txPower", fac.newQuantity(URL_DEF + "txPower", null, null, "dBm"));
+ bleData.addComponent("RSSI", fac.newQuantity(URL_DEF + "rssi", null, null, "dBm")); // Is this value measured, and is it affected by the settings in the beacon
+ bleData.addComponent("distance", fac.newQuantity(URL_DEF + "distance", null, null, "m"));
+
+ dataEncoding = fac.newTextEncoding(",", "\n");
+
+ // Other fields that can be added
+ // Extra Data Fields
+ // Manufacturer
+ // Service UUID
+ // MultiFrameBeacon
+ // Parser Identifier // Note: this is part of ABL, not the beacon itself
+
+ // BLEBeacon Initialization
+ bleBeacon = new BLEBeacon(parent.getConfiguration().androidContext);
+ }
+
+ private void sendMeasurement(){
+ // Get the data from the beacon manager
+ // Build the DataBlock
+ DataBlock dataBlock = bleData.createDataBlock();
+// dataBlock.setDoubleValue(0, time);
+
+ // Push Data
+ latestRecord = dataBlock;
+ latestRecordTime = System.currentTimeMillis();
+ eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, BLEBeaconRawOutput.this, latestRecord));
+ }
+
+ public void start(Handler handler){
+ bleBeacon.BeaconManagerSetup();
+ }
+
+ public void stop(){
+ bleBeacon.unbind();
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public DataComponent getRecordDescription() {
+ return bleData;
+ }
+
+ @Override
+ public DataEncoding getRecommendedEncoding() {
+ return dataEncoding;
+ }
+
+ @Override
+ public double getAverageSamplingPeriod() {
+ return 0; // TODO: implement a calculation for this
+ }
+}
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLETest.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLETest.java
deleted file mode 100644
index 55a44d33..00000000
--- a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLETest.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package org.sensorhub.impl.sensor.blebeacon;
-
-public class BLETest {
-}
From b6b567b63811dc7fe3dbb6803503e888113e3b2e Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 3 Oct 2019 15:30:44 -0500
Subject: [PATCH 080/207] Migrate previous code into BLEBeaconRawOutput for
ease of handling for now
---
.../impl/sensor/blebeacon/BLEBeacon.java | 2 +-
.../sensor/blebeacon/BLEBeaconRawOutput.java | 104 ++++++++++++++++--
2 files changed, 97 insertions(+), 9 deletions(-)
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeacon.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeacon.java
index 1d65ee3b..eb9c3317 100644
--- a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeacon.java
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeacon.java
@@ -21,7 +21,7 @@
public class BLEBeacon implements BeaconConsumer, RangeNotifier {
private Context parentContext;
- private String TAG = "BLEBeacon-DeafultTAG";
+ private String TAG = "BLEBeacon-DefaultTAG";
private BeaconManager mBeaconManager;
private Map beacons;
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconRawOutput.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconRawOutput.java
index bfa8c7fe..74133506 100644
--- a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconRawOutput.java
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconRawOutput.java
@@ -1,7 +1,12 @@
package org.sensorhub.impl.sensor.blebeacon;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
import android.hardware.SensorEventListener;
import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
import net.opengis.swe.v20.DataBlock;
import net.opengis.swe.v20.DataComponent;
@@ -11,9 +16,23 @@
import org.sensorhub.impl.sensor.AbstractSensorOutput;
import org.vast.swe.SWEHelper;
-public class BLEBeaconRawOutput extends AbstractSensorOutput implements {
+import org.altbeacon.beacon.Beacon;
+import org.altbeacon.beacon.BeaconConsumer;
+import org.altbeacon.beacon.BeaconManager;
+import org.altbeacon.beacon.BeaconParser;
+import org.altbeacon.beacon.Identifier;
+import org.altbeacon.beacon.RangeNotifier;
+import org.altbeacon.beacon.Region;
+import org.altbeacon.beacon.utils.UrlBeaconUrlCompressor;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class BLEBeaconRawOutput extends AbstractSensorOutput implements BeaconConsumer, RangeNotifier {
private static final String BLE_BEACON_DEF = "http://sensorml.com/ont/swe/property/BLEBeacon";
private static final String URL_DEF = "http://sensorml.com/ont/swe/property/";
+ private static final String TAG = "BLEBeaconOutputRaw";
String name = "BLE Beacon Raw Data";
boolean enabled;
@@ -21,7 +40,9 @@ public class BLEBeaconRawOutput extends AbstractSensorOutput im
DataEncoding dataEncoding;
double samplingPeriod;
long systemTimeOffset = -1L;
- BLEBeacon bleBeacon;
+
+ BeaconManager mBeaconManager;
+ private Map beacons;
protected BLEBeaconRawOutput(BLEBeaconDriver parent) {
@@ -53,9 +74,6 @@ protected BLEBeaconRawOutput(BLEBeaconDriver parent) {
// Service UUID
// MultiFrameBeacon
// Parser Identifier // Note: this is part of ABL, not the beacon itself
-
- // BLEBeacon Initialization
- bleBeacon = new BLEBeacon(parent.getConfiguration().androidContext);
}
private void sendMeasurement(){
@@ -70,12 +88,21 @@ private void sendMeasurement(){
eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, BLEBeaconRawOutput.this, latestRecord));
}
- public void start(Handler handler){
- bleBeacon.BeaconManagerSetup();
+ public void start(){
+ // BLE Beacon Initialization
+ mBeaconManager = BeaconManager.getInstanceForApplication(getParentModule().getConfiguration().androidContext);
+ mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_URL_LAYOUT));
+ mBeaconManager.bind(this);
}
public void stop(){
- bleBeacon.unbind();
+ try {
+ mBeaconManager.stopRangingBeaconsInRegion(new Region("url-beacons-region", null, null, null));
+ } catch (RemoteException e){
+ Log.d(TAG, "unbind: " + e);
+ }
+
+ mBeaconManager.unbind(this);
}
@Override
@@ -97,4 +124,65 @@ public DataEncoding getRecommendedEncoding() {
public double getAverageSamplingPeriod() {
return 0; // TODO: implement a calculation for this
}
+
+ // BLE Beacon Consumer/Range Notifier Require Implementations
+ @Override
+ public void onBeaconServiceConnect() {
+ Region region = new Region("all-beacons-region", null, null, null);
+ try {
+ mBeaconManager.startRangingBeaconsInRegion(region);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ mBeaconManager.setRangeNotifier(this);
+ }
+
+ @Override
+ public Context getApplicationContext() {
+ return getParentModule().getConfiguration().androidContext;
+ }
+
+ @Override
+ public void unbindService(ServiceConnection serviceConnection) {
+
+ }
+
+ @Override
+ public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
+ return false;
+ }
+
+ @Override
+ public void didRangeBeaconsInRegion(Collection beacons, Region region) {
+ for (Beacon beacon: beacons) {
+ if (beacon.getServiceUuid() == 0xfeaa && beacon.getBeaconTypeCode() == 0x10) {
+ // This is an Eddystone-URL frame
+ String url = UrlBeaconUrlCompressor.uncompress(beacon.getId1().toByteArray());
+ Log.d(TAG, "Beacon ID: "+ beacon.getId1() + "Beacon URL: " + url +
+ " approximately " + beacon.getDistance() + " meters away.");
+ // TODO: Need to improve this to handle non-EsURL beacons that have info in the other ID slots
+ this.beacons.put(beacon.getId1(), beacon);
+ sendBeaconRecord(beacon);
+ }
+ }
+ }
+
+ public void sendBeaconRecord(Beacon beacon){
+ double time = System.currentTimeMillis() / 1000.;
+ DataBlock dataBlock = bleData.createDataBlock();
+
+ dataBlock.setDoubleValue(0, time);
+ dataBlock.setStringValue(1, "test-ble-beacon-id");
+ dataBlock.setStringValue(2, beacon.getBluetoothName());
+ dataBlock.setStringValue(3, beacon.getId1().toString());
+ dataBlock.setStringValue(4, beacon.getId2().toString());
+ dataBlock.setStringValue(5, beacon.getId3().toString());
+ dataBlock.setDoubleValue(6, beacon.getTxPower());
+ dataBlock.setDoubleValue(7, beacon.getRssi());
+ dataBlock.setDoubleValue(8, beacon.getDistance());
+
+ // Push the data
+ latestRecordTime = System.currentTimeMillis();
+ eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, BLEBeaconRawOutput.this, dataBlock));
+ }
}
From 61fb7dcc5a9c5e0e978d3a0e07e1c9c84a78779c Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 3 Oct 2019 17:06:55 -0500
Subject: [PATCH 081/207] Add BLE Beacon to MainActivity
---
.../src/org/sensorhub/android/MainActivity.java | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 693adf17..665938ec 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -68,6 +68,7 @@
import org.sensorhub.impl.persistence.h2.MVStorageConfig;
import org.sensorhub.impl.sensor.android.AndroidSensorsConfig;
import org.sensorhub.impl.sensor.angel.AngelSensorConfig;
+import org.sensorhub.impl.sensor.blebeacon.BLEBeaconConfig;
import org.sensorhub.impl.sensor.swe.ProxySensor.ProxySensor;
import org.sensorhub.impl.sensor.swe.ProxySensor.ProxySensorConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
@@ -479,6 +480,14 @@ private SensorConfig createSensorConfig(Sensors sensor) {
((FlirOneCameraConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
} else if (Sensors.ProxySensor.equals(sensor)) {
sensorConfig = new ProxySensorConfig();
+ }else if(true){
+ // TODO: Add option to UI after testing
+ // Add the BLE Beacon Scanner
+ sensorConfig = new BLEBeaconConfig();
+ sensorConfig.id = "BLE_BEACON_SCANNER";
+ sensorConfig.name = "BLE Beacon Scanner [" + deviceName + "]";
+ sensorConfig.autoStart = true;
+ Log.d(TAG, "createSensorConfig: Added BLE Beacon Scanner");
} else {
sensorConfig = new SensorConfig();
}
From 0af5001c7bb57729f5bd402ea2f014b8465ee28f Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 3 Oct 2019 21:44:47 -0500
Subject: [PATCH 082/207] Pull BLE back out, trying to resolve dependency
duplication issues
---
.../org/sensorhub/android/MainActivity.java | 225 +++---------------
1 file changed, 39 insertions(+), 186 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 665938ec..4e360ce0 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -13,36 +13,36 @@
package org.sensorhub.android;
-import android.app.ListActivity;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothManager;
-import android.bluetooth.le.BluetoothLeScanner;
-import android.bluetooth.le.ScanCallback;
-import android.bluetooth.le.ScanResult;
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.AlertDialog;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
import android.hardware.Sensor;
import android.hardware.SensorManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.preference.PreferenceManager;
+import android.provider.Settings.Secure;
+import android.text.Html;
import android.util.Log;
-import android.view.*;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.TextureView;
+import android.view.WindowManager;
+import android.widget.EditText;
+import android.widget.TextView;
import org.sensorhub.android.comm.BluetoothCommProvider;
import org.sensorhub.android.comm.BluetoothCommProviderConfig;
@@ -50,7 +50,6 @@
import org.sensorhub.android.comm.ble.BleNetwork;
import org.sensorhub.api.common.Event;
import org.sensorhub.api.common.IEventListener;
-import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.api.module.IModuleConfigRepository;
import org.sensorhub.api.module.ModuleEvent;
import org.sensorhub.api.sensor.ISensorDataInterface;
@@ -60,7 +59,6 @@
import org.sensorhub.impl.client.sost.SOSTClientConfig;
import org.sensorhub.impl.driver.flir.FlirOneCameraConfig;
import org.sensorhub.impl.module.InMemoryConfigDb;
-import org.sensorhub.impl.module.ModuleRegistry;
import org.sensorhub.impl.persistence.GenericStreamStorage;
import org.sensorhub.impl.persistence.MaxAgeAutoPurgeConfig;
import org.sensorhub.impl.persistence.StreamStorageConfig;
@@ -68,34 +66,25 @@
import org.sensorhub.impl.persistence.h2.MVStorageConfig;
import org.sensorhub.impl.sensor.android.AndroidSensorsConfig;
import org.sensorhub.impl.sensor.angel.AngelSensorConfig;
-import org.sensorhub.impl.sensor.blebeacon.BLEBeaconConfig;
-import org.sensorhub.impl.sensor.swe.ProxySensor.ProxySensor;
import org.sensorhub.impl.sensor.swe.ProxySensor.ProxySensorConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
+import org.sensorhub.impl.service.HttpServerConfig;
import org.sensorhub.impl.service.sos.SOSServiceConfig;
import org.sensorhub.impl.service.sos.SensorDataProviderConfig;
import org.sensorhub.test.sensor.trupulse.SimulatedDataStream;
-import org.sensorhub.impl.service.HttpServerConfig;
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.preference.PreferenceManager;
-import android.provider.Settings.Secure;
-import android.text.Html;
-import android.widget.BaseAdapter;
-import android.widget.EditText;
-import android.widget.TextView;
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
import static android.content.ContentValues.TAG;
@@ -339,13 +328,11 @@ private boolean isPushingSensor(Sensors sensor) {
if (prefs.getBoolean("location_enable", false)
&& prefs.getStringSet("location_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
- if (prefs.getBoolean("video_enable", false)
- && prefs.getStringSet("video_options", Collections.emptySet()).contains("PUSH_REMOTE"))
- return true;
+ return prefs.getBoolean("video_enable", false)
+ && prefs.getStringSet("video_options", Collections.emptySet()).contains("PUSH_REMOTE");
} else if (Sensors.TruPulse.equals(sensor) || Sensors.TruPulseSim.equals(sensor)) {
- if (prefs.getBoolean("trupulse_enable", false)
- && prefs.getStringSet("trupulse_options", Collections.emptySet()).contains("PUSH_REMOTE"))
- return true;
+ return prefs.getBoolean("trupulse_enable", false)
+ && prefs.getStringSet("trupulse_options", Collections.emptySet()).contains("PUSH_REMOTE");
}
return false;
@@ -480,14 +467,6 @@ private SensorConfig createSensorConfig(Sensors sensor) {
((FlirOneCameraConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
} else if (Sensors.ProxySensor.equals(sensor)) {
sensorConfig = new ProxySensorConfig();
- }else if(true){
- // TODO: Add option to UI after testing
- // Add the BLE Beacon Scanner
- sensorConfig = new BLEBeaconConfig();
- sensorConfig.id = "BLE_BEACON_SCANNER";
- sensorConfig.name = "BLE Beacon Scanner [" + deviceName + "]";
- sensorConfig.autoStart = true;
- Log.d(TAG, "createSensorConfig: Added BLE Beacon Scanner");
} else {
sensorConfig = new SensorConfig();
}
@@ -825,63 +804,6 @@ protected void onCreate(Bundle savedInstanceState) {
displayHandler = new Handler(Looper.getMainLooper());
setupBroadcastReceivers();
-
- // TODO: Integrate into BLEBeacon Sensor after POC
- BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- Log.d(TAG, bluetoothAdapter.getName());
- BluetoothLeScanner bleScanner = bluetoothAdapter.getBluetoothLeScanner();
- ScanCallback scb = new ScanCallback() {
- @Override
- public void onScanResult(int callbackType, ScanResult result) {
- super.onScanResult(callbackType, result);
- Log.d(TAG, result.toString());
- }
- };
- bleScanner.startScan(scb);
-
-
- // Listen to and Log from nearby BLE beacons
- /*int REQUEST_ENABLE_BT = 1; // Make sure this is the correct usage
-
- BluetoothAdapter bluetoothAdapter;
- // Initializes Bluetooth adapter.
- final BluetoothManager bluetoothManager =
- (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
- bluetoothAdapter = bluetoothManager.getAdapter();
-
- // Ensures Bluetooth is available on the device and it is enabled. If not,
- // displays a dialog requesting user permission to enable Bluetooth.
- if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
- Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
- startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
- }
-
- final boolean[] mScanning = new boolean[1];
- Handler handler = new Handler();
- LeDeviceListAdapter leDeviceListAdapter;
- BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
- @Override
- public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- leDe
- }
- });
- }
- };
-
- final long SCAN_PERIOD = 10000;
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- mScanning[0] = false;
- bluetoothAdapter.stopLeScan(leScanCallback);
- }
- }, SCAN_PERIOD);
-
- mScanning[0] = true;
- bluetoothAdapter.startLeScan(leScanCallback);*/
}
@@ -1279,72 +1201,3 @@ public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
}
-
-
-// TODO: Deal with this in BLEBeacon's own module later
-
-
-/*
-public class LeDeviceListAdapter extends BaseAdapter {
- private ArrayList mLeDevices;
- private LayoutInflater mInflator;
-
-
- public LeDeviceListAdapter() {
- super();
- mLeDevices = new ArrayList();
- mInflator = this.getLayoutInflater();
- }
-
- public void addDevice(BluetoothDevice device) {
- if (!mLeDevices.contains(device)) {
- mLeDevices.add(device);
- }
- }
-
- public BluetoothDevice getDevice(int position) {
- return mLeDevices.get(position);
- }
-
- public void clear() {
- mLeDevices.clear();
- }
-
- @Override
- public int getCount() {
- return mLeDevices.size();
- }
-
- @Override
- public Object getItem(int i) {
- return mLeDevices.get(i);
- }
-
- @Override
- public long getItemId(int i) {
- return i;
- }
-
- @Override
- public View getView(int i, View view, ViewGroup viewGroup) {
- ViewHolder viewHolder;
- // General ListView optimization code.
- if (view == null) {
- view = mInflator.inflate(R.layout.listitem_device, null);
- viewHolder = new ViewHolder();
- viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
- viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
- view.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) view.getTag();
- }
- BluetoothDevice device = mLeDevices.get(i);
- final String deviceName = device.getName();
- if (deviceName != null && deviceName.length() > 0)
- viewHolder.deviceName.setText(deviceName);
- else
- viewHolder.deviceName.setText(R.string.unknown_device);
- viewHolder.deviceAddress.setText(device.getAddress());
- return view;
- }
-}*/
From 85b1bee791dcac9bb22bb106d4b9ce8f678e6023 Mon Sep 17 00:00:00 2001
From: Alex Robin
Date: Fri, 4 Oct 2019 09:29:48 +0200
Subject: [PATCH 083/207] Updated Gradle config to make it compile
---
build.gradle | 6 +++---
settings.gradle | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/build.gradle b/build.gradle
index 8679a18c..0acea4ed 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
ext.oshCoreVersion = '1.3.3'
-ext.compileSdkVersion = 21
-ext.minSdkVersion = 21
-ext.targetSdkVersion = 21
+ext.compileSdkVersion = 26
+ext.minSdkVersion = 26
+ext.targetSdkVersion = 26
ext.buildToolsVersion = "28.0.3"
version = oshCoreVersion
diff --git a/settings.gradle b/settings.gradle
index 707c30e5..f5007d1d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -4,7 +4,7 @@ def oshMainDir = "$rootDir/.."
// include builds from other repos
def repos = [
- 'osh-core':['lib-swe-common', 'lib-sensorml', 'lib-ows', 'sensorhub-core', 'sensorhub-service-swe', 'sensorhub-storage-h2'],
+ 'osh-core':['lib-swe-common', 'lib-sensorml', 'lib-ows', 'sensorhub-core', 'sensorhub-service-swe', 'sensorhub-storage-perst'],
'osh-addons/persistence':['sensorhub-storage-h2'],
'osh-addons/comm':['sensorhub-comm-ble', 'sensorhub-comm-ble-dbus'],
'osh-addons/sensors/health':['sensorhub-driver-angelsensor'],
From f48a8f2f71bf6da712e01c6948c13bd85384ea39 Mon Sep 17 00:00:00 2001
From: Alex Robin
Date: Fri, 4 Oct 2019 09:37:10 +0200
Subject: [PATCH 084/207] Added BLE beacon driver
---
sensorhub-android-lib/build.gradle | 1 +
1 file changed, 1 insertion(+)
diff --git a/sensorhub-android-lib/build.gradle b/sensorhub-android-lib/build.gradle
index 279f0a57..40c76043 100644
--- a/sensorhub-android-lib/build.gradle
+++ b/sensorhub-android-lib/build.gradle
@@ -18,6 +18,7 @@ dependencies {
api project(':sensorhub-driver-trupulse')
api project(':sensorhub-driver-angelsensor')
api project(':sensorhub-driver-android')
+ api project(':sensorhub-android-blebeacon')
api project(':sensorhub-android-flirone')
//api project(':sensorhub-android-dji')
implementation 'org.slf4j:slf4j-android:1.6.1-RC1'
From 0492fd8e5c29bd6f6995c106c16d6663b5d0239b Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Tue, 8 Oct 2019 14:08:39 -0500
Subject: [PATCH 085/207] fix crash on startup
---
build.gradle | 2 +-
.../src/org/sensorhub/android/MainActivity.java | 15 +++++++++++++++
sensorhub-android-blebeacon/build.gradle | 4 ++--
.../src/main/AndroidManifest.xml | 3 ++-
4 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/build.gradle b/build.gradle
index 0acea4ed..8658622d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
ext.oshCoreVersion = '1.3.3'
-ext.compileSdkVersion = 26
+ext.compileSdkVersion = 28
ext.minSdkVersion = 26
ext.targetSdkVersion = 26
ext.buildToolsVersion = "28.0.3"
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 4e360ce0..8b755774 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -66,6 +66,9 @@
import org.sensorhub.impl.persistence.h2.MVStorageConfig;
import org.sensorhub.impl.sensor.android.AndroidSensorsConfig;
import org.sensorhub.impl.sensor.angel.AngelSensorConfig;
+import org.sensorhub.impl.sensor.blebeacon.BLEBeacon;
+import org.sensorhub.impl.sensor.blebeacon.BLEBeaconConfig;
+import org.sensorhub.impl.sensor.blebeacon.BLEBeaconDriver;
import org.sensorhub.impl.sensor.swe.ProxySensor.ProxySensorConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
import org.sensorhub.impl.service.HttpServerConfig;
@@ -788,6 +791,7 @@ protected void addSosTConfig(SensorConfig sensorConf, String sosUser, String sos
@SuppressLint("HandlerLeak")
@Override
protected void onCreate(Bundle savedInstanceState) {
+ Log.d(TAG, "onCreate: Should appear in logs");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textArea = (TextView) findViewById(R.id.text);
@@ -804,6 +808,17 @@ protected void onCreate(Bundle savedInstanceState) {
displayHandler = new Handler(Looper.getMainLooper());
setupBroadcastReceivers();
+
+ Log.d(TAG, "onCreate: Creating BLE Config");
+ BLEBeaconConfig beaconConfig = new BLEBeaconConfig();
+ beaconConfig.id = "BLE_BEACON_SCANNER";
+ beaconConfig.name = "BLE Scanner [" + deviceName + "]";
+// beaconConfig.moduleClass = BLEBeaconDriver.class.getCanonicalName();
+ beaconConfig.androidContext = this.getApplicationContext();
+ beaconConfig.autoStart = true;
+ Log.d(TAG, "onCreate: Adding config to sensorhub config");
+// sensorhubConfig.add(beaconConfig);
+ Log.d(TAG, "onCreate: BLE Config Added");
}
diff --git a/sensorhub-android-blebeacon/build.gradle b/sensorhub-android-blebeacon/build.gradle
index e4e35ea8..0b21b602 100644
--- a/sensorhub-android-blebeacon/build.gradle
+++ b/sensorhub-android-blebeacon/build.gradle
@@ -5,8 +5,8 @@ android {
defaultConfig {
- minSdkVersion 22
- targetSdkVersion 28
+ minSdkVersion 26
+ targetSdkVersion 26
versionCode 1
versionName "1.0"
diff --git a/sensorhub-android-blebeacon/src/main/AndroidManifest.xml b/sensorhub-android-blebeacon/src/main/AndroidManifest.xml
index 0a6f2047..f6a6a09d 100644
--- a/sensorhub-android-blebeacon/src/main/AndroidManifest.xml
+++ b/sensorhub-android-blebeacon/src/main/AndroidManifest.xml
@@ -1,2 +1,3 @@
+ package="org.sensorhub.impl.sensor.blebeacon">
+
From 9b97d6b38b1ae8d40f3d52661ad348a46a4a85af Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Tue, 8 Oct 2019 14:19:38 -0500
Subject: [PATCH 086/207] change ble_beacon unique id to actually be unique
---
.../org/sensorhub/android/MainActivity.java | 24 +++++++++++--------
.../sensor/blebeacon/BLEBeaconDriver.java | 2 +-
2 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 8b755774..5fba2b5d 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -225,6 +225,19 @@ protected void updateConfig(SharedPreferences prefs, String runName) {
addSosTConfig(flironeConfig, sosUser, sosPwd);
}
+ if(true){
+ Log.d(TAG, "onCreate: Creating BLE Config");
+ BLEBeaconConfig beaconConfig = new BLEBeaconConfig();
+ beaconConfig.id = "BLE_BEACON_SCANNER";
+ beaconConfig.name = "BLE Scanner [" + deviceName + "]";
+// beaconConfig.moduleClass = BLEBeaconDriver.class.getCanonicalName();
+ beaconConfig.androidContext = this.getApplicationContext();
+ beaconConfig.autoStart = true;
+ Log.d(TAG, "onCreate: Adding config to sensorhub config");
+ sensorhubConfig.add(beaconConfig);
+ Log.d(TAG, "onCreate: BLE Config Added");
+ }
+
/*
// DJI Drone
enabled = prefs.getBoolean("dji_enabled", false);
@@ -809,16 +822,7 @@ protected void onCreate(Bundle savedInstanceState) {
setupBroadcastReceivers();
- Log.d(TAG, "onCreate: Creating BLE Config");
- BLEBeaconConfig beaconConfig = new BLEBeaconConfig();
- beaconConfig.id = "BLE_BEACON_SCANNER";
- beaconConfig.name = "BLE Scanner [" + deviceName + "]";
-// beaconConfig.moduleClass = BLEBeaconDriver.class.getCanonicalName();
- beaconConfig.androidContext = this.getApplicationContext();
- beaconConfig.autoStart = true;
- Log.d(TAG, "onCreate: Adding config to sensorhub config");
-// sensorhubConfig.add(beaconConfig);
- Log.d(TAG, "onCreate: BLE Config Added");
+
}
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconDriver.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconDriver.java
index 8e735d49..ec4e0cee 100644
--- a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconDriver.java
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconDriver.java
@@ -38,7 +38,7 @@ public synchronized void init() throws SensorHubException{
String deviceID = Settings.Secure.getString(androidContext.getContentResolver(), Settings.Secure.ANDROID_ID);
this.xmlID = "ANDROID_SENSORS_" + Build.SERIAL; // Deprecated in API level 26
- this.uniqueID = "urn:android:device:" + deviceID;
+ this.uniqueID = "urn:android:device:" + "ble_beacon";
this.localFrameURI = this.uniqueID + "#" + LOCAL_REF_FRAME;
rawOutput = new BLEBeaconRawOutput(this);
From 1ff73c83b8d6f7c63ba26ac4e8aede989727e14a Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Wed, 9 Oct 2019 16:30:06 -0500
Subject: [PATCH 087/207] Migrate some code from BLERawOutput to the driver
itself
---
.../res/xml/pref_sensors.xml | 8 +-
.../org/sensorhub/android/MainActivity.java | 1 +
.../sensor/blebeacon/BLEBeaconDriver.java | 87 +++++++++++++++++--
.../blebeacon/BLEBeaconLocationOutput.java | 68 +++++++++++++++
.../sensor/blebeacon/BLEBeaconRawOutput.java | 80 ++++++++---------
5 files changed, 191 insertions(+), 53 deletions(-)
create mode 100644 sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconLocationOutput.java
diff --git a/sensorhub-android-app/res/xml/pref_sensors.xml b/sensorhub-android-app/res/xml/pref_sensors.xml
index 4231c454..4d9b4be0 100644
--- a/sensorhub-android-app/res/xml/pref_sensors.xml
+++ b/sensorhub-android-app/res/xml/pref_sensors.xml
@@ -1,4 +1,5 @@
-
+
+
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/layout/activity_spot_report.xml b/sensorhub-android-app/res/layout/activity_spot_report.xml
deleted file mode 100644
index 5243c93e..00000000
--- a/sensorhub-android-app/res/layout/activity_spot_report.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/layout/spot_report_aid.xml b/sensorhub-android-app/res/layout/spot_report_aid.xml
deleted file mode 100644
index 07bab566..00000000
--- a/sensorhub-android-app/res/layout/spot_report_aid.xml
+++ /dev/null
@@ -1,275 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/layout/spot_report_flooding.xml b/sensorhub-android-app/res/layout/spot_report_flooding.xml
deleted file mode 100644
index 9a430b90..00000000
--- a/sensorhub-android-app/res/layout/spot_report_flooding.xml
+++ /dev/null
@@ -1,272 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/layout/spot_report_image_capture.xml b/sensorhub-android-app/res/layout/spot_report_image_capture.xml
deleted file mode 100644
index 316be03d..00000000
--- a/sensorhub-android-app/res/layout/spot_report_image_capture.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/layout/spot_report_medical.xml b/sensorhub-android-app/res/layout/spot_report_medical.xml
deleted file mode 100644
index 28b7d6e0..00000000
--- a/sensorhub-android-app/res/layout/spot_report_medical.xml
+++ /dev/null
@@ -1,220 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/layout/spot_report_streetclosure.xml b/sensorhub-android-app/res/layout/spot_report_streetclosure.xml
deleted file mode 100644
index 46f6df0d..00000000
--- a/sensorhub-android-app/res/layout/spot_report_streetclosure.xml
+++ /dev/null
@@ -1,207 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/layout/spot_report_track.xml b/sensorhub-android-app/res/layout/spot_report_track.xml
deleted file mode 100644
index 745367bf..00000000
--- a/sensorhub-android-app/res/layout/spot_report_track.xml
+++ /dev/null
@@ -1,211 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/layout/spot_report_web_view.xml b/sensorhub-android-app/res/layout/spot_report_web_view.xml
deleted file mode 100644
index 369d9436..00000000
--- a/sensorhub-android-app/res/layout/spot_report_web_view.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-app/res/menu/main.xml b/sensorhub-android-app/res/menu/main.xml
index c8b1fa25..167d47d8 100644
--- a/sensorhub-android-app/res/menu/main.xml
+++ b/sensorhub-android-app/res/menu/main.xml
@@ -13,10 +13,10 @@
android:orderInCategory="110"
android:title="@string/action_start" />
-
+
+
+
+
parent, View view, int position, long id)
- {
- Location location = null;
-
- String selectedItem = parent.getItemAtPosition(position).toString();
-
- if (PackageManager.PERMISSION_GRANTED ==
- ContextCompat.checkSelfPermission(parent.getContext(), Manifest.permission.ACCESS_FINE_LOCATION)) {
-
- LocationManager locationManager = (LocationManager) this.activity.getSystemService(Context.LOCATION_SERVICE);
-
- if (selectedItem.equalsIgnoreCase("GPS")) {
-
- location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
-
- } else if (selectedItem.equalsIgnoreCase("Network")) {
-
- location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
- }
-
- if (null != location) {
-
- if(latId != 0) {
-
- ((TextView) activity.findViewById(latId)).setText(
- String.format(Locale.ENGLISH, "%f", location.getLatitude()));
- }
-
- if(lonId != 0) {
-
- ((TextView) activity.findViewById(lonId)).setText(
- String.format(Locale.ENGLISH, "%f", location.getLongitude()));
- }
- }
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent)
- {
-
- }
-}
diff --git a/sensorhub-android-app/src/org/sensorhub/android/spotreport/ReportTypeListener.java b/sensorhub-android-app/src/org/sensorhub/android/spotreport/ReportTypeListener.java
deleted file mode 100644
index fe4f1404..00000000
--- a/sensorhub-android-app/src/org/sensorhub/android/spotreport/ReportTypeListener.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
-
- ******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.spotreport;
-
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.Spinner;
-
-import org.sensorhub.android.R;
-
-/**
- *
- */
-class ReportTypeListener implements AdapterView.OnItemSelectedListener {
-
- private boolean layoutSwitched = false;
-
- private SpotReportActivity activity;
-
- ReportTypeListener(SpotReportActivity activity) {
-
- this.activity = activity;
- }
-
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id)
- {
- if (!layoutSwitched) {
-
- String selectedItem = parent.getItemAtPosition(position).toString();
-
- if (selectedItem.equalsIgnoreCase("Street Closure")) {
-
- activity.initializeStreetClosureLayout();
- layoutSwitched = true;
-
- } else if (selectedItem.equalsIgnoreCase("Flooding")) {
-
- activity.initializeFloodLayout();
- layoutSwitched = true;
-
- } else if (selectedItem.equalsIgnoreCase("Medical")) {
-
- activity.initializeMedicalLayout();
- layoutSwitched = true;
-
- } else if (selectedItem.equalsIgnoreCase("Aid")) {
-
- activity.initializeAidLayout();
- layoutSwitched = true;
-
- } else if (selectedItem.equalsIgnoreCase("Track")) {
-
- activity.initializeTrackLayout();
- layoutSwitched = true;
-
- } else if(selectedItem.equalsIgnoreCase("Image Capture")) {
-
- activity.initializeImageCaptureLayout();
- layoutSwitched = true;
- }
-
- ((Spinner) activity.findViewById(R.id.reportType)).setSelection(position);
- ((Spinner) activity.findViewById(R.id.reportType)).setOnItemSelectedListener(this);
-
- } else {
-
- layoutSwitched = false;
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent)
- {
-
- }
-}
diff --git a/sensorhub-android-app/src/org/sensorhub/android/spotreport/SpotReportActions.java b/sensorhub-android-app/src/org/sensorhub/android/spotreport/SpotReportActions.java
deleted file mode 100644
index fb9c4c65..00000000
--- a/sensorhub-android-app/src/org/sensorhub/android/spotreport/SpotReportActions.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
-
- ******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.spotreport;
-
-class SpotReportActions {
-
- static final String ACTION_SUBMIT_AID_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_AID";
- static final String ACTION_SUBMIT_FLOODING_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_FLOODING";
- static final String ACTION_SUBMIT_IMAGE_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_IMAGE";
- static final String ACTION_SUBMIT_MEDICAL_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_MEDICAL";
- static final String ACTION_SUBMIT_STREET_CLOSURE_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_STREET_CLOSURE";
- static final String ACTION_SUBMIT_TRACK_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_TRACK";
-}
diff --git a/sensorhub-android-app/src/org/sensorhub/android/spotreport/SpotReportActivity.java b/sensorhub-android-app/src/org/sensorhub/android/spotreport/SpotReportActivity.java
deleted file mode 100644
index 03d2d108..00000000
--- a/sensorhub-android-app/src/org/sensorhub/android/spotreport/SpotReportActivity.java
+++ /dev/null
@@ -1,1388 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
-
-******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.spotreport;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.icu.text.SimpleDateFormat;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.provider.MediaStore;
-import android.support.v4.content.FileProvider;
-import android.util.Log;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.SeekBar;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import org.eclipse.paho.client.mqttv3.IMqttToken;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.sensorhub.android.R;
-import org.sensorhub.android.mqtt.IMqttSubscriber;
-import org.sensorhub.android.mqtt.MqttConnectionListener;
-import org.sensorhub.android.mqtt.MqttHelper;
-import org.sensorhub.android.mqtt.MqttMessageHandler;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import java.util.UUID;
-
-public class SpotReportActivity extends Activity implements IMqttSubscriber {
-
- private static final String TAG = "SpotReportActivity";
-
- // Data Associated with Broadcast Receivers and Intents
- private static final int REQUEST_IMAGE_CAPTURE = 1;
-
- private final SubmitRequestResultReceiver submitRequestResultReceiver =
- new SubmitRequestResultReceiver(this, new Handler());
-
- // MQTT Messaging data
- private MqttHelper mqttHelper;
-
- private static final String MQTT_USER = "botts";
- private static final String MQTT_PASSWORD = "scira04";
- private static final String MQTT_URL = "tcp://ogc-hub.compusult.com:1883";
-
- private static final String FLOODING_TOPIC_ID = "Datastreams(192)/Observations";
- private static final String STREET_CLOSURE_TOPIC_ID = "Datastreams(232)/Observations";
- private static final String AID_TOPIC_ID = "Datastreams(235)/Observations";
- private static final String TRACK_TOPIC_ID = "Datastreams(236)/Observations";
- private static final String MED_TOPIC_ID = "Datastreams(237)/Observations";
-
- private static final String[] topics = {
- "Observations",
- FLOODING_TOPIC_ID,
- STREET_CLOSURE_TOPIC_ID,
- AID_TOPIC_ID,
- TRACK_TOPIC_ID,
- MED_TOPIC_ID
- };
-
- private final MqttMessageHandler mqttMessageHandler = new MqttMessageHandler(this);
-
- // UI components and data structures
- private ImageView imageView;
- private Bitmap imageBitmap = null;
- private Uri imageUri;
- private String lastAction = null;
- private List aidReportIds = new ArrayList<>();
- private List streetClosureReportIds = new ArrayList<>();
- private List floodReportIds = new ArrayList<>();
- private List medicalReportIds = new ArrayList<>();
-
- enum Forms {
-
- NONE,
- WEB,
- AID,
- STREET_CLOSURE,
- FLOOD,
- MEDICAL,
- TRACK,
- IMAGE
- }
-
- Forms currentForm = Forms.NONE;
-
- private final ReportTypeListener reportTypeListener = new ReportTypeListener(this);
-
- private static final String APP_PREFERENCES = "SpotReportPreferences";
- SharedPreferences sharedPreferences;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
-
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.activity_spot_report);
- Spinner spinner = findViewById(R.id.reportType);
- spinner.setOnItemSelectedListener(reportTypeListener);
-
- mqttHelper = new MqttHelper();
-
- IMqttToken connection = mqttHelper.connect(this, MQTT_USER, MQTT_PASSWORD, MQTT_URL);
- connection.setActionCallback(new MqttConnectionListener(mqttHelper, this));
-
- sharedPreferences = getSharedPreferences(APP_PREFERENCES, MODE_PRIVATE);
-
- Set aidReports = sharedPreferences.getStringSet("aidReportIds", null);
-
- if(null != aidReports) {
- for (String id : aidReports) {
-
- aidReportIds.add(id);
- }
- }
-
- Set closureReports =
- sharedPreferences.getStringSet("streetClosureReportIds", null);
-
- if(null != closureReports) {
- for (String id : closureReports) {
-
- streetClosureReportIds.add(id);
- }
- }
-
- Set floodReports = sharedPreferences.getStringSet("floodReportIds", null);
-
- if(null != floodReports) {
- for (String id : floodReports) {
-
- floodReportIds.add(id);
- }
- }
-
- Set medReports = sharedPreferences.getStringSet("medicalReportIds", null);
-
- if(null != medReports) {
- for (String id : medReports) {
-
- medicalReportIds.add(id);
- }
- }
- }
-
- @Override
- protected void onDestroy() {
-
- for (String topic : topics) {
-
- try {
-
- mqttHelper.unsubscribe(topic);
-
- } catch (Exception e) {
-
- Log.e(TAG, "Failed on unsubscribe of topic:" + topic);
- }
- }
-
- mqttHelper.disconnect();
-
- super.onDestroy();
- }
-
- @Override
- public void onBackPressed() {
-
- if (currentForm == Forms.WEB) {
-
- currentForm = Forms.NONE;
- if(!getActionBar().isShowing()) {
-
- getActionBar().show();
- }
- setContentView(R.layout.activity_spot_report);
- Spinner spinner = findViewById(R.id.reportType);
- spinner.setOnItemSelectedListener(reportTypeListener);
- setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
- }
- else {
-
- super.onBackPressed();
- }
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-
- super.onActivityResult(requestCode, resultCode, data);
-
- if (requestCode == REQUEST_IMAGE_CAPTURE) {
-
- if (resultCode == Activity.RESULT_OK) {
-
- try {
-
- imageBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
-
- imageView.setImageBitmap(imageBitmap);
-
- } catch (Exception e) {
-
- Log.e(TAG, e.toString());
- }
- }
- }
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
-
- super.onConfigurationChanged(newConfig);
-
- if (null != imageView) {
-
- imageView.setImageBitmap(imageBitmap);
- }
- }
-
- @Override
- public void subscribeToTopics() {
-
- Log.d(TAG, "subscribeToTopics");
-
- for(String topic : topics) {
-
- mqttHelper.subscribe(topic, mqttMessageHandler);
- }
- }
-
- @Override
- public void onMessage(String message) {
-
- Log.d(TAG, "onMessage");
-
- try {
-
- List reportIds = null;
- Spinner reportIdsSpinner = findViewById(R.id.spotReportId);
-
- JSONObject receivedTask = new JSONObject(message);
- JSONObject observation = receivedTask.getJSONObject("result");
- String id = observation.getString("id");
- String timeStamp = observation.getString("timeStamp");
- String type = observation.getString("observationType");
-
- JSONObject params = observation.getJSONObject("params");
- String action = params.getString("action");
-
- JSONObject location = params.getJSONObject("location");
- JSONObject geometry = location.getJSONObject("geometry");
- JSONArray coords = geometry.getJSONArray("coordinates");
- double longitude = coords.getDouble(0);
- double latitude = coords.getDouble(1);
-
- boolean showAlert = true;
- String title = "Tasking Notification";
-
- StringBuilder taskingNotification = new StringBuilder();
- taskingNotification.append("Type: ");
-
- if(type.equalsIgnoreCase("streetclosure")) {
-
- taskingNotification.append("Street Closure");
- reportIds = streetClosureReportIds;
- }
- else if (type.equalsIgnoreCase("flood")) {
-
- taskingNotification.append("Flood Report");
- reportIds = floodReportIds;
- }
-// else if (type.equalsIgnoreCase("med")) {
-//
-// taskingNotification.append("Medical Emergency");
-// reportIds = medicalReportIds;
-// }
- else if (type.equalsIgnoreCase("aid")) {
-
- taskingNotification.append("Assist Person(s)");
- reportIds = aidReportIds;
- }
- else {
-
- showAlert = false;
- }
-
- taskingNotification
- .append("\n")
- .append("Time: ")
- .append(timeStamp)
- .append("\n")
- .append("Location: \n")
- .append("\tLon: ")
- .append(longitude)
- .append("\n")
- .append("\tLat: ")
- .append(latitude);
-
- if(action.equalsIgnoreCase("open") && showAlert && currentForm != Forms.WEB) {
-
- // Ad the id to the list of ids
- reportIds.add(id);
-
- if(null != reportIdsSpinner) {
-
- ((ArrayAdapter)reportIdsSpinner.getAdapter()).notifyDataSetChanged();
- }
-
- // Pop up error dialog, noting fields need to be corrected
- new AlertDialog.Builder(this)
- .setTitle(title)
- .setMessage(taskingNotification.toString())
- .setCancelable(true)
- .setNegativeButton("DISMISS", null)
- .setPositiveButton("ACCEPT",
- new TaskAcceptanceListener(this, message, longitude, latitude))
- .show();
-
- } else if(action.equalsIgnoreCase("close")) {
-
- reportIds.remove(id);
-
- if(null != reportIdsSpinner) {
-
- ((ArrayAdapter)reportIdsSpinner.getAdapter()).notifyDataSetChanged();
- }
- }
-
- persistReports();
-
- } catch (JSONException exception) {
-
- Log.d(TAG, "Failed parsing JSON message");
- }
- }
-
- void persistReports() {
-
- sharedPreferences.edit().clear();
- Set data = new HashSet<>();
- data.addAll(aidReportIds);
- sharedPreferences.edit().putStringSet("aidReportIds", data);
- data = new HashSet<>();
- data.addAll(streetClosureReportIds);
- sharedPreferences.edit().putStringSet("streetClosureReportIds", data);
- data = new HashSet<>();
- data.addAll(floodReportIds);
- sharedPreferences.edit().putStringSet("floodReportIds", data);
- data = new HashSet<>();
- data.addAll(medicalReportIds);
- sharedPreferences.edit().putStringSet("medicalReportIds", data);
- }
-
- void taskAccepted(String id, String type) {
-
- List reportIds = null;
- Spinner reportIdsSpinner = findViewById(R.id.spotReportId);
-
- if(type.equalsIgnoreCase("streetclosure")) {
-
- reportIds = streetClosureReportIds;
- }
- else if (type.equalsIgnoreCase("flood")) {
-
- reportIds = floodReportIds;
- }
- else if (type.equalsIgnoreCase("med")) {
-
- reportIds = medicalReportIds;
- }
- else if (type.equalsIgnoreCase("aid")) {
-
- reportIds = aidReportIds;
- }
-
- // Ad the id to the list of ids
- reportIds.remove(id);
-
- if(null != reportIdsSpinner) {
-
- ((ArrayAdapter)reportIdsSpinner.getAdapter()).notifyDataSetChanged();
- }
-
- persistReports();
- }
-
- Forms getCurrentForm() {
-
- return currentForm;
- }
-
- void setCurrentForm(Forms currentForm) {
-
- this.currentForm = currentForm;
- }
-
- void setLastAction(String action) {
-
- lastAction = action;
- }
-
- String getLastAction() {
-
- return lastAction;
- }
-
- void clearLastAction() {
-
- lastAction = null;
- }
-
- void setImageView() {
-
- imageView = findViewById(R.id.imageView);
- }
-
- Uri getImageUri() {
-
- return imageUri;
- }
-
- void clearImageData() {
-
- imageView.setImageBitmap(null);
- imageUri = null;
- imageBitmap = null;
- }
-
- void sendAidMessage(String latString, String lonString, int radius, String aidType,
- String numPersons, String urgency, String description,
- String reporter, String action, String spotReportId) {
-
- // Create and transmit report
- setLastAction(SpotReportActions.ACTION_SUBMIT_AID_REPORT);
- Intent submitReportIntent = new Intent(SpotReportActions.ACTION_SUBMIT_AID_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("lat", latString);
- submitReportIntent.putExtra("lon", lonString);
- submitReportIntent.putExtra("radius", radius);
- submitReportIntent.putExtra("aidType", aidType);
- submitReportIntent.putExtra("numPersons", numPersons);
- submitReportIntent.putExtra("urgency", urgency);
- submitReportIntent.putExtra("description", description);
- submitReportIntent.putExtra("reporter", reporter);
- submitReportIntent.putExtra("action", action);
- submitReportIntent.putExtra("id", spotReportId);
- submitReportIntent.putExtra(Intent.EXTRA_RESULT_RECEIVER, submitRequestResultReceiver);
- sendBroadcast(submitReportIntent);
- }
-
- void sendFloodMessage(String latString, String lonString, int radius, String featureType,
- int depth, String method, String action, String spotReportId) {
-
- // Create and transmit report
- setLastAction(SpotReportActions.ACTION_SUBMIT_FLOODING_REPORT);
- Intent submitReportIntent = new Intent(SpotReportActions.ACTION_SUBMIT_FLOODING_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("lat", latString);
- submitReportIntent.putExtra("lon", lonString);
- submitReportIntent.putExtra("radius", radius);
- submitReportIntent.putExtra("featureType", featureType);
- submitReportIntent.putExtra("depth", depth);
- submitReportIntent.putExtra("method", method);
- submitReportIntent.putExtra("action", action);
- submitReportIntent.putExtra("id", spotReportId);
- submitReportIntent.putExtra(Intent.EXTRA_RESULT_RECEIVER, submitRequestResultReceiver);
- sendBroadcast(submitReportIntent);
- }
-
- void sendMedicalMessage(String latString, String lonString, int radius, String description,
- String measure, boolean emergency, String action, String spotReportId) {
-
- // Create and transmit report
- setLastAction(SpotReportActions.ACTION_SUBMIT_MEDICAL_REPORT);
- Intent submitReportIntent = new Intent(SpotReportActions.ACTION_SUBMIT_MEDICAL_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("lat", latString);
- submitReportIntent.putExtra("lon", lonString);
- submitReportIntent.putExtra("radius", radius);
- submitReportIntent.putExtra("description", description);
- submitReportIntent.putExtra("measure", measure);
- submitReportIntent.putExtra("emergency", emergency);
- submitReportIntent.putExtra("action", action);
- submitReportIntent.putExtra("id", spotReportId);
- submitReportIntent.putExtra(Intent.EXTRA_RESULT_RECEIVER, submitRequestResultReceiver);
- sendBroadcast(submitReportIntent);
- }
-
- void sendStreetClosureMessage(String latString, String lonString, int radius, String type,
- String action, String spotReportId) {
-
- // Create and transmit report
- setLastAction(SpotReportActions.ACTION_SUBMIT_STREET_CLOSURE_REPORT);
- Intent submitReportIntent = new Intent(SpotReportActions.ACTION_SUBMIT_STREET_CLOSURE_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("lat", latString);
- submitReportIntent.putExtra("lon", lonString);
- submitReportIntent.putExtra("radius", radius);
- submitReportIntent.putExtra("type", type);
- submitReportIntent.putExtra("action", action);
- submitReportIntent.putExtra("id", spotReportId);
- submitReportIntent.putExtra(Intent.EXTRA_RESULT_RECEIVER, submitRequestResultReceiver);
- sendBroadcast(submitReportIntent);
- }
-
- private boolean createImageFile() throws IOException {
-
- String timeStamp =
- new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault()).format(new Date());
-
- String imageFileName = "SpotReport_IMG_" + timeStamp + ".jpg";
-
- File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
-
- File file = new File(storageDir + "/" + imageFileName);
-
- boolean result = file.createNewFile();
-
- if (result) {
-
- imageUri = FileProvider.getUriForFile(this,"org.sensorhub.android.provider", file);
-
- }
-
- return result;
- }
-
- private void dispatchTakePictureIntent() {
-
- Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
-
- if (null != takePictureIntent.resolveActivity(getPackageManager())) {
-
- try {
-
- if (createImageFile()) {
-
- takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
-
- startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
-
- }
-
- } catch (IOException e) {
-
- // Error occurred while creating the File
- Log.e(TAG, e.toString());
- }
- }
- }
-
- void initializeAidLayout() {
-
- currentForm = Forms.AID;
-
- if(!getActionBar().isShowing()) {
-
- getActionBar().show();
- }
- setContentView(R.layout.spot_report_aid);
-
- ((Spinner)findViewById(R.id.action)).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
-
- String selectedItem = parent.getItemAtPosition(position).toString();
-
- View reportIdView = findViewById(R.id.spotReportId);
- reportIdView.setEnabled(false);
-
- if (selectedItem.equalsIgnoreCase("close")) {
-
- reportIdView.setEnabled(true);
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
-
- }
- });
-
- findViewById(R.id.aidLatitude).setEnabled(false);
- findViewById(R.id.aidLongitude).setEnabled(false);
-
- Spinner closureIds = findViewById(R.id.spotReportId);
- ArrayAdapter adapter = new ArrayAdapter<>(this,
- android.R.layout.simple_spinner_item, streetClosureReportIds);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- closureIds.setAdapter(adapter);
-
- EditText text = findViewById(R.id.aidRadiusNum);
- text.setEnabled(false);
- text.setText(String.format(Locale.ENGLISH, "%d", 0));
-
- ((SeekBar)findViewById(R.id.aidRadiusValue)).setOnSeekBarChangeListener(
- new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- ((EditText)findViewById(R.id.aidRadiusNum)).setText(
- String.format(Locale.ENGLISH, "%d", progress));
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
-
- }
- }
- );
-
- ((Spinner)findViewById(R.id.locationSource)).setOnItemSelectedListener(
- new LocationTypeListener(this, R.id.aidLatitude, R.id.aidLongitude));
-
- Button submitReportButton = findViewById(R.id.submitReport);
- submitReportButton.setOnClickListener((View view)-> {
-
- String latString = ((EditText)findViewById(R.id.aidLatitude)).getText().toString();
- String lonString = ((EditText)findViewById(R.id.aidLongitude)).getText().toString();
- int radius = Integer.parseInt(((EditText)findViewById(R.id.aidRadiusNum)).getText().toString());
- String aidType = ((Spinner)findViewById(R.id.aidType)).getSelectedItem().toString();
- int aidPosition = ((Spinner)findViewById(R.id.aidType)).getSelectedItemPosition();
- String numPersons = ((EditText)findViewById(R.id.aidNum)).getText().toString();
- String urgency = ((Spinner)findViewById(R.id.aidUrgency)).getSelectedItem().toString();
- int urgencyPosition = ((Spinner)findViewById(R.id.aidUrgency)).getSelectedItemPosition();
- String description = ((EditText)findViewById(R.id.aidDescription)).getText().toString();
- String reporter = ((EditText)findViewById(R.id.aidReporter)).getText().toString();
- String action = ((Spinner)findViewById(R.id.action)).getSelectedItem().toString();
- Object spotReportId = ((Spinner)findViewById(R.id.spotReportId)).getSelectedItem();
-
- String reportId = null;
- if(action.equalsIgnoreCase("open") || spotReportId == null){
-
- // Generate a new report id
- reportId = UUID.randomUUID().toString();
- }
- else {
-
- reportId = spotReportId.toString();
- }
-
- ArrayList errors = new ArrayList<>();
-
- if(!action.equalsIgnoreCase("open") && !action.equalsIgnoreCase("close")) {
-
- errors.add("Specify report action\n" +
- "\tOpen - Submit a new report\n" +
- "\tClose - Close task by Ref Id.\n\n");
- }
-
- if (radius <= 0) {
-
- errors.add("Radius - Specify a radius > 0\n\n");
- }
-
- if(0 == numPersons.length()) {
-
- errors.add("Num Persons - Specify the number of persons\n\n");
- }
-
- if (0 == aidPosition) {
-
- errors.add("Aid Type - Specify aid needed\n\n");
- }
-
- if (0 == urgencyPosition) {
-
- errors.add("Urgency - Specify urgency level\n\n");
- }
-
- if(0 == description.length()) {
-
- errors.add("Description - Describe the need\n\n");
- }
-
- if(0 == reporter.length()) {
-
- errors.add("Reporter - Enter your name or id\n\n");
- }
-
- if(errors.isEmpty()) {
-
- sendAidMessage(latString, lonString, radius, aidType, numPersons, urgency,
- description, reporter, action, reportId);
- }
- else {
-
- StringBuilder messageBuilder = new StringBuilder();
- messageBuilder.append("The following fields have errors:\n\n");
-
- for(String error: errors) {
-
- messageBuilder.append(error);
- }
-
- // Pop up error dialog, noting fields need to be corrected
- new AlertDialog.Builder(this)
- .setTitle("Incomplete Form")
- .setMessage(messageBuilder.toString())
- .setCancelable(true)
- .setPositiveButton("OK", null)
- .show();
- }
- });
- }
-
- void initializeStreetClosureLayout() {
-
- currentForm = Forms.STREET_CLOSURE;
-
- if(!getActionBar().isShowing()) {
-
- getActionBar().show();
- }
- setContentView(R.layout.spot_report_streetclosure);
-
- ((Spinner)findViewById(R.id.action)).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
-
- String selectedItem = parent.getItemAtPosition(position).toString();
-
- View reportIdView = findViewById(R.id.spotReportId);
- reportIdView.setEnabled(false);
-
- if (selectedItem.equalsIgnoreCase("close")) {
-
- reportIdView.setEnabled(true);
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
-
- }
- });
-
- findViewById(R.id.scLatitude).setEnabled(false);
- findViewById(R.id.scLongitude).setEnabled(false);
-
- Spinner closureIds = findViewById(R.id.spotReportId);
- ArrayAdapter adapter = new ArrayAdapter<>(this,
- android.R.layout.simple_spinner_item, streetClosureReportIds);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- closureIds.setAdapter(adapter);
-
- EditText text = findViewById(R.id.scRadiusNum);
- text.setEnabled(false);
- text.setText(String.format(Locale.ENGLISH, "%d", 0));
-
- ((SeekBar)findViewById(R.id.scRadiusValue)).setOnSeekBarChangeListener(
- new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- ((EditText)findViewById(R.id.scRadiusNum)).setText(
- String.format(Locale.ENGLISH, "%d", progress));
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
-
- }
- }
- );
-
- ((Spinner)findViewById(R.id.locationSource)).setOnItemSelectedListener(
- new LocationTypeListener(this, R.id.scLatitude, R.id.scLongitude));
-
- Button submitReportButton = findViewById(R.id.submitReport);
- submitReportButton.setOnClickListener((View view)-> {
-
- String latString = ((EditText)findViewById(R.id.scLatitude)).getText().toString();
- String lonString = ((EditText)findViewById(R.id.scLongitude)).getText().toString();
- int radius = Integer.parseInt(((EditText)findViewById(R.id.scRadiusNum)).getText().toString());
- String type = ((Spinner)findViewById(R.id.closureType)).getSelectedItem().toString();
- int typePosition = ((Spinner)findViewById(R.id.closureType)).getSelectedItemPosition();
- int actionPosition = ((Spinner)findViewById(R.id.action)).getSelectedItemPosition();
- String action = ((Spinner)findViewById(R.id.action)).getSelectedItem().toString();
- Object spotReportId = ((Spinner)findViewById(R.id.spotReportId)).getSelectedItem();
-
- String reportId = null;
- if(action.equalsIgnoreCase("open") || spotReportId == null){
-
- // Generate a new report id
- reportId = UUID.randomUUID().toString();
- }
- else {
-
- reportId = spotReportId.toString();
- }
-
- ArrayList errors = new ArrayList<>();
-
- if(!action.equalsIgnoreCase("open") && !action.equalsIgnoreCase("close")) {
-
- errors.add("Specify report action\n" +
- "\tOpen - Submit a new report\n" +
- "\tClose - Close task by Ref Id.\n\n");
- }
-
- if (radius <= 0) {
-
- errors.add("Radius - Specify a radius > 0\n\n");
- }
-
- if(0 == typePosition) {
-
- errors.add("Type - Specify a type\n\n");
- }
-
- if(0 == actionPosition) {
-
- errors.add("Action - Specify an action\n\n");
- }
-
- if(errors.isEmpty()) {
-
- sendStreetClosureMessage(latString, lonString, radius, type,
- action, reportId);
- }
- else {
-
- StringBuilder messageBuilder = new StringBuilder();
- messageBuilder.append("The following fields have errors:\n\n");
-
- for(String error: errors) {
-
- messageBuilder.append(error);
- }
-
- // Pop up error dialog, noting fields need to be corrected
- new AlertDialog.Builder(this)
- .setTitle("Incomplete Form")
- .setMessage(messageBuilder.toString())
- .setCancelable(true)
- .setPositiveButton("OK", null)
- .show();
- }
- });
- }
-
- void initializeFloodLayout() {
-
- currentForm = Forms.FLOOD;
-
- if(!getActionBar().isShowing()) {
-
- getActionBar().show();
- }
- setContentView(R.layout.spot_report_flooding);
-
- ((Spinner)findViewById(R.id.action)).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
-
- String selectedItem = parent.getItemAtPosition(position).toString();
-
- View reportIdView = findViewById(R.id.spotReportId);
- reportIdView.setEnabled(false);
-
- if (selectedItem.equalsIgnoreCase("close")) {
-
- reportIdView.setEnabled(true);
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
-
- }
- });
-
- findViewById(R.id.floodLatitude).setEnabled(false);
- findViewById(R.id.floodLongitude).setEnabled(false);
-
- Spinner closureIds = findViewById(R.id.spotReportId);
- ArrayAdapter adapter = new ArrayAdapter<>(this,
- android.R.layout.simple_spinner_item, streetClosureReportIds);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- closureIds.setAdapter(adapter);
-
- EditText text = findViewById(R.id.floodRadiusNum);
- text.setEnabled(false);
- text.setText(String.format(Locale.ENGLISH, "%d", 0));
-
- ((SeekBar)findViewById(R.id.floodRadiusValue)).setOnSeekBarChangeListener(
- new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- ((EditText)findViewById(R.id.floodRadiusNum)).setText(
- String.format(Locale.ENGLISH, "%d", progress));
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
-
- }
- }
- );
-
- EditText depthText = findViewById(R.id.floodDepthNum);
- depthText.setEnabled(false);
- depthText.setText(String.format(Locale.ENGLISH, "%d", 0));
- ((SeekBar)findViewById(R.id.floodDepthValue)).setOnSeekBarChangeListener(
- new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- ((EditText)findViewById(R.id.floodDepthNum)).setText(
- String.format(Locale.ENGLISH, "%d", progress));
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
-
- }
- }
- );
-
- ((Spinner) findViewById(R.id.locationSource)).setOnItemSelectedListener(
- new LocationTypeListener(this, R.id.floodLatitude, R.id.floodLongitude));
-
- Button submitReportButton = findViewById(R.id.submitReport);
- submitReportButton.setOnClickListener((View view)-> {
-
- String latString = ((EditText)findViewById(R.id.floodLatitude)).getText().toString();
- String lonString = ((EditText)findViewById(R.id.floodLongitude)).getText().toString();
- int radius = Integer.parseInt(((EditText)findViewById(R.id.floodRadiusNum)).getText().toString());
- String featureType = ((Spinner)findViewById(R.id.featureType)).getSelectedItem().toString();
- int featureTypePosition = ((Spinner)findViewById(R.id.featureType)).getSelectedItemPosition();
- int depth = Integer.parseInt(((EditText)findViewById(R.id.floodDepthNum)).getText().toString());
- String method = ((Spinner)findViewById(R.id.observationMode)).getSelectedItem().toString();
- int methodPosition = ((Spinner)findViewById(R.id.observationMode)).getSelectedItemPosition();
- String action = ((Spinner)findViewById(R.id.action)).getSelectedItem().toString();
- Object spotReportId = ((Spinner)findViewById(R.id.spotReportId)).getSelectedItem();
-
- String reportId = null;
- if(action.equalsIgnoreCase("open") || spotReportId == null){
-
- // Generate a new report id
- reportId = UUID.randomUUID().toString();
- }
- else {
-
- reportId = spotReportId.toString();
- }
-
- ArrayList errors = new ArrayList<>();
-
- if(!action.equalsIgnoreCase("open") && !action.equalsIgnoreCase("close")) {
-
- errors.add("Specify report action\n" +
- "\tOpen - Submit a new report\n" +
- "\tClose - Close task by Ref Id.\n\n");
- }
-
- if (radius <= 0) {
-
- errors.add("Radius - Specify a radius > 0\n\n");
- }
-
- if(0 == featureTypePosition) {
-
- errors.add("Feature Type - Specify a type\n\n");
- }
-
- if(depth <= 0) {
-
- errors.add("Depth - Specify a depth measurement > 0\n\n");
- }
-
- if(0 == methodPosition) {
-
- errors.add("Method - Specify method of observation\n\n");
- }
-
- if(errors.isEmpty()) {
-
- sendFloodMessage(latString, lonString, radius, featureType, depth, method,
- action, reportId);
- }
- else {
-
- StringBuilder messageBuilder = new StringBuilder();
- messageBuilder.append("The following fields have errors:\n\n");
-
- for(String error: errors) {
-
- messageBuilder.append(error);
- }
-
- // Pop up error dialog, noting fields need to be corrected
- new AlertDialog.Builder(this)
- .setTitle("Incomplete Form")
- .setMessage(messageBuilder.toString())
- .setCancelable(true)
- .setPositiveButton("OK", null)
- .show();
- }
- });
- }
-
- void initializeMedicalLayout() {
-
- currentForm = Forms.MEDICAL;
-
- if(!getActionBar().isShowing()) {
-
- getActionBar().show();
- }
- setContentView(R.layout.spot_report_medical);
-
- ((Spinner)findViewById(R.id.action)).setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
-
- String selectedItem = parent.getItemAtPosition(position).toString();
-
- View reportIdView = findViewById(R.id.spotReportId);
- reportIdView.setEnabled(false);
-
- if (selectedItem.equalsIgnoreCase("close")) {
-
- reportIdView.setEnabled(true);
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
-
- }
- });
-
- findViewById(R.id.medLatitude).setEnabled(false);
- findViewById(R.id.medLongitude).setEnabled(false);
-
- Spinner closureIds = findViewById(R.id.spotReportId);
- ArrayAdapter adapter = new ArrayAdapter<>(this,
- android.R.layout.simple_spinner_item, streetClosureReportIds);
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- closureIds.setAdapter(adapter);
-
- EditText text = findViewById(R.id.medRadiusNum);
- text.setEnabled(false);
- text.setText(String.format(Locale.ENGLISH, "%d", 0));
-
- ((SeekBar)findViewById(R.id.medRadiusValue)).setOnSeekBarChangeListener(
- new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- ((EditText)findViewById(R.id.medRadiusNum)).setText(
- String.format(Locale.ENGLISH, "%d", progress));
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
-
- }
- }
- );
-
- ((Spinner)findViewById(R.id.locationSource)).setOnItemSelectedListener(
- new LocationTypeListener(this, R.id.medLatitude, R.id.medLongitude));
-
- Button submitReportButton = findViewById(R.id.submitReport);
- submitReportButton.setOnClickListener((View view)-> {
-
- String latString = ((EditText)findViewById(R.id.medLatitude)).getText().toString();
- String lonString = ((EditText)findViewById(R.id.medLongitude)).getText().toString();
- int radius = Integer.parseInt(((EditText)findViewById(R.id.medRadiusNum)).getText().toString());
- String description = ((EditText)findViewById(R.id.medSign)).getText().toString();
- String measure = ((EditText)findViewById(R.id.medValue)).getText().toString();
- boolean emergency = ((CheckBox)findViewById(R.id.isEmergency)).isChecked();
- String action = ((Spinner)findViewById(R.id.action)).getSelectedItem().toString();
- Object spotReportId = ((Spinner)findViewById(R.id.spotReportId)).getSelectedItem();
-
- String reportId = null;
- if(action.equalsIgnoreCase("open") || spotReportId == null){
-
- // Generate a new report id
- reportId = UUID.randomUUID().toString();
- }
- else {
-
- reportId = spotReportId.toString();
- }
-
- ArrayList errors = new ArrayList<>();
-
- if(!action.equalsIgnoreCase("open") && !action.equalsIgnoreCase("close")) {
-
- errors.add("Specify report action\n" +
- "\tOpen - Submit a new report\n" +
- "\tClose - Close task by Ref Id.\n\n");
- }
-
- if(radius <= 0) {
-
- errors.add("Radius - Specify a radius > 0\n\n");
- }
-
- if(0 == description.length()) {
-
- errors.add("Description - Describe medical condition\n\n");
- }
-
- if(0 == measure.length()) {
-
- errors.add("Measure - Enter measurement (heart rate, bp, etc).\n\n");
- }
-
- if(errors.isEmpty()) {
-
- sendMedicalMessage(latString, lonString, radius, description, measure, emergency,
- action, reportId);
- }
- else {
-
- StringBuilder messageBuilder = new StringBuilder();
- messageBuilder.append("The following fields have errors:\n\n");
-
- for(String error: errors) {
-
- messageBuilder.append(error);
- }
-
- // Pop up error dialog, noting fields need to be corrected
- new AlertDialog.Builder(this)
- .setTitle("Incomplete Form")
- .setMessage(messageBuilder.toString())
- .setCancelable(true)
- .setPositiveButton("OK", null)
- .show();
- }
- });
- }
-
- void initializeTrackLayout() {
-
- currentForm = Forms.MEDICAL;
-
- if(!getActionBar().isShowing()) {
-
- getActionBar().show();
- }
- setContentView(R.layout.spot_report_track);
- findViewById(R.id.trackLatitude).setEnabled(false);
- findViewById(R.id.trackLongitude).setEnabled(false);
-
- EditText text = findViewById(R.id.trackConfidenceNum);
- text.setEnabled(false);
- text.setText(String.format(Locale.ENGLISH, "%d", 0));
- ((SeekBar)findViewById(R.id.trackConfidenceValue)).setOnSeekBarChangeListener(
- new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- ((EditText)findViewById(R.id.trackConfidenceNum)).setText(
- String.format(Locale.ENGLISH, "%d", progress));
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
-
- }
- }
- );
-
- ((Spinner)findViewById(R.id.locationSource)).setOnItemSelectedListener(
- new LocationTypeListener(this, R.id.trackLatitude, R.id.trackLongitude));
-
- Button submitReportButton = findViewById(R.id.submitReport);
- submitReportButton.setOnClickListener((View view)-> {
-
- double latString = Double.valueOf(((EditText)findViewById(R.id.trackLatitude)).getText().toString());
- double lonString = Double.valueOf(((EditText)findViewById(R.id.trackLongitude)).getText().toString());
- double confidence = Double.valueOf(((EditText)findViewById(R.id.trackConfidenceNum)).getText().toString());
- String resourceType = ((Spinner)findViewById(R.id.trackedResource)).getSelectedItem().toString();
- int typePosition = ((Spinner)findViewById(R.id.trackedResource)).getSelectedItemPosition();
- String resourceId = ((EditText)findViewById(R.id.trackResourceId)).getText().toString();
- String resourceLabel = ((EditText)findViewById(R.id.trackLabel)).getText().toString();
- String trackingMethod = ((Spinner)findViewById(R.id.trackedMethod)).getSelectedItem().toString();
- int methodPosition = ((Spinner)findViewById(R.id.trackedMethod)).getSelectedItemPosition();
-
- ArrayList errors = new ArrayList<>();
-
- if (confidence <= 0) {
-
- errors.add("confidence - Specify a confidence > 0\n\n");
- }
-
- if(0 == typePosition) {
-
- errors.add("Type - Specify a type\n\n");
- }
-
- if(0 == resourceId.length()) {
-
- errors.add("Resource Id - Specify a resource id\n\n");
- }
-
- if(0 == resourceLabel.length()) {
-
- errors.add("Resource Label - Specify a resource label\n\n");
- }
-
- if(0 == methodPosition) {
-
- errors.add("Tracking Method - Specify a method\n\n");
- }
-
- if(errors.isEmpty()) {
-
- // Create and transmit report
- setLastAction(SpotReportActions.ACTION_SUBMIT_TRACK_REPORT);
- Intent submitReportIntent = new Intent(SpotReportActions.ACTION_SUBMIT_TRACK_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("lat", latString);
- submitReportIntent.putExtra("lon", lonString);
- submitReportIntent.putExtra("confidence", confidence);
- submitReportIntent.putExtra("type", resourceType);
- submitReportIntent.putExtra("resourceId", resourceId);
- submitReportIntent.putExtra("resourceLabel", resourceLabel);
- submitReportIntent.putExtra("method", trackingMethod);
- submitReportIntent.putExtra("action", "open");
- submitReportIntent.putExtra("id", UUID.randomUUID().toString());
- submitReportIntent.putExtra(Intent.EXTRA_RESULT_RECEIVER, submitRequestResultReceiver);
- sendBroadcast(submitReportIntent);
- }
- else {
-
- StringBuilder messageBuilder = new StringBuilder();
- messageBuilder.append("The following fields have errors:\n\n");
-
- for(String error: errors) {
-
- messageBuilder.append(error);
- }
-
- // Pop up error dialog, noting fields need to be corrected
- new AlertDialog.Builder(this)
- .setTitle("Incomplete Form")
- .setMessage(messageBuilder.toString())
- .setCancelable(true)
- .setPositiveButton("OK", null)
- .show();
- }
- });
- }
-
- void initializeImageCaptureLayout() {
-
- currentForm = Forms.IMAGE;
-
- setImageView();
-
- if(!getActionBar().isShowing()) {
-
- getActionBar().show();
- }
- setContentView(R.layout.spot_report_image_capture);
-
- Button captureImageButton = findViewById(R.id.captureImage);
- captureImageButton.setOnClickListener((View v)-> dispatchTakePictureIntent());
-
- Button submitReportButton = findViewById(R.id.submitReport);
- submitReportButton.setOnClickListener((View view)-> {
-
- // Get data from incident type field
- Spinner spinner = findViewById(R.id.reportType);
- int categoryPos = spinner.getSelectedItemPosition();
- String category = spinner.getSelectedItem().toString();
-
- // Get location data from selected source
- String locationSource = ((Spinner)findViewById(R.id.locationSource)).getSelectedItem().toString();
-
- // Get the name of the report/observation
- String reportName = ((TextView)findViewById(R.id.reportName)).getText().toString();
-
- // Get the description
- String reportDescription = ((TextView)findViewById(R.id.description)).getText().toString();
-
- // If the user has filled out the form completely
- if ((0 == categoryPos) || reportName.isEmpty()) {
-
- StringBuilder messageBuilder = new StringBuilder();
- messageBuilder.append("The following fields have errors:\n\n");
-
- if (0 == categoryPos) {
- messageBuilder.append("Report Category - Select report category\n\n");
- }
-
- if (reportName.isEmpty()) {
- messageBuilder.append("Report Name - Enter name\n\n");
- }
-
- // Pop up error dialog, noting fields need to be corrected
- new AlertDialog.Builder(this)
- .setTitle("Incomplete Form")
- .setMessage(messageBuilder.toString())
- .setCancelable(true)
- .setPositiveButton("OK", null)
- .show();
- }
- else {
-
- // Create and transmit report
- setLastAction(SpotReportActions.ACTION_SUBMIT_IMAGE_REPORT);
- Intent submitReportIntent = new Intent(SpotReportActions.ACTION_SUBMIT_IMAGE_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("item", category);
- submitReportIntent.putExtra("location", locationSource);
- submitReportIntent.putExtra("name", reportName);
- submitReportIntent.putExtra("description", reportDescription);
- String uriString = null;
- Uri imageUri = getImageUri();
- if (null != imageUri) {
-
- uriString = imageUri.toString();
- }
- submitReportIntent.putExtra("uriString", uriString);
- submitReportIntent.putExtra(Intent.EXTRA_RESULT_RECEIVER, submitRequestResultReceiver);
- sendBroadcast(submitReportIntent);
- }
- });
- }
-}
diff --git a/sensorhub-android-app/src/org/sensorhub/android/spotreport/SubmitRequestResultReceiver.java b/sensorhub-android-app/src/org/sensorhub/android/spotreport/SubmitRequestResultReceiver.java
deleted file mode 100644
index 0a0a0298..00000000
--- a/sensorhub-android-app/src/org/sensorhub/android/spotreport/SubmitRequestResultReceiver.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
-
- ******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.spotreport;
-
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.ResultReceiver;
-import android.widget.EditText;
-import android.widget.TextView;
-
-import org.sensorhub.android.R;
-
-/**
- *
- */
-class SubmitRequestResultReceiver extends ResultReceiver {
-
- private static final int SUBMIT_REPORT_FAILURE = 0;
- private static final int SUBMIT_REPORT_SUCCESS = 1;
-
- SpotReportActivity activity;
-
- SubmitRequestResultReceiver(SpotReportActivity activity, Handler handler) {
-
- super(handler);
- this.activity = activity;
- }
-
- @Override
- protected void onReceiveResult(int resultCode, Bundle resultData) {
- super.onReceiveResult(resultCode, resultData);
-
- DialogInterface.OnClickListener clickListener = null;
- String title = null;
- String message = null;
-
- if (resultCode == SUBMIT_REPORT_FAILURE) {
-
- title = "Report Submission Failed";
- message = "Report failed to be submit, check general settings.";
- }
- else if (resultCode == SUBMIT_REPORT_SUCCESS) {
-
- title = "Report Submitted";
- message = "Report Submitted Successfully";
-
- if (activity.getLastAction().equals(SpotReportActions.ACTION_SUBMIT_IMAGE_REPORT)) {
-
- clickListener = (DialogInterface dialogInterface, int i) -> {
- ((TextView) activity.findViewById(R.id.reportName)).setText(null);
- ((TextView) activity.findViewById(R.id.description)).setText(null);
- activity.clearImageData();
- };
-
- }
- else if (activity.getLastAction().equals(SpotReportActions.ACTION_SUBMIT_MEDICAL_REPORT)) {
-
- clickListener = (DialogInterface dialogInterface, int i) -> {
- ((EditText) activity.findViewById(R.id.medSign)).setText(null);
- ((EditText) activity.findViewById(R.id.medValue)).setText(null);
- };
- }
- else {
-
- clickListener = (DialogInterface dialogInterface, int i) -> { };
- }
-
- activity.clearLastAction();
- }
-
- new AlertDialog.Builder(activity)
- .setTitle(title)
- .setMessage(message)
- .setCancelable(true)
- .setPositiveButton("OK", clickListener)
- .show();
- }
-}
diff --git a/sensorhub-android-app/src/org/sensorhub/android/spotreport/TaskAcceptanceListener.java b/sensorhub-android-app/src/org/sensorhub/android/spotreport/TaskAcceptanceListener.java
deleted file mode 100644
index 8bfc7293..00000000
--- a/sensorhub-android-app/src/org/sensorhub/android/spotreport/TaskAcceptanceListener.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
-
- ******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.spotreport;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.location.Location;
-import android.location.LocationManager;
-import android.support.v4.content.ContextCompat;
-import android.util.Log;
-import android.webkit.HttpAuthHandler;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.sensorhub.android.R;
-
-public class TaskAcceptanceListener implements DialogInterface.OnClickListener {
-
- private static final String TAG = "TaskAcceptanceListener";
-
- WebClient webClient;
-
- SpotReportActivity spotReportActivity;
- String taskMessage;
-
- public TaskAcceptanceListener(SpotReportActivity activity, String task, double longitude, double latitude) {
-
- webClient = new WebClient(activity, longitude, latitude);
- taskMessage = task;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- if (spotReportActivity.getCurrentForm() != SpotReportActivity.Forms.WEB) {
-
- spotReportActivity.setCurrentForm(SpotReportActivity.Forms.WEB);
-
- spotReportActivity.getActionBar().hide();
- spotReportActivity.setContentView(R.layout.spot_report_web_view);
- WebView webView = spotReportActivity.findViewById(R.id.webView);
- WebView.setWebContentsDebuggingEnabled(true);
- webView.getSettings().setJavaScriptEnabled(true);
- spotReportActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-
- webView.loadUrl("http://scira.georobotix.io:8181/");
-
- webView.setWebViewClient(webClient);
- }
-
- try {
-
- JSONObject receivedTask = new JSONObject(taskMessage);
- JSONObject observation = receivedTask.getJSONObject("result");
- String id = observation.getString("id");
- String type = observation.getString("observationType");
-
- JSONObject params = observation.getJSONObject("params");
-
- JSONObject location = params.getJSONObject("location");
- JSONObject geometry = location.getJSONObject("geometry");
- JSONArray coords = geometry.getJSONArray("coordinates");
- String longitude = coords.getString(0);
- String latitude = coords.getString(1);
-
- if("aid".equalsIgnoreCase(type)) {
-
- String aidType = params.getString("aidType");
- String urgency = params.getString("urgency");
- String numPersons = params.getString("aidPersons");
- String description = params.getString("description");
- String reporter = params.getString("reporter");
- int radius = geometry.getInt("radius");
-
- spotReportActivity.sendAidMessage(latitude, longitude, radius, aidType,
- numPersons, urgency, description, reporter, "ongoing", id);
-
- spotReportActivity.taskAccepted(id, type);
- }
- else if("flood".equalsIgnoreCase(type)) {
-
- String featureType = params.getString("featureType");
- String method = params.getString("method");
- double depth = params.getDouble("obsDepth");
- int radius = geometry.getInt("radius");
-
- spotReportActivity.sendFloodMessage(latitude, longitude, radius, featureType,
- (int)depth, method, "ongoing", id);
-
- spotReportActivity.taskAccepted(id, type);
- }
-// else if ("med".equalsIgnoreCase(type)) {
-//
-// String description = params.getString("description");
-// int radius = geometry.getInt("radius");
-//
-// spotReportActivity.sendMedicalMessage(latitude, longitude, radius, description,
-// String measure, boolean emergency, "ongoing", id);
-//
-// spotReportActivity.taskAccepted(id, type);
-// }
- else {
-
- String closureType = params.getString("closureType");
- int radius = geometry.getInt("radius");
-
- spotReportActivity.sendStreetClosureMessage(latitude, longitude, radius, closureType,
- "ongoing", id);
-
- spotReportActivity.taskAccepted(id, type);
- }
-
- } catch(JSONException e) {
-
- Log.d(TAG, "Failed parsing JSON message");
- }
-
- }
-}
diff --git a/sensorhub-android-app/src/org/sensorhub/android/spotreport/WebClient.java b/sensorhub-android-app/src/org/sensorhub/android/spotreport/WebClient.java
deleted file mode 100644
index 01b65ee9..00000000
--- a/sensorhub-android-app/src/org/sensorhub/android/spotreport/WebClient.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.sensorhub.android.spotreport;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.location.Location;
-import android.location.LocationManager;
-import android.support.v4.content.ContextCompat;
-import android.util.Log;
-import android.webkit.HttpAuthHandler;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-public class WebClient extends WebViewClient {
-
- private static final String TAG = "WebClient";
-
- SpotReportActivity spotReportActivity;
- double toLongitude;
- double toLatitude;
-
- public WebClient(SpotReportActivity activity, double longitude, double latitude) {
-
- spotReportActivity = activity;
- toLongitude = longitude;
- toLatitude = latitude;
- }
-
- private JSONObject buildRequest() {
-
- JSONObject jsonRequest = null;
-
- try
- {
- int grant = ContextCompat.checkSelfPermission(spotReportActivity,
- Manifest.permission.ACCESS_FINE_LOCATION);
-
- if (PackageManager.PERMISSION_GRANTED == grant) {
-
- LocationManager locationManager =
- (LocationManager)spotReportActivity.getSystemService(Context.LOCATION_SERVICE);
-
- Location location =
- locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
-
- JSONArray jsonStartCoord = new JSONArray();
- jsonStartCoord.put(location.getLongitude());
- jsonStartCoord.put(location.getLatitude());
-
- JSONArray jsonStopCoord = new JSONArray();
- jsonStopCoord.put(toLongitude);
- jsonStopCoord.put(toLatitude);
-
- JSONArray jsonCoordArray = new JSONArray();
- jsonCoordArray.put(jsonStartCoord);
- jsonCoordArray.put(jsonStopCoord);
-
- JSONObject waypointsJson = new JSONObject();
- waypointsJson.put("type", "MultiPoint");
- waypointsJson.put("coordinates", jsonCoordArray);
-
- jsonRequest = new JSONObject();
- jsonRequest.put("name", "TestRoute");
- jsonRequest.put("waypoints", waypointsJson);
- jsonRequest.put("dataset", "SCIRA");
- jsonRequest.put("context", "evacuation");
- }
-
- } catch (JSONException e) {
-
- Log.e(TAG, "Failed to build JSON payload for route");
- }
-
- return jsonRequest;
- }
-
- @Override
- public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
- String host, String realm) {
-
- handler.proceed("user", "user@SCIRA");
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
-
- JSONObject jsonRequest = buildRequest();
-
- if (null != jsonRequest) {
-
- String routeUrl = "'http://skymanticswps.eastus.azurecontainer.io:8080/scira/routes?mode=sync'";
-
- StringBuilder request = new StringBuilder();
- request.append("javascript:makeRouteRequest(")
- .append(routeUrl)
- .append(",")
- .append("'")
- .append(jsonRequest.toString())
- .append("'")
- .append(")");
-
- Log.d(TAG, request.toString());
-
- view.evaluateJavascript(request.toString(), null);
- }
- }
-}
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconLocationOutput.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconLocationOutput.java
index 9f5e1e91..5c3fa8e1 100644
--- a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconLocationOutput.java
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/BLEBeaconLocationOutput.java
@@ -105,28 +105,6 @@ public double getAverageSamplingPeriod() {
protected void sendMeasurement(double[] estLocation, Beacon[] beacons) {
- Log.d("BLEBeaconLocationOutput", "Publishing Intent");
-
- Intent submitReportIntent = new Intent(ACTION_SUBMIT_TRACK_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("lat", estLocation[0]);
- submitReportIntent.putExtra("lon", estLocation[1]);
- double confidence = 0;
-
- if (parentSensor.getBeaconDistance(beacons[0]) > 0) {
-
- confidence = (1 / parentSensor.getBeaconDistance(beacons[0]));
- }
-
- submitReportIntent.putExtra("confidence", confidence);
- submitReportIntent.putExtra("type", "device");
- submitReportIntent.putExtra("resourceId", parentSensor.getConfiguration().name);
- submitReportIntent.putExtra("resourceLabel", parentSensor.getConfiguration().name);
- submitReportIntent.putExtra("method", "bt_beacon");
- parentSensor.getConfiguration().androidContext.sendBroadcast(submitReportIntent);
-
- Log.d("BLEBeaconLocationOutput", "Published Intent");
-
DataBlock dataBlock = posDataStruct.createDataBlock();
double sampleTime = System.currentTimeMillis() / 1000;
// TODO: Handle null or {0,0,0} better
diff --git a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/NearestBeaconOutput.java b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/NearestBeaconOutput.java
index 7d517c18..ef2f92b8 100644
--- a/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/NearestBeaconOutput.java
+++ b/sensorhub-android-blebeacon/src/main/java/org/sensorhub/impl/sensor/blebeacon/NearestBeaconOutput.java
@@ -88,31 +88,6 @@ protected void sendMeasurement(Beacon beacon, String roomDesc) {
double sampleTime = System.currentTimeMillis() / 1000;
double[] locationDecDeg = parentSensor.getBeaconLocation(beacon);
- Log.d("NearestBeaconOutput", "Publishing Intent");
-
- Intent submitReportIntent = new Intent(ACTION_SUBMIT_TRACK_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("lat", locationDecDeg[0]);
- submitReportIntent.putExtra("lon", locationDecDeg[1]);
- double confidence = 0;
-
- if (parentSensor.getBeaconDistance(beacon) > 0) {
-
- confidence = (1 / parentSensor.getBeaconDistance(beacon));
- }
-
- submitReportIntent.putExtra("confidence", confidence);
- submitReportIntent.putExtra("type", "device");
- submitReportIntent.putExtra("resourceId", parentSensor.getConfiguration().name);
- submitReportIntent.putExtra("resourceLabel", parentSensor.getConfiguration().name);
- submitReportIntent.putExtra("method", "bt_beacon");
- submitReportIntent.putExtra("featureReference", roomDesc); // TODO: make sure spot report can receive this
- submitReportIntent.putExtra("action", "open");
- parentSensor.getConfiguration().androidContext.sendBroadcast(submitReportIntent);
-
- Log.d("NearestBeaconOutput", "Published Intent");
-
-
dataBlock.setDoubleValue(0, sampleTime);
dataBlock.setDoubleValue(1, locationDecDeg[0]);
dataBlock.setDoubleValue(2, locationDecDeg[1]);
diff --git a/sensorhub-android-lib/build.gradle b/sensorhub-android-lib/build.gradle
index 19120e18..d12a8325 100644
--- a/sensorhub-android-lib/build.gradle
+++ b/sensorhub-android-lib/build.gradle
@@ -20,7 +20,7 @@ dependencies {
api project(':sensorhub-driver-android')
api project(':sensorhub-android-blebeacon')
api project(':sensorhub-android-flirone')
- api project(':sensorhub-android-spotreport')
+// api project(':sensorhub-android-spotreport')
//api project(':sensorhub-android-dji')
implementation 'org.slf4j:slf4j-android:1.6.1-RC1'
implementation 'javax.xml.stream:stax-api:1.0-2'
diff --git a/sensorhub-android-spotreport/.gitignore b/sensorhub-android-spotreport/.gitignore
deleted file mode 100644
index d4a54541..00000000
--- a/sensorhub-android-spotreport/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/sdk_javadoc/
diff --git a/sensorhub-android-spotreport/AndroidManifest.xml b/sensorhub-android-spotreport/AndroidManifest.xml
deleted file mode 100644
index 8dce83b0..00000000
--- a/sensorhub-android-spotreport/AndroidManifest.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
diff --git a/sensorhub-android-spotreport/assets/empty b/sensorhub-android-spotreport/assets/empty
deleted file mode 100644
index e69de29b..00000000
diff --git a/sensorhub-android-spotreport/build.gradle b/sensorhub-android-spotreport/build.gradle
deleted file mode 100644
index c81918b5..00000000
--- a/sensorhub-android-spotreport/build.gradle
+++ /dev/null
@@ -1,33 +0,0 @@
-apply plugin: 'com.android.library'
-
-description = 'Spot Report'
-ext.details = 'Driver for Spot Reports'
-
-dependencies {
- //compile 'org.sensorhub:sensorhub-core:' + oshCoreVersion
- //compile 'org.sensorhub:sensorhub-driver-videocam:[1.0,2.0)'
- api project(':sensorhub-core')
- api project(':sensorhub-driver-videocam')
- api fileTree(dir: 'libs', include: ['*.jar'])
-}
-
-android {
- compileSdkVersion rootProject.compileSdkVersion
- buildToolsVersion rootProject.buildToolsVersion
-
- defaultConfig {
- minSdkVersion rootProject.minSdkVersion
- targetSdkVersion rootProject.targetSdkVersion
- }
-
- sourceSets {
- main {
- manifest.srcFile 'AndroidManifest.xml'
- java.srcDirs = ['src']
- res.srcDirs = ['res']
- assets.srcDirs = ['assets']
- jniLibs.srcDirs = ['libs']
- }
- }
-}
-
diff --git a/sensorhub-android-spotreport/proguard-project.txt b/sensorhub-android-spotreport/proguard-project.txt
deleted file mode 100644
index f2fe1559..00000000
--- a/sensorhub-android-spotreport/proguard-project.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# To enable ProGuard in your project, edit project.properties
-# to define the proguard.config property as described in that file.
-#
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in ${sdk.dir}/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the ProGuard
-# include property in project.properties.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/sensorhub-android-spotreport/project.properties b/sensorhub-android-spotreport/project.properties
deleted file mode 100644
index c1f4faf7..00000000
--- a/sensorhub-android-spotreport/project.properties
+++ /dev/null
@@ -1,16 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-21
-android.library=true
-android.library.reference.1=../sensorhub-android-lib
diff --git a/sensorhub-android-spotreport/res/values/strings.xml b/sensorhub-android-spotreport/res/values/strings.xml
deleted file mode 100644
index fd5562fb..00000000
--- a/sensorhub-android-spotreport/res/values/strings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- sensorhub-android-spotreport
-
-
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportAidOutput.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportAidOutput.java
deleted file mode 100644
index e25eb36e..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportAidOutput.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/**************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
- ******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import net.opengis.swe.v20.DataBlock;
-import net.opengis.swe.v20.DataComponent;
-import net.opengis.swe.v20.DataEncoding;
-import net.opengis.swe.v20.Quantity;
-import net.opengis.swe.v20.Text;
-import net.opengis.swe.v20.Time;
-import net.opengis.swe.v20.Vector;
-
-import org.sensorhub.api.sensor.SensorDataEvent;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.vast.swe.SWEHelper;
-import org.vast.swe.helper.GeoPosHelper;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-import java.util.UUID;
-
-/**
- *
- * Implementation of data interface for Spot Reports
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportAidOutput extends AbstractSensorOutput {
-
- // keep logger name short because in LogCat it's max 23 chars
- private static final Logger log = LoggerFactory.getLogger(SpotReportAidOutput.class.getSimpleName());
-
- // Data Associated with Broadcast Receivers and Intents
- private static final String ACTION_SUBMIT_AID_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_AID";
- private static final int SUBMIT_REPORT_FAILURE = 0;
- private static final int SUBMIT_REPORT_SUCCESS = 1;
-
- private static final String DATA_ID = "id";
- private static final String DATA_LAT = "lat";
- private static final String DATA_LON = "lon";
- private static final String DATA_RADIUS = "radius";
- private static final String DATA_AID_TYPE = "aidType";
- private static final String DATA_NUM_PERSONS = "numPersons";
- private static final String DATA_URGENCY = "urgency";
- private static final String DATA_DESCRIPTION = "description";
- private static final String DATA_REPORTER = "reporter";
- private static final String DATA_ACTION = "action";
- private SpotReportReceiver broadcastReceiver = new SpotReportReceiver();
-
- // SWE DataBlock elements
- private static final String DATA_RECORD_REPORT_TIME_LABEL = "time";
- private static final String DATA_RECORD_REPORT_ID_LABEL = "id";
- private static final String DATA_RECORD_REPORT_LOC_LABEL = "location";
- private static final String DATA_RECORD_REPORT_RADIUS_LABEL = "radius";
- private static final String DATA_RECORD_REPORT_AID_TYPE_LABEL = "aidType";
- private static final String DATA_RECORD_REPORT_NUM_PERSONS_LABEL = "numPersons";
- private static final String DATA_RECORD_REPORT_URGENCY_LABEL = "urgency";
- private static final String DATA_RECORD_REPORT_DESCRIPTION_LABEL = "description";
- private static final String DATA_RECORD_REPORT_REPORTER_LABEL = "reporter";
- private static final String DATA_RECORD_REPORT_ACTION_LABEL = "action";
-
- private static final String DATA_RECORD_NAME = "Aid Spot Report";
- private static final String DATA_RECORD_DESCRIPTION =
- "A report generated by visual observance and classification which is accompanied by a" +
- " location, description, and other data";
- private static final String DATA_RECORD_DEFINITION =
- SWEHelper.getPropertyUri("AidSpotReport");
-
- private DataComponent dataStruct;
- private DataEncoding dataEncoding;
-
- private Context context;
- private String name;
-
- SpotReportAidOutput(SpotReportDriver parentModule) {
-
- super(parentModule);
- this.name = parentModule.getName() + " Aid";
- context = getParentModule().getConfiguration().androidContext;
- }
-
- @Override
- public String getName() {
-
- return name;
- }
-
- /**
- * Initialize the output data structure
- *
- * @throws SensorException
- */
- void init() throws SensorException {
-
- // Build data structure ********************************************************************
- SWEHelper sweHelper = new SWEHelper();
- dataStruct = sweHelper.newDataRecord();
- dataStruct.setDescription(DATA_RECORD_DESCRIPTION);
- dataStruct.setDefinition(DATA_RECORD_DEFINITION);
- dataStruct.setName(DATA_RECORD_NAME);
-
- // Add time stamp component to data record
- Time time = sweHelper.newTimeStampIsoUTC();
- dataStruct.addComponent(DATA_RECORD_REPORT_TIME_LABEL, time);
-
- Text id = sweHelper.newText(SWEHelper.getPropertyUri("ID"),
- "ID",
- "A unique identifier for the report");
- dataStruct.addComponent(DATA_RECORD_REPORT_ID_LABEL, id);
-
- // Add the location component of the data record
- GeoPosHelper geoPosHelper = new GeoPosHelper();
- Vector locationVectorLLA = geoPosHelper.newLocationVectorLLA(null);
- locationVectorLLA.setLocalFrame(parentSensor.localFrameURI);
- dataStruct.addComponent(DATA_RECORD_REPORT_LOC_LABEL, locationVectorLLA);
-
- Quantity radius = sweHelper.newQuantity(SWEHelper.getPropertyUri("Radius"),
- "Radius",
- "Radius in ft. of reported location where observation may be contained or found",
- "ft.");
- dataStruct.addComponent(DATA_RECORD_REPORT_RADIUS_LABEL, radius);
-
- Text aidType = sweHelper.newText(SWEHelper.getPropertyUri("AidType"),
- "Aid Type",
- "An identifier of the type of aid required");
- dataStruct.addComponent(DATA_RECORD_REPORT_AID_TYPE_LABEL, aidType);
-
- Text numPersons = sweHelper.newText(SWEHelper.getPropertyUri("NumPersons"),
- "Number of Persons",
- "A magnitude value denoting the number of persons needing assistance at the location");
- dataStruct.addComponent(DATA_RECORD_REPORT_NUM_PERSONS_LABEL, numPersons);
-
- Text urgency = sweHelper.newText(SWEHelper.getPropertyUri("Urgency"),
- "Urgency",
- "An identifier of the level of urgency for the need described by this report");
- dataStruct.addComponent(DATA_RECORD_REPORT_URGENCY_LABEL, urgency);
-
- Text description = sweHelper.newText(SWEHelper.getPropertyUri("Description"),
- "Description",
- "A description of conditions, observation, or other information necessary to convey need of aid");
- dataStruct.addComponent(DATA_RECORD_REPORT_DESCRIPTION_LABEL, description);
-
- Text reporter = sweHelper.newText(SWEHelper.getPropertyUri("Reporter"),
- "Reporter",
- "An identifier of the person who submitted the report");
- dataStruct.addComponent(DATA_RECORD_REPORT_REPORTER_LABEL, reporter);
-
- Text action = sweHelper.newText(SWEHelper.getPropertyUri("Action"),
- "Action",
- "The action associated with the event");
- dataStruct.addComponent(DATA_RECORD_REPORT_ACTION_LABEL, action);
-
- // Setup data encoding *********************************************************************
- this.dataEncoding = sweHelper.newTextEncoding(",", "\n");
- }
-
- /**
- * Populate and submit an instance of the SpotReport.
- *
- * @param id
- * @param lat Latitude
- * @param lon Longitude
- * @param radius Radius of validity
- * @param aidType Type of aid being requested
- * @param numPersons Number of persons requiring aid
- * @param urgency Urgency for the aid
- * @param description Description of the observation
- * @param reporter Identifier for person making the report
- */
- private void submitReport(String id, String lat, String lon, int radius, String aidType,
- String numPersons, String urgency, String description,
- String reporter, String action) {
-
- double samplingTime = System.currentTimeMillis() / 1000.0;
-
- // generate new data record
- DataBlock newRecord;
-
- if (latestRecord == null) {
-
- newRecord = dataStruct.createDataBlock();
- } else {
-
- newRecord = latestRecord.renew();
- }
-
- newRecord.setDoubleValue(0, samplingTime);
- newRecord.setStringValue(1, id);
- newRecord.setDoubleValue(2, Double.parseDouble(lat));
- newRecord.setDoubleValue(3, Double.parseDouble(lon));
- newRecord.setDoubleValue(4, 0.0);
- newRecord.setIntValue(5, radius);
- newRecord.setStringValue(6, aidType);
- newRecord.setStringValue(7, numPersons);
- newRecord.setStringValue(8, urgency);
- newRecord.setStringValue(9, description);
- newRecord.setStringValue(10, reporter);
- newRecord.setStringValue(11, action);
-
- // update latest record and send event
- latestRecord = newRecord;
- latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, newRecord));
- }
-
- public void start() {
-
- context.registerReceiver(broadcastReceiver, new IntentFilter(ACTION_SUBMIT_AID_REPORT));
- }
-
- @Override
- public void stop() {
-
- context.unregisterReceiver(broadcastReceiver);
- }
-
- @Override
- public double getAverageSamplingPeriod() {
-
- return 1;
- }
-
- @Override
- public DataComponent getRecordDescription() {
-
- return dataStruct;
- }
-
- @Override
- public DataEncoding getRecommendedEncoding() {
-
- return dataEncoding;
- }
-
- @Override
- public DataBlock getLatestRecord() {
-
- return latestRecord;
- }
-
- @Override
- public long getLatestRecordTime() {
-
- return latestRecordTime;
- }
-
- /**
- * Broadcast receiver to register with OS for IPC with SpotReportActivity
- */
- private class SpotReportReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- ResultReceiver resultReceiver = intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
-
- try {
-
- if (ACTION_SUBMIT_AID_REPORT.equals(intent.getAction())) {
-
- String id = intent.getStringExtra(DATA_ID);
- String lat = intent.getStringExtra(DATA_LAT);
- String lon = intent.getStringExtra(DATA_LON);
- int radius = intent.getIntExtra(DATA_RADIUS, 0);
- String aidType = intent.getStringExtra(DATA_AID_TYPE);
- String numPersons = intent.getStringExtra(DATA_NUM_PERSONS);
- String urgency = intent.getStringExtra(DATA_URGENCY);
- String description = intent.getStringExtra(DATA_DESCRIPTION);
- String reporter = intent.getStringExtra(DATA_REPORTER);
- String action = intent.getStringExtra(DATA_ACTION);
-
- submitReport(id, lat, lon, radius, aidType, numPersons, urgency, description, reporter, action);
-
- resultReceiver.send(SUBMIT_REPORT_SUCCESS, null);
-
- }
-
- } catch (Exception e) {
-
- Log.e("SpotReportAidOutput", e.toString());
- resultReceiver.send(SUBMIT_REPORT_FAILURE, null);
- }
- }
- }
-}
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportConfig.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportConfig.java
deleted file mode 100644
index 6dd91c41..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportConfig.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
-The contents of this file are subject to the Mozilla Public License, v. 2.0.
-If a copy of the MPL was not distributed with this file, You can obtain one
-at http://mozilla.org/MPL/2.0/.
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the License.
-
-Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
-
-******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import org.sensorhub.api.module.ModuleConfig;
-import org.sensorhub.api.sensor.SensorConfig;
-import android.content.Context;
-
-/**
- *
- * Configuration class for the Spot Report driver
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportConfig extends SensorConfig {
-
- public String runName;
- public String runDescription;
-
- public transient Context androidContext;
-
- public SpotReportConfig() {
-
- this.moduleClass = SpotReportDriver.class.getCanonicalName();
- }
-
- @Override
- public ModuleConfig clone()
- {
- return this; // disable clone for now as it crashes Android app
- }
-}
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportDescriptor.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportDescriptor.java
deleted file mode 100644
index 6e5155d2..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportDescriptor.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
-The contents of this file are subject to the Mozilla Public License, v. 2.0.
-If a copy of the MPL was not distributed with this file, You can obtain one
-at http://mozilla.org/MPL/2.0/.
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the License.
-
-Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
-
-******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import org.sensorhub.api.module.IModule;
-import org.sensorhub.api.module.IModuleProvider;
-import org.sensorhub.api.module.ModuleConfig;
-
-/**
- *
- * Descriptor of Android sensors driver module for automatic discovery
- * by the ModuleRegistry
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportDescriptor implements IModuleProvider
-{
-
- @Override
- public String getModuleName()
- {
- return "Spot Report Driver";
- }
-
-
- @Override
- public String getModuleDescription()
- {
- return "Driver for Spot Reports submitted from Android devices";
- }
-
-
- @Override
- public String getModuleVersion()
- {
- return "0.5";
- }
-
-
- @Override
- public String getProviderName()
- {
- return "Botts Innovative Research, Inc.";
- }
-
-
- @Override
- public Class extends IModule>> getModuleClass()
- {
- return SpotReportDriver.class;
- }
-
-
- @Override
- public Class extends ModuleConfig> getModuleConfigClass()
- {
- return SpotReportConfig.class;
- }
-
-}
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportDriver.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportDriver.java
deleted file mode 100644
index 0d19550e..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportDriver.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
-The contents of this file are subject to the Mozilla Public License, v. 2.0.
-If a copy of the MPL was not distributed with this file, You can obtain one
-at http://mozilla.org/MPL/2.0/.
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the License.
-
-Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
-
-******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import javax.xml.namespace.QName;
-import net.opengis.gml.v32.AbstractFeature;
-import net.opengis.sensorml.v20.SpatialFrame;
-import net.opengis.sensorml.v20.impl.SpatialFrameImpl;
-import org.sensorhub.api.common.SensorHubException;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorModule;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.vast.ogc.gml.GenericFeatureImpl;
-import org.vast.sensorML.SMLStaxBindings;
-
-import android.provider.Settings.Secure;
-
-/**
- *
- * Main driver class for Android Spot Reports
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportDriver extends AbstractSensorModule {
-
- // keep logger name short because in LogCat it's max 23 chars
- private static final Logger log = LoggerFactory.getLogger(SpotReportDriver.class.getSimpleName());
- private static final String LOCAL_REF_FRAME = "LOCAL_FRAME";
-
- protected String localFrameURI;
-// private SpotReportImageOutput spotReportImageOutput;
- private SpotReportAidOutput spotReportAidOutput;
- private SpotReportFloodingOutput spotReportFloodingOutput;
- private SpotReportMedicalOutput spotReportMedicalOutput;
- private SpotReportStreetClosureOutput spotReportStreetClosureOutput;
- private SpotReportTrackingOutput spotReportTrackingOutput;
-
- public SpotReportDriver() {
- }
-
- @Override
- public void init() throws SensorHubException {
-
- super.init();
-
- // generate identifiers
- String deviceID = Secure.getString(config.androidContext.getContentResolver(), Secure.ANDROID_ID);
- this.uniqueID = "urn:android:spotreport:" + deviceID;
- this.xmlID = "SPOT_REPORT_" + deviceID;
- this.localFrameURI = this.uniqueID + "#" + LOCAL_REF_FRAME;
-
- // create outputs
-// spotReportImageOutput = new SpotReportImageOutput(this);
-// this.addOutput(spotReportImageOutput, false);
-// spotReportImageOutput.init();
-
- spotReportAidOutput = new SpotReportAidOutput(this);
- this.addOutput(spotReportAidOutput, false);
- spotReportAidOutput.init();
-
- spotReportFloodingOutput = new SpotReportFloodingOutput(this);
- this.addOutput(spotReportFloodingOutput, false);
- spotReportFloodingOutput.init();
-
- spotReportMedicalOutput = new SpotReportMedicalOutput(this);
- this.addOutput(spotReportMedicalOutput, false);
- spotReportMedicalOutput.init();
-
- spotReportStreetClosureOutput = new SpotReportStreetClosureOutput(this);
- this.addOutput(spotReportStreetClosureOutput, false);
- spotReportStreetClosureOutput.init();
-
- spotReportTrackingOutput = new SpotReportTrackingOutput(this);
- this.addOutput(spotReportTrackingOutput, false);
- spotReportTrackingOutput.init();
- }
-
- @Override
- public void start() throws SensorException {
-
-// spotReportImageOutput.start();
- spotReportAidOutput.start();
- spotReportFloodingOutput.start();
- spotReportMedicalOutput.start();
- spotReportStreetClosureOutput.start();
- spotReportTrackingOutput.start();
- }
-
- @Override
- public void stop() throws SensorException {
-
-// if (spotReportImageOutput != null) {
-//
-// spotReportImageOutput.stop();
-// }
-
- if (spotReportAidOutput != null) {
-
- spotReportAidOutput.stop();
- }
-
- if (spotReportFloodingOutput != null) {
-
- spotReportFloodingOutput.stop();
- }
-
- if (spotReportMedicalOutput != null) {
-
- spotReportMedicalOutput.stop();
- }
-
- if (spotReportStreetClosureOutput != null) {
-
- spotReportStreetClosureOutput.stop();
- }
-
- if (spotReportTrackingOutput != null) {
-
- spotReportTrackingOutput.stop();
- }
- }
-
- @Override
- protected void updateSensorDescription() {
-
- synchronized (sensorDescLock) {
-
- super.updateSensorDescription();
-
- sensorDescription.setDescription("Spot Reports, providing the user the ability to submit manual observations.");
-
- SpatialFrame localRefFrame = new SpatialFrameImpl();
- localRefFrame.setId(LOCAL_REF_FRAME);
- localRefFrame.setOrigin("Center of the device screen");
- localRefFrame.addAxis("x", "The X axis is in the plane of the screen and points to the right");
- localRefFrame.addAxis("y", "The Y axis is in the plane of the screen and points up");
- localRefFrame.addAxis("z", "The Z axis points towards the outside of the front face of the screen");
- sensorDescription.addLocalReferenceFrame(localRefFrame);
-
- // add FOI
- AbstractFeature foi = getCurrentFeatureOfInterest();
-
- if (foi != null) {
- sensorDescription.getFeaturesOfInterest().addFeature(foi);
- }
- }
- }
-
- @Override
- public AbstractFeature getCurrentFeatureOfInterest() {
-
- if (config.runName != null && config.runName.length() > 0) {
-
- AbstractFeature foi = new GenericFeatureImpl(new QName(SMLStaxBindings.NS_URI, "Feature", "sml"));
- String uid = "urn:android:spotreport:foi:" + config.runName.replaceAll("[ |']", "");
- foi.setUniqueIdentifier(uid);
- foi.setName(config.runName);
- foi.setDescription(config.runDescription);
- return foi;
- }
-
- return null;
- }
-
- @Override
- public boolean isConnected() {
- return true;
- }
-
- @Override
- public void cleanup() throws SensorHubException {
- }
-}
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportFloodingOutput.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportFloodingOutput.java
deleted file mode 100644
index 6d980e01..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportFloodingOutput.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/**************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
- ******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import net.opengis.swe.v20.DataBlock;
-import net.opengis.swe.v20.DataComponent;
-import net.opengis.swe.v20.DataEncoding;
-import net.opengis.swe.v20.Quantity;
-import net.opengis.swe.v20.Text;
-import net.opengis.swe.v20.Time;
-import net.opengis.swe.v20.Vector;
-
-import org.sensorhub.api.sensor.SensorDataEvent;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.vast.swe.SWEHelper;
-import org.vast.swe.helper.GeoPosHelper;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-import java.util.UUID;
-
-/**
- *
- * Implementation of data interface for Spot Reports
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportFloodingOutput extends AbstractSensorOutput {
-
- // keep logger name short because in LogCat it's max 23 chars
- private static final Logger log = LoggerFactory.getLogger(SpotReportFloodingOutput.class.getSimpleName());
-
- // Data Associated with Broadcast Receivers and Intents
- private static final String ACTION_SUBMIT_FLOODING_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_FLOODING";
- private static final int SUBMIT_REPORT_FAILURE = 0;
- private static final int SUBMIT_REPORT_SUCCESS = 1;
-
- private static final String DATA_ID = "id";
- private static final String DATA_LAT = "lat";
- private static final String DATA_LON = "lon";
- private static final String DATA_RADIUS = "radius";
- private static final String DATA_FEATURE_TYPE = "featureType";
- private static final String DATA_DEPTH = "depth";
- private static final String DATA_METHOD = "method";
- private static final String DATA_ACTION = "action";
- private SpotReportReceiver broadcastReceiver = new SpotReportReceiver();
-
- // SWE DataBlock elements
- private static final String DATA_RECORD_REPORT_TIME_LABEL = "time";
- private static final String DATA_RECORD_REPORT_ID_LABEL = "id";
- private static final String DATA_RECORD_REPORT_LOC_LABEL = "location";
- private static final String DATA_RECORD_REPORT_RADIUS_LABEL = "radius";
- private static final String DATA_RECORD_REPORT_FEATURE_TYPE_LABEL = "featureType";
- private static final String DATA_RECORD_REPORT_DEPTH_LABEL = "depth";
- private static final String DATA_RECORD_REPORT_METHOD_LABEL = "method";
- private static final String DATA_RECORD_REPORT_ACTION_LABEL = "action";
-
- private static final String DATA_RECORD_NAME = "Flooding Spot Report";
- private static final String DATA_RECORD_DESCRIPTION =
- "A report generated by visual observance and classification which is accompanied by a" +
- " location, description, and other data";
- private static final String DATA_RECORD_DEFINITION =
- SWEHelper.getPropertyUri("FloodingSpotReport");
-
- private DataComponent dataStruct;
- private DataEncoding dataEncoding;
-
- private Context context;
- private String name;
-
- SpotReportFloodingOutput(SpotReportDriver parentModule) {
-
- super(parentModule);
- this.name = parentModule.getName() + " Flooding";
- context = getParentModule().getConfiguration().androidContext;
- }
-
- @Override
- public String getName() {
-
- return name;
- }
-
- /**
- * Initialize the output data structure
- *
- * @throws SensorException
- */
- void init() throws SensorException {
-
- // Build data structure ********************************************************************
- SWEHelper sweHelper = new SWEHelper();
- dataStruct = sweHelper.newDataRecord();
- dataStruct.setDescription(DATA_RECORD_DESCRIPTION);
- dataStruct.setDefinition(DATA_RECORD_DEFINITION);
- dataStruct.setName(DATA_RECORD_NAME);
-
- // Add time stamp component to data record
- Time time = sweHelper.newTimeStampIsoUTC();
- dataStruct.addComponent(DATA_RECORD_REPORT_TIME_LABEL, time);
-
- Text id = sweHelper.newText(SWEHelper.getPropertyUri("ID"),
- "ID",
- "A unique identifier for the report");
- dataStruct.addComponent(DATA_RECORD_REPORT_ID_LABEL, id);
-
- // Add the location component of the data record
- GeoPosHelper geoPosHelper = new GeoPosHelper();
- Vector locationVectorLLA = geoPosHelper.newLocationVectorLLA(null);
- locationVectorLLA.setLocalFrame(parentSensor.localFrameURI);
- dataStruct.addComponent(DATA_RECORD_REPORT_LOC_LABEL, locationVectorLLA);
-
- Quantity radius = sweHelper.newQuantity(SWEHelper.getPropertyUri("Radius"),
- "Radius",
- "Radius in ft. of reported location where observation may be contained or found",
- "ft.");
- dataStruct.addComponent(DATA_RECORD_REPORT_RADIUS_LABEL, radius);
-
- Text aidType = sweHelper.newText(SWEHelper.getPropertyUri("FeatureType"),
- "Feature Type",
- "An identifier of the type of feature associated with the flooding");
- dataStruct.addComponent(DATA_RECORD_REPORT_FEATURE_TYPE_LABEL, aidType);
-
- Quantity depth = sweHelper.newQuantity(SWEHelper.getPropertyUri("Depth"),
- "Depth",
- "A magnitude value denoting the depth of flood in feet",
- "ft.");
- dataStruct.addComponent(DATA_RECORD_REPORT_DEPTH_LABEL, depth);
-
- Text method = sweHelper.newText(SWEHelper.getPropertyUri("Method"),
- "Method",
- "An identifier for the method of observation used in determining flooding depth");
- dataStruct.addComponent(DATA_RECORD_REPORT_METHOD_LABEL, method);
-
- Text action = sweHelper.newText(SWEHelper.getPropertyUri("Action"),
- "Action",
- "The action associated with the event");
- dataStruct.addComponent(DATA_RECORD_REPORT_ACTION_LABEL, action);
-
- // Setup data encoding *********************************************************************
- this.dataEncoding = sweHelper.newTextEncoding(",", "\n");
- }
-
- /**
- * Populate and submit an instance of the SpotReport.
- *
- * @param id
- * @param lat Latitude
- * @param lon Longitude
- * @param radius Radius of validity
- * @param featureType Type of feature observed
- * @param depth Depth in feet of the flooding
- * @param method Method used to report observation
- * @param action
- */
- private void submitReport(String id, String lat, String lon, int radius, String featureType,
- int depth, String method, String action) {
-
- double samplingTime = System.currentTimeMillis() / 1000.0;
-
- // generate new data record
- DataBlock newRecord = dataStruct.createDataBlock();
-
-// if (latestRecord == null) {
-//
-// newRecord = dataStruct.createDataBlock();
-// } else {
-//
-// newRecord = latestRecord.renew();
-// }
-
- newRecord.setDoubleValue(0, samplingTime);
- newRecord.setStringValue(1, id);
- newRecord.setDoubleValue(2, Double.parseDouble(lat));
- newRecord.setDoubleValue(3, Double.parseDouble(lon));
- newRecord.setDoubleValue(4, 0.0);
- newRecord.setIntValue(5, radius);
- newRecord.setStringValue(6, featureType);
- newRecord.setIntValue(7, depth);
- newRecord.setStringValue(8, method);
- newRecord.setStringValue(9, action);
-
- // update latest record and send event
-// latestRecord = newRecord;
- latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, newRecord));
- }
-
- public void start() {
-
- context.registerReceiver(broadcastReceiver, new IntentFilter(ACTION_SUBMIT_FLOODING_REPORT));
- }
-
- @Override
- public void stop() {
-
- context.unregisterReceiver(broadcastReceiver);
- }
-
- @Override
- public double getAverageSamplingPeriod() {
-
- return 1;
- }
-
- @Override
- public DataComponent getRecordDescription() {
-
- return dataStruct;
- }
-
- @Override
- public DataEncoding getRecommendedEncoding() {
-
- return dataEncoding;
- }
-
- @Override
- public DataBlock getLatestRecord() {
-
- return latestRecord;
- }
-
- @Override
- public long getLatestRecordTime() {
-
- return latestRecordTime;
- }
-
- /**
- * Broadcast receiver to register with OS for IPC with SpotReportActivity
- */
- private class SpotReportReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- ResultReceiver resultReceiver = intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
-
- try {
-
- if (ACTION_SUBMIT_FLOODING_REPORT.equals(intent.getAction())) {
-
- String id = intent.getStringExtra(DATA_ID);
- String lat = intent.getStringExtra(DATA_LAT);
- String lon = intent.getStringExtra(DATA_LON);
- int radius = intent.getIntExtra(DATA_RADIUS, 0);
- String featureType = intent.getStringExtra(DATA_FEATURE_TYPE);
- int depth = intent.getIntExtra(DATA_DEPTH, 0);
- String method = intent.getStringExtra(DATA_METHOD);
- String action = intent.getStringExtra(DATA_ACTION);
-
- submitReport(id, lat, lon, radius, featureType, depth, method, action);
-
- resultReceiver.send(SUBMIT_REPORT_SUCCESS, null);
-
- }
-
- } catch (Exception e) {
-
- Log.e("SpotReportFloodingOutput", e.toString());
- resultReceiver.send(SUBMIT_REPORT_FAILURE, null);
- }
- }
- }
-}
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportImageOutput.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportImageOutput.java
deleted file mode 100644
index c1325f9e..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportImageOutput.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/**************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
- ******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import java.util.List;
-
-import net.opengis.swe.v20.DataBlock;
-import net.opengis.swe.v20.DataComponent;
-import net.opengis.swe.v20.DataEncoding;
-import net.opengis.swe.v20.Text;
-import net.opengis.swe.v20.Time;
-import net.opengis.swe.v20.Vector;
-
-import org.sensorhub.api.sensor.SensorDataEvent;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.vast.data.AbstractDataBlock;
-import org.vast.data.DataBlockMixed;
-import org.vast.swe.SWEHelper;
-import org.vast.swe.helper.GeoPosHelper;
-
-import android.Manifest;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.location.Location;
-import android.location.LocationManager;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-/**
- *
- * Implementation of data interface for Spot Reports
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportImageOutput extends AbstractSensorOutput {
-
- // keep logger name short because in LogCat it's max 23 chars
- private static final Logger log = LoggerFactory.getLogger(SpotReportImageOutput.class.getSimpleName());
-
- // Data Associated with Broadcast Receivers and Intents
- private static final String ACTION_SUBMIT_IMAGE_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_IMAGE";
- private static final int SUBMIT_REPORT_FAILURE = 0;
- private static final int SUBMIT_REPORT_SUCCESS = 1;
- private static final String DATA_LOC = "location";
- private static final String DATA_REPORT_NAME = "name";
- private static final String DATA_REPORT_DESCRIPTION = "description";
- private static final String DATA_REPORT_CATEGORY = "item";
- private SpotReportReceiver broadcastReceiver = new SpotReportReceiver();
-
- // SWE DataBlock elements
- private static final String DATA_RECORD_REPORT_TIME_LABEL = "time";
- private static final String DATA_RECORD_REPORT_LOC_LABEL = "location";
- private static final String DATA_RECORD_REPORT_NAME_LABEL = "name";
- private static final String DATA_RECORD_REPORT_DESCRIPTION_LABEL = "description";
- private static final String DATA_RECORD_REPORTING_CATEGORY_LABEL = "category";
-
- private static final String DATA_RECORD_NAME = "Spot Report";
- private static final String DATA_RECORD_DESCRIPTION =
- "A report generated by visual observance and classification which is accompanied by a" +
- " location, description, and other data";
- private static final String DATA_RECORD_DEFINITION =
- SWEHelper.getPropertyUri("SpotReport");
-
- private DataComponent dataStruct;
- private DataEncoding dataEncoding;
-
- private Context context;
- private String name;
-
- SpotReportImageOutput(SpotReportDriver parentModule) {
-
- super(parentModule);
- this.name = parentModule.getName() + " Image";
- context = getParentModule().getConfiguration().androidContext;
- }
-
- @Override
- public String getName() {
-
- return name;
- }
-
- /**
- * Initialize the output data structure
- *
- * @throws SensorException
- */
- void init() throws SensorException {
-
- // Build data structure ********************************************************************
- SWEHelper sweHelper = new SWEHelper();
- dataStruct = sweHelper.newDataRecord();
- dataStruct.setDescription(DATA_RECORD_DESCRIPTION);
- dataStruct.setDefinition(DATA_RECORD_DEFINITION);
- dataStruct.setName(DATA_RECORD_NAME);
-
- // Add time stamp component to data record
- Time time = sweHelper.newTimeStampIsoUTC();
- dataStruct.addComponent(DATA_RECORD_REPORT_TIME_LABEL, time);
-
- // Add the report name component of the data record
- Text name = sweHelper.newText(SWEHelper.getPropertyUri("ReportName"),
- "Report Name",
- "An identifier used as a describer for the report");
- dataStruct.addComponent(DATA_RECORD_REPORT_NAME_LABEL, name);
-
- // Add the report description component of the data record
- Text description = sweHelper.newText(SWEHelper.getPropertyUri("ReportDescription"),
- "Report Description",
- "A verbose description of the observed event");
- dataStruct.addComponent(DATA_RECORD_REPORT_DESCRIPTION_LABEL, description);
-
- // Add the reporting item component of the data record
- Text category = sweHelper.newText(SWEHelper.getPropertyUri("ReportCategory"),
- "Report Category",
- "A categorical value used to identify a report as belonging to a kind, " +
- "family, or group of reports");
- dataStruct.addComponent(DATA_RECORD_REPORTING_CATEGORY_LABEL, category);
-
- // Add the location component of the data record
- GeoPosHelper geoPosHelper = new GeoPosHelper();
- Vector locationVectorLLA = geoPosHelper.newLocationVectorLLA(null);
- locationVectorLLA.setLocalFrame(parentSensor.localFrameURI);
- dataStruct.addComponent(DATA_RECORD_REPORT_LOC_LABEL, locationVectorLLA);
-
- // Setup data encoding *********************************************************************
- this.dataEncoding = sweHelper.newTextEncoding(",", "\n");
- }
-
- /**
- * Populate and submit an instance of the SpotReport.
- *
- * @param category The category for the spot report
- * @param locationSource The location source name for the spot report
- * @param name The name of the report
- * @param description A description of the report
- */
- private void submitReport(String category, String locationSource, String name, String description) {
-
- Location location;
-
- location = getLocation(locationSource);
-
- double samplingTime = location.getTime() / 1000.0;
-
- // generate new data record
- DataBlock newRecord;
-
- if (latestRecord == null) {
-
- newRecord = dataStruct.createDataBlock();
- } else {
-
- newRecord = latestRecord.renew();
- }
-
- newRecord.setDoubleValue(0, samplingTime);
- newRecord.setStringValue(1, name);
- newRecord.setStringValue(2, description);
- newRecord.setStringValue(3, category);
-
- AbstractDataBlock locationData = ((DataBlockMixed) newRecord).getUnderlyingObject()[4];
- locationData.setDoubleValue(0, location.getLatitude());
- locationData.setDoubleValue(1, location.getLongitude());
- locationData.setDoubleValue(2, location.getAltitude());
-
- // update latest record and send event
- latestRecord = newRecord;
- latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, newRecord));
- }
-
- public void start() {
-
- context.registerReceiver(broadcastReceiver, new IntentFilter(ACTION_SUBMIT_IMAGE_REPORT));
- }
-
- @Override
- public void stop() {
-
- context.unregisterReceiver(broadcastReceiver);
- }
-
- @Override
- public double getAverageSamplingPeriod() {
-
- return 1;
- }
-
- @Override
- public DataComponent getRecordDescription() {
-
- return dataStruct;
- }
-
- @Override
- public DataEncoding getRecommendedEncoding() {
-
- return dataEncoding;
- }
-
- @Override
- public DataBlock getLatestRecord() {
-
- return latestRecord;
- }
-
- @Override
- public long getLatestRecordTime() {
-
- return latestRecordTime;
- }
-
- /**
- * Get the location provider based on the given name of the location source
- *
- * @param locationSource The name of the source for location data
- * @return Instance of the location provider
- */
- private Location getLocation(String locationSource) {
-
- Location location = null;
-
- // Attempt to get location based given location source
- if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION)) {
-
- // Retrieve the location manager
- LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
-
- // Get a list of all location providers
- List locProviders = locationManager.getAllProviders();
-
- // Scan through the list until a provider is matched
- for (String providerName : locProviders) {
-
- if (providerName.equalsIgnoreCase(locationSource)) {
-
- log.debug("Detected location provider " + providerName);
-
- if (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
- context.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
-
- location = locationManager.getLastKnownLocation(providerName);
-
- log.debug("Location " + location.toString());
- }
- }
- }
- }
-
- return location;
- }
-
- /**
- * Broadcast receiver to register with OS for IPC with SpotReportActivity
- */
- private class SpotReportReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- ResultReceiver resultReceiver = intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
-
- try {
-
- if (ACTION_SUBMIT_IMAGE_REPORT.equals(intent.getAction())) {
-
- String category = intent.getStringExtra(DATA_REPORT_CATEGORY);
- String locationSource = intent.getStringExtra(DATA_LOC);
- String name = intent.getStringExtra(DATA_REPORT_NAME);
- String description = intent.getStringExtra(DATA_REPORT_DESCRIPTION);
-
- submitReport(category, locationSource, name, description);
-
- resultReceiver.send(SUBMIT_REPORT_SUCCESS, null);
-
- }
-
- } catch (Exception e) {
-
- Log.e("SpotReportImageOutput", e.toString());
- resultReceiver.send(SUBMIT_REPORT_FAILURE, null);
- }
- }
- }
-}
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportMedicalOutput.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportMedicalOutput.java
deleted file mode 100644
index ffb94df9..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportMedicalOutput.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/**************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
- ******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import net.opengis.swe.v20.Boolean;
-import net.opengis.swe.v20.DataBlock;
-import net.opengis.swe.v20.DataComponent;
-import net.opengis.swe.v20.DataEncoding;
-import net.opengis.swe.v20.Quantity;
-import net.opengis.swe.v20.Text;
-import net.opengis.swe.v20.Time;
-import net.opengis.swe.v20.Vector;
-
-import org.sensorhub.api.sensor.SensorDataEvent;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.vast.swe.SWEHelper;
-import org.vast.swe.helper.GeoPosHelper;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-import java.util.UUID;
-
-/**
- *
- * Implementation of data interface for Spot Reports
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportMedicalOutput extends AbstractSensorOutput {
-
- // keep logger name short because in LogCat it's max 23 chars
- private static final Logger log = LoggerFactory.getLogger(SpotReportMedicalOutput.class.getSimpleName());
-
- // Data Associated with Broadcast Receivers and Intents
- private static final String ACTION_SUBMIT_MEDICAL_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_MEDICAL";
- private static final int SUBMIT_REPORT_FAILURE = 0;
- private static final int SUBMIT_REPORT_SUCCESS = 1;
-
- private static final String DATA_ID = "id";
- private static final String DATA_LAT = "lat";
- private static final String DATA_LON = "lon";
- private static final String DATA_RADIUS = "radius";
- private static final String DATA_DESCRIPTION = "description";
- private static final String DATA_MEASURE = "measure";
- private static final String DATA_EMERGENCY = "emergency";
- private static final String DATA_ACTION = "action";
- private SpotReportReceiver broadcastReceiver = new SpotReportReceiver();
-
- // SWE DataBlock elements
- private static final String DATA_RECORD_REPORT_TIME_LABEL = "time";
- private static final String DATA_RECORD_REPORT_ID_LABEL = "id";
- private static final String DATA_RECORD_REPORT_LOC_LABEL = "location";
- private static final String DATA_RECORD_REPORT_RADIUS_LABEL = "radius";
- private static final String DATA_RECORD_REPORT_DESCRIPTION_LABEL = "description";
- private static final String DATA_RECORD_REPORT_MEASURE_LABEL = "measure";
- private static final String DATA_RECORD_REPORT_EMERGENCY_LABEL = "emergency";
- private static final String DATA_RECORD_REPORT_ACTION_LABEL = "action";
-
- private static final String DATA_RECORD_NAME = "Medical Spot Report";
- private static final String DATA_RECORD_DESCRIPTION =
- "A report generated by visual observance and classification which is accompanied by a" +
- " location, description, and other data";
- private static final String DATA_RECORD_DEFINITION =
- SWEHelper.getPropertyUri("MedicalSpotReport");
-
- private DataComponent dataStruct;
- private DataEncoding dataEncoding;
-
- private Context context;
- private String name;
-
- SpotReportMedicalOutput(SpotReportDriver parentModule) {
-
- super(parentModule);
- this.name = parentModule.getName() + " Medical";
- context = getParentModule().getConfiguration().androidContext;
- }
-
- @Override
- public String getName() {
-
- return name;
- }
-
- /**
- * Initialize the output data structure
- *
- * @throws SensorException
- */
- void init() throws SensorException {
-
- // Build data structure ********************************************************************
- SWEHelper sweHelper = new SWEHelper();
- dataStruct = sweHelper.newDataRecord();
- dataStruct.setDescription(DATA_RECORD_DESCRIPTION);
- dataStruct.setDefinition(DATA_RECORD_DEFINITION);
- dataStruct.setName(DATA_RECORD_NAME);
-
- // Add time stamp component to data record
- Time time = sweHelper.newTimeStampIsoUTC();
- dataStruct.addComponent(DATA_RECORD_REPORT_TIME_LABEL, time);
-
- Text id = sweHelper.newText(SWEHelper.getPropertyUri("ID"),
- "ID",
- "A unique identifier for the report");
- dataStruct.addComponent(DATA_RECORD_REPORT_ID_LABEL, id);
-
- // Add the location component of the data record
- GeoPosHelper geoPosHelper = new GeoPosHelper();
- Vector locationVectorLLA = geoPosHelper.newLocationVectorLLA(null);
- locationVectorLLA.setLocalFrame(parentSensor.localFrameURI);
- dataStruct.addComponent(DATA_RECORD_REPORT_LOC_LABEL, locationVectorLLA);
-
- Quantity radius = sweHelper.newQuantity(SWEHelper.getPropertyUri("Radius"),
- "Radius",
- "Radius in ft. of reported location where observation may be contained or found",
- "ft.");
- dataStruct.addComponent(DATA_RECORD_REPORT_RADIUS_LABEL, radius);
-
- Text description = sweHelper.newText(SWEHelper.getPropertyUri("Description"),
- "Description",
- "A description of the medical symptoms or issues being observed");
- dataStruct.addComponent(DATA_RECORD_REPORT_DESCRIPTION_LABEL, description);
-
- Text vitalSignMeasurement = sweHelper.newText(SWEHelper.getPropertyUri("VitalSignMeasurement"),
- "Vital Sign Measurement",
- "Measurements of vital signs");
- dataStruct.addComponent(DATA_RECORD_REPORT_MEASURE_LABEL, vitalSignMeasurement);
-
- Boolean emergency = sweHelper.newBoolean(SWEHelper.getPropertyUri("Emergency"),
- "Emergency",
- "Flag indicating if issue rises to level of medical emergency");
- dataStruct.addComponent(DATA_RECORD_REPORT_EMERGENCY_LABEL, emergency);
-
- Text action = sweHelper.newText(SWEHelper.getPropertyUri("Action"),
- "Action",
- "The action associated with the event");
- dataStruct.addComponent(DATA_RECORD_REPORT_ACTION_LABEL, action);
-
- // Setup data encoding *********************************************************************
- this.dataEncoding = sweHelper.newTextEncoding(",", "\n");
- }
-
- /**
- * Populate and submit an instance of the SpotReport.
- *
- * @param id
- * @param lat Latitude
- * @param lon Longitude
- * @param radius Radius of validity
- * @param description Description of the medical situation needing attention
- * @param vitalSignMeasurement Measurements of vital signs
- * @param emergency Flag indicating if issue rises to level of medical emergency
- * @param action
- */
- private void submitReport(String id, String lat, String lon, int radius, String description,
- String vitalSignMeasurement, boolean emergency, String action) {
-
- double samplingTime = System.currentTimeMillis() / 1000.0;
-
- // generate new data record
- DataBlock newRecord = dataStruct.createDataBlock();
-
-// if (latestRecord == null) {
-//
-// newRecord = dataStruct.createDataBlock();
-// } else {
-//
-// newRecord = latestRecord.renew();
-// }
-
- newRecord.setDoubleValue(0, samplingTime);
- newRecord.setStringValue(1, id);
- newRecord.setDoubleValue(2, Double.parseDouble(lat));
- newRecord.setDoubleValue(3, Double.parseDouble(lon));
- newRecord.setDoubleValue(4, 0.0);
- newRecord.setIntValue(5, radius);
- newRecord.setStringValue(6, description);
- newRecord.setStringValue(7, vitalSignMeasurement);
- newRecord.setBooleanValue(8, emergency);
- newRecord.setStringValue(9, action);
-
- // update latest record and send event
-// latestRecord = newRecord;
- latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, newRecord));
- }
-
- public void start() {
-
- context.registerReceiver(broadcastReceiver, new IntentFilter(ACTION_SUBMIT_MEDICAL_REPORT));
- }
-
- @Override
- public void stop() {
-
- context.unregisterReceiver(broadcastReceiver);
- }
-
- @Override
- public double getAverageSamplingPeriod() {
-
- return 1;
- }
-
- @Override
- public DataComponent getRecordDescription() {
-
- return dataStruct;
- }
-
- @Override
- public DataEncoding getRecommendedEncoding() {
-
- return dataEncoding;
- }
-
- @Override
- public DataBlock getLatestRecord() {
-
- return latestRecord;
- }
-
- @Override
- public long getLatestRecordTime() {
-
- return latestRecordTime;
- }
-
- /**
- * Broadcast receiver to register with OS for IPC with SpotReportActivity
- */
- private class SpotReportReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- ResultReceiver resultReceiver = intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
-
- try {
-
- if (ACTION_SUBMIT_MEDICAL_REPORT.equals(intent.getAction())) {
-
- String id = intent.getStringExtra(DATA_ID);
- String lat = intent.getStringExtra(DATA_LAT);
- String lon = intent.getStringExtra(DATA_LON);
- int radius = intent.getIntExtra(DATA_RADIUS, 0);
- String description = intent.getStringExtra(DATA_DESCRIPTION);
- String vitalSignMeasurement = intent.getStringExtra(DATA_MEASURE);
- boolean emergency = intent.getBooleanExtra(DATA_EMERGENCY, false);
- String action = intent.getStringExtra(DATA_ACTION);
-
- submitReport(id, lat, lon, radius, description, vitalSignMeasurement, emergency, action);
-
- resultReceiver.send(SUBMIT_REPORT_SUCCESS, null);
-
- }
-
- } catch (Exception e) {
-
- Log.e("SpotReportMedicalOutput", e.toString());
- resultReceiver.send(SUBMIT_REPORT_FAILURE, null);
- }
- }
- }
-}
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportStreetClosureOutput.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportStreetClosureOutput.java
deleted file mode 100644
index 83f689c7..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportStreetClosureOutput.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/**************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
- ******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import net.opengis.swe.v20.DataBlock;
-import net.opengis.swe.v20.DataComponent;
-import net.opengis.swe.v20.DataEncoding;
-import net.opengis.swe.v20.Quantity;
-import net.opengis.swe.v20.Text;
-import net.opengis.swe.v20.Time;
-import net.opengis.swe.v20.Vector;
-
-import org.sensorhub.api.sensor.SensorDataEvent;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.vast.swe.SWEHelper;
-import org.vast.swe.helper.GeoPosHelper;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-import java.util.UUID;
-
-/**
- *
- * Implementation of data interface for Spot Reports
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportStreetClosureOutput extends AbstractSensorOutput {
-
- // keep logger name short because in LogCat it's max 23 chars
- private static final Logger log = LoggerFactory.getLogger(SpotReportStreetClosureOutput.class.getSimpleName());
-
- // Data Associated with Broadcast Receivers and Intents
- private static final String ACTION_SUBMIT_STREET_CLOSURE_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_STREET_CLOSURE";
- private static final int SUBMIT_REPORT_FAILURE = 0;
- private static final int SUBMIT_REPORT_SUCCESS = 1;
-
- private static final String DATA_ID = "id";
- private static final String DATA_LAT = "lat";
- private static final String DATA_LON = "lon";
- private static final String DATA_RADIUS = "radius";
- private static final String DATA_TYPE = "type";
- private static final String DATA_ACTION = "action";
- private static final String DATA_REFERENCE_ID = "reference";
- private SpotReportReceiver broadcastReceiver = new SpotReportReceiver();
-
- // SWE DataBlock elements
- private static final String DATA_RECORD_REPORT_TIME_LABEL = "time";
- private static final String DATA_RECORD_REPORT_ID_LABEL = "id";
- private static final String DATA_RECORD_REPORT_LOC_LABEL = "location";
- private static final String DATA_RECORD_REPORT_RADIUS_LABEL = "radius";
- private static final String DATA_RECORD_REPORT_TYPE_LABEL = "type";
- private static final String DATA_RECORD_REPORT_ACTION_LABEL = "action";
- private static final String DATA_RECORD_REPORT_REFERENCE_LABEL = "reference";
-
- private static final String DATA_RECORD_NAME = "Street Closure Spot Report";
- private static final String DATA_RECORD_DESCRIPTION =
- "A report generated by visual observance and classification which is accompanied by a" +
- " location, description, and other data";
- private static final String DATA_RECORD_DEFINITION =
- SWEHelper.getPropertyUri("StreetClosureSpotReport");
-
- private DataComponent dataStruct;
- private DataEncoding dataEncoding;
-
- private Context context;
- private String name;
-
- SpotReportStreetClosureOutput(SpotReportDriver parentModule) {
-
- super(parentModule);
- this.name = parentModule.getName() + " Street Closure";
- context = getParentModule().getConfiguration().androidContext;
- }
-
- @Override
- public String getName() {
-
- return name;
- }
-
- /**
- * Initialize the output data structure
- *
- * @throws SensorException
- */
- void init() throws SensorException {
-
- // Build data structure ********************************************************************
- SWEHelper sweHelper = new SWEHelper();
- dataStruct = sweHelper.newDataRecord();
- dataStruct.setDescription(DATA_RECORD_DESCRIPTION);
- dataStruct.setDefinition(DATA_RECORD_DEFINITION);
- dataStruct.setName(DATA_RECORD_NAME);
-
- // Add time stamp component to data record
- Time time = sweHelper.newTimeStampIsoUTC();
- dataStruct.addComponent(DATA_RECORD_REPORT_TIME_LABEL, time);
-
- Text id = sweHelper.newText(SWEHelper.getPropertyUri("ID"),
- "ID",
- "A unique identifier for the report");
- dataStruct.addComponent(DATA_RECORD_REPORT_ID_LABEL, id);
-
- // Add the location component of the data record
- GeoPosHelper geoPosHelper = new GeoPosHelper();
- Vector locationVectorLLA = geoPosHelper.newLocationVectorLLA(null);
- locationVectorLLA.setLocalFrame(parentSensor.localFrameURI);
- dataStruct.addComponent(DATA_RECORD_REPORT_LOC_LABEL, locationVectorLLA);
-
- Quantity radius = sweHelper.newQuantity(SWEHelper.getPropertyUri("Radius"),
- "Radius",
- "Radius in ft. of reported location where observation may be contained or found",
- "ft.");
- dataStruct.addComponent(DATA_RECORD_REPORT_RADIUS_LABEL, radius);
-
- Text type = sweHelper.newText(SWEHelper.getPropertyUri("Type"),
- "Type",
- "A description of the type pf closer, all or public");
- dataStruct.addComponent(DATA_RECORD_REPORT_TYPE_LABEL, type);
-
- Text action = sweHelper.newText(SWEHelper.getPropertyUri("Action"),
- "Action",
- "The action associated with the closure event");
- dataStruct.addComponent(DATA_RECORD_REPORT_ACTION_LABEL, action);
-
- Text reference = sweHelper.newText(SWEHelper.getPropertyUri("Reference"),
- "Reference",
- "If not empty, denotes the associated observation for this event");
- dataStruct.addComponent(DATA_RECORD_REPORT_REFERENCE_LABEL, reference);
-
- // Setup data encoding *********************************************************************
- this.dataEncoding = sweHelper.newTextEncoding(",", "\n");
- }
-
- /**
- * Populate and submit an instance of the SpotReport.
- *
- * @param id
- * @param lat Latitude
- * @param lon Longitude
- * @param radius Radius of validity
- * @param type Describes the type of closure event
- * @param action Describes the action, close or open
- * @param reference Reference id of related observation
- */
- private void submitReport(String id, String lat, String lon, int radius, String type,
- String action, String reference) {
-
- double samplingTime = System.currentTimeMillis() / 1000.0;
-
- // generate new data record
- DataBlock newRecord = dataStruct.createDataBlock();
-
-// if (latestRecord == null) {
-//
-// newRecord = dataStruct.createDataBlock();
-// } else {
-//
-// newRecord = latestRecord.renew();
-// }
-
- newRecord.setDoubleValue(0, samplingTime);
- newRecord.setStringValue(1, id);
- newRecord.setDoubleValue(2, Double.parseDouble(lat));
- newRecord.setDoubleValue(3, Double.parseDouble(lon));
- newRecord.setDoubleValue(4, 0.0);
- newRecord.setIntValue(5, radius);
- newRecord.setStringValue(6, type);
- newRecord.setStringValue(7, action);
- newRecord.setStringValue(8, reference);
-
- // update latest record and send event
-// latestRecord = newRecord;
- latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, newRecord));
- }
-
- public void start() {
-
- context.registerReceiver(broadcastReceiver, new IntentFilter(ACTION_SUBMIT_STREET_CLOSURE_REPORT));
- }
-
- @Override
- public void stop() {
-
- context.unregisterReceiver(broadcastReceiver);
- }
-
- @Override
- public double getAverageSamplingPeriod() {
-
- return 1;
- }
-
- @Override
- public DataComponent getRecordDescription() {
-
- return dataStruct;
- }
-
- @Override
- public DataEncoding getRecommendedEncoding() {
-
- return dataEncoding;
- }
-
- @Override
- public DataBlock getLatestRecord() {
-
- return latestRecord;
- }
-
- @Override
- public long getLatestRecordTime() {
-
- return latestRecordTime;
- }
-
- /**
- * Broadcast receiver to register with OS for IPC with SpotReportActivity
- */
- private class SpotReportReceiver extends BroadcastReceiver {
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- ResultReceiver resultReceiver = intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
-
- try {
-
- if (ACTION_SUBMIT_STREET_CLOSURE_REPORT.equals(intent.getAction())) {
-
- String id = intent.getStringExtra(DATA_ID);
- String lat = intent.getStringExtra(DATA_LAT);
- String lon = intent.getStringExtra(DATA_LON);
- int radius = intent.getIntExtra(DATA_RADIUS, 0);
- String type = intent.getStringExtra(DATA_TYPE);
- String action = intent.getStringExtra(DATA_ACTION);
- String reference = intent.getStringExtra(DATA_REFERENCE_ID);
-
- if(null == reference) {
-
- reference = "";
- }
-
- submitReport(id, lat, lon, radius, type, action, reference);
-
- resultReceiver.send(SUBMIT_REPORT_SUCCESS, null);
-
- }
-
- } catch (Exception e) {
-
- Log.e("SpotReportStreetClosureOutput", e.toString());
- resultReceiver.send(SUBMIT_REPORT_FAILURE, null);
- }
- }
- }
-}
diff --git a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportTrackingOutput.java b/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportTrackingOutput.java
deleted file mode 100644
index 2fdb0737..00000000
--- a/sensorhub-android-spotreport/src/org/sensorhub/impl/driver/spotreport/SpotReportTrackingOutput.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/**************************** BEGIN LICENSE BLOCK ***************************
-
- The contents of this file are subject to the Mozilla Public License, v. 2.0.
- If a copy of the MPL was not distributed with this file, You can obtain one
- at http://mozilla.org/MPL/2.0/.
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the License.
-
- Copyright (C) 2019 Botts Innovative Research, Inc. All Rights Reserved.
- ******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.driver.spotreport;
-
-import net.opengis.swe.v20.DataBlock;
-import net.opengis.swe.v20.DataComponent;
-import net.opengis.swe.v20.DataEncoding;
-import net.opengis.swe.v20.Quantity;
-import net.opengis.swe.v20.Text;
-import net.opengis.swe.v20.Time;
-import net.opengis.swe.v20.Vector;
-
-import org.sensorhub.api.sensor.SensorDataEvent;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorOutput;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.vast.swe.SWEHelper;
-import org.vast.swe.helper.GeoPosHelper;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.ResultReceiver;
-import android.util.Log;
-
-import java.util.UUID;
-
-/**
- *
- * Implementation of data interface for Spot Reports
- *
- *
- * @author Nicolas Garay
- * @since Nov 9, 2019
- */
-public class SpotReportTrackingOutput extends AbstractSensorOutput {
-
- // keep logger name short because in LogCat it's max 23 chars
- private static final Logger log = LoggerFactory.getLogger(SpotReportTrackingOutput.class.getSimpleName());
-
- // Data Associated with Broadcast Receivers and Intents
- private static final String ACTION_SUBMIT_TRACK_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_TRACK";
- private static final int SUBMIT_REPORT_FAILURE = 0;
- private static final int SUBMIT_REPORT_SUCCESS = 1;
-
- private static final String DATA_ID = "id";
- private static final String DATA_LAT = "lat";
- private static final String DATA_LON = "lon";
- private static final String DATA_CONFIDENCE = "confidence";
- private static final String DATA_TYPE = "type";
- private static final String DATA_RESOURCE_ID = "resourceId";
- private static final String DATA_RESOURCE_LABEL = "resourceLabel";
- private static final String DATA_METHOD = "method";
- private static final String DATA_FEATURE_REFERENCE = "featureReference";
- private static final String DATA_ACTION = "action";
- private SpotReportReceiver broadcastReceiver = new SpotReportReceiver();
-
- // SWE DataBlock elements
- private static final String DATA_RECORD_REPORT_TIME_LABEL = "time";
- private static final String DATA_RECORD_REPORT_ID_LABEL = "id";
- private static final String DATA_RECORD_REPORT_LOC_LABEL = "location";
- private static final String DATA_RECORD_REPORT_CONFIDENCE_LABEL = "confidence";
- private static final String DATA_RECORD_REPORT_TYPE_LABEL = "type";
- private static final String DATA_RECORD_REPORT_RESOURCE_ID_LABEL = "resourceId";
- private static final String DATA_RECORD_REPORT_RESOURCE_LABEL = "resourceLabel";
- private static final String DATA_RECORD_REPORT_METHOD_LABEL = "method";
- private static final String DATA_RECORD_REPORT_FEATURE_REF_LABEL = "featureReference";
- private static final String DATA_RECORD_REPORT_ACTION_LABEL = "action";
-
- private static final String DATA_RECORD_NAME = "Tracking Spot Report";
- private static final String DATA_RECORD_DESCRIPTION =
- "A report generated by visual observance and classification which is accompanied by a" +
- " location, description, and other data";
- private static final String DATA_RECORD_DEFINITION =
- SWEHelper.getPropertyUri("TrackingSpotReport");
-
- private DataComponent dataStruct;
- private DataEncoding dataEncoding;
-
- private Context context;
- private String name;
-
- SpotReportTrackingOutput(SpotReportDriver parentModule) {
-
- super(parentModule);
- this.name = parentModule.getName() + " Tracking";
- context = getParentModule().getConfiguration().androidContext;
- }
-
- @Override
- public String getName() {
-
- return name;
- }
-
- /**
- * Initialize the output data structure
- *
- * @throws SensorException
- */
- void init() throws SensorException {
-
- // Build data structure ********************************************************************
- SWEHelper sweHelper = new SWEHelper();
- dataStruct = sweHelper.newDataRecord();
- dataStruct.setDescription(DATA_RECORD_DESCRIPTION);
- dataStruct.setDefinition(DATA_RECORD_DEFINITION);
- dataStruct.setName(DATA_RECORD_NAME);
-
- // Add time stamp component to data record
- Time time = sweHelper.newTimeStampIsoUTC();
- dataStruct.addComponent(DATA_RECORD_REPORT_TIME_LABEL, time);
-
- Text id = sweHelper.newText(SWEHelper.getPropertyUri("ID"),
- "ID",
- "A unique identifier for the report");
- dataStruct.addComponent(DATA_RECORD_REPORT_ID_LABEL, id);
-
- // Add the location component of the data record
- GeoPosHelper geoPosHelper = new GeoPosHelper();
- Vector locationVectorLLA = geoPosHelper.newLocationVectorLLA(null);
- locationVectorLLA.setLocalFrame(parentSensor.localFrameURI);
- dataStruct.addComponent(DATA_RECORD_REPORT_LOC_LABEL, locationVectorLLA);
-
- Quantity radius = sweHelper.newQuantity(SWEHelper.getPropertyUri("Radius"),
- "Radius",
- "Radius in ft. of reported location where observation may be contained or found",
- "ft.");
- dataStruct.addComponent(DATA_RECORD_REPORT_CONFIDENCE_LABEL, radius);
-
- Text type = sweHelper.newText(SWEHelper.getPropertyUri("Type"),
- "Type",
- "Type of resource being tracked");
- dataStruct.addComponent(DATA_RECORD_REPORT_TYPE_LABEL, type);
-
- Text resourceId = sweHelper.newText(SWEHelper.getPropertyUri("ResourceId"),
- "Resource Id",
- "The id of the resource being tracked");
- dataStruct.addComponent(DATA_RECORD_REPORT_RESOURCE_ID_LABEL, resourceId);
-
- Text resourceLabel = sweHelper.newText(SWEHelper.getPropertyUri("ResourceLabel"),
- "Resource Label",
- "The label associated with the resource");
- dataStruct.addComponent(DATA_RECORD_REPORT_RESOURCE_LABEL, resourceLabel);
-
- Text method = sweHelper.newText(SWEHelper.getPropertyUri("Method"),
- "Method",
- "An identifier of the method used in tracking the resource");
- dataStruct.addComponent(DATA_RECORD_REPORT_METHOD_LABEL, method);
-
- Text reference = sweHelper.newText(SWEHelper.getPropertyUri("FeatureReference"),
- "Feature Reference",
- "A reference to the feature where beacon is located");
- dataStruct.addComponent(DATA_RECORD_REPORT_FEATURE_REF_LABEL, reference);
-
- Text action = sweHelper.newText(SWEHelper.getPropertyUri("Action"),
- "Action",
- "The action associated with the event");
- dataStruct.addComponent(DATA_RECORD_REPORT_ACTION_LABEL, action);
-
- // Setup data encoding *********************************************************************
- this.dataEncoding = sweHelper.newTextEncoding(",", "\n");
- }
-
- /**
- * Populate and submit an instance of the SpotReport.
- *
- * @param id
- * @param lat Latitude
- * @param lon Longitude
- * @param confidence Radius of validity
- * @param resourceType Describes the type of resource being tracked
- * @param resourceId The id of the resource being tracked
- * @param resourceLabel A label associated with the resource
- * @param trackingMethod Method employed to perform tracking
- * @param referenceId Method employed to perform tracking
- * @param action
- */
- private void submitReport(String id, double lat, double lon, double confidence, String resourceType,
- String resourceId, String resourceLabel, String trackingMethod,
- String referenceId, String action) {
-
- double samplingTime = System.currentTimeMillis() / 1000.0;
-
- // generate new data record
- DataBlock newRecord = dataStruct.createDataBlock();
-
-// if (latestRecord == null) {
-//
-// newRecord = dataStruct.createDataBlock();
-// } else {
-//
-// newRecord = latestRecord.renew();
-// }
-
- newRecord.setDoubleValue(0, samplingTime);
- newRecord.setStringValue(1, id);
- newRecord.setDoubleValue(2, lat);
- newRecord.setDoubleValue(3, lon);
- newRecord.setDoubleValue(4, 0.0);
- newRecord.setDoubleValue(5, confidence);
- newRecord.setStringValue(6, resourceType);
- newRecord.setStringValue(7, resourceId);
- newRecord.setStringValue(8, resourceLabel);
- newRecord.setStringValue(9, trackingMethod);
- newRecord.setStringValue(10, referenceId);
- newRecord.setStringValue(11, action);
-
- // update latest record and send event
-// latestRecord = newRecord;
- latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, newRecord));
- }
-
- public void start() {
-
- context.registerReceiver(broadcastReceiver, new IntentFilter(ACTION_SUBMIT_TRACK_REPORT));
- }
-
- @Override
- public void stop() {
-
- context.unregisterReceiver(broadcastReceiver);
- }
-
- @Override
- public double getAverageSamplingPeriod() {
-
- return 1;
- }
-
- @Override
- public DataComponent getRecordDescription() {
-
- return dataStruct;
- }
-
- @Override
- public DataEncoding getRecommendedEncoding() {
-
- return dataEncoding;
- }
-
- @Override
- public DataBlock getLatestRecord() {
-
- return latestRecord;
- }
-
- @Override
- public long getLatestRecordTime() {
-
- return latestRecordTime;
- }
-
- /**
- * Broadcast receiver to register with OS for IPC with SpotReportActivity
- */
- private class SpotReportReceiver extends BroadcastReceiver {
-
- int count = 0;
-
- @Override
- public void onReceive(Context context, Intent intent) {
-
- ResultReceiver resultReceiver = intent.getParcelableExtra(Intent.EXTRA_RESULT_RECEIVER);
-
- try {
-
- if (ACTION_SUBMIT_TRACK_REPORT.equals(intent.getAction()) && count == 10) {
-
- count = 0;
-
- Log.d("SpotReportTrackingOutput", "Received Intent");
-
-// String id = intent.getStringExtra(DATA_ID);
- String id = UUID.randomUUID().toString();
- double lat = intent.getDoubleExtra(DATA_LAT, 0.0);
- double lon = intent.getDoubleExtra(DATA_LON, 0.0);
- double confidence = intent.getDoubleExtra(DATA_CONFIDENCE, 0.0);
- String resourceType = intent.getStringExtra(DATA_TYPE);
- String resourceId = intent.getStringExtra(DATA_RESOURCE_ID);
- String resourceLabel = intent.getStringExtra(DATA_RESOURCE_LABEL);
- String trackingMethod = intent.getStringExtra(DATA_METHOD);
- String referenceId = intent.getStringExtra(DATA_FEATURE_REFERENCE);
- String action = intent.getStringExtra(DATA_ACTION);
-
- if (null == referenceId) {
-
- referenceId = "NONE";
- }
-
- submitReport(id, lat, lon, confidence, resourceType, resourceId, resourceLabel,
- trackingMethod, referenceId, action);
-
- Log.d("SpotReportTrackingOutput", "Submitted Report");
-
- // If a response expected via result receiver sent with intent
- if (null != resultReceiver) {
-
- resultReceiver.send(SUBMIT_REPORT_SUCCESS, null);
- }
- }
- else {
-
- ++count;
- }
-
- } catch (Exception e) {
-
- Log.d("SpotReportTrackingOutput", e.toString());
-
- Log.e("SpotReportTrackingOutput", e.toString());
-
- // If a response expected via result receiver sent with intent
- if (null != resultReceiver) {
-
- resultReceiver.send(SUBMIT_REPORT_FAILURE, null);
- }
- }
- }
- }
-}
diff --git a/sensorhub-driver-android/AndroidManifest.xml b/sensorhub-driver-android/AndroidManifest.xml
index a11d911f..7f381954 100644
--- a/sensorhub-driver-android/AndroidManifest.xml
+++ b/sensorhub-driver-android/AndroidManifest.xml
@@ -2,4 +2,6 @@
package="org.sensorhub.impl.sensor.android"
android:versionCode="1"
android:versionName="1.0" >
+
+
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidLocationOutput.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidLocationOutput.java
index f9a5e96a..074efbd3 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidLocationOutput.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidLocationOutput.java
@@ -41,7 +41,7 @@
*/
public class AndroidLocationOutput extends AbstractSensorOutput implements IAndroidOutput, LocationListener
{
- private static final String ACTION_SUBMIT_TRACK_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_TRACK";
+// private static final String ACTION_SUBMIT_TRACK_REPORT = "org.sensorhub.android.intent.SPOT_REPORT_TRACK";
LocationManager locManager;
LocationProvider locProvider;
@@ -140,17 +140,6 @@ public long getLatestRecordTime()
@Override
public void onLocationChanged(Location location)
{
- Intent submitReportIntent = new Intent(ACTION_SUBMIT_TRACK_REPORT);
- submitReportIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
- submitReportIntent.putExtra("lat", location.getLatitude());
- submitReportIntent.putExtra("lon", location.getLongitude());
- submitReportIntent.putExtra("confidence", 16.0);
- submitReportIntent.putExtra("type", "device");
- submitReportIntent.putExtra("resourceId", parentSensor.getConfiguration().name);
- submitReportIntent.putExtra("resourceLabel", parentSensor.getConfiguration().name);
- submitReportIntent.putExtra("method", "gps");
- parentSensor.getConfiguration().androidContext.sendBroadcast(submitReportIntent);
-
/*log.debug("Location received from " + getName() + ": "
+ location.getLatitude() + ", " +
+ location.getLongitude() + ", " +
From 673e4650c053e14cfbaf604567ae88fc217a8fdb Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 27 Feb 2020 17:42:26 -0600
Subject: [PATCH 172/207] Add automatic request for user permissions (Location,
Camera, Storage)
---
build.gradle | 2 +-
.../src/org/sensorhub/android/MainActivity.java | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 858f7b61..2190e96d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,4 @@
-ext.oshCoreVersion = '1.4.0a'
+ext.oshCoreVersion = '1.4.0-alpha'
ext.compileSdkVersion = 28
ext.minSdkVersion = 26
ext.targetSdkVersion = 26
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index d1efabe1..3786f873 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -13,6 +13,7 @@
package org.sensorhub.android;
+import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
@@ -35,6 +36,8 @@
import android.os.Looper;
import android.preference.PreferenceManager;
import android.provider.Settings.Secure;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
import android.text.Html;
import android.util.Log;
import android.view.Menu;
@@ -1198,6 +1201,17 @@ protected void hideVideo() {
@Override
protected void onStart() {
super.onStart();
+ // check for permissions
+ // TODO: Add app defined constants for requestCodes below
+ if (ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},1);
+ }
+ if (ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},2);
+ }
+ if (ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission_group.STORAGE) != PackageManager.PERMISSION_GRANTED){
+ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission_group.STORAGE},3);
+ }
}
From 93bb527d887a76525cc2a94012f620dd496ed651 Mon Sep 17 00:00:00 2001
From: Alex Robin
Date: Wed, 11 Mar 2020 10:57:29 +0100
Subject: [PATCH 173/207] Fixed support for TruPulse simulated data and
geolocation
---
sensorhub-android-app/res/values/strings.xml | 2 +-
.../org/sensorhub/android/MainActivity.java | 66 +++++++++++--------
2 files changed, 40 insertions(+), 28 deletions(-)
diff --git a/sensorhub-android-app/res/values/strings.xml b/sensorhub-android-app/res/values/strings.xml
index ca638c10..b16290d3 100644
--- a/sensorhub-android-app/res/values/strings.xml
+++ b/sensorhub-android-app/res/values/strings.xml
@@ -61,7 +61,7 @@
STREAM
- SIMULATE
+ SIMULATEDSTREAM
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 3786f873..fd31d420 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -30,6 +30,8 @@
import android.graphics.SurfaceTexture;
import android.hardware.Sensor;
import android.hardware.SensorManager;
+import android.location.LocationManager;
+import android.location.LocationProvider;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -74,6 +76,7 @@
import org.sensorhub.impl.sensor.blebeacon.BLEBeaconConfig;
import org.sensorhub.impl.sensor.swe.ProxySensor.ProxySensorConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
+import org.sensorhub.impl.sensor.trupulse.TruPulseWithGeolocConfig;
import org.sensorhub.impl.service.HttpServerConfig;
import org.sensorhub.impl.service.sos.SOSServiceConfig;
import org.sensorhub.impl.service.sos.SensorDataProviderConfig;
@@ -96,6 +99,7 @@
public class MainActivity extends Activity implements TextureView.SurfaceTextureListener, IEventListener {
public static final String ACTION_BROADCAST_RECEIVER = "org.sensorhub.android.BROADCAST_RECEIVER";
+ public static final String ANDROID_SENSORS_MODULE_ID = "ANDROID_SENSORS";
String deviceID;
String deviceName;
@@ -200,7 +204,7 @@ protected void updateConfig(SharedPreferences prefs, String runName) {
boolean enabled = prefs.getBoolean("trupulse_enable", false);
if (enabled) {
String truPulseDevice = prefs.getString("trupulse_datasource", "SIMULATED");
- TruPulseConfig truPulseConfig = truPulseDevice == "SIMULATED"
+ TruPulseConfig truPulseConfig = "SIMULATED".equals(truPulseDevice)
? (TruPulseConfig) createSensorConfig(Sensors.TruPulseSim)
: (TruPulseConfig) createSensorConfig(Sensors.TruPulse);
sensorhubConfig.add(truPulseConfig);
@@ -254,29 +258,6 @@ protected void updateConfig(SharedPreferences prefs, String runName) {
Log.d(TAG, "onCreate: BLE Config Added");
}
- /*
- // DJI Drone
- enabled = prefs.getBoolean("dji_enabled", false);
- if (enabled)
- {
- DjiConfig djiConfig = new DjiConfig();
- djiConfig.id = "DJI_DRONE";
- djiConfig.name = "DJI Aircraft [" + deviceName + "]";
- djiConfig.autoStart = true;
- djiConfig.androidContext = this.getApplicationContext();
- djiConfig.camPreviewTexture = boundService.getVideoTexture();
- showVideo = true;
- sensorhubConfig.add(djiConfig);
- addSosTConfig(djiConfig, sosUser, sosPwd);
-
- SensorDataProviderConfig djiDataProviderConfig = new SensorDataProviderConfig();
- djiDataConsumerConfig.sensorID = djiConfig.id;
- djiDataConsumerConfig.offeringID = djiConfig.id+"-sos";
- djiDataConsumerConfig.enabled = true;
- sosConfig.dataConsumers.add(djiDataConsumerConfig);
- }
- */
-
/*
// Get SOS-T URL from config
String sostUriConfig = prefs.getString("sost_uri", "");
@@ -428,7 +409,7 @@ private SensorConfig createSensorConfig(Sensors sensor) {
if (Sensors.Android.equals(sensor)) {
sensorConfig = new AndroidSensorsConfig();
- sensorConfig.id = "urn:android:device:" + deviceID;
+ sensorConfig.id = ANDROID_SENSORS_MODULE_ID;
sensorConfig.name = "Android Sensors [" + deviceName + "]";
sensorConfig.autoStart = true;
@@ -456,7 +437,7 @@ private SensorConfig createSensorConfig(Sensors sensor) {
((AndroidSensorsConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
((AndroidSensorsConfig) sensorConfig).runName = runName;
} else if (Sensors.TruPulse.equals(sensor)) {
- sensorConfig = new TruPulseConfig();
+ sensorConfig = createTruPulseConfig();
sensorConfig.id = "TRUPULSE_SENSOR";
sensorConfig.name = "TruPulse Range Finder [" + deviceName + "]";
sensorConfig.autoStart = true;
@@ -467,7 +448,7 @@ private SensorConfig createSensorConfig(Sensors sensor) {
((TruPulseConfig) sensorConfig).commSettings = btConf;
((TruPulseConfig) sensorConfig).serialNumber = deviceID;
} else if (Sensors.TruPulseSim.equals(sensor)) {
- sensorConfig = new TruPulseConfig();
+ sensorConfig = createTruPulseConfig();
sensorConfig.id = "TRUPULSE_SENSOR_SIMULATED";
sensorConfig.name = "Simulated TruPulse Range Finder [" + deviceName + "]";
sensorConfig.autoStart = true;
@@ -513,6 +494,37 @@ private SensorConfig createSensorConfig(Sensors sensor) {
return sensorConfig;
}
+ private TruPulseConfig createTruPulseConfig() {
+
+ // get handle to AndroidSensorsConfig
+ AndroidSensorsConfig androidSensorsConfig = (AndroidSensorsConfig)sensorhubConfig.get(ANDROID_SENSORS_MODULE_ID);
+
+ // add target geolocation processing if GPS is enabled
+ if (androidSensorsConfig != null && androidSensorsConfig.activateGpsLocation)
+ {
+ String gpsOutputName = null;
+ if (getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION))
+ {
+ LocationManager locationManager = (LocationManager)getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
+ List locProviders = locationManager.getAllProviders();
+ for (String provName: locProviders)
+ {
+ LocationProvider locProvider = locationManager.getProvider(provName);
+ if (locProvider.requiresSatellite())
+ gpsOutputName = locProvider.getName().replaceAll(" ", "_") + "_data";
+ }
+ }
+
+ TruPulseWithGeolocConfig trupulseConfig = new TruPulseWithGeolocConfig();
+ trupulseConfig.locationSourceID = androidSensorsConfig.id;
+ trupulseConfig.locationOutputName = gpsOutputName;
+ return trupulseConfig;
+ }
+
+ // else only output raw range finder data
+ return new TruPulseConfig();
+ }
+
protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig storageConf) {
if (sensorConf instanceof AndroidSensorsConfig) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
From 2c67bd025e093a0fac71118722b67714d145fbb1 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 12 Mar 2020 11:21:39 -0500
Subject: [PATCH 174/207] Add back EulerOrientationOutputs
---
.../AndroidOrientationEulerOutput.java | 95 +++++++++++--------
1 file changed, 54 insertions(+), 41 deletions(-)
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidOrientationEulerOutput.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidOrientationEulerOutput.java
index 276a5121..c10aee9f 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidOrientationEulerOutput.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidOrientationEulerOutput.java
@@ -12,8 +12,8 @@
******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.impl.sensor.android;
-
+package org.sensorhub.impl.sensor.android;
+
import net.opengis.swe.v20.AllowedValues;
import net.opengis.swe.v20.DataBlock;
import net.opengis.swe.v20.Quantity;
@@ -22,20 +22,20 @@
import org.sensorhub.algo.vecmath.Vect3d;
import org.sensorhub.api.sensor.SensorDataEvent;
import org.vast.swe.helper.GeoPosHelper;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-
-
-/**
- *
- * Implementation of data interface for Android rotation vector sensors
- *
- *
- * @author Alex Robin
- * @since Jan 18, 2015
- */
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+
+
+/**
+ *
+ * Implementation of data interface for Android rotation vector sensors
+ *
+ *
+ * @author Alex Robin
+ * @since Jan 18, 2015
+ */
public class AndroidOrientationEulerOutput extends AndroidSensorOutput implements SensorEventListener
{
private static final String HEADING_DEF = "http://sensorml.com/ont/swe/property/AngleToNorth";
@@ -84,15 +84,15 @@ protected AndroidOrientationEulerOutput(AndroidSensorsDriver parentModule, Senso
}
- @Override
- public void onAccuracyChanged(Sensor sensor, int arg1)
- {
- }
-
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int arg1)
+ {
+ }
+
@Override
- public void onSensorChanged(SensorEvent e)
- {
+ public void onSensorChanged(SensorEvent e)
+ {
double sampleTime = getJulianTimeStamp(e.timestamp);
// convert to euler angles
@@ -110,26 +110,39 @@ public void onSensorChanged(SensorEvent e)
// rotate to ENU
att.rotate(look, look);
- double heading = 90. - Math.toDegrees(Math.atan2(look.y, look.x));
+ /*double heading = 90. - Math.toDegrees(Math.atan2(look.y, look.x));
if (heading > 180.)
heading -= 360.;
double pitch = 0.0;//Math.toDegrees(Math.atan2(look.y, look.x)) - 90.;
- double roll = 0.0;
-
- /*double sqw = q.w*q.w;
- double sqx = q.x*q.x;
- double sqy = q.y*q.y;
- double sqz = q.z*q.z;
- System.out.println(q0);
- euler.z = Math.atan2(2.0 * (q.x*q.y + q.z*q.W), sqx - sqy - sqz + sqw); // heading
- euler.y = Math.atan2(2.0 * (q.y*q.z + q.x*q.w), -sqx - sqy + sqz + sqw); // pitch
- euler.x = Math.asin(-2.0 * (q.x*q.z - q.y*q.w)); // roll
+ double roll = 0.0;*/
+
+ // Conversion from Orientation Quat to Euler
+ // Use JPL Quaternion [q0, q1, q2, q3] = [qw, qx, qy, qz]
+ double[] q = {att.s, att.x, att.y, att.z};
+ double[] qSQ = {q[0]*q[0], q[1]*q[1], q[2]*q[2], q[3]*q[3]};
+
+// double sqw = q.w*q.w;
+// double sqx = q.x*q.x;
+// double sqy = q.y*q.y;
+// double sqz = q.z*q.z;
+
+ euler.z = Math.atan2(2 * (q[1]*q[2] + q[3]*q[0]), qSQ[1] - qSQ[2] - qSQ[3] + qSQ[0]); // heading
+ euler.y = Math.atan2(2 * (q[2]*q[3] + q[1]*q[0]), -qSQ[1] - qSQ[2] + qSQ[3] + qSQ[0]); // pitch
+ euler.x = Math.asin(-2 * (q[1]*q[3] - q[2]*q[0])); // roll
+
+// euler.z = Math.atan2(2.0 * (q.x*q.y + q.z*q.W), sqx - sqy - sqz + sqw); // heading
+// euler.y = Math.atan2(2.0 * (q.y*q.z + q.x*q.w), -sqx - sqy + sqz + sqw); // pitch
+// euler.x = Math.asin(-2.0 * (q.x*q.z - q.y*q.w)); // roll
euler.scale(180./Math.PI);
-
- double oldx = euler.x; // convert to ENU
- euler.x = euler.y;
- euler.y = oldx;
- euler.z = -euler.z;*/
+
+ double heading = euler.z;
+ double pitch = euler.y;
+ double roll = euler.x;
+
+// double oldx = euler.x; // convert to ENU
+// euler.x = euler.y;
+// euler.y = oldx;
+// euler.z = -euler.z;
// build and populate datablock
DataBlock dataBlock = dataStruct.createDataBlock();
@@ -142,6 +155,6 @@ public void onSensorChanged(SensorEvent e)
// update latest record and send event
latestRecord = dataBlock;
latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, dataBlock));
+ eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, dataBlock));
}
-}
+}
From a65453831c835c6cc27ff7e775d124c06266bd0f Mon Sep 17 00:00:00 2001
From: Alex Robin
Date: Tue, 23 Mar 2021 22:59:29 +0100
Subject: [PATCH 175/207] Initial support for AAC audio stream
---
sensorhub-android-app/AndroidManifest.xml | 1 +
sensorhub-android-app/res/values/strings.xml | 10 +
sensorhub-android-app/res/xml/pref_audio.xml | 29 ++
.../res/xml/pref_headers.xml | 3 +
.../res/xml/pref_sensors.xml | 6 +
.../org/sensorhub/android/MainActivity.java | 11 +-
.../android/UserSettingsActivity.java | 35 ++
.../sensor/android/AndroidSensorsConfig.java | 3 +
.../sensor/android/AndroidSensorsDriver.java | 23 +
.../impl/sensor/android/SensorMLBuilder.java | 63 +--
.../android/audio/AndroidAudioOutput.java | 395 ++++++++++++++++++
.../android/audio/AndroidAudioOutputAAC.java | 113 +++++
.../android/audio/AudioEncoderConfig.java | 40 ++
.../android/video/AndroidCameraOutput.java | 12 +-
14 files changed, 706 insertions(+), 38 deletions(-)
create mode 100644 sensorhub-android-app/res/xml/pref_audio.xml
create mode 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
create mode 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputAAC.java
create mode 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AudioEncoderConfig.java
diff --git a/sensorhub-android-app/AndroidManifest.xml b/sensorhub-android-app/AndroidManifest.xml
index 1ddef0e1..3ac5ba8a 100644
--- a/sensorhub-android-app/AndroidManifest.xml
+++ b/sensorhub-android-app/AndroidManifest.xml
@@ -10,6 +10,7 @@
+
diff --git a/sensorhub-android-app/res/values/strings.xml b/sensorhub-android-app/res/values/strings.xml
index d70a0e67..1399276a 100644
--- a/sensorhub-android-app/res/values/strings.xml
+++ b/sensorhub-android-app/res/values/strings.xml
@@ -14,4 +14,14 @@
VP9VP8
+
+
+ AAC
+ AMR-NB
+ AMR-WB
+ FLAC
+ VORBIS
+ OPUS
+ PCM
+
diff --git a/sensorhub-android-app/res/xml/pref_audio.xml b/sensorhub-android-app/res/xml/pref_audio.xml
new file mode 100644
index 00000000..f23302f1
--- /dev/null
+++ b/sensorhub-android-app/res/xml/pref_audio.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
diff --git a/sensorhub-android-app/res/xml/pref_headers.xml b/sensorhub-android-app/res/xml/pref_headers.xml
index d84db848..442cac23 100644
--- a/sensorhub-android-app/res/xml/pref_headers.xml
+++ b/sensorhub-android-app/res/xml/pref_headers.xml
@@ -9,5 +9,8 @@
+
diff --git a/sensorhub-android-app/res/xml/pref_sensors.xml b/sensorhub-android-app/res/xml/pref_sensors.xml
index 9b19865e..a91ecef4 100644
--- a/sensorhub-android-app/res/xml/pref_sensors.xml
+++ b/sensorhub-android-app/res/xml/pref_sensors.xml
@@ -54,6 +54,12 @@
android:summary="Include video roll data in video frame header"
android:title="Video Roll Data" />
+
+
sampleRateList = Arrays.asList("8000", "11025", "22050", "44100", "48000");
+ List bitRateList = Arrays.asList("32", "64", "96", "128", "160", "192");
+
+ // add list of supported sample rates
+ ListPreference sampleRatePrefList = (ListPreference)audioOptsScreen.findPreference("audio_samplerate");
+ sampleRatePrefList.setEntries(sampleRateList.toArray(new String[0]));
+ sampleRatePrefList.setEntryValues(sampleRateList.toArray(new String[0]));
+ bindPreferenceSummaryToValue(findPreference("audio_samplerate"));
+
+ // add list of supported bitrates
+ ListPreference bitRatePrefList = (ListPreference)audioOptsScreen.findPreference("audio_bitrate");
+ bitRatePrefList.setEntries(bitRateList.toArray(new String[0]));
+ bitRatePrefList.setEntryValues(bitRateList.toArray(new String[0]));
+ bindPreferenceSummaryToValue(findPreference("audio_samplerate"));
+ }
+ }
+
+
@Override
protected boolean isValidFragment(String fragmentName)
{
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsConfig.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsConfig.java
index eb505e95..36ba6dce 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsConfig.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsConfig.java
@@ -17,6 +17,7 @@
import android.graphics.SurfaceTexture;
import org.sensorhub.api.module.ModuleConfig;
import org.sensorhub.api.sensor.SensorConfig;
+import org.sensorhub.impl.sensor.android.audio.AudioEncoderConfig;
import org.sensorhub.impl.sensor.android.video.VideoEncoderConfig;
import android.content.Context;
@@ -43,6 +44,8 @@ public class AndroidSensorsConfig extends SensorConfig
public boolean activateFrontCamera = false;
public VideoEncoderConfig videoConfig = new VideoEncoderConfig();
public boolean outputVideoRoll = false;
+ public boolean activateMicAudio = false;
+ public AudioEncoderConfig audioConfig = new AudioEncoderConfig();
public String deviceName;
public String runName;
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
index d5da92d0..d5646f36 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
@@ -32,6 +32,8 @@
import org.sensorhub.api.sensor.ISensorDataInterface;
import org.sensorhub.api.sensor.SensorException;
import org.sensorhub.impl.sensor.AbstractSensorModule;
+import org.sensorhub.impl.sensor.android.audio.AndroidAudioOutputAAC;
+import org.sensorhub.impl.sensor.android.audio.AudioEncoderConfig;
import org.sensorhub.impl.sensor.android.video.AndroidCameraOutputH264;
import org.sensorhub.impl.sensor.android.video.AndroidCameraOutputH265;
import org.sensorhub.impl.sensor.android.video.AndroidCameraOutputMJPEG;
@@ -138,6 +140,10 @@ public synchronized void init() throws SensorHubException
// create data interfaces for cameras
if (androidContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
createCameraOutputs(androidContext);
+
+ // create data interfaces for audio
+ if (androidContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE))
+ createAudioOutputs(androidContext);
}
@@ -207,6 +213,15 @@ else if (VideoEncoderConfig.VP8_CODEC.equals(config.videoConfig.codec))
}
}
}
+
+
+ protected void createAudioOutputs(Context androidContext) throws SensorException
+ {
+ if (AudioEncoderConfig.AAC_CODEC.equals(config.audioConfig.codec))
+ useAudio(new AndroidAudioOutputAAC(this), "MIC");
+ else
+ throw new SensorException("Unsupported codec " + config.audioConfig.codec);
+ }
protected void useSensor(ISensorDataInterface output, Sensor sensor)
@@ -239,6 +254,14 @@ protected void useCamera2(ISensorDataInterface output, String cameraId)
smlComponents.add(smlBuilder.getComponentDescription(cameraId));
log.info("Getting data from camera #" + cameraId);
}
+
+
+ protected void useAudio(ISensorDataInterface output, String srcName)
+ {
+ addOutput(output, false);
+ smlComponents.add(smlBuilder.getAudioComponentDescription(srcName));
+ log.info("Getting data from audio source " + srcName);
+ }
@Override
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/SensorMLBuilder.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/SensorMLBuilder.java
index 47e2db2e..23f8673c 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/SensorMLBuilder.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/SensorMLBuilder.java
@@ -1,24 +1,24 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
-The contents of this file are subject to the Mozilla Public License, v. 2.0.
-If a copy of the MPL was not distributed with this file, You can obtain one
-at http://mozilla.org/MPL/2.0/.
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the License.
-
-Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
-
-******************************* END LICENSE BLOCK ***************************/
-
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
package org.sensorhub.impl.sensor.android;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vast.data.SWEFactory;
import org.vast.sensorML.SMLFactory;
-import net.opengis.sensorml.v20.PhysicalComponent;
+import net.opengis.sensorml.v20.PhysicalComponent;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.LocationManager;
@@ -93,18 +93,27 @@ else if (val instanceof Object[])
}*/
return comp;
- }
-
-
- /*
- * Version to support older camera API on devices with SDK < 21
- */
- public PhysicalComponent getComponentDescription(int cameraId)
- {
- PhysicalComponent comp = smlFac.newPhysicalComponent();
- comp.setId("CAM_" + cameraId);
- comp.setName("Android Camera #" + cameraId);
- return comp;
+ }
+
+
+ /*
+ * Version to support older camera API on devices with SDK < 21
+ */
+ public PhysicalComponent getComponentDescription(int cameraId)
+ {
+ PhysicalComponent comp = smlFac.newPhysicalComponent();
+ comp.setId("CAM_" + cameraId);
+ comp.setName("Android Camera #" + cameraId);
+ return comp;
+ }
+
+
+ public PhysicalComponent getAudioComponentDescription(String audioSrcName)
+ {
+ PhysicalComponent comp = smlFac.newPhysicalComponent();
+ comp.setId("AUDIO_" + audioSrcName);
+ comp.setName("Android Audio " + audioSrcName);
+ return comp;
}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
new file mode 100644
index 00000000..5315f36f
--- /dev/null
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
@@ -0,0 +1,395 @@
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android.audio;
+
+import android.graphics.ImageFormat;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.media.AudioFormat;
+import android.media.AudioRecord;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaRecorder;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+
+import net.opengis.swe.v20.BinaryBlock;
+import net.opengis.swe.v20.BinaryComponent;
+import net.opengis.swe.v20.BinaryEncoding;
+import net.opengis.swe.v20.ByteEncoding;
+import net.opengis.swe.v20.ByteOrder;
+import net.opengis.swe.v20.DataBlock;
+import net.opengis.swe.v20.DataComponent;
+import net.opengis.swe.v20.DataEncoding;
+import net.opengis.swe.v20.DataRecord;
+import net.opengis.swe.v20.DataStream;
+import net.opengis.swe.v20.DataType;
+import net.opengis.swe.v20.Quantity;
+
+import org.sensorhub.algo.vecmath.Vect3d;
+import org.sensorhub.api.sensor.SensorDataEvent;
+import org.sensorhub.api.sensor.SensorException;
+import org.sensorhub.impl.sensor.AbstractSensorOutput;
+import org.sensorhub.impl.sensor.android.AndroidSensorsDriver;
+import org.sensorhub.impl.sensor.android.IAndroidOutput;
+import org.sensorhub.impl.sensor.android.video.VideoEncoderConfig;
+import org.sensorhub.impl.sensor.videocam.VideoCamHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.vast.cdm.common.CDMException;
+import org.vast.data.AbstractDataBlock;
+import org.vast.data.DataBlockMixed;
+import org.vast.swe.SWEConstants;
+import org.vast.swe.SWEHelper;
+import org.vast.swe.helper.GeoPosHelper;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+
+/**
+ *
+ * Implementation of data interface capturing audio data using Android
+ * AudioRecord API. See https://www.codota.com/code/java/classes/android.media.AudioRecord
+ *
+ *
+ * @author Alex Robin
+ * @since Mar 22, 2021
+ */
+@SuppressWarnings("deprecation")
+public abstract class AndroidAudioOutput extends AbstractSensorOutput implements IAndroidOutput
+{
+ // keep logger name short because in LogCat it's max 23 chars
+ static final Logger log = LoggerFactory.getLogger(AndroidAudioOutput.class.getSimpleName());
+
+ DataComponent dataStruct;
+ DataEncoding dataEncoding;
+ int sampleRateHz = 11025;
+ int pcmEncoding = AudioFormat.ENCODING_PCM_16BIT;
+ double samplingPeriod = 0.5; // seconds
+ int numSamplesPerRecord;
+ int bytesPerSample;
+ int bytesPerRecord;
+ int bitrate = 64 * 1000; // bits/s
+
+ Looper bgLooper;
+ AudioRecord audioRecord;
+ long systemTimeOffset = -1L;
+ byte[] codecInfoData;
+ MediaCodec mCodec;
+ BufferInfo bufferInfo = new BufferInfo();
+ int packetHeaderSize = 0;
+
+ protected abstract String getCodecName();
+
+ protected abstract void initCodec(int inputBufferSize) throws SensorException;
+
+ protected abstract void addPacketHeader(byte[] packet, int packetLen);
+
+
+ protected AndroidAudioOutput(AndroidSensorsDriver parentModule, String name) throws SensorException
+ {
+ super(name, parentModule);
+
+ // init audio recorder and codec
+ initAudio();
+ initCodec(bytesPerRecord);
+ initOutputStructure();
+ }
+
+
+ protected void initOutputStructure()
+ {
+ // create SWE Common data structure and encoding
+ SWEHelper swe = new SWEHelper();
+ String numSamplesId = "NUM_SAMPLES";
+ dataStruct = swe.createRecord()
+ .name(getName())
+ .definition(SWEHelper.getPropertyUri("AudioFrame"))
+ .addField("time", swe.createTime().asPhenomenonTimeIsoUTC().build())
+ .addField("sampleRate", swe.createQuantity()
+ .label("Sample Rate")
+ .description("Number of audio samples per second")
+ .definition(SWEHelper.getQudtUri("DataRate"))
+ .uomCode("Hz"))
+ .addField("numSamples", swe.createCount()
+ .id(numSamplesId)
+ .label("Num Samples")
+ .description("Number of audio samples packaged in this record"))
+ .addField("samples", swe.createArray()
+ .withVariableSize(numSamplesId)
+ .withElement("sample", swe.createCount()
+ .label("Audio Sample")
+ .definition(SWEConstants.DEF_DN)
+ .dataType(DataType.SHORT))
+ .build())
+ .build();
+
+ //////////////////////////
+ // binary encoding spec //
+ //////////////////////////
+ BinaryEncoding dataEnc = swe.newBinaryEncoding();
+ dataEnc.setByteEncoding(ByteEncoding.RAW);
+ dataEnc.setByteOrder(ByteOrder.BIG_ENDIAN);
+ BinaryComponent comp;
+
+ // time stamp
+ comp = swe.newBinaryComponent();
+ comp.setRef("/" + dataStruct.getComponent(0).getName());
+ comp.setCdmDataType(DataType.DOUBLE);
+ dataEnc.addMemberAsComponent(comp);
+
+ // sample rate
+ comp = swe.newBinaryComponent();
+ comp.setRef("/" + dataStruct.getComponent(1).getName());
+ comp.setCdmDataType(DataType.INT);
+ dataEnc.addMemberAsComponent(comp);
+
+ // num samples
+ comp = swe.newBinaryComponent();
+ comp.setRef("/" + dataStruct.getComponent(2).getName());
+ comp.setCdmDataType(DataType.INT);
+ dataEnc.addMemberAsComponent(comp);
+
+ // audio codec
+ BinaryBlock compressedBlock = swe.newBinaryBlock();
+ compressedBlock.setRef("/" + dataStruct.getComponent(3).getName());
+ compressedBlock.setCompression(getCodecName());
+ dataEnc.addMemberAsBlock(compressedBlock);
+
+ try
+ {
+ SWEHelper.assignBinaryEncoding(dataStruct, dataEnc);
+ }
+ catch (CDMException e)
+ {
+ throw new RuntimeException("Invalid binary encoding configuration", e);
+ };
+
+ this.dataEncoding = dataEnc;
+ }
+
+
+ protected void initAudio() throws SensorException
+ {
+ AudioEncoderConfig audioConfig = parentSensor.getConfiguration().audioConfig;
+ sampleRateHz = audioConfig.sampleRate;
+ bitrate = audioConfig.bitRate * 1000;
+
+ numSamplesPerRecord = (int)(samplingPeriod * sampleRateHz);
+ bytesPerSample = (pcmEncoding == AudioFormat.ENCODING_PCM_8BIT) ? 1 : 2;
+ bytesPerRecord = numSamplesPerRecord*bytesPerSample;
+
+ // create audio recorder object
+ // we use an internal buffer twice as big as the read buffer
+ // so we have time to compress a chunk while we're recording the next one
+ audioRecord = new AudioRecord(
+ MediaRecorder.AudioSource.MIC,
+ sampleRateHz,
+ AudioFormat.CHANNEL_IN_MONO,
+ pcmEncoding,
+ bytesPerRecord*2);
+ }
+
+
+ @Override
+ public void start(Handler eventHandler) throws SensorException
+ {
+ try
+ {
+ // start codec
+ if (mCodec != null)
+ mCodec.start();
+
+ // read audio samples in background thread
+ Thread bgThread = new Thread() {
+ public void run()
+ {
+ try
+ {
+ byte[] buffer = new byte[numSamplesPerRecord*2]; // 16 bits samples
+ audioRecord.startRecording();
+
+ while (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED) {
+ readAndEncodeAudioData();
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ };
+ bgThread.start();
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot start codec " + mCodec.getName(), e);
+ }
+ }
+
+
+ private void readAndEncodeAudioData()
+ {
+ // get next available buffer from codec
+ int inputBufferIndex = mCodec.dequeueInputBuffer(0);
+ if (inputBufferIndex >= 0)
+ {
+ ByteBuffer inputBuffer = mCodec.getInputBuffer(inputBufferIndex);
+ inputBuffer.clear();
+
+ long timeStamp = SystemClock.elapsedRealtimeNanos() / 1000;
+ int readBytes = audioRecord.read(inputBuffer, bytesPerRecord);
+ log.debug(timeStamp + ": " + readBytes + " audio bytes read");
+ mCodec.queueInputBuffer(inputBufferIndex, 0, readBytes, timeStamp, 0);
+
+ encode();
+ }
+ }
+
+
+ private void encode()
+ {
+ int outputBufferIndex;
+
+ do {
+ outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 0);
+ if (outputBufferIndex >= 0) {
+ ByteBuffer outBuffer = mCodec.getOutputBuffer(outputBufferIndex);
+ int outDataSize = outBuffer.remaining();
+ log.debug(bufferInfo.presentationTimeUs + ": " + outDataSize + " compressed audio bytes");
+ int outDataOffset = packetHeaderSize;
+
+ // create buffer to hold packet header + data
+ byte[] outData = new byte[outDataSize + outDataOffset];
+
+ // copy encoded data
+ outBuffer.get(outData, outDataOffset, outDataSize);
+ addPacketHeader(outData, outDataSize);
+
+ // release output buffer
+ mCodec.releaseOutputBuffer(outputBufferIndex, false);
+
+ // send it to output (but skip codec config bytes)
+ if (bufferInfo.flags != MediaCodec.BUFFER_FLAG_CODEC_CONFIG)
+ sendCompressedData(bufferInfo.presentationTimeUs, outData);
+ }
+ }
+ while (outputBufferIndex >= 0);
+ }
+
+
+ protected void sendCompressedData(long timeStamp, byte[] compressedData)
+ {
+ // generate new data record
+ DataBlock newRecord;
+ if (latestRecord == null)
+ newRecord = dataStruct.createDataBlock();
+ else
+ newRecord = latestRecord.renew();
+
+ // set time stamp
+ int idx = 0;
+ double samplingTime = getJulianTimeStamp(timeStamp);
+ newRecord.setDoubleValue(idx++, samplingTime);
+ newRecord.setIntValue(idx++, sampleRateHz);
+ newRecord.setIntValue(idx++, numSamplesPerRecord);
+
+ // set encoded data
+ AbstractDataBlock audioData = ((DataBlockMixed) newRecord).getUnderlyingObject()[idx++];
+ audioData.setUnderlyingObject(compressedData);
+
+ // send event
+ latestRecord = newRecord;
+ latestRecordTime = System.currentTimeMillis();
+ eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, latestRecord));
+ }
+
+
+ @Override
+ public void stop()
+ {
+ if (audioRecord != null)
+ {
+ audioRecord.stop();
+ audioRecord = null;
+ }
+
+ if (mCodec != null)
+ {
+ mCodec.stop();
+ mCodec.release();
+ }
+
+ if (bgLooper != null)
+ {
+ bgLooper.quit();
+ bgLooper = null;
+ }
+ }
+
+
+ @Override
+ public double getAverageSamplingPeriod()
+ {
+ return samplingPeriod;
+ }
+
+
+ @Override
+ public DataComponent getRecordDescription()
+ {
+ return dataStruct;
+ }
+
+
+ @Override
+ public DataEncoding getRecommendedEncoding()
+ {
+ return dataEncoding;
+ }
+
+
+ @Override
+ public DataBlock getLatestRecord()
+ {
+ return latestRecord;
+ }
+
+
+ @Override
+ public long getLatestRecordTime()
+ {
+ return latestRecordTime;
+ }
+
+
+ protected double getJulianTimeStamp(long sensorTimeStampUs)
+ {
+ long sensorTimeMillis = sensorTimeStampUs / 1000;
+
+ if (systemTimeOffset < 0)
+ systemTimeOffset = System.currentTimeMillis() - sensorTimeMillis;
+
+ return (systemTimeOffset + sensorTimeMillis) / 1000.;
+ }
+}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputAAC.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputAAC.java
new file mode 100644
index 00000000..40923535
--- /dev/null
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputAAC.java
@@ -0,0 +1,113 @@
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android.audio;
+
+import android.graphics.SurfaceTexture;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+
+import org.sensorhub.api.sensor.SensorException;
+import org.sensorhub.impl.sensor.android.AndroidSensorsDriver;
+
+
+/**
+ *
+ * Implementation of data interface capturing audio data and compressing it
+ * using AAC codec.
+ *
+ *
+ * @author Alex Robin
+ * @since March 22, 2021
+ */
+@SuppressWarnings("deprecation")
+public class AndroidAudioOutputAAC extends AndroidAudioOutput
+{
+ private static final String CODEC_NAME = "AAC";
+ private static int[] ADTS_FREQ_TABLE = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 };
+
+ int adtsFreqIdx;
+
+
+ public AndroidAudioOutputAAC(AndroidSensorsDriver parentModule) throws SensorException
+ {
+ super(parentModule, "audio" + "_" + CODEC_NAME);
+ }
+
+ @Override
+ protected String getCodecName()
+ {
+ return CODEC_NAME;
+ }
+
+ @Override
+ protected void initCodec(int inputBufferSize) throws SensorException
+ {
+ try {
+ final String videoCodec = MediaFormat.MIMETYPE_AUDIO_AAC;
+ mCodec = MediaCodec.createEncoderByType(videoCodec);
+ MediaFormat mediaFormat = MediaFormat.createAudioFormat(videoCodec, sampleRateHz, 1);
+ mediaFormat.setInteger("pcm-encoding", pcmEncoding);
+ mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, inputBufferSize);
+ mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+ mediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
+ mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
+ mCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+ log.debug("MediaCodec initialized");
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot initialize codec " + mCodec.getName(), e);
+ }
+ }
+
+
+ @Override
+ protected void initAudio() throws SensorException
+ {
+ super.initAudio();
+
+ // set ADTS packet header size
+ packetHeaderSize = 7;
+
+ // compute sample rate index to be used in ADTS headers
+ adtsFreqIdx = -1;
+ for (int i = 0; i < ADTS_FREQ_TABLE.length; i++)
+ {
+ if (ADTS_FREQ_TABLE[i] == sampleRateHz)
+ adtsFreqIdx = i;
+ }
+ if (adtsFreqIdx < 0)
+ throw new SensorException("Unsupported sample rate for AAC: " + sampleRateHz);
+ }
+
+
+ protected void addPacketHeader(byte[] packet, int dataLen)
+ {
+ int profile = 2; // AAC LC
+ int freqIdx = adtsFreqIdx;
+ int chanCfg = 1; // mono
+ int frameLen = dataLen + packetHeaderSize;
+
+ // fill in ADTS data
+ packet[0] = (byte)0xFF;
+ packet[1] = (byte)0xF1;
+ packet[2] = (byte)(((profile - 1) << 6) + (freqIdx << 2) +(chanCfg >> 2));
+ packet[3] = (byte)(((chanCfg & 3) << 6) + (frameLen >> 11));
+ packet[4] = (byte)((frameLen & 0x7FF) >> 3);
+ packet[5] = (byte)(((frameLen & 7) << 5) + 0x1F);
+ packet[6] = (byte)0xFC;
+ }
+}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AudioEncoderConfig.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AudioEncoderConfig.java
new file mode 100644
index 00000000..7525b4a5
--- /dev/null
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AudioEncoderConfig.java
@@ -0,0 +1,40 @@
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android.audio;
+
+
+/**
+ *
+ * Configuration of audio encoding parameters
+ *
+ *
+ * @author Alex Robin
+ * @since Mar 22, 2021
+ */
+public class AudioEncoderConfig
+{
+ public final static String AAC_CODEC = "AAC";
+ public final static String AMRNB_CODEC = "AMR-NB";
+ public final static String AMRWB_CODEC = "AMR-WB";
+ public final static String FLAC_CODEC = "FLAC";
+ public final static String OPUS_CODEC = "OPUS";
+ public final static String VORBIS_CODEC = "VORBIS";
+ public final static String PCM_CODEC = "PCM";
+
+
+ public String codec = AAC_CODEC;
+ public int sampleRate = 8000; // Hz
+ public int bitRate = 64; // kbits/sec
+}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
index c8240a54..495096a1 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
@@ -88,7 +88,6 @@ public abstract class AndroidCameraOutput extends AbstractSensorOutput
Date: Mon, 12 Apr 2021 14:46:11 +0200
Subject: [PATCH 176/207] Compute exact timestamps based on number of recorded
samples
---
.../android/audio/AndroidAudioOutput.java | 17 +++++++++++------
.../android/audio/AndroidAudioOutputAAC.java | 8 +++++---
2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
index 5315f36f..ea0f6c48 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
@@ -85,7 +85,6 @@ public abstract class AndroidAudioOutput extends AbstractSensorOutput
Date: Mon, 12 Apr 2021 14:47:47 +0200
Subject: [PATCH 177/207] Added support for OPUS audio codec
---
.../sensor/android/AndroidSensorsDriver.java | 3 +
.../android/audio/AndroidAudioOutputOPUS.java | 87 +++++++++++++++++++
2 files changed, 90 insertions(+)
create mode 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputOPUS.java
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
index d5646f36..40f2b20b 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
@@ -33,6 +33,7 @@
import org.sensorhub.api.sensor.SensorException;
import org.sensorhub.impl.sensor.AbstractSensorModule;
import org.sensorhub.impl.sensor.android.audio.AndroidAudioOutputAAC;
+import org.sensorhub.impl.sensor.android.audio.AndroidAudioOutputOPUS;
import org.sensorhub.impl.sensor.android.audio.AudioEncoderConfig;
import org.sensorhub.impl.sensor.android.video.AndroidCameraOutputH264;
import org.sensorhub.impl.sensor.android.video.AndroidCameraOutputH265;
@@ -219,6 +220,8 @@ protected void createAudioOutputs(Context androidContext) throws SensorException
{
if (AudioEncoderConfig.AAC_CODEC.equals(config.audioConfig.codec))
useAudio(new AndroidAudioOutputAAC(this), "MIC");
+ else if (AudioEncoderConfig.OPUS_CODEC.equals(config.audioConfig.codec))
+ useAudio(new AndroidAudioOutputOPUS(this), "MIC");
else
throw new SensorException("Unsupported codec " + config.audioConfig.codec);
}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputOPUS.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputOPUS.java
new file mode 100644
index 00000000..588e3e8b
--- /dev/null
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputOPUS.java
@@ -0,0 +1,87 @@
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android.audio;
+
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+
+import org.sensorhub.api.sensor.SensorException;
+import org.sensorhub.impl.sensor.android.AndroidSensorsDriver;
+
+
+/**
+ *
+ * Implementation of data interface capturing audio data and compressing it
+ * using the Opus codec.
+ *
+ *
+ * @author Alex Robin
+ * @since March 29, 2021
+ */
+@SuppressWarnings("deprecation")
+public class AndroidAudioOutputOPUS extends AndroidAudioOutput
+{
+ private static final String CODEC_NAME = "OPUS";
+
+ int adtsFreqIdx;
+
+
+ public AndroidAudioOutputOPUS(AndroidSensorsDriver parentModule) throws SensorException
+ {
+ super(parentModule, "audio" + "_" + CODEC_NAME);
+ }
+
+ @Override
+ protected String getCodecName()
+ {
+ return CODEC_NAME;
+ }
+
+ @Override
+ protected void initCodec(int inputBufferSize) throws SensorException
+ {
+ try {
+ final String audioCodec = MediaFormat.MIMETYPE_AUDIO_OPUS;
+ mCodec = MediaCodec.createEncoderByType(audioCodec);
+ MediaFormat mediaFormat = MediaFormat.createAudioFormat(audioCodec, sampleRateHz, 1);
+ mediaFormat.setInteger("pcm-encoding", pcmEncoding);
+ mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, inputBufferSize);
+ mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+ mediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
+ mCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+ log.debug("MediaCodec initialized");
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot initialize codec " + mCodec.getName(), e);
+ }
+ }
+
+
+ @Override
+ protected void initAudio() throws SensorException
+ {
+ super.initAudio();
+
+ // no header for opus
+ packetHeaderSize = 0;
+ }
+
+
+ protected void addPacketHeader(byte[] packet, int dataLen)
+ {
+ }
+}
From 5db1e326faa11e448f1e6b75955b01373f5ff087 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Mon, 26 Apr 2021 21:33:42 -0500
Subject: [PATCH 178/207] Video data being transmitted, no preview
---
.../android/AndroidCameraOutputH264.java | 819 +++++++++---------
.../android/AndroidCameraOutputMJPEG.java | 618 ++++++-------
.../sensor/android/AndroidSensorsDriver.java | 11 +-
3 files changed, 724 insertions(+), 724 deletions(-)
mode change 100755 => 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputMJPEG.java
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputH264.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputH264.java
index 48e9301e..33eba00d 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputH264.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputH264.java
@@ -1,410 +1,409 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
-The contents of this file are subject to the Mozilla Public License, v. 2.0.
-If a copy of the MPL was not distributed with this file, You can obtain one
-at http://mozilla.org/MPL/2.0/.
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the License.
-
-Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
-
-******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.sensor.android;
-
-import java.nio.ByteBuffer;
-
-import android.graphics.SurfaceTexture;
-import android.os.Handler;
-import net.opengis.swe.v20.DataBlock;
-import net.opengis.swe.v20.DataComponent;
-import net.opengis.swe.v20.DataEncoding;
-import net.opengis.swe.v20.DataStream;
-import org.sensorhub.api.sensor.SensorDataEvent;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorOutput;
-import org.sensorhub.impl.sensor.videocam.VideoCamHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.vast.data.AbstractDataBlock;
-import org.vast.data.DataBlockMixed;
-import android.graphics.ImageFormat;
-import android.hardware.Camera;
-import android.hardware.Camera.Parameters;
-import android.media.MediaCodec;
-import android.media.MediaCodec.BufferInfo;
-import android.media.MediaCodecInfo;
-import android.media.MediaFormat;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.view.SurfaceHolder;
-
-
-/**
- *
- * Implementation of data interface for Android cameras using legacy Camera API.
- * This will encode the video frames as a raw H264 stream (i.e. NAL units).
- *
- *
- * @author Alex Robin
- * @since June 11, 2015
- */
-@SuppressWarnings("deprecation")
-public class AndroidCameraOutputH264 extends AbstractSensorOutput implements IAndroidOutput, Camera.PreviewCallback
-{
- // keep logger name short because in LogCat it's max 23 chars
- static final Logger log = LoggerFactory.getLogger(AndroidCameraOutputH264.class.getSimpleName());
- protected static final String TIME_REF = "http://www.opengis.net/def/trs/BIPM/0/UTC";
-
- Looper bgLooper;
- int cameraId;
- Camera camera;
- int imgHeight, imgWidth, frameRate;
- byte[] imgBuf1, imgBuf2;
- byte[] codecInfoData;
- MediaCodec mCodec;
- BufferInfo bufferInfo = new BufferInfo();
- SurfaceTexture previewTexture;
-
- String name;
- DataComponent dataStruct;
- DataEncoding dataEncoding;
- int samplingPeriod;
- long systemTimeOffset = -1L;
-
-
- protected AndroidCameraOutputH264(AndroidSensorsDriver parentModule, int cameraId, SurfaceTexture previewTexture) throws SensorException
- {
- super(parentModule);
- this.cameraId = cameraId;
- this.name = "camera" + cameraId + "_H264";
- //this.previewSurfaceHolder = previewSurfaceHolder;
- this.previewTexture = previewTexture;
-
- // init camera hardware and H264 codec
- initCam();
- initCodec();
-
- // create SWE Common data structure and encoding
- VideoCamHelper fac = new VideoCamHelper();
- DataStream videoStream = fac.newVideoOutputH264(getName(), imgWidth, imgHeight);
- dataStruct = videoStream.getElementType();
- dataEncoding = videoStream.getEncoding();
- }
-
-
- protected void initCam() throws SensorException
- {
- android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
- android.hardware.Camera.getCameraInfo(cameraId, info);
-
- // handle camera in its own thread
- // this is to avoid running in the same thread as other sensors
- Thread bgThread = new Thread() {
- public void run()
- {
- try
- {
- // we need an Android looper to process camera messages
- Looper.prepare();
- bgLooper = Looper.myLooper();
-
- // open camera and get parameters
- camera = Camera.open(cameraId);
-
- // start processing messages
- Looper.loop();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
- synchronized (this)
- {
- notify();
- }
- }
- };
- bgThread.start();
-
- // wait until camera is opened
- synchronized (bgThread)
- {
- try
- {
- bgThread.wait(1000);
- }
- catch (InterruptedException e)
- {
- }
- }
-
- // if camera was successfully opened, prepare for video capture
- if (camera != null)
- {
- try
- {
- Parameters camParams = camera.getParameters();
-
- // get supported preview sizes
- for (Camera.Size imgSize : camParams.getSupportedPreviewSizes())
- {
- if (imgSize.width >= 600 && imgSize.width <= 800)
- {
- imgWidth = imgSize.width;
- imgHeight = imgSize.height;
- break;
- }
- }
- frameRate = 1;
-
- // set parameters
- camParams.setPreviewSize(imgWidth, imgHeight);
- camParams.setPreviewFormat(ImageFormat.NV21);
- camParams.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
- camera.setParameters(camParams);
-
- // setup buffers and callback
- int bufSize = imgWidth * imgHeight * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
- imgBuf1 = new byte[bufSize];
- imgBuf2 = new byte[bufSize];
- camera.addCallbackBuffer(imgBuf1);
- camera.addCallbackBuffer(imgBuf2);
- camera.setPreviewCallbackWithBuffer(AndroidCameraOutputH264.this);
- camera.setDisplayOrientation(info.orientation);
- }
- catch (Exception e)
- {
- throw new SensorException("Cannot initialize camera " + cameraId, e);
- }
- }
- else
- {
- throw new SensorException("Cannot open camera " + cameraId);
- }
- }
-
-
- protected void initCodec() throws SensorException
- {
- try
- {
- mCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
- MediaFormat mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, imgWidth, imgHeight);
- mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
- mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
- mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
- mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
- mCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
- log.debug("MediaCodec initialized");
- }
- catch (Exception e)
- {
- throw new SensorException("Cannot initialize codec " + mCodec.getName(), e);
- }
- }
-
-
- @Override
- public void start(Handler eventHandler) throws SensorException
- {
- try
- {
- // start codec
- if (mCodec != null)
- mCodec.start();
- }
- catch (Exception e)
- {
- throw new SensorException("Cannot start codec " + mCodec.getName(), e);
- }
-
- try
- {
- // start streaming video
- if (previewTexture != null)
- camera.setPreviewTexture(previewTexture);
- camera.startPreview();
- }
- catch (Exception e)
- {
- throw new SensorException("Cannot start capture on camera " + cameraId, e);
- }
- }
-
-
- @Override
- public void onPreviewFrame(byte[] data, Camera camera)
- {
- long timeStamp = SystemClock.elapsedRealtimeNanos() / 1000;
-
- // convert to NV12
- int uvPos = imgWidth * imgHeight;
- for (int i = uvPos; i < data.length; i+=2)
- {
- byte b = data[i];
- data[i] = data[i+1];
- data[i+1] = b;
- }
-
- // compress using selected codec
- encode(timeStamp, data);
-
- // release buffer for next frame
- camera.addCallbackBuffer(data);
- }
-
-
- private void encode(long timeStamp, byte[] data)
- {
- // copy frame data to buffer
- int inputBufferIndex = mCodec.dequeueInputBuffer(0);
- if (inputBufferIndex >= 0)
- {
- ByteBuffer inputBuffer = mCodec.getInputBuffer(inputBufferIndex);
- inputBuffer.clear();
- inputBuffer.put(data);
- mCodec.queueInputBuffer(inputBufferIndex, 0, data.length, timeStamp, 0);
- }
- else
- {
- // skip frame if no buffer is available
- return;
- }
-
- int outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 0);
- if (outputBufferIndex >= 0)
- {
- ByteBuffer outBuffer = mCodec.getOutputBuffer(outputBufferIndex);
- int outDataSize = bufferInfo.size - bufferInfo.offset;
- int outDataOffset = 0;
- byte[] outData;
-
- // insert SPS/PPS before each key frame
- if (codecInfoData != null && bufferInfo.flags == MediaCodec.BUFFER_FLAG_KEY_FRAME)
- {
- outDataOffset = codecInfoData.length;
- outData = new byte[outDataSize + outDataOffset];
- System.arraycopy(codecInfoData, 0, outData, 0, codecInfoData.length);
- }
- else
- outData = new byte[outDataSize];
-
- // copy encoded data
- outBuffer.position(bufferInfo.offset);
- outBuffer.get(outData, outDataOffset, bufferInfo.size);
-
- // release output buffer
- mCodec.releaseOutputBuffer(outputBufferIndex, false);
-
- if (bufferInfo.flags == MediaCodec.BUFFER_FLAG_CODEC_CONFIG)
- codecInfoData = outData;
- else
- sendCompressedData(bufferInfo.presentationTimeUs, outData);
- }
- }
-
-
- private void sendCompressedData(long timeStamp, byte[] compressedData)
- {
- // generate new data record
- DataBlock newRecord;
- if (latestRecord == null)
- newRecord = dataStruct.createDataBlock();
- else
- newRecord = latestRecord.renew();
-
- // set time stamp
- double samplingTime = getJulianTimeStamp(timeStamp);
- newRecord.setDoubleValue(0, samplingTime);
-
- // set encoded data
- AbstractDataBlock frameData = ((DataBlockMixed) newRecord).getUnderlyingObject()[1];
- frameData.setUnderlyingObject(compressedData);
-
- // send event
- latestRecord = newRecord;
- latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, AndroidCameraOutputH264.this, latestRecord));
- }
-
-
- @Override
- public void stop()
- {
- if (camera != null)
- {
- camera.stopPreview();
- camera.release();
- camera = null;
- }
-
- if (mCodec != null)
- {
- mCodec.stop();
- mCodec.release();
- }
-
- if (bgLooper != null)
- {
- bgLooper.quit();
- bgLooper = null;
- }
- }
-
-
- @Override
- public String getName()
- {
- return name;
- }
-
-
- @Override
- public double getAverageSamplingPeriod()
- {
- return 1. / (double) frameRate;
- }
-
-
- @Override
- public DataComponent getRecordDescription()
- {
- return dataStruct;
- }
-
-
- @Override
- public DataEncoding getRecommendedEncoding()
- {
- return dataEncoding;
- }
-
-
- @Override
- public DataBlock getLatestRecord()
- {
- return latestRecord;
- }
-
-
- @Override
- public long getLatestRecordTime()
- {
- return latestRecordTime;
- }
-
-
- protected final double getJulianTimeStamp(long sensorTimeStampUs)
- {
- long sensorTimeMillis = sensorTimeStampUs / 1000;
-
- if (systemTimeOffset < 0)
- systemTimeOffset = System.currentTimeMillis() - sensorTimeMillis;
-
- return (systemTimeOffset + sensorTimeMillis) / 1000.;
- }
-}
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android;
+
+import java.nio.ByteBuffer;
+
+import android.graphics.SurfaceTexture;
+import android.os.Handler;
+import net.opengis.swe.v20.DataBlock;
+import net.opengis.swe.v20.DataComponent;
+import net.opengis.swe.v20.DataEncoding;
+import net.opengis.swe.v20.DataStream;
+import org.sensorhub.api.sensor.SensorDataEvent;
+import org.sensorhub.api.sensor.SensorException;
+import org.sensorhub.impl.sensor.AbstractSensorOutput;
+import org.sensorhub.impl.sensor.videocam.VideoCamHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.vast.data.AbstractDataBlock;
+import org.vast.data.DataBlockMixed;
+import android.graphics.ImageFormat;
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+import android.os.Looper;
+import android.os.SystemClock;
+
+
+/**
+ *
+ * Implementation of data interface for Android cameras using legacy Camera API.
+ * This will encode the video frames as a raw H264 stream (i.e. NAL units).
+ *
+ *
+ * @author Alex Robin
+ * @since June 11, 2015
+ */
+@SuppressWarnings("deprecation")
+public class AndroidCameraOutputH264 extends AbstractSensorOutput implements IAndroidOutput, Camera.PreviewCallback
+{
+ // keep logger name short because in LogCat it's max 23 chars
+ static final Logger log = LoggerFactory.getLogger(AndroidCameraOutputH264.class.getSimpleName());
+ protected static final String TIME_REF = "http://www.opengis.net/def/trs/BIPM/0/UTC";
+
+ Looper bgLooper;
+ int cameraId;
+ Camera camera;
+ int imgHeight, imgWidth, frameRate;
+ byte[] imgBuf1, imgBuf2;
+ byte[] codecInfoData;
+ MediaCodec mCodec;
+ BufferInfo bufferInfo = new BufferInfo();
+ SurfaceTexture previewTexture;
+
+ String name;
+ DataComponent dataStruct;
+ DataEncoding dataEncoding;
+ int samplingPeriod;
+ long systemTimeOffset = -1L;
+
+
+ protected AndroidCameraOutputH264(AndroidSensorsDriver parentModule, int cameraId, SurfaceTexture previewTexture) throws SensorException
+ {
+ super(parentModule);
+ this.cameraId = cameraId;
+ this.name = "camera" + cameraId + "_H264";
+ //this.previewSurfaceHolder = previewSurfaceHolder;
+ this.previewTexture = previewTexture;
+
+ // init camera hardware and H264 codec
+ initCam();
+ initCodec();
+
+ // create SWE Common data structure and encoding
+ VideoCamHelper fac = new VideoCamHelper();
+ DataStream videoStream = fac.newVideoOutputH264(getName(), imgWidth, imgHeight);
+ dataStruct = videoStream.getElementType();
+ dataEncoding = videoStream.getEncoding();
+ }
+
+
+ protected void initCam() throws SensorException
+ {
+ android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
+ android.hardware.Camera.getCameraInfo(cameraId, info);
+
+ // handle camera in its own thread
+ // this is to avoid running in the same thread as other sensors
+ Thread bgThread = new Thread() {
+ public void run()
+ {
+ try
+ {
+ // we need an Android looper to process camera messages
+ Looper.prepare();
+ bgLooper = Looper.myLooper();
+
+ // open camera and get parameters
+ camera = Camera.open(cameraId);
+
+ // start processing messages
+ Looper.loop();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ synchronized (this)
+ {
+ notify();
+ }
+ }
+ };
+ bgThread.start();
+
+ // wait until camera is opened
+ synchronized (bgThread)
+ {
+ try
+ {
+ bgThread.wait(1000);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+
+ // if camera was successfully opened, prepare for video capture
+ if (camera != null)
+ {
+ try
+ {
+ Parameters camParams = camera.getParameters();
+
+ // get supported preview sizes
+ for (Camera.Size imgSize : camParams.getSupportedPreviewSizes())
+ {
+ if (imgSize.width >= 600 && imgSize.width <= 800)
+ {
+ imgWidth = imgSize.width;
+ imgHeight = imgSize.height;
+ break;
+ }
+ }
+ frameRate = 1;
+
+ // set parameters
+ camParams.setPreviewSize(imgWidth, imgHeight);
+ camParams.setPreviewFormat(ImageFormat.NV21);
+ camParams.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
+ camera.setParameters(camParams);
+
+ // setup buffers and callback
+ int bufSize = imgWidth * imgHeight * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
+ imgBuf1 = new byte[bufSize];
+ imgBuf2 = new byte[bufSize];
+ camera.addCallbackBuffer(imgBuf1);
+ camera.addCallbackBuffer(imgBuf2);
+ camera.setPreviewCallbackWithBuffer(AndroidCameraOutputH264.this);
+ camera.setDisplayOrientation(info.orientation);
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot initialize camera " + cameraId, e);
+ }
+ }
+ else
+ {
+ throw new SensorException("Cannot open camera " + cameraId);
+ }
+ }
+
+
+ protected void initCodec() throws SensorException
+ {
+ try
+ {
+ mCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
+ MediaFormat mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, imgWidth, imgHeight);
+ mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
+ mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
+ mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
+ mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
+ mCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+ log.debug("MediaCodec initialized");
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot initialize codec " + mCodec.getName(), e);
+ }
+ }
+
+
+ @Override
+ public void start(Handler eventHandler) throws SensorException
+ {
+ try
+ {
+ // start codec
+ if (mCodec != null)
+ mCodec.start();
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot start codec " + mCodec.getName(), e);
+ }
+
+ try
+ {
+ // start streaming video
+ if (previewTexture != null)
+ camera.setPreviewTexture(previewTexture);
+ camera.startPreview();
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot start capture on camera " + cameraId, e);
+ }
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera)
+ {
+ long timeStamp = SystemClock.elapsedRealtimeNanos() / 1000;
+
+ // convert to NV12
+ int uvPos = imgWidth * imgHeight;
+ for (int i = uvPos; i < data.length; i+=2)
+ {
+ byte b = data[i];
+ data[i] = data[i+1];
+ data[i+1] = b;
+ }
+
+ // compress using selected codec
+ encode(timeStamp, data);
+
+ // release buffer for next frame
+ camera.addCallbackBuffer(data);
+ }
+
+
+ private void encode(long timeStamp, byte[] data)
+ {
+ // copy frame data to buffer
+ int inputBufferIndex = mCodec.dequeueInputBuffer(0);
+ if (inputBufferIndex >= 0)
+ {
+ ByteBuffer inputBuffer = mCodec.getInputBuffer(inputBufferIndex);
+ inputBuffer.clear();
+ inputBuffer.put(data);
+ mCodec.queueInputBuffer(inputBufferIndex, 0, data.length, timeStamp, 0);
+ }
+ else
+ {
+ // skip frame if no buffer is available
+ return;
+ }
+
+ int outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 0);
+ if (outputBufferIndex >= 0)
+ {
+ ByteBuffer outBuffer = mCodec.getOutputBuffer(outputBufferIndex);
+ int outDataSize = bufferInfo.size - bufferInfo.offset;
+ int outDataOffset = 0;
+ byte[] outData;
+
+ // insert SPS/PPS before each key frame
+ if (codecInfoData != null && bufferInfo.flags == MediaCodec.BUFFER_FLAG_KEY_FRAME)
+ {
+ outDataOffset = codecInfoData.length;
+ outData = new byte[outDataSize + outDataOffset];
+ System.arraycopy(codecInfoData, 0, outData, 0, codecInfoData.length);
+ }
+ else
+ outData = new byte[outDataSize];
+
+ // copy encoded data
+ outBuffer.position(bufferInfo.offset);
+ outBuffer.get(outData, outDataOffset, bufferInfo.size);
+
+ // release output buffer
+ mCodec.releaseOutputBuffer(outputBufferIndex, false);
+
+ if (bufferInfo.flags == MediaCodec.BUFFER_FLAG_CODEC_CONFIG)
+ codecInfoData = outData;
+ else
+ sendCompressedData(bufferInfo.presentationTimeUs, outData);
+ }
+ }
+
+
+ private void sendCompressedData(long timeStamp, byte[] compressedData)
+ {
+ // generate new data record
+ DataBlock newRecord;
+ if (latestRecord == null)
+ newRecord = dataStruct.createDataBlock();
+ else
+ newRecord = latestRecord.renew();
+
+ // set time stamp
+ double samplingTime = getJulianTimeStamp(timeStamp);
+ newRecord.setDoubleValue(0, samplingTime);
+
+ // set encoded data
+ AbstractDataBlock frameData = ((DataBlockMixed) newRecord).getUnderlyingObject()[1];
+ frameData.setUnderlyingObject(compressedData);
+
+ // send event
+ latestRecord = newRecord;
+ latestRecordTime = System.currentTimeMillis();
+ eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, AndroidCameraOutputH264.this, latestRecord));
+ }
+
+
+ @Override
+ public void stop()
+ {
+ if (camera != null)
+ {
+ camera.stopPreview();
+ camera.release();
+ camera = null;
+ }
+
+ if (mCodec != null)
+ {
+ mCodec.stop();
+ mCodec.release();
+ }
+
+ if (bgLooper != null)
+ {
+ bgLooper.quit();
+ bgLooper = null;
+ }
+ }
+
+
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
+
+ @Override
+ public double getAverageSamplingPeriod()
+ {
+ return 1. / (double) frameRate;
+ }
+
+
+ @Override
+ public DataComponent getRecordDescription()
+ {
+ return dataStruct;
+ }
+
+
+ @Override
+ public DataEncoding getRecommendedEncoding()
+ {
+ return dataEncoding;
+ }
+
+
+ @Override
+ public DataBlock getLatestRecord()
+ {
+ return latestRecord;
+ }
+
+
+ @Override
+ public long getLatestRecordTime()
+ {
+ return latestRecordTime;
+ }
+
+
+ protected final double getJulianTimeStamp(long sensorTimeStampUs)
+ {
+ long sensorTimeMillis = sensorTimeStampUs / 1000;
+
+ if (systemTimeOffset < 0)
+ systemTimeOffset = System.currentTimeMillis() - sensorTimeMillis;
+
+ return (systemTimeOffset + sensorTimeMillis) / 1000.;
+ }
+}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputMJPEG.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputMJPEG.java
old mode 100755
new mode 100644
index 8af60cef..12c52e4b
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputMJPEG.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidCameraOutputMJPEG.java
@@ -1,309 +1,309 @@
-/***************************** BEGIN LICENSE BLOCK ***************************
-
-The contents of this file are subject to the Mozilla Public License, v. 2.0.
-If a copy of the MPL was not distributed with this file, You can obtain one
-at http://mozilla.org/MPL/2.0/.
-
-Software distributed under the License is distributed on an "AS IS" basis,
-WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-for the specific language governing rights and limitations under the License.
-
-Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
-
-******************************* END LICENSE BLOCK ***************************/
-
-package org.sensorhub.impl.sensor.android;
-
-import java.io.ByteArrayOutputStream;
-
-import android.graphics.SurfaceTexture;
-import android.os.Handler;
-import net.opengis.swe.v20.DataBlock;
-import net.opengis.swe.v20.DataComponent;
-import net.opengis.swe.v20.DataEncoding;
-import net.opengis.swe.v20.DataStream;
-import org.sensorhub.api.sensor.SensorDataEvent;
-import org.sensorhub.api.sensor.SensorException;
-import org.sensorhub.impl.sensor.AbstractSensorOutput;
-import org.sensorhub.impl.sensor.videocam.VideoCamHelper;
-import org.vast.data.AbstractDataBlock;
-import org.vast.data.DataBlockMixed;
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.graphics.YuvImage;
-import android.hardware.Camera;
-import android.hardware.Camera.Parameters;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.view.SurfaceHolder;
-
-
-/**
- *
- * Implementation of data interface for Android cameras using legacy Camera API.
- * This will encode the video frames as JPEG to produce a MJPEG stream.
- *
- *
- * @author Alex Robin
- * @since June 11, 2015
- */
-@SuppressWarnings("deprecation")
-public class AndroidCameraOutputMJPEG extends AbstractSensorOutput implements IAndroidOutput, Camera.PreviewCallback
-{
- protected static final String TIME_REF = "http://www.opengis.net/def/trs/BIPM/0/UTC";
-
- Looper bgLooper;
- int cameraId;
- Camera camera;
- int imgHeight, imgWidth, frameRate;
- byte[] imgBuf1, imgBuf2;
- YuvImage yuvImg1, yuvImg2;
- Rect imgArea;
- ByteArrayOutputStream jpegBuf = new ByteArrayOutputStream();
- SurfaceTexture previewTexture;
-
- String name;
- DataComponent dataStruct;
- DataEncoding dataEncoding;
- int samplingPeriod;
- long systemTimeOffset = -1L;
-
-
- protected AndroidCameraOutputMJPEG(AndroidSensorsDriver parentModule, int cameraId, SurfaceTexture previewTexture) throws SensorException
- {
- super(parentModule);
- this.cameraId = cameraId;
- this.name = "camera" + cameraId + "_MJPEG";
- this.previewTexture = previewTexture;
-
- // init camera hardware
- initCam();
-
- // create output structure
- VideoCamHelper fac = new VideoCamHelper();
- DataStream videoStream = fac.newVideoOutputMJPEG(getName(), imgWidth, imgHeight);
- dataStruct = videoStream.getElementType();
- dataEncoding = videoStream.getEncoding();
- }
-
-
- protected void initCam() throws SensorException
- {
- android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
- android.hardware.Camera.getCameraInfo(cameraId, info);
-
- // handle camera in its own thread
- // this is to avoid running in the same thread as other sensors
- Thread bgThread = new Thread() {
- public void run()
- {
- try
- {
- // we need an Android looper to process camera messages
- Looper.prepare();
- bgLooper = Looper.myLooper();
-
- // open camera and get parameters
- camera = Camera.open(cameraId);
-
- // start processing messages
- Looper.loop();
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
-
- synchronized (this)
- {
- notify();
- }
- }
- };
- bgThread.start();
-
- // wait until camera is opened
- synchronized (bgThread)
- {
- try
- {
- bgThread.wait(1000);
- }
- catch (InterruptedException e)
- {
- }
- }
-
- // if camera was successfully opened, prepare for video capture
- if (camera != null)
- {
- try
- {
- Parameters camParams = camera.getParameters();
-
- // get supported preview sizes
- for (Camera.Size imgSize: camParams.getSupportedPreviewSizes())
- {
- if (imgSize.width >= 600 && imgSize.width <= 800)
- {
- imgWidth = imgSize.width;
- imgHeight = imgSize.height;
- break;
- }
- }
- frameRate = 1;
-
- // set parameters
- camParams.setPreviewSize(imgWidth, imgHeight);
- camParams.setPreviewFormat(ImageFormat.NV21);
- camParams.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
- camera.setParameters(camParams);
-
- // setup buffers and callback
- imgArea = new Rect(0, 0, imgWidth, imgHeight);
- int bufSize = imgWidth*imgHeight*ImageFormat.getBitsPerPixel(ImageFormat.NV21)/8;
- imgBuf1 = new byte[bufSize];
- yuvImg1 = new YuvImage(imgBuf1, ImageFormat.NV21, imgWidth, imgHeight, null);
- imgBuf2 = new byte[bufSize];
- yuvImg2 = new YuvImage(imgBuf2, ImageFormat.NV21, imgWidth, imgHeight, null);
- camera.addCallbackBuffer(imgBuf1);
- camera.addCallbackBuffer(imgBuf2);
- camera.setPreviewCallbackWithBuffer(AndroidCameraOutputMJPEG.this);
- camera.setDisplayOrientation(info.orientation);
- }
- catch (Exception e)
- {
- throw new SensorException("Cannot initialize camera " + cameraId, e);
- }
- }
- else
- {
- throw new SensorException("Cannot open camera " + cameraId);
- }
- }
-
-
- @Override
- public void start(Handler eventHandler) throws SensorException
- {
- try
- {
- // start streaming video
- if (previewTexture != null)
- camera.setPreviewTexture(previewTexture);
- camera.startPreview();
- }
- catch (Exception e)
- {
- parentSensor.reportError("Cannot start capture on camera " + cameraId, e);
- }
- }
-
-
- @Override
- public void onPreviewFrame(byte[] data, Camera camera)
- {
- long timeStamp = SystemClock.elapsedRealtimeNanos();
-
- // select current buffer
- YuvImage yuvImg = (data == imgBuf1) ? yuvImg1 : yuvImg2;
-
- // compress as JPEG
- jpegBuf.reset();
- yuvImg.compressToJpeg(imgArea, 90, jpegBuf);
-
- // release buffer for next frame
- camera.addCallbackBuffer(data);
-
- // generate new data record
- DataBlock newRecord;
- if (latestRecord == null)
- newRecord = dataStruct.createDataBlock();
- else
- newRecord = latestRecord.renew();
-
- // set time stamp
- double samplingTime = getJulianTimeStamp(timeStamp);
- newRecord.setDoubleValue(0, samplingTime);
-
- // set encoded data
- AbstractDataBlock frameData = ((DataBlockMixed)newRecord).getUnderlyingObject()[1];
- frameData.setUnderlyingObject(jpegBuf.toByteArray());
-
- // send event
- latestRecord = newRecord;
- latestRecordTime = System.currentTimeMillis();
- eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, AndroidCameraOutputMJPEG.this, latestRecord));
- }
-
-
- @Override
- public void stop()
- {
- if (camera != null)
- {
- camera.stopPreview();
- camera.release();
- camera = null;
- }
-
- if (bgLooper != null)
- {
- bgLooper.quit();
- bgLooper = null;
- }
- }
-
-
- @Override
- public String getName()
- {
- return name;
- }
-
-
- @Override
- public double getAverageSamplingPeriod()
- {
- return 1./ (double)frameRate;
- }
-
-
- @Override
- public DataComponent getRecordDescription()
- {
- return dataStruct;
- }
-
-
- @Override
- public DataEncoding getRecommendedEncoding()
- {
- return dataEncoding;
- }
-
-
- @Override
- public DataBlock getLatestRecord()
- {
- return latestRecord;
- }
-
-
- @Override
- public long getLatestRecordTime()
- {
- return latestRecordTime;
- }
-
-
- protected final double getJulianTimeStamp(long sensorTimeStampNanos)
- {
- long sensorTimeMillis = sensorTimeStampNanos / 1000000;
-
- if (systemTimeOffset < 0)
- systemTimeOffset = System.currentTimeMillis() - sensorTimeMillis;
-
- return (systemTimeOffset + sensorTimeMillis) / 1000.;
- }
-}
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+ The contents of this file are subject to the Mozilla Public License, v. 2.0.
+ If a copy of the MPL was not distributed with this file, You can obtain one
+ at http://mozilla.org/MPL/2.0/.
+
+ Software distributed under the License is distributed on an "AS IS" basis,
+ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ for the specific language governing rights and limitations under the License.
+
+ Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+ ******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android;
+
+import java.io.ByteArrayOutputStream;
+
+import android.graphics.SurfaceTexture;
+import android.os.Handler;
+import net.opengis.swe.v20.DataBlock;
+import net.opengis.swe.v20.DataComponent;
+import net.opengis.swe.v20.DataEncoding;
+import net.opengis.swe.v20.DataStream;
+import org.sensorhub.api.sensor.SensorDataEvent;
+import org.sensorhub.api.sensor.SensorException;
+import org.sensorhub.impl.sensor.AbstractSensorOutput;
+import org.sensorhub.impl.sensor.videocam.VideoCamHelper;
+import org.vast.data.AbstractDataBlock;
+import org.vast.data.DataBlockMixed;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.graphics.YuvImage;
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.view.SurfaceHolder;
+
+
+/**
+ *
+ * Implementation of data interface for Android cameras using legacy Camera API.
+ * This will encode the video frames as JPEG to produce a MJPEG stream.
+ *
+ *
+ * @author Alex Robin
+ * @since June 11, 2015
+ */
+@SuppressWarnings("deprecation")
+public class AndroidCameraOutputMJPEG extends AbstractSensorOutput implements IAndroidOutput, Camera.PreviewCallback
+{
+ protected static final String TIME_REF = "http://www.opengis.net/def/trs/BIPM/0/UTC";
+
+ Looper bgLooper;
+ int cameraId;
+ Camera camera;
+ int imgHeight, imgWidth, frameRate;
+ byte[] imgBuf1, imgBuf2;
+ YuvImage yuvImg1, yuvImg2;
+ Rect imgArea;
+ ByteArrayOutputStream jpegBuf = new ByteArrayOutputStream();
+ SurfaceTexture previewTexture;
+
+ String name;
+ DataComponent dataStruct;
+ DataEncoding dataEncoding;
+ int samplingPeriod;
+ long systemTimeOffset = -1L;
+
+
+ protected AndroidCameraOutputMJPEG(AndroidSensorsDriver parentModule, int cameraId, SurfaceTexture previewTexture) throws SensorException
+ {
+ super(parentModule);
+ this.cameraId = cameraId;
+ this.name = "camera" + cameraId + "_MJPEG";
+ this.previewTexture = previewTexture;
+
+ // init camera hardware
+ initCam();
+
+ // create output structure
+ VideoCamHelper fac = new VideoCamHelper();
+ DataStream videoStream = fac.newVideoOutputMJPEG(getName(), imgWidth, imgHeight);
+ dataStruct = videoStream.getElementType();
+ dataEncoding = videoStream.getEncoding();
+ }
+
+
+ protected void initCam() throws SensorException
+ {
+ android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
+ android.hardware.Camera.getCameraInfo(cameraId, info);
+
+ // handle camera in its own thread
+ // this is to avoid running in the same thread as other sensors
+ Thread bgThread = new Thread() {
+ public void run()
+ {
+ try
+ {
+ // we need an Android looper to process camera messages
+ Looper.prepare();
+ bgLooper = Looper.myLooper();
+
+ // open camera and get parameters
+ camera = Camera.open(cameraId);
+
+ // start processing messages
+ Looper.loop();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ synchronized (this)
+ {
+ notify();
+ }
+ }
+ };
+ bgThread.start();
+
+ // wait until camera is opened
+ synchronized (bgThread)
+ {
+ try
+ {
+ bgThread.wait(1000);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+
+ // if camera was successfully opened, prepare for video capture
+ if (camera != null)
+ {
+ try
+ {
+ Parameters camParams = camera.getParameters();
+
+ // get supported preview sizes
+ for (Camera.Size imgSize: camParams.getSupportedPreviewSizes())
+ {
+ if (imgSize.width >= 600 && imgSize.width <= 800)
+ {
+ imgWidth = imgSize.width;
+ imgHeight = imgSize.height;
+ break;
+ }
+ }
+ frameRate = 1;
+
+ // set parameters
+ camParams.setPreviewSize(imgWidth, imgHeight);
+ camParams.setPreviewFormat(ImageFormat.NV21);
+ camParams.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
+ camera.setParameters(camParams);
+
+ // setup buffers and callback
+ imgArea = new Rect(0, 0, imgWidth, imgHeight);
+ int bufSize = imgWidth*imgHeight*ImageFormat.getBitsPerPixel(ImageFormat.NV21)/8;
+ imgBuf1 = new byte[bufSize];
+ yuvImg1 = new YuvImage(imgBuf1, ImageFormat.NV21, imgWidth, imgHeight, null);
+ imgBuf2 = new byte[bufSize];
+ yuvImg2 = new YuvImage(imgBuf2, ImageFormat.NV21, imgWidth, imgHeight, null);
+ camera.addCallbackBuffer(imgBuf1);
+ camera.addCallbackBuffer(imgBuf2);
+ camera.setPreviewCallbackWithBuffer(AndroidCameraOutputMJPEG.this);
+ camera.setDisplayOrientation(info.orientation);
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot initialize camera " + cameraId, e);
+ }
+ }
+ else
+ {
+ throw new SensorException("Cannot open camera " + cameraId);
+ }
+ }
+
+
+ @Override
+ public void start(Handler eventHandler) throws SensorException
+ {
+ try
+ {
+ // start streaming video
+ if (previewTexture != null)
+ camera.setPreviewTexture(previewTexture);
+ camera.startPreview();
+ }
+ catch (Exception e)
+ {
+ parentSensor.reportError("Cannot start capture on camera " + cameraId, e);
+ }
+ }
+
+
+ @Override
+ public void onPreviewFrame(byte[] data, Camera camera)
+ {
+ long timeStamp = SystemClock.elapsedRealtimeNanos();
+
+ // select current buffer
+ YuvImage yuvImg = (data == imgBuf1) ? yuvImg1 : yuvImg2;
+
+ // compress as JPEG
+ jpegBuf.reset();
+ yuvImg.compressToJpeg(imgArea, 90, jpegBuf);
+
+ // release buffer for next frame
+ camera.addCallbackBuffer(data);
+
+ // generate new data record
+ DataBlock newRecord;
+ if (latestRecord == null)
+ newRecord = dataStruct.createDataBlock();
+ else
+ newRecord = latestRecord.renew();
+
+ // set time stamp
+ double samplingTime = getJulianTimeStamp(timeStamp);
+ newRecord.setDoubleValue(0, samplingTime);
+
+ // set encoded data
+ AbstractDataBlock frameData = ((DataBlockMixed)newRecord).getUnderlyingObject()[1];
+ frameData.setUnderlyingObject(jpegBuf.toByteArray());
+
+ // send event
+ latestRecord = newRecord;
+ latestRecordTime = System.currentTimeMillis();
+ eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, AndroidCameraOutputMJPEG.this, latestRecord));
+ }
+
+
+ @Override
+ public void stop()
+ {
+ if (camera != null)
+ {
+ camera.stopPreview();
+ camera.release();
+ camera = null;
+ }
+
+ if (bgLooper != null)
+ {
+ bgLooper.quit();
+ bgLooper = null;
+ }
+ }
+
+
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
+
+ @Override
+ public double getAverageSamplingPeriod()
+ {
+ return 1./ (double)frameRate;
+ }
+
+
+ @Override
+ public DataComponent getRecordDescription()
+ {
+ return dataStruct;
+ }
+
+
+ @Override
+ public DataEncoding getRecommendedEncoding()
+ {
+ return dataEncoding;
+ }
+
+
+ @Override
+ public DataBlock getLatestRecord()
+ {
+ return latestRecord;
+ }
+
+
+ @Override
+ public long getLatestRecordTime()
+ {
+ return latestRecordTime;
+ }
+
+
+ protected final double getJulianTimeStamp(long sensorTimeStampNanos)
+ {
+ long sensorTimeMillis = sensorTimeStampNanos / 1000000;
+
+ if (systemTimeOffset < 0)
+ systemTimeOffset = System.currentTimeMillis() - sensorTimeMillis;
+
+ return (systemTimeOffset + sensorTimeMillis) / 1000.;
+ }
+}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
index d7ef1c8b..7d7384b0 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
@@ -37,13 +37,9 @@
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorManager;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Build;
-import android.os.Looper;
import android.provider.Settings.Secure;
import android.util.Log;
@@ -62,6 +58,7 @@ public class AndroidSensorsDriver extends AbstractSensorModule smlComponents;
+ boolean cameraInUse = false;
public AndroidSensorsDriver()
@@ -199,8 +196,10 @@ protected void createCameraOutputs(Context androidContext) throws SensorExceptio
}
else*/
{
+ // TODO: when a camera is picked we should try stopping the loop and going from there.
for (int cameraId = 0; cameraId < android.hardware.Camera.getNumberOfCameras(); cameraId++)
{
+ if(cameraInUse) break;
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
@@ -212,7 +211,7 @@ protected void createCameraOutputs(Context androidContext) throws SensorExceptio
else if (AndroidSensorsConfig.H264_CODEC.equals(config.videoCodec))
useCamera(new AndroidCameraOutputH264(this, cameraId, config.camPreviewTexture), cameraId);
else
- throw new SensorException("Unsupported codec " + config.videoCodec);
+ throw new SensorException("Camera in use or Unsupported codec " + config.videoCodec);
}
}
}
@@ -240,6 +239,7 @@ protected void useCamera(ISensorDataInterface output, int cameraId)
addOutput(output, false);
smlComponents.add(smlBuilder.getComponentDescription(cameraId));
log.info("Getting data from camera #" + cameraId);
+ cameraInUse = true;
}
@@ -267,6 +267,7 @@ public void stop() throws SensorException
this.removeAllOutputs();
this.removeAllControlInputs();
+ this.cameraInUse = false;
}
From a3a0abc6938b3549a393af579f0c47321e06bcf6 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Tue, 7 Sep 2021 21:27:24 -0500
Subject: [PATCH 179/207] update build files as necessary to remove errors,
move proxy sensor to a separate module so we can build without it
---
ProxySensor/.gitignore | 1 +
ProxySensor/build.gradle | 37 +++++++++++++++++++
ProxySensor/consumer-rules.pro | 0
ProxySensor/proguard-rules.pro | 21 +++++++++++
.../proxysensor/ExampleInstrumentedTest.java | 25 +++++++++++++
ProxySensor/src/main/AndroidManifest.xml | 5 +++
.../impl/swe/proxysensor}/ProxySensor.java | 8 +---
.../swe/proxysensor}/ProxySensorConfig.java | 2 +-
.../proxysensor}/ProxySensorDescriptor.java | 2 +-
.../swe/proxysensor}/ProxySensorOutput.java | 2 +-
.../impl/swe/proxysensor/ExampleUnitTest.java | 17 +++++++++
sensorhub-android-app/build.gradle | 9 +++++
sensorhub-android-blebeacon/build.gradle | 10 ++---
settings.gradle | 1 +
14 files changed, 125 insertions(+), 15 deletions(-)
create mode 100644 ProxySensor/.gitignore
create mode 100644 ProxySensor/build.gradle
create mode 100644 ProxySensor/consumer-rules.pro
create mode 100644 ProxySensor/proguard-rules.pro
create mode 100644 ProxySensor/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java
create mode 100644 ProxySensor/src/main/AndroidManifest.xml
rename {sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor => ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor}/ProxySensor.java (97%)
rename {sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor => ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor}/ProxySensorConfig.java (90%)
rename {sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor => ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor}/ProxySensorDescriptor.java (93%)
rename {sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor => ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor}/ProxySensorOutput.java (97%)
create mode 100644 ProxySensor/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java
diff --git a/ProxySensor/.gitignore b/ProxySensor/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/ProxySensor/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/ProxySensor/build.gradle b/ProxySensor/build.gradle
new file mode 100644
index 00000000..050001e4
--- /dev/null
+++ b/ProxySensor/build.gradle
@@ -0,0 +1,37 @@
+plugins {
+ id 'com.android.library'
+}
+
+android {
+ compileSdk 31
+
+ defaultConfig {
+ minSdk 21
+ targetSdk 31
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles "consumer-rules.pro"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ implementation project(path: ':sensorml-core')
+ implementation project(path: ':sensorhub-core')
+ implementation project(path: ':sensorhub-service-swe')
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+}
\ No newline at end of file
diff --git a/ProxySensor/consumer-rules.pro b/ProxySensor/consumer-rules.pro
new file mode 100644
index 00000000..e69de29b
diff --git a/ProxySensor/proguard-rules.pro b/ProxySensor/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/ProxySensor/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/ProxySensor/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java b/ProxySensor/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java
new file mode 100644
index 00000000..8db3f988
--- /dev/null
+++ b/ProxySensor/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java
@@ -0,0 +1,25 @@
+package org.sensorhub.impl.swe.proxysensor;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("org.sensorhub.impl.swe.proxysensor.test", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/ProxySensor/src/main/AndroidManifest.xml b/ProxySensor/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..bad8a116
--- /dev/null
+++ b/ProxySensor/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java b/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensor.java
similarity index 97%
rename from sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
rename to ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensor.java
index 6e0b9e20..ba7c24f8 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensor.java
+++ b/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensor.java
@@ -1,4 +1,4 @@
-package org.sensorhub.impl.sensor.swe.ProxySensor;
+package org.sensorhub.impl.swe.proxysensor;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -7,17 +7,11 @@
import android.util.Log;
import org.sensorhub.android.SOSServiceWithIPCConfig;
-import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.api.sensor.ISensorDataInterface;
import org.sensorhub.impl.sensor.swe.SWEVirtualSensor;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
import net.opengis.gml.v32.AbstractFeature;
import net.opengis.sensorml.v20.AbstractPhysicalProcess;
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java b/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorConfig.java
similarity index 90%
rename from sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java
rename to ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorConfig.java
index 5737b520..36910192 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorConfig.java
+++ b/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorConfig.java
@@ -1,4 +1,4 @@
-package org.sensorhub.impl.sensor.swe.ProxySensor;
+package org.sensorhub.impl.swe.proxysensor;
import android.content.Context;
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorDescriptor.java b/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorDescriptor.java
similarity index 93%
rename from sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorDescriptor.java
rename to ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorDescriptor.java
index 0c1024a2..d643d46b 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorDescriptor.java
+++ b/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorDescriptor.java
@@ -1,4 +1,4 @@
-package org.sensorhub.impl.sensor.swe.ProxySensor;
+package org.sensorhub.impl.swe.proxysensor;
import org.sensorhub.api.module.IModule;
import org.sensorhub.api.module.IModuleProvider;
diff --git a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java b/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorOutput.java
similarity index 97%
rename from sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
rename to ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorOutput.java
index 36397598..912c6d33 100644
--- a/sensorhub-android-app/src/org/sensorhub/impl/sensor/swe/ProxySensor/ProxySensorOutput.java
+++ b/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorOutput.java
@@ -1,4 +1,4 @@
-package org.sensorhub.impl.sensor.swe.ProxySensor;
+package org.sensorhub.impl.swe.proxysensor;
import android.util.Log;
diff --git a/ProxySensor/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java b/ProxySensor/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java
new file mode 100644
index 00000000..1bd8a253
--- /dev/null
+++ b/ProxySensor/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package org.sensorhub.impl.swe.proxysensor;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/sensorhub-android-app/build.gradle b/sensorhub-android-app/build.gradle
index 9441e669..b16d5107 100644
--- a/sensorhub-android-app/build.gradle
+++ b/sensorhub-android-app/build.gradle
@@ -3,8 +3,17 @@ apply plugin: 'com.android.application'
description = 'OSH Demo Android App'
ext.details = 'OSH demo app for Android'
+repositories {
+ maven {
+ url "https://repo.eclipse.org/content/repositories/paho-releases/"
+ }
+}
+
dependencies {
api project(':sensorhub-android-lib')
+
+ implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
+ implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
}
android {
diff --git a/sensorhub-android-blebeacon/build.gradle b/sensorhub-android-blebeacon/build.gradle
index c078449a..26b596ce 100644
--- a/sensorhub-android-blebeacon/build.gradle
+++ b/sensorhub-android-blebeacon/build.gradle
@@ -5,7 +5,7 @@ android {
defaultConfig {
- minSdkVersion 26
+ minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
@@ -30,9 +30,9 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
- compile project(path: ':sensorhub-core')
- compile 'org.altbeacon:android-beacon-library:2.16.2'
- compile project(path: ':sensorhub-process-vecmath')
- compile project(path: ':sensorhub-process-geoloc')
+ implementation project(path: ':sensorhub-core')
+ implementation 'org.altbeacon:android-beacon-library:2.16.2'
+ implementation project(path: ':sensorhub-process-vecmath')
+ implementation project(path: ':sensorhub-process-geoloc')
implementation 'com.android.volley:volley:1.1.1'
}
diff --git a/settings.gradle b/settings.gradle
index 449173ac..b8e6089c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -58,3 +58,4 @@ subprojects.files.each { File f ->
}
}
+include ':ProxySensor'
From 318b0ecc27df4d14ec7d34d8203d101918a54f64 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Wed, 8 Sep 2021 16:40:37 -0500
Subject: [PATCH 180/207] update module names for ProxySensor and SOS IPC
---
.../.gitignore | 0
.../build.gradle | 0
.../consumer-rules.pro | 0
.../proguard-rules.pro | 0
.../proxysensor/ExampleInstrumentedTest.java | 0
.../src/main/AndroidManifest.xml | 0
.../impl/swe/proxysensor/ProxySensor.java | 0
.../swe/proxysensor/ProxySensorConfig.java | 0
.../proxysensor/ProxySensorDescriptor.java | 0
.../swe/proxysensor/ProxySensorOutput.java | 0
.../proxysensor}/mqtt/IMqttSubscriber.java | 2 +-
.../mqtt/MqttConnectionListener.java | 2 +-
.../swe/proxysensor}/mqtt/MqttHelper.java | 2 +-
.../proxysensor}/mqtt/MqttMessageHandler.java | 2 +-
.../impl/swe/proxysensor/ExampleUnitTest.java | 0
sensorhub-android-sos-ipc/.gitignore | 1 +
sensorhub-android-sos-ipc/build.gradle | 34 +++++++++++++++++++
sensorhub-android-sos-ipc/consumer-rules.pro | 0
sensorhub-android-sos-ipc/proguard-rules.pro | 21 ++++++++++++
.../ExampleInstrumentedTest.java | 25 ++++++++++++++
.../src/main/AndroidManifest.xml | 5 +++
.../SOSServiceWithIPC.java | 4 +--
.../SOSServiceWithIPCConfig.java | 2 +-
.../ExampleUnitTest.java | 17 ++++++++++
settings.gradle | 3 +-
25 files changed, 111 insertions(+), 9 deletions(-)
rename {ProxySensor => sensorhub-android-proxysensor}/.gitignore (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/build.gradle (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/consumer-rules.pro (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/proguard-rules.pro (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/src/main/AndroidManifest.xml (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensor.java (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorConfig.java (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorDescriptor.java (100%)
rename {ProxySensor => sensorhub-android-proxysensor}/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorOutput.java (100%)
rename {sensorhub-android-app/src/org/sensorhub/android => sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor}/mqtt/IMqttSubscriber.java (93%)
rename {sensorhub-android-app/src/org/sensorhub/android => sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor}/mqtt/MqttConnectionListener.java (97%)
rename {sensorhub-android-app/src/org/sensorhub/android => sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor}/mqtt/MqttHelper.java (98%)
rename {sensorhub-android-app/src/org/sensorhub/android => sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor}/mqtt/MqttMessageHandler.java (97%)
rename {ProxySensor => sensorhub-android-proxysensor}/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java (100%)
create mode 100644 sensorhub-android-sos-ipc/.gitignore
create mode 100644 sensorhub-android-sos-ipc/build.gradle
create mode 100644 sensorhub-android-sos-ipc/consumer-rules.pro
create mode 100644 sensorhub-android-sos-ipc/proguard-rules.pro
create mode 100644 sensorhub-android-sos-ipc/src/androidTest/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleInstrumentedTest.java
create mode 100644 sensorhub-android-sos-ipc/src/main/AndroidManifest.xml
rename {sensorhub-android-app/src/org/sensorhub/android => sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos}/SOSServiceWithIPC.java (97%)
rename {sensorhub-android-app/src/org/sensorhub/android => sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos}/SOSServiceWithIPCConfig.java (88%)
create mode 100644 sensorhub-android-sos-ipc/src/test/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleUnitTest.java
diff --git a/ProxySensor/.gitignore b/sensorhub-android-proxysensor/.gitignore
similarity index 100%
rename from ProxySensor/.gitignore
rename to sensorhub-android-proxysensor/.gitignore
diff --git a/ProxySensor/build.gradle b/sensorhub-android-proxysensor/build.gradle
similarity index 100%
rename from ProxySensor/build.gradle
rename to sensorhub-android-proxysensor/build.gradle
diff --git a/ProxySensor/consumer-rules.pro b/sensorhub-android-proxysensor/consumer-rules.pro
similarity index 100%
rename from ProxySensor/consumer-rules.pro
rename to sensorhub-android-proxysensor/consumer-rules.pro
diff --git a/ProxySensor/proguard-rules.pro b/sensorhub-android-proxysensor/proguard-rules.pro
similarity index 100%
rename from ProxySensor/proguard-rules.pro
rename to sensorhub-android-proxysensor/proguard-rules.pro
diff --git a/ProxySensor/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java b/sensorhub-android-proxysensor/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java
similarity index 100%
rename from ProxySensor/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java
rename to sensorhub-android-proxysensor/src/androidTest/java/org/sensorhub/impl/swe/proxysensor/ExampleInstrumentedTest.java
diff --git a/ProxySensor/src/main/AndroidManifest.xml b/sensorhub-android-proxysensor/src/main/AndroidManifest.xml
similarity index 100%
rename from ProxySensor/src/main/AndroidManifest.xml
rename to sensorhub-android-proxysensor/src/main/AndroidManifest.xml
diff --git a/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensor.java b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensor.java
similarity index 100%
rename from ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensor.java
rename to sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensor.java
diff --git a/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorConfig.java b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorConfig.java
similarity index 100%
rename from ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorConfig.java
rename to sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorConfig.java
diff --git a/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorDescriptor.java b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorDescriptor.java
similarity index 100%
rename from ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorDescriptor.java
rename to sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorDescriptor.java
diff --git a/ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorOutput.java b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorOutput.java
similarity index 100%
rename from ProxySensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorOutput.java
rename to sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/ProxySensorOutput.java
diff --git a/sensorhub-android-app/src/org/sensorhub/android/mqtt/IMqttSubscriber.java b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/IMqttSubscriber.java
similarity index 93%
rename from sensorhub-android-app/src/org/sensorhub/android/mqtt/IMqttSubscriber.java
rename to sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/IMqttSubscriber.java
index 4a399bcf..2265b953 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/mqtt/IMqttSubscriber.java
+++ b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/IMqttSubscriber.java
@@ -11,7 +11,7 @@
Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.mqtt;
+package org.sensorhub.impl.swe.proxysensor.mqtt;
public interface IMqttSubscriber {
diff --git a/sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttConnectionListener.java b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttConnectionListener.java
similarity index 97%
rename from sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttConnectionListener.java
rename to sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttConnectionListener.java
index bbf156b4..f53edcef 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttConnectionListener.java
+++ b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttConnectionListener.java
@@ -11,7 +11,7 @@
Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.mqtt;
+package org.sensorhub.impl.swe.proxysensor.mqtt;
import android.util.Log;
diff --git a/sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttHelper.java b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttHelper.java
similarity index 98%
rename from sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttHelper.java
rename to sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttHelper.java
index 35d1778e..90b08c3c 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttHelper.java
+++ b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttHelper.java
@@ -11,7 +11,7 @@
Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.mqtt;
+package org.sensorhub.impl.swe.proxysensor.mqtt;
import android.content.Context;
import android.util.Log;
diff --git a/sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttMessageHandler.java b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttMessageHandler.java
similarity index 97%
rename from sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttMessageHandler.java
rename to sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttMessageHandler.java
index 1900356f..547deb90 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/mqtt/MqttMessageHandler.java
+++ b/sensorhub-android-proxysensor/src/main/java/org/sensorhub/impl/swe/proxysensor/mqtt/MqttMessageHandler.java
@@ -11,7 +11,7 @@
Copyright (C) 2020 Botts Innovative Research, Inc. All Rights Reserved.
******************************* END LICENSE BLOCK ***************************/
-package org.sensorhub.android.mqtt;
+package org.sensorhub.impl.swe.proxysensor.mqtt;
import android.os.Bundle;
import android.os.Handler;
diff --git a/ProxySensor/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java b/sensorhub-android-proxysensor/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java
similarity index 100%
rename from ProxySensor/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java
rename to sensorhub-android-proxysensor/src/test/java/org/sensorhub/impl/swe/proxysensor/ExampleUnitTest.java
diff --git a/sensorhub-android-sos-ipc/.gitignore b/sensorhub-android-sos-ipc/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/sensorhub-android-sos-ipc/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/build.gradle b/sensorhub-android-sos-ipc/build.gradle
new file mode 100644
index 00000000..2027c5f1
--- /dev/null
+++ b/sensorhub-android-sos-ipc/build.gradle
@@ -0,0 +1,34 @@
+plugins {
+ id 'com.android.library'
+}
+
+android {
+ compileSdk 31
+
+ defaultConfig {
+ minSdk 21
+ targetSdk 31
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles "consumer-rules.pro"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+
+ implementation 'com.android.support:appcompat-v7:28.0.0'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+}
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/consumer-rules.pro b/sensorhub-android-sos-ipc/consumer-rules.pro
new file mode 100644
index 00000000..e69de29b
diff --git a/sensorhub-android-sos-ipc/proguard-rules.pro b/sensorhub-android-sos-ipc/proguard-rules.pro
new file mode 100644
index 00000000..481bb434
--- /dev/null
+++ b/sensorhub-android-sos-ipc/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/src/androidTest/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleInstrumentedTest.java b/sensorhub-android-sos-ipc/src/androidTest/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleInstrumentedTest.java
new file mode 100644
index 00000000..6fa9e291
--- /dev/null
+++ b/sensorhub-android-sos-ipc/src/androidTest/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleInstrumentedTest.java
@@ -0,0 +1,25 @@
+package org.sensorhun.impl.service.sensorhub_android_sos;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("org.sensorhun.impl.service.sensorhub_android_sos.test", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/src/main/AndroidManifest.xml b/sensorhub-android-sos-ipc/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..a4f387f9
--- /dev/null
+++ b/sensorhub-android-sos-ipc/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPC.java b/sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPC.java
similarity index 97%
rename from sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPC.java
rename to sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPC.java
index f3016065..358d9d17 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPC.java
+++ b/sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPC.java
@@ -1,4 +1,4 @@
-package org.sensorhub.android;
+package org.sensorhun.impl.service.sensorhub_android_sos;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -18,8 +18,6 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import static android.content.ContentValues.TAG;
-
public class SOSServiceWithIPC extends SOSService
{
public static final String SQAN_TEST = "SA";
diff --git a/sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPCConfig.java b/sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPCConfig.java
similarity index 88%
rename from sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPCConfig.java
rename to sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPCConfig.java
index a9701650..0078f248 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPCConfig.java
+++ b/sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPCConfig.java
@@ -1,4 +1,4 @@
-package org.sensorhub.android;
+package org.sensorhun.impl.service.sensorhub_android_sos;
import android.content.Context;
diff --git a/sensorhub-android-sos-ipc/src/test/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleUnitTest.java b/sensorhub-android-sos-ipc/src/test/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleUnitTest.java
new file mode 100644
index 00000000..3a543263
--- /dev/null
+++ b/sensorhub-android-sos-ipc/src/test/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package org.sensorhun.impl.service.sensorhub_android_sos;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index b8e6089c..b8c0d0c2 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -58,4 +58,5 @@ subprojects.files.each { File f ->
}
}
-include ':ProxySensor'
+include ':sensorhub-android-proxysensor'
+include ':sensorhub-android-sos-ipc'
From d0819a9886b1d29ae21ebf39ffd67d6d99094bda Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Fri, 10 Sep 2021 17:54:58 -0500
Subject: [PATCH 181/207] [WIP] Update to add HTTPServerConfig to Main and
SensorHubService
---
.../src/org/sensorhub/android/MainActivity.java | 8 ++++++++
.../src/org/sensorhub/android/SensorHubService.java | 11 +++++++++++
2 files changed, 19 insertions(+)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index ececc346..b2f9167b 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -58,6 +58,7 @@
import org.sensorhub.impl.sensor.angel.AngelSensorConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseWithGeolocConfig;
+import org.sensorhub.impl.service.HttpServerConfig;
import org.sensorhub.test.sensor.trupulse.SimulatedDataStream;
import android.annotation.SuppressLint;
import android.app.Activity;
@@ -172,6 +173,13 @@ public boolean verify(String arg0, SSLSession arg1) {
}
}
+ // Setup HTTPServerConfig for enabling more complete node functionality
+ HttpServerConfig serverConfig = new HttpServerConfig();
+ serverConfig.proxyBaseUrl = "";
+ serverConfig.httpPort = 8585;
+ serverConfig.autoStart = true;
+ sensorhubConfig.add(serverConfig);
+
// get device name
String deviceID = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
String deviceName = prefs.getString("device_name", null);
diff --git a/sensorhub-android-service/src/org/sensorhub/android/SensorHubService.java b/sensorhub-android-service/src/org/sensorhub/android/SensorHubService.java
index c46056d7..d73ae5f2 100644
--- a/sensorhub-android-service/src/org/sensorhub/android/SensorHubService.java
+++ b/sensorhub-android-service/src/org/sensorhub/android/SensorHubService.java
@@ -26,12 +26,14 @@
import android.view.SurfaceView;
import android.view.WindowManager;
import org.sensorhub.api.common.IEventListener;
+import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.api.module.IModuleConfigRepository;
import org.sensorhub.api.module.ModuleConfig;
import org.sensorhub.impl.SensorHub;
import org.sensorhub.impl.SensorHubConfig;
import org.sensorhub.impl.common.EventBus;
import org.sensorhub.impl.module.ModuleRegistry;
+import org.sensorhub.impl.service.HttpServer;
import org.vast.xml.XMLImplFinder;
import android.app.Service;
import android.content.Intent;
@@ -133,6 +135,15 @@ public void run() {
sensorhub.stop();
SensorHub.clearInstance();
sensorhub = null;
+
+ // Make sure the server gets cleaned up
+ try {
+ if (HttpServer.getInstance() != null) {
+ HttpServer.getInstance().cleanup();
+ }
+ } catch (SensorHubException e) {
+ e.printStackTrace();
+ }
}
});
}
From f55c8c25454bfbe745b86bab1a071da3dccf8faf Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Tue, 14 Sep 2021 19:57:51 -0500
Subject: [PATCH 182/207] add things necessary for sos configuration and setup
---
sensorhub-android-app/build.gradle | 1 +
.../org/sensorhub/android/MainActivity.java | 458 +++++++++++++++++-
sensorhub-android-lib/build.gradle | 1 +
3 files changed, 450 insertions(+), 10 deletions(-)
diff --git a/sensorhub-android-app/build.gradle b/sensorhub-android-app/build.gradle
index b16d5107..f9b7a477 100644
--- a/sensorhub-android-app/build.gradle
+++ b/sensorhub-android-app/build.gradle
@@ -14,6 +14,7 @@ dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
+// implementation project(path: ':sensorhub-storage-h2')
}
android {
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 509b2314..1caa4dfd 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -14,21 +14,28 @@
package org.sensorhub.android;
+import static android.content.ContentValues.TAG;
+
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
+import java.io.File;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.preference.DialogPreference;
@@ -51,6 +58,11 @@
//import org.sensorhub.impl.driver.dji.DjiConfig;
import org.sensorhub.impl.driver.flir.FlirOneCameraConfig;
import org.sensorhub.impl.module.InMemoryConfigDb;
+import org.sensorhub.impl.persistence.GenericStreamStorage;
+import org.sensorhub.impl.persistence.MaxAgeAutoPurgeConfig;
+import org.sensorhub.impl.persistence.StreamStorageConfig;
+import org.sensorhub.impl.persistence.h2.MVMultiStorageImpl;
+import org.sensorhub.impl.persistence.h2.MVStorageConfig;
import org.sensorhub.impl.sensor.android.AndroidSensorsConfig;
import org.sensorhub.impl.sensor.android.AndroidSensorsDriver;
import org.sensorhub.impl.sensor.android.video.VideoEncoderConfig;
@@ -59,6 +71,8 @@
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseWithGeolocConfig;
import org.sensorhub.impl.service.HttpServerConfig;
+import org.sensorhub.impl.service.sos.SOSServiceConfig;
+import org.sensorhub.impl.service.sos.SensorDataProviderConfig;
import org.sensorhub.test.sensor.trupulse.SimulatedDataStream;
import android.annotation.SuppressLint;
import android.app.Activity;
@@ -102,6 +116,18 @@ public class MainActivity extends Activity implements TextureView.SurfaceTexture
AndroidSensorsDriver androidSensors;
URL sosUrl = null;
boolean showVideo;
+ String deviceID;
+
+ enum Sensors {
+ Android,
+ TruPulse,
+ TruPulseSim,
+ Angel,
+ FlirOne,
+ DJIDrone,
+ ProxySensor,
+ BLELocation
+ }
private ServiceConnection sConn = new ServiceConnection()
@@ -120,6 +146,7 @@ public void onServiceDisconnected(ComponentName className)
protected void updateConfig(SharedPreferences prefs, String runName)
{
+ deviceID = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
sensorhubConfig = new InMemoryConfigDb();
// get SOS URL from config
@@ -173,13 +200,6 @@ public boolean verify(String arg0, SSLSession arg1) {
}
}
- // Setup HTTPServerConfig for enabling more complete node functionality
- HttpServerConfig serverConfig = new HttpServerConfig();
- serverConfig.proxyBaseUrl = "";
- serverConfig.httpPort = 8585;
- serverConfig.autoStart = true;
- sensorhubConfig.add(serverConfig);
-
// get device name
String deviceID = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
String deviceName = prefs.getString("device_name", null);
@@ -237,8 +257,48 @@ public boolean verify(String arg0, SSLSession arg1) {
sensorsConfig.outputVideoRoll = prefs.getBoolean("video_roll_enabled", false);
sensorsConfig.runName = runName;
- sensorhubConfig.add(sensorsConfig);
- addSosTConfig(sensorsConfig, sosUser, sosPwd);
+// sensorhubConfig.add(sensorsConfig);
+// addSosTConfig(sensorsConfig, sosUser, sosPwd);
+
+ // START SOS Config ************************************************************************
+ // Setup HTTPServerConfig for enabling more complete node functionality
+ HttpServerConfig serverConfig = new HttpServerConfig();
+ serverConfig.proxyBaseUrl = "";
+ serverConfig.httpPort = 8585;
+ serverConfig.autoStart = true;
+ sensorhubConfig.add(serverConfig);
+
+ // SOS Config
+ SOSServiceConfig sosConfig = new SOSServiceConfig();
+ sosConfig.moduleClass = SOSServiceConfig.class.getCanonicalName();
+ // SensorHubService already references the app context
+ //((SOSServiceConfig) sosConfig).androidContext = this.getApplicationContext();
+ sosConfig.id = "SOS_SERVICE";
+ sosConfig.name = "SOS Service";
+ sosConfig.autoStart = true;
+ sosConfig.enableTransactional = true;
+
+ // Push Sensors Config
+ AndroidSensorsConfig androidSensorsConfig = sensorsConfig;
+ sensorhubConfig.add(androidSensorsConfig);
+ if (isPushingSensor(Sensors.Android)) {
+ addSosTConfig(androidSensorsConfig, sosUser, sosPwd);
+ }
+
+ File dbFile = new File(getApplicationContext().getFilesDir() + "/db/");
+ dbFile.mkdirs();
+ MVStorageConfig basicStorageConfig = new MVStorageConfig();
+ basicStorageConfig.moduleClass = "org.sensorhub.impl.persistence.h2.MVObsStorageImpl";
+ basicStorageConfig.storagePath = dbFile.getAbsolutePath() + "/${STORAGE_ID}.dat";
+ basicStorageConfig.autoStart = true;
+ sosConfig.newStorageConfig = basicStorageConfig;
+
+ StreamStorageConfig androidStreamStorageConfig = createStreamStorageConfig(androidSensorsConfig);
+ addStorageConfig(androidSensorsConfig, androidStreamStorageConfig);
+
+ SensorDataProviderConfig androidDataProviderConfig = createDataProviderConfig(androidSensorsConfig);
+ addSosServerConfig(sosConfig, androidDataProviderConfig);
+ // END SOS CONFIG **************************************************************************
// TruPulse sensor
boolean enabled = prefs.getBoolean("trupulse_enabled", false);
@@ -458,7 +518,10 @@ public void onClick(DialogInterface dialog, int whichButton)
AndroidSensorsConfig androidSensorConfig = (AndroidSensorsConfig) sensorhubConfig.get("ANDROID_SENSORS");
VideoEncoderConfig videoConfig = androidSensorConfig.videoConfig;
- if ((androidSensorConfig.activateBackCamera || androidSensorConfig.activateFrontCamera) && videoConfig.selectedPreset < 0 || videoConfig.selectedPreset >= videoConfig.presets.length) {
+ boolean cameraInUse = (androidSensorConfig.activateBackCamera || androidSensorConfig.activateFrontCamera);
+ boolean improperVideoSettings = (videoConfig.selectedPreset < 0 || videoConfig.selectedPreset >= videoConfig.presets.length);
+
+ if (cameraInUse && improperVideoSettings) {
showVideoConfigErrorPopup();
newStatusMessage("Video Config Error: Check Settings");
} else {
@@ -724,6 +787,381 @@ protected void hideVideo()
{
}
+ private boolean isPushingSensor(Sensors sensor) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
+
+ if (Sensors.Android.equals(sensor)) {
+ if (prefs.getBoolean("accelerometer_enable", false)
+ && prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ return true;
+ if (prefs.getBoolean("gyroscope_enable", false)
+ && prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ return true;
+ if (prefs.getBoolean("magnetometer_enable", false)
+ && prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ return true;
+ if (prefs.getBoolean("orientation_enable", false)
+ && prefs.getStringSet("orientation_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ return true;
+ if (prefs.getBoolean("location_enable", false)
+ && prefs.getStringSet("location_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ return true;
+ return prefs.getBoolean("video_enable", false)
+ && prefs.getStringSet("video_options", Collections.emptySet()).contains("PUSH_REMOTE");
+ } else if (Sensors.TruPulse.equals(sensor) || Sensors.TruPulseSim.equals(sensor)) {
+ return prefs.getBoolean("trupulse_enable", false)
+ && prefs.getStringSet("trupulse_options", Collections.emptySet()).contains("PUSH_REMOTE");
+ } else if(Sensors.BLELocation.equals(sensor)){
+ return prefs.getBoolean("ble_enable", false) && prefs.getStringSet("ble_options", Collections.emptySet()).contains("PUSH_REMOTE");
+ }
+
+ return false;
+ }
+
+ private SensorDataProviderConfig createDataProviderConfig(AndroidSensorsConfig sensorConfig) {
+ SensorDataProviderConfig dataProviderConfig = new SensorDataProviderConfig();
+ dataProviderConfig.sensorID = sensorConfig.id;
+ dataProviderConfig.offeringID = sensorConfig.id + ":offering";
+ dataProviderConfig.storageID = sensorConfig.id + "#storage";
+ dataProviderConfig.enabled = true;
+ dataProviderConfig.liveDataTimeout = 600.0;
+ dataProviderConfig.maxFois = 10;
+
+ return dataProviderConfig;
+ }
+
+ private StreamStorageConfig createStreamStorageConfig(AndroidSensorsConfig sensorConfig) {
+ // H2 Storage Config
+ File dbFile = new File(getApplicationContext().getFilesDir() + "/db/", deviceID + "_h2.dat");
+ dbFile.getParentFile().mkdirs();
+ if (!dbFile.exists()) {
+ try {
+ dbFile.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ MVStorageConfig storageConfig = new MVStorageConfig();
+ storageConfig.moduleClass = MVMultiStorageImpl.class.getCanonicalName();
+ storageConfig.storagePath = dbFile.getPath();
+ storageConfig.autoStart = true;
+ storageConfig.memoryCacheSize = 102400;
+ storageConfig.autoCommitBufferSize = 1024;
+
+ // TODO: Base this on size instead of time. This might error when earliest record is purged and then requested. Test if the capabilities updates...
+ // Auto Purge Config
+ MaxAgeAutoPurgeConfig autoPurgeConfig = new MaxAgeAutoPurgeConfig();
+ autoPurgeConfig.enabled = true;
+ autoPurgeConfig.purgePeriod = 24.0 * 60.0 * 60.0;
+ autoPurgeConfig.maxRecordAge = 24.0 * 60.0 * 60.0;
+
+ // Stream Storage Config
+ StreamStorageConfig streamStorageConfig = new StreamStorageConfig();
+ streamStorageConfig.moduleClass = GenericStreamStorage.class.getCanonicalName();
+ streamStorageConfig.id = sensorConfig.id + "#storage";
+ streamStorageConfig.name = sensorConfig.name + " Storage";
+ streamStorageConfig.dataSourceID = sensorConfig.id;
+ streamStorageConfig.autoStart = true;
+ streamStorageConfig.processEvents = true;
+ streamStorageConfig.minCommitPeriod = 10000;
+ streamStorageConfig.autoPurgeConfig = autoPurgeConfig;
+ streamStorageConfig.storageConfig = storageConfig;
+ return streamStorageConfig;
+ }
+
+ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig storageConf) {
+ if (sensorConf instanceof AndroidSensorsConfig) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
+ SensorManager sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
+ List deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
+
+ String sensorName;
+ for (Sensor sensor : deviceSensors) {
+ if (sensor.isWakeUpSensor()) {
+ continue;
+ }
+
+ Log.d(TAG, "addStorageConfig: sensor: " + sensor.getName());
+
+ switch (sensor.getType()) {
+ case Sensor.TYPE_ACCELEROMETER:
+ if (!prefs.getBoolean("accelerometer_enable", false)
+ || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addStorageConfig: excluding accelerometer");
+
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ storageConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addStorageConfig: NOT excluding accelerometer");
+ }
+ break;
+ case Sensor.TYPE_GYROSCOPE:
+ if (!prefs.getBoolean("gyroscope_enable", false)
+ || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addStorageConfig: excluding gyroscope");
+
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ storageConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addStorageConfig: NOT excluding gyroscope");
+ }
+ break;
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ if (!prefs.getBoolean("magnetometer_enable", false)
+ || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addStorageConfig: excluding magnetometer");
+
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ storageConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addStorageConfig: NOT excluding magnetometer");
+ }
+ break;
+ case Sensor.TYPE_ROTATION_VECTOR:
+ if (!prefs.getBoolean("orientation_enable", false)
+ || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addStorageConfig: excluding orientation");
+
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ storageConf.excludedOutputs.add(sensorName);
+ sensorName = "quat_orientation_data";
+ storageConf.excludedOutputs.add(sensorName);
+ sensorName = "euler_orientation_data";
+ storageConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addStorageConfig: NOT excluding orientation");
+ }
+ break;
+ }
+ }
+ if (!prefs.getBoolean("location_enable", false)
+ || !prefs.getStringSet("location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addStorageConfig: excluding location");
+
+ sensorName = "gps_data";
+ storageConf.excludedOutputs.add(sensorName);
+ sensorName = "network_data";
+ storageConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addStorageConfig: NOT excluding location");
+ }
+ if (!prefs.getBoolean("video_enable", false)
+ || !prefs.getStringSet("video_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addStorageConfig: excluding video");
+
+ sensorName = "camera0_MJPEG";
+ storageConf.excludedOutputs.add(sensorName);
+ sensorName = "camera0_H264";
+ storageConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addStorageConfig: NOT excluding video");
+ }
+ }
+
+ sensorhubConfig.add(storageConf);
+ }
+
+ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderConfig dataProviderConf) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
+ SensorManager sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
+ List deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
+
+ String sensorName;
+ for (Sensor sensor : deviceSensors) {
+ if (sensor.isWakeUpSensor()) {
+ continue;
+ }
+
+ Log.d(TAG, "addSosServerConfig: sensor: " + sensor.getName());
+
+ switch (sensor.getType()) {
+ case Sensor.TYPE_ACCELEROMETER:
+ if (!prefs.getBoolean("accelerometer_enable", false)
+ || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addSosServerConfig: excluding accelerometer");
+
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addSosServerConfig: NOT excluding accelerometer");
+ }
+ break;
+ case Sensor.TYPE_GYROSCOPE:
+ if (!prefs.getBoolean("gyroscope_enable", false)
+ || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addSosServerConfig: excluding gyroscope");
+
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addSosServerConfig: NOT excluding gyroscope");
+ }
+ break;
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ if (!prefs.getBoolean("magnetometer_enable", false)
+ || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addSosServerConfig: excluding magnetometer");
+
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addSosServerConfig: NOT excluding magnetometer");
+ }
+ break;
+ case Sensor.TYPE_ROTATION_VECTOR:
+ if (!prefs.getBoolean("orientation_enable", false)
+ || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addSosServerConfig: excluding orientation");
+
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ sensorName = "quat_orientation_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ sensorName = "euler_orientation_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addSosServerConfig: NOT excluding orientation");
+ }
+ break;
+ }
+ }
+ if (!prefs.getBoolean("location_enable", false)
+ || !prefs.getStringSet("location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addSosServerConfig: excluding location");
+
+ sensorName = "gps_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ sensorName = "network_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addSosServerConfig: NOT excluding location");
+ }
+ if (!prefs.getBoolean("video_enable", false)
+ || !prefs.getStringSet("video_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addSosServerConfig: excluding video");
+
+ sensorName = "camera0_MJPEG";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ sensorName = "camera0_H264";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ } else {
+ Log.d(TAG, "addSosServerConfig: NOT excluding video");
+ }
+ if (!prefs.getBoolean("ble_enable", false)
+ || !prefs.getStringSet("ble_location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ sensorName = "BLEBeacon";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ sensorName = "BLEBeaconLocation";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ sensorName = "NearestBeacon";
+ dataProviderConf.excludedOutputs.add(sensorName);
+ }
+
+ sosConf.dataProviders.add(dataProviderConf);
+ }
+
+ /*private SensorConfig createSensorConfig(Sensors sensor) {
+ SensorConfig sensorConfig;
+
+ if (Sensors.Android.equals(sensor)) {
+ sensorConfig = new AndroidSensorsConfig();
+ sensorConfig.id = ANDROID_SENSORS_MODULE_ID;
+ sensorConfig.name = "Android Sensors [" + deviceName + "]";
+ sensorConfig.autoStart = true;
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
+
+ ((AndroidSensorsConfig) sensorConfig).activateAccelerometer = prefs.getBoolean("accelerometer_enable", false);
+ ((AndroidSensorsConfig) sensorConfig).activateGyrometer = prefs.getBoolean("gyroscope_enable", false);
+ ((AndroidSensorsConfig) sensorConfig).activateMagnetometer = prefs.getBoolean("magnetometer_enable", false);
+ if (prefs.getBoolean("orientation_enable", false)) {
+ ((AndroidSensorsConfig) sensorConfig).activateOrientationQuat = prefs.getStringSet("orientation_angles", Collections.emptySet()).contains("QUATERNION");
+ ((AndroidSensorsConfig) sensorConfig).activateOrientationEuler = prefs.getStringSet("orientation_angles", Collections.emptySet()).contains("EULER");
+ }
+ if (prefs.getBoolean("location_enable", false)) {
+ ((AndroidSensorsConfig) sensorConfig).activateGpsLocation = prefs.getStringSet("location_type", Collections.emptySet()).contains("GPS");
+ ((AndroidSensorsConfig) sensorConfig).activateNetworkLocation = prefs.getStringSet("location_type", Collections.emptySet()).contains("NETWORK");
+ }
+ if (prefs.getBoolean("video_enable", false)) {
+ showVideo = true;
+
+ ((AndroidSensorsConfig) sensorConfig).activateBackCamera = true;
+ ((AndroidSensorsConfig) sensorConfig).videoCodec = prefs.getString("video_codec", AndroidSensorsConfig.JPEG_CODEC);
+ }
+
+ ((AndroidSensorsConfig) sensorConfig).androidContext = this.getApplicationContext();
+ ((AndroidSensorsConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
+ ((AndroidSensorsConfig) sensorConfig).runName = runName;
+ } else if (Sensors.TruPulse.equals(sensor)) {
+ sensorConfig = createTruPulseConfig();
+ sensorConfig.id = "TRUPULSE_SENSOR";
+ sensorConfig.name = "TruPulse Range Finder [" + deviceName + "]";
+ sensorConfig.autoStart = true;
+
+ BluetoothCommProviderConfig btConf = new BluetoothCommProviderConfig();
+ btConf.protocol.deviceName = "TP360RB.*";
+ btConf.moduleClass = BluetoothCommProvider.class.getCanonicalName();
+ ((TruPulseConfig) sensorConfig).commSettings = btConf;
+ ((TruPulseConfig) sensorConfig).serialNumber = deviceID;
+ } else if (Sensors.TruPulseSim.equals(sensor)) {
+ sensorConfig = createTruPulseConfig();
+ sensorConfig.id = "TRUPULSE_SENSOR_SIMULATED";
+ sensorConfig.name = "Simulated TruPulse Range Finder [" + deviceName + "]";
+ sensorConfig.autoStart = true;
+
+ BluetoothCommProviderConfig btConf = new BluetoothCommProviderConfig();
+ btConf.protocol.deviceName = "TP360RB.*";
+ btConf.moduleClass = SimulatedDataStream.class.getCanonicalName();
+ ((TruPulseConfig) sensorConfig).commSettings = btConf;
+ ((TruPulseConfig) sensorConfig).serialNumber = deviceID;
+ } else if (Sensors.Angel.equals(sensor)) {
+ sensorConfig = new AngelSensorConfig();
+ sensorConfig.id = "ANGEL_SENSOR";
+ sensorConfig.name = "Angel Sensor [" + deviceName + "]";
+ sensorConfig.autoStart = true;
+
+ BleConfig bleConf = new BleConfig();
+ bleConf.id = "BLE";
+ bleConf.moduleClass = BleNetwork.class.getCanonicalName();
+ bleConf.androidContext = this.getApplicationContext();
+ bleConf.autoStart = true;
+ sensorhubConfig.add(bleConf);
+
+ ((AngelSensorConfig) sensorConfig).networkID = bleConf.id;
+ } else if (Sensors.FlirOne.equals(sensor)) {
+ sensorConfig = new FlirOneCameraConfig();
+ sensorConfig.id = "FLIRONE_SENSOR";
+ sensorConfig.name = "FLIR One Camera [" + deviceName + "]";
+ sensorConfig.autoStart = true;
+
+ ((FlirOneCameraConfig) sensorConfig).androidContext = this.getApplicationContext();
+ ((FlirOneCameraConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
+ } else if (Sensors.ProxySensor.equals(sensor)) {
+ sensorConfig = new ProxySensorConfig();
+ } else if(Sensors.BLELocation.equals(sensor)){
+ sensorConfig = new BLEBeaconConfig();
+ sensorConfig.id = "BLE_BEACON_SCANNER";
+ sensorConfig.name = "BLE Scanner [" + deviceName + "]";
+ sensorConfig.autoStart = true;
+ }else {
+ sensorConfig = new SensorConfig();
+ }
+
+ return sensorConfig;
+ }*/
+
@Override
protected void onStart()
diff --git a/sensorhub-android-lib/build.gradle b/sensorhub-android-lib/build.gradle
index fbb0c756..89568014 100644
--- a/sensorhub-android-lib/build.gradle
+++ b/sensorhub-android-lib/build.gradle
@@ -10,6 +10,7 @@ dependencies {
api project(':sensorhub-driver-android')
api project(':sensorhub-android-flirone')
//api project(':sensorhub-android-dji')
+ api project(':sensorhub-storage-h2')
implementation 'org.slf4j:slf4j-android:1.6.1-RC1'
}
From c1d2c51c46d5cd9aba8dea380e3c810cd62d8bab Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 16 Sep 2021 16:15:51 -0500
Subject: [PATCH 183/207] fixes issue causing SOST clients to not be created
---
.../org/sensorhub/android/MainActivity.java | 38 +++++++++++--------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 1caa4dfd..96f0acfc 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -103,6 +103,9 @@
public class MainActivity extends Activity implements TextureView.SurfaceTextureListener, IEventListener
{
+ public static final String ACTION_BROADCAST_RECEIVER = "org.sensorhub.android.BROADCAST_RECEIVER";
+ public static final String ANDROID_SENSORS_MODULE_ID = "ANDROID_SENSORS";
+
TextView mainInfoArea;
TextView videoInfoArea;
SensorHubService boundService;
@@ -116,7 +119,10 @@ public class MainActivity extends Activity implements TextureView.SurfaceTexture
AndroidSensorsDriver androidSensors;
URL sosUrl = null;
boolean showVideo;
+
String deviceID;
+ String deviceName;
+ String runName;
enum Sensors {
Android,
@@ -284,6 +290,7 @@ public boolean verify(String arg0, SSLSession arg1) {
if (isPushingSensor(Sensors.Android)) {
addSosTConfig(androidSensorsConfig, sosUser, sosPwd);
}
+ addSosTConfig(sensorsConfig,sosUser,sosPwd);
File dbFile = new File(getApplicationContext().getFilesDir() + "/db/");
dbFile.mkdirs();
@@ -511,7 +518,7 @@ public void onClick(DialogInterface dialog, int whichButton)
{
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
String runName = input.getText().toString();
- newStatusMessage("Starting SensorHub...");
+
updateConfig(PreferenceManager.getDefaultSharedPreferences(MainActivity.this), runName);
@@ -525,6 +532,7 @@ public void onClick(DialogInterface dialog, int whichButton)
showVideoConfigErrorPopup();
newStatusMessage("Video Config Error: Check Settings");
} else {
+ newStatusMessage("Starting SensorHub...");
sostClients.clear();
boundService.startSensorHub(sensorhubConfig, showVideo, MainActivity.this);
@@ -1072,7 +1080,7 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
sosConf.dataProviders.add(dataProviderConf);
}
- /*private SensorConfig createSensorConfig(Sensors sensor) {
+ private SensorConfig createSensorConfig(Sensors sensor) {
SensorConfig sensorConfig;
if (Sensors.Android.equals(sensor)) {
@@ -1094,17 +1102,17 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
((AndroidSensorsConfig) sensorConfig).activateGpsLocation = prefs.getStringSet("location_type", Collections.emptySet()).contains("GPS");
((AndroidSensorsConfig) sensorConfig).activateNetworkLocation = prefs.getStringSet("location_type", Collections.emptySet()).contains("NETWORK");
}
- if (prefs.getBoolean("video_enable", false)) {
- showVideo = true;
-
- ((AndroidSensorsConfig) sensorConfig).activateBackCamera = true;
- ((AndroidSensorsConfig) sensorConfig).videoCodec = prefs.getString("video_codec", AndroidSensorsConfig.JPEG_CODEC);
- }
-
- ((AndroidSensorsConfig) sensorConfig).androidContext = this.getApplicationContext();
- ((AndroidSensorsConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
- ((AndroidSensorsConfig) sensorConfig).runName = runName;
- } else if (Sensors.TruPulse.equals(sensor)) {
+// if (prefs.getBoolean("video_enable", false)) {
+// showVideo = true;
+//
+// ((AndroidSensorsConfig) sensorConfig).activateBackCamera = true;
+// ((AndroidSensorsConfig) sensorConfig).videoCodec = prefs.getString("video_codec", AndroidSensorsConfig.JPEG_CODEC);
+// }
+//
+// ((AndroidSensorsConfig) sensorConfig).androidContext = this.getApplicationContext();
+// ((AndroidSensorsConfig) sensorConfig).camPreviewTexture = boundService.getVideoTexture();
+// ((AndroidSensorsConfig) sensorConfig).runName = runName;
+ }/* else if (Sensors.TruPulse.equals(sensor)) {
sensorConfig = createTruPulseConfig();
sensorConfig.id = "TRUPULSE_SENSOR";
sensorConfig.name = "TruPulse Range Finder [" + deviceName + "]";
@@ -1155,12 +1163,12 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
sensorConfig.id = "BLE_BEACON_SCANNER";
sensorConfig.name = "BLE Scanner [" + deviceName + "]";
sensorConfig.autoStart = true;
- }else {
+ }*/else {
sensorConfig = new SensorConfig();
}
return sensorConfig;
- }*/
+ }
@Override
From ffe10ce1146299f40a80b1aceb2178270b51ce0e Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Sat, 18 Sep 2021 15:14:14 -0500
Subject: [PATCH 184/207] [WIP] going to reimplement SOS w/ IPC module to
hopefully get the full server/servlet working as it does in v1.4 branch
---
.../org/sensorhub/android/MainActivity.java | 93 +++++++++++--------
1 file changed, 55 insertions(+), 38 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 96f0acfc..77e6af5c 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -16,31 +16,37 @@
import static android.content.ContentValues.TAG;
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.cert.X509Certificate;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.LocationManager;
import android.location.LocationProvider;
-import android.preference.DialogPreference;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.preference.PreferenceManager;
+import android.provider.Settings.Secure;
+import android.text.Html;
import android.util.Log;
-import android.view.*;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.TextureView;
+import android.view.WindowManager;
+import android.widget.EditText;
+import android.widget.TextView;
+
import org.sensorhub.android.comm.BluetoothCommProvider;
import org.sensorhub.android.comm.BluetoothCommProviderConfig;
import org.sensorhub.android.comm.ble.BleConfig;
@@ -49,13 +55,11 @@
import org.sensorhub.api.common.IEventListener;
import org.sensorhub.api.data.IStreamingDataInterface;
import org.sensorhub.api.module.IModuleConfigRepository;
-import org.sensorhub.api.module.ModuleConfig;
import org.sensorhub.api.module.ModuleEvent;
import org.sensorhub.api.sensor.SensorConfig;
import org.sensorhub.impl.client.sost.SOSTClient;
import org.sensorhub.impl.client.sost.SOSTClient.StreamInfo;
import org.sensorhub.impl.client.sost.SOSTClientConfig;
-//import org.sensorhub.impl.driver.dji.DjiConfig;
import org.sensorhub.impl.driver.flir.FlirOneCameraConfig;
import org.sensorhub.impl.module.InMemoryConfigDb;
import org.sensorhub.impl.persistence.GenericStreamStorage;
@@ -71,27 +75,24 @@
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseWithGeolocConfig;
import org.sensorhub.impl.service.HttpServerConfig;
+import org.sensorhub.impl.service.sos.SOSService;
import org.sensorhub.impl.service.sos.SOSServiceConfig;
import org.sensorhub.impl.service.sos.SensorDataProviderConfig;
import org.sensorhub.test.sensor.trupulse.SimulatedDataStream;
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.preference.PreferenceManager;
-import android.provider.Settings.Secure;
-import android.text.Html;
-import android.widget.EditText;
-import android.widget.TextView;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
@@ -217,6 +218,9 @@ public boolean verify(String arg0, SSLSession arg1) {
sensorsConfig.name = "Android Sensors [" + deviceName + "]";
sensorsConfig.id = "ANDROID_SENSORS";
sensorsConfig.autoStart = true;
+ //TODO: try adding a few options
+// sensorsConfig.
+
sensorsConfig.activateAccelerometer = prefs.getBoolean("accel_enabled", false);
sensorsConfig.activateGyrometer = prefs.getBoolean("gyro_enabled", false);
sensorsConfig.activateMagnetometer = prefs.getBoolean("mag_enabled", false);
@@ -276,7 +280,7 @@ public boolean verify(String arg0, SSLSession arg1) {
// SOS Config
SOSServiceConfig sosConfig = new SOSServiceConfig();
- sosConfig.moduleClass = SOSServiceConfig.class.getCanonicalName();
+ sosConfig.moduleClass = SOSService.class.getCanonicalName();
// SensorHubService already references the app context
//((SOSServiceConfig) sosConfig).androidContext = this.getApplicationContext();
sosConfig.id = "SOS_SERVICE";
@@ -538,6 +542,19 @@ public void onClick(DialogInterface dialog, int whichButton)
if (boundService.hasVideo())
mainInfoArea.setBackgroundColor(0x80FFFFFF);
+
+ /*SOSServiceCapabilities caps = null;
+ try {
+ GetCapabilitiesRequest getCap = new GetCapabilitiesRequest();
+ getCap.setService(SOSUtils.SOS);
+ getCap.setVersion("V2.0");
+ getCap.setGetServer(PreferenceManager.getDefaultSharedPreferences(MainActivity.this).getString("sos_uri", ""));
+ OWSUtils owsUtils = new OWSUtils();
+ caps = owsUtils.sendRequest(getCap, false);
+ } catch (OWSException e) {
+// throw new SensorHubException("Cannot retrieve SOS capabilities", e);
+ Log.e(TAG, "ERR: Cannot retrieve SOS Capabilities", e);
+ }*/
}
}
From 83c530f8be8f12d33aae84392296268a4aa0029c Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Tue, 21 Sep 2021 02:30:45 -0500
Subject: [PATCH 185/207] [WIP] move SOS w/ IPC back. Currently won't start as
expected.
---
build.gradle | 2 +-
sensorhub-android-app/build.gradle | 1 +
.../org/sensorhub/android/MainActivity.java | 68 +++++++++++++++++--
.../sensorhub/android}/SOSServiceWithIPC.java | 2 +-
.../android}/SOSServiceWithIPCConfig.java | 2 +-
sensorhub-android-sos-ipc/.gitignore | 1 -
sensorhub-android-sos-ipc/build.gradle | 34 ----------
sensorhub-android-sos-ipc/consumer-rules.pro | 0
sensorhub-android-sos-ipc/proguard-rules.pro | 21 ------
.../ExampleInstrumentedTest.java | 25 -------
.../src/main/AndroidManifest.xml | 5 --
.../ExampleUnitTest.java | 17 -----
settings.gradle | 1 -
13 files changed, 66 insertions(+), 113 deletions(-)
rename {sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos => sensorhub-android-app/src/org/sensorhub/android}/SOSServiceWithIPC.java (98%)
rename {sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos => sensorhub-android-app/src/org/sensorhub/android}/SOSServiceWithIPCConfig.java (88%)
delete mode 100644 sensorhub-android-sos-ipc/.gitignore
delete mode 100644 sensorhub-android-sos-ipc/build.gradle
delete mode 100644 sensorhub-android-sos-ipc/consumer-rules.pro
delete mode 100644 sensorhub-android-sos-ipc/proguard-rules.pro
delete mode 100644 sensorhub-android-sos-ipc/src/androidTest/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleInstrumentedTest.java
delete mode 100644 sensorhub-android-sos-ipc/src/main/AndroidManifest.xml
delete mode 100644 sensorhub-android-sos-ipc/src/test/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleUnitTest.java
diff --git a/build.gradle b/build.gradle
index 8509801e..b7520f1e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
ext.oshCoreVersion = '1.4.0'
-ext.compileSdkVersion = 21
+ext.compileSdkVersion = 31
ext.minSdkVersion = 21
ext.targetSdkVersion = 21
ext.buildToolsVersion = "30.0.2"
diff --git a/sensorhub-android-app/build.gradle b/sensorhub-android-app/build.gradle
index f9b7a477..b0a35a03 100644
--- a/sensorhub-android-app/build.gradle
+++ b/sensorhub-android-app/build.gradle
@@ -14,6 +14,7 @@ dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
+// implementation project(path: ':sensorhub-android-sos-ipc')
// implementation project(path: ':sensorhub-storage-h2')
}
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 77e6af5c..dbe78fa8 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -19,10 +19,12 @@
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
@@ -75,7 +77,6 @@
import org.sensorhub.impl.sensor.trupulse.TruPulseConfig;
import org.sensorhub.impl.sensor.trupulse.TruPulseWithGeolocConfig;
import org.sensorhub.impl.service.HttpServerConfig;
-import org.sensorhub.impl.service.sos.SOSService;
import org.sensorhub.impl.service.sos.SOSServiceConfig;
import org.sensorhub.impl.service.sos.SensorDataProviderConfig;
import org.sensorhub.test.sensor.trupulse.SimulatedDataStream;
@@ -157,7 +158,7 @@ protected void updateConfig(SharedPreferences prefs, String runName)
sensorhubConfig = new InMemoryConfigDb();
// get SOS URL from config
- String sosUriConfig = prefs.getString("sos_uri", "");
+ String sosUriConfig = prefs.getString("sos_uri", "http://127.0.0.1:8585");
String sosUser = prefs.getString("sos_username", null);
String sosPwd = prefs.getString("sos_password", null);
if (sosUriConfig != null && sosUriConfig.trim().length() > 0)
@@ -279,10 +280,9 @@ public boolean verify(String arg0, SSLSession arg1) {
sensorhubConfig.add(serverConfig);
// SOS Config
- SOSServiceConfig sosConfig = new SOSServiceConfig();
- sosConfig.moduleClass = SOSService.class.getCanonicalName();
- // SensorHubService already references the app context
- //((SOSServiceConfig) sosConfig).androidContext = this.getApplicationContext();
+ SOSServiceConfig sosConfig = new SOSServiceWithIPCConfig();
+ sosConfig.moduleClass = SOSServiceWithIPC.class.getCanonicalName();
+ ((SOSServiceWithIPCConfig) sosConfig).androidContext = this.getApplicationContext();
sosConfig.id = "SOS_SERVICE";
sosConfig.name = "SOS Service";
sosConfig.autoStart = true;
@@ -405,6 +405,9 @@ public boolean verify(String arg0, SSLSession arg1) {
sensorhubConfig.add(djiConfig);
addSosTConfig(djiConfig, sosUser, sosPwd);
}*/
+
+ // TODO add missing SOS SERVICE config to sensorhub
+ sensorhubConfig.add(sosConfig);
}
@@ -451,6 +454,8 @@ protected void onCreate(Bundle savedInstanceState)
// handler to refresh sensor status in UI
displayHandler = new Handler(Looper.getMainLooper());
+
+ setupBroadcastReceivers();
}
@@ -1188,6 +1193,57 @@ private SensorConfig createSensorConfig(Sensors sensor) {
}
+ private void setupBroadcastReceivers() {
+ BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String origin = intent.getStringExtra("src");
+ if (!context.getPackageName().equalsIgnoreCase(origin)) {
+ String sosEndpointUrl = intent.getStringExtra("sosEndpointUrl");
+ String name = intent.getStringExtra("name");
+ String sensorId = intent.getStringExtra("sensorId");
+ ArrayList properties = intent.getStringArrayListExtra("properties");
+
+ if (sosEndpointUrl == null || name == null || sensorId == null || properties.size() == 0) {
+ return;
+ }
+
+ /* ProxySensorConfig proxySensorConfig = (ProxySensorConfig) createSensorConfig(Sensors.ProxySensor);
+ proxySensorConfig.androidContext = getApplicationContext();
+ proxySensorConfig.sosEndpointUrl = sosEndpointUrl;
+ proxySensorConfig.name = name;
+ proxySensorConfig.id = sensorId;
+ proxySensorConfig.sensorUID = sensorId;
+ proxySensorConfig.observedProperties.addAll(properties);
+ proxySensorConfig.sosUseWebsockets = true;
+ proxySensorConfig.autoStart = true;
+ proxySensorConfigs.add(proxySensorConfig);*/
+
+ // register and "start" new sensor, data stream doesn't begin until someone requests data;
+ try {
+ boundService.stopSensorHub();
+ Thread.sleep(2000);
+ Log.d("OSHApp", "Starting Sensorhub Again");
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ updateConfig(PreferenceManager.getDefaultSharedPreferences(MainActivity.this), runName);
+ sostClients.clear();
+ boundService.startSensorHub(sensorhubConfig, showVideo, MainActivity.this);
+ if (boundService.hasVideo())
+ mainInfoArea.setBackgroundColor(0x80FFFFFF);
+ } catch (InterruptedException e) {
+ Log.e("OSHApp", "Error Loading Proxy Sensor", e);
+ }
+
+ }
+ }
+ };
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_BROADCAST_RECEIVER);
+
+ registerReceiver(receiver, filter);
+ }
+
+
@Override
protected void onStart()
{
diff --git a/sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPC.java b/sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPC.java
similarity index 98%
rename from sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPC.java
rename to sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPC.java
index 358d9d17..a471ed1c 100644
--- a/sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPC.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPC.java
@@ -1,4 +1,4 @@
-package org.sensorhun.impl.service.sensorhub_android_sos;
+package org.sensorhub.android;
import android.content.BroadcastReceiver;
import android.content.Context;
diff --git a/sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPCConfig.java b/sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPCConfig.java
similarity index 88%
rename from sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPCConfig.java
rename to sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPCConfig.java
index 0078f248..a9701650 100644
--- a/sensorhub-android-sos-ipc/src/main/java/org/sensorhun/impl/service/sensorhub_android_sos/SOSServiceWithIPCConfig.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/SOSServiceWithIPCConfig.java
@@ -1,4 +1,4 @@
-package org.sensorhun.impl.service.sensorhub_android_sos;
+package org.sensorhub.android;
import android.content.Context;
diff --git a/sensorhub-android-sos-ipc/.gitignore b/sensorhub-android-sos-ipc/.gitignore
deleted file mode 100644
index 42afabfd..00000000
--- a/sensorhub-android-sos-ipc/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/build.gradle b/sensorhub-android-sos-ipc/build.gradle
deleted file mode 100644
index 2027c5f1..00000000
--- a/sensorhub-android-sos-ipc/build.gradle
+++ /dev/null
@@ -1,34 +0,0 @@
-plugins {
- id 'com.android.library'
-}
-
-android {
- compileSdk 31
-
- defaultConfig {
- minSdk 21
- targetSdk 31
-
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
- consumerProguardFiles "consumer-rules.pro"
- }
-
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
- }
- }
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
- }
-}
-
-dependencies {
-
- implementation 'com.android.support:appcompat-v7:28.0.0'
- testImplementation 'junit:junit:4.13.2'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
-}
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/consumer-rules.pro b/sensorhub-android-sos-ipc/consumer-rules.pro
deleted file mode 100644
index e69de29b..00000000
diff --git a/sensorhub-android-sos-ipc/proguard-rules.pro b/sensorhub-android-sos-ipc/proguard-rules.pro
deleted file mode 100644
index 481bb434..00000000
--- a/sensorhub-android-sos-ipc/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/src/androidTest/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleInstrumentedTest.java b/sensorhub-android-sos-ipc/src/androidTest/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleInstrumentedTest.java
deleted file mode 100644
index 6fa9e291..00000000
--- a/sensorhub-android-sos-ipc/src/androidTest/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.sensorhun.impl.service.sensorhub_android_sos;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumented test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
- assertEquals("org.sensorhun.impl.service.sensorhub_android_sos.test", appContext.getPackageName());
- }
-}
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/src/main/AndroidManifest.xml b/sensorhub-android-sos-ipc/src/main/AndroidManifest.xml
deleted file mode 100644
index a4f387f9..00000000
--- a/sensorhub-android-sos-ipc/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/sensorhub-android-sos-ipc/src/test/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleUnitTest.java b/sensorhub-android-sos-ipc/src/test/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleUnitTest.java
deleted file mode 100644
index 3a543263..00000000
--- a/sensorhub-android-sos-ipc/src/test/java/org/sensorhun/impl/service/sensorhub_android_sos/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.sensorhun.impl.service.sensorhub_android_sos;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index b8c0d0c2..6b3f128a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -59,4 +59,3 @@ subprojects.files.each { File f ->
}
include ':sensorhub-android-proxysensor'
-include ':sensorhub-android-sos-ipc'
From a8b4df37b720808d6c4c2ddec8feffa8fcc06f17 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Tue, 21 Sep 2021 17:16:46 -0500
Subject: [PATCH 186/207] SOS service and http server now start as expected
---
build.gradle | 4 ++--
sensorhub-android-lib/build.gradle | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/build.gradle b/build.gradle
index b7520f1e..b67b8475 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,7 +1,7 @@
ext.oshCoreVersion = '1.4.0'
ext.compileSdkVersion = 31
-ext.minSdkVersion = 21
-ext.targetSdkVersion = 21
+ext.minSdkVersion = 26
+ext.targetSdkVersion = 26
ext.buildToolsVersion = "30.0.2"
version = oshCoreVersion
diff --git a/sensorhub-android-lib/build.gradle b/sensorhub-android-lib/build.gradle
index 89568014..70e2b5a7 100644
--- a/sensorhub-android-lib/build.gradle
+++ b/sensorhub-android-lib/build.gradle
@@ -13,14 +13,15 @@ dependencies {
api project(':sensorhub-storage-h2')
implementation 'org.slf4j:slf4j-android:1.6.1-RC1'
+ implementation('javax.xml.stream:stax-api:1.0-2')
}
configurations {
api {
// exclude stuff from APK
- exclude group: "javax.servlet"
+// exclude group: "javax.servlet"
exclude group: "xml-apis"
- exclude group: "org.eclipse.jetty"
+// exclude group: "org.eclipse.jetty"
exclude group: "org.n52.amused"
exclude group: "ch.qos.logback"
exclude group: "org.apache.felix"
From 6465324966b4f680870062834e2fc1cff7aabe0c Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Wed, 22 Sep 2021 16:24:17 -0500
Subject: [PATCH 187/207] Update UI to account for push/store options Not yet
implemented in MainActivity
---
.../res/xml/pref_general.xml | 2 +-
.../res/xml/pref_sensors.xml | 295 ++++++++++++------
.../android/UserSettingsActivity.java | 102 ++++++
3 files changed, 311 insertions(+), 88 deletions(-)
diff --git a/sensorhub-android-app/res/xml/pref_general.xml b/sensorhub-android-app/res/xml/pref_general.xml
index 95c67703..8d57837d 100644
--- a/sensorhub-android-app/res/xml/pref_general.xml
+++ b/sensorhub-android-app/res/xml/pref_general.xml
@@ -68,7 +68,7 @@
android:summary="Enter SOS-T password or leave blank" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java b/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
index e54e97e3..57c9c5a7 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
@@ -17,6 +17,7 @@
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
+import android.content.SharedPreferences;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
@@ -168,6 +169,107 @@ public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_sensors);
bindPreferenceSummaryToValue(findPreference("angel_address"));
+
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+
+ Preference accelerometerEnable = getPreferenceScreen().findPreference("accel_enabled");
+ Preference accelerometerOptions = getPreferenceScreen().findPreference("accel_options");
+ accelerometerOptions.setEnabled(prefs.getBoolean(accelerometerEnable.getKey(), false));
+ accelerometerEnable.setOnPreferenceChangeListener((preference, newValue) -> {
+ accelerometerOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference gyroEnabled = getPreferenceScreen().findPreference("gyro_enabled");
+ Preference gyroOptions = getPreferenceScreen().findPreference("gyro_options");
+ gyroOptions.setEnabled(prefs.getBoolean(gyroEnabled.getKey(), false));
+ gyroEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ gyroOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference magEnabled = getPreferenceScreen().findPreference("mag_enabled");
+ Preference magOptions = getPreferenceScreen().findPreference("mag_options");
+ magOptions.setEnabled(prefs.getBoolean(magEnabled.getKey(), false));
+ magEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ magOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference orientQuatEnabled = getPreferenceScreen().findPreference("orient_quat_enabled");
+ Preference orientQuatOptions = getPreferenceScreen().findPreference("orient_quat_options");
+ orientQuatOptions.setEnabled(prefs.getBoolean(orientQuatEnabled.getKey(), false));
+ orientQuatEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ orientQuatOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference orientEulerEnabled = getPreferenceScreen().findPreference("orient_euler_enabled");
+ Preference orientEulerOptions = getPreferenceScreen().findPreference("orient_euler_options");
+ orientEulerOptions.setEnabled(prefs.getBoolean(orientEulerEnabled.getKey(), false));
+ orientEulerEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ orientEulerOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference gpsEnabled = getPreferenceScreen().findPreference("gps_enabled");
+ Preference gpsOptions = getPreferenceScreen().findPreference("gps_options");
+ gpsOptions.setEnabled(prefs.getBoolean(gpsEnabled.getKey(), false));
+ gpsEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ gpsOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference netlocEnabled = getPreferenceScreen().findPreference("netloc_enabled");
+ Preference netlocOptions = getPreferenceScreen().findPreference("netloc_options");
+ netlocOptions.setEnabled(prefs.getBoolean(netlocEnabled.getKey(), false));
+ netlocEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ netlocOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference camEnabled = getPreferenceScreen().findPreference("cam_enabled");
+ Preference camOptions = getPreferenceScreen().findPreference("cam_options");
+ camOptions.setEnabled(prefs.getBoolean(camEnabled.getKey(), false));
+ camEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ camOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference videoRollEnabled = getPreferenceScreen().findPreference("video_roll_enabled");
+ Preference videoRollOptions = getPreferenceScreen().findPreference("video_roll_options");
+ videoRollOptions.setEnabled(prefs.getBoolean(videoRollEnabled.getKey(), false));
+ videoRollEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ videoRollOptions.setEnabled((boolean) newValue);
+ return true;
+ });
+
+ Preference trupulseEnabled = getPreferenceScreen().findPreference("trupulse_enabled");
+ Preference trupulseOptions = getPreferenceScreen().findPreference("trupulse_options");
+ Preference trupulseDatasource = getPreferenceScreen().findPreference("trupulse_datasource");
+ trupulseOptions.setEnabled(prefs.getBoolean(trupulseEnabled.getKey(), false));
+ trupulseDatasource.setEnabled(prefs.getBoolean(trupulseEnabled.getKey(), false));
+ trupulseEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
+ trupulseOptions.setEnabled((boolean) newValue);
+ trupulseDatasource.setEnabled((boolean) newValue);
+ return true;
+ });
+
+// Preference bleEnable = getPreferenceScreen().findPreference("ble_enabled");
+// Preference bleLocationMethod = getPreferenceScreen().findPreference("ble_loc_method");
+// Preference bleOptions = getPreferenceScreen().findPreference("ble_options");
+// Preference bleConfigURL = getPreferenceScreen().findPreference("ble_config_url");
+// bleLocationMethod.setEnabled(prefs.getBoolean(bleEnable.getKey(), false));
+// bleOptions.setEnabled((prefs.getBoolean(bleEnable.getKey(), false)));
+// bleConfigURL.setEnabled((prefs.getBoolean(bleEnable.getKey(), false)));
+// bleEnable.setOnPreferenceChangeListener(((preference, newValue) -> {
+// bleLocationMethod.setEnabled((boolean) newValue);
+// bleOptions.setEnabled((boolean) newValue);
+// bleConfigURL.setEnabled((boolean) newValue);
+// return true;
+// }));
+
+ // TODO: introduce FLIR and ANGEL sensors
}
}
From 19bb6cf396396a77071121c51faabe5cceb33790 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Wed, 22 Sep 2021 19:37:47 -0500
Subject: [PATCH 188/207] Update methods in MainActivity to reflect names of
preferences properly
---
.../org/sensorhub/android/MainActivity.java | 147 +++++++++++-------
1 file changed, 94 insertions(+), 53 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index dbe78fa8..0b97613d 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -294,7 +294,7 @@ public boolean verify(String arg0, SSLSession arg1) {
if (isPushingSensor(Sensors.Android)) {
addSosTConfig(androidSensorsConfig, sosUser, sosPwd);
}
- addSosTConfig(sensorsConfig,sosUser,sosPwd);
+// addSosTConfig(sensorsConfig,sosUser,sosPwd);
File dbFile = new File(getApplicationContext().getFilesDir() + "/db/");
dbFile.mkdirs();
@@ -821,25 +821,31 @@ private boolean isPushingSensor(Sensors sensor) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
if (Sensors.Android.equals(sensor)) {
- if (prefs.getBoolean("accelerometer_enable", false)
- && prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ if (prefs.getBoolean("accel_enabled", false)
+ && prefs.getStringSet("accel_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
- if (prefs.getBoolean("gyroscope_enable", false)
- && prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ if (prefs.getBoolean("gyro_enabled", false)
+ && prefs.getStringSet("gyro_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
- if (prefs.getBoolean("magnetometer_enable", false)
- && prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ if (prefs.getBoolean("mag_enabled", false)
+ && prefs.getStringSet("mag_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
- if (prefs.getBoolean("orientation_enable", false)
- && prefs.getStringSet("orientation_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ if (prefs.getBoolean("orient_quat_enabled", false)
+ && prefs.getStringSet("orient_quat_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
- if (prefs.getBoolean("location_enable", false)
- && prefs.getStringSet("location_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ if (prefs.getBoolean("orient_euler_enabled", false)
+ && prefs.getStringSet("orient_euler_options", Collections.emptySet()).contains("PUSH_REMOTE"))
return true;
- return prefs.getBoolean("video_enable", false)
- && prefs.getStringSet("video_options", Collections.emptySet()).contains("PUSH_REMOTE");
+ if (prefs.getBoolean("gps_enabled", false)
+ && prefs.getStringSet("gps_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ return true;
+ if (prefs.getBoolean("netloc_enabled", false)
+ && prefs.getStringSet("netloc_options", Collections.emptySet()).contains("PUSH_REMOTE"))
+ return true;
+ return prefs.getBoolean("cam_enabled", false)
+ && prefs.getStringSet("cam_options", Collections.emptySet()).contains("PUSH_REMOTE");
} else if (Sensors.TruPulse.equals(sensor) || Sensors.TruPulseSim.equals(sensor)) {
- return prefs.getBoolean("trupulse_enable", false)
+ return prefs.getBoolean("trupulse_enabled", false)
&& prefs.getStringSet("trupulse_options", Collections.emptySet()).contains("PUSH_REMOTE");
} else if(Sensors.BLELocation.equals(sensor)){
return prefs.getBoolean("ble_enable", false) && prefs.getStringSet("ble_options", Collections.emptySet()).contains("PUSH_REMOTE");
@@ -915,8 +921,8 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
- if (!prefs.getBoolean("accelerometer_enable", false)
- || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("accel_enable", false)
+ || !prefs.getStringSet("accel_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding accelerometer");
@@ -927,8 +933,8 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
}
break;
case Sensor.TYPE_GYROSCOPE:
- if (!prefs.getBoolean("gyroscope_enable", false)
- || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("gyro_enable", false)
+ || !prefs.getStringSet("gyro_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding gyroscope");
@@ -939,8 +945,8 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
}
break;
case Sensor.TYPE_MAGNETIC_FIELD:
- if (!prefs.getBoolean("magnetometer_enable", false)
- || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("mag_enable", false)
+ || !prefs.getStringSet("mag_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding magnetometer");
@@ -951,40 +957,58 @@ protected void addStorageConfig(SensorConfig sensorConf, StreamStorageConfig sto
}
break;
case Sensor.TYPE_ROTATION_VECTOR:
- if (!prefs.getBoolean("orientation_enable", false)
- || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ // TODO: double check, this probably will have an issue when both are checked
+ if (!prefs.getBoolean("orient_quat_enabled", false)
+ || !prefs.getStringSet("orient_quat_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding orientation");
-
sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
storageConf.excludedOutputs.add(sensorName);
sensorName = "quat_orientation_data";
storageConf.excludedOutputs.add(sensorName);
+
+ } else if(!prefs.getBoolean("orient_euler_enabled", false)
+ || !prefs.getStringSet("orient_euler_options", Collections.emptySet()).contains("STORE_LOCAL")){
+
+ Log.d(TAG, "addStorageConfig: excluding orientation");
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ storageConf.excludedOutputs.add(sensorName);
sensorName = "euler_orientation_data";
storageConf.excludedOutputs.add(sensorName);
+
} else {
Log.d(TAG, "addStorageConfig: NOT excluding orientation");
}
break;
}
}
- if (!prefs.getBoolean("location_enable", false)
- || !prefs.getStringSet("location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("gps_enabled", false)
+ || !prefs.getStringSet("gps_options", Collections.emptySet()).contains("STORE_LOCAL")) {
- Log.d(TAG, "addStorageConfig: excluding location");
+ Log.d(TAG, "addStorageConfig: excluding gps location");
sensorName = "gps_data";
storageConf.excludedOutputs.add(sensorName);
+
+ } else {
+ Log.d(TAG, "addStorageConfig: NOT excluding gps location");
+ }
+ if (!prefs.getBoolean("netloc_enabled", false)
+ || !prefs.getStringSet("netloc_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addStorageConfig: excluding network location");
+
sensorName = "network_data";
storageConf.excludedOutputs.add(sensorName);
} else {
- Log.d(TAG, "addStorageConfig: NOT excluding location");
+ Log.d(TAG, "addStorageConfig: NOT excluding network location");
}
- if (!prefs.getBoolean("video_enable", false)
- || !prefs.getStringSet("video_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("cam_enabled", false)
+ || !prefs.getStringSet("cam_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addStorageConfig: excluding video");
+ // TODO: double check that sensor name here is correct, or makes sense
sensorName = "camera0_MJPEG";
storageConf.excludedOutputs.add(sensorName);
sensorName = "camera0_H264";
@@ -1012,8 +1036,8 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
switch (sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
- if (!prefs.getBoolean("accelerometer_enable", false)
- || !prefs.getStringSet("accelerometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("accel_enable", false)
+ || !prefs.getStringSet("accel_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding accelerometer");
@@ -1024,8 +1048,8 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
}
break;
case Sensor.TYPE_GYROSCOPE:
- if (!prefs.getBoolean("gyroscope_enable", false)
- || !prefs.getStringSet("gyroscope_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("gyro_enable", false)
+ || !prefs.getStringSet("gyro_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding gyroscope");
@@ -1036,8 +1060,8 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
}
break;
case Sensor.TYPE_MAGNETIC_FIELD:
- if (!prefs.getBoolean("magnetometer_enable", false)
- || !prefs.getStringSet("magnetometer_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("mag_enable", false)
+ || !prefs.getStringSet("mag_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding magnetometer");
@@ -1048,37 +1072,53 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
}
break;
case Sensor.TYPE_ROTATION_VECTOR:
- if (!prefs.getBoolean("orientation_enable", false)
- || !prefs.getStringSet("orientation_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("orient_quat_enabled", false)
+ || !prefs.getStringSet("orient_quat_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding orientation");
-
sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
dataProviderConf.excludedOutputs.add(sensorName);
sensorName = "quat_orientation_data";
dataProviderConf.excludedOutputs.add(sensorName);
+
+ } else if(!prefs.getBoolean("orient_euler_enabled", false)
+ || !prefs.getStringSet("orient_euler_options", Collections.emptySet()).contains("STORE_LOCAL")){
+
+ Log.d(TAG, "addSosServerConfig: excluding orientation");
+ sensorName = sensor.getName().replaceAll(" ", "_") + "_data";
+ dataProviderConf.excludedOutputs.add(sensorName);
sensorName = "euler_orientation_data";
dataProviderConf.excludedOutputs.add(sensorName);
+
} else {
Log.d(TAG, "addSosServerConfig: NOT excluding orientation");
}
break;
}
}
- if (!prefs.getBoolean("location_enable", false)
- || !prefs.getStringSet("location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("gps_enabled", false)
+ || !prefs.getStringSet("gps_options", Collections.emptySet()).contains("STORE_LOCAL")) {
- Log.d(TAG, "addSosServerConfig: excluding location");
+ Log.d(TAG, "addSosServerConfig: excluding gps location");
sensorName = "gps_data";
dataProviderConf.excludedOutputs.add(sensorName);
+
+ } else {
+ Log.d(TAG, "addSosServerConfig: NOT excluding gps location");
+ }
+ if (!prefs.getBoolean("netloc_enabled", false)
+ || !prefs.getStringSet("netloc_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+
+ Log.d(TAG, "addSosServerConfig: excluding network location");
+
sensorName = "network_data";
dataProviderConf.excludedOutputs.add(sensorName);
} else {
- Log.d(TAG, "addSosServerConfig: NOT excluding location");
+ Log.d(TAG, "addSosServerConfig: NOT excluding network location");
}
- if (!prefs.getBoolean("video_enable", false)
- || !prefs.getStringSet("video_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+ if (!prefs.getBoolean("cam_enabled", false)
+ || !prefs.getStringSet("cam_options", Collections.emptySet()).contains("STORE_LOCAL")) {
Log.d(TAG, "addSosServerConfig: excluding video");
@@ -1089,15 +1129,16 @@ protected void addSosServerConfig(SOSServiceConfig sosConf, SensorDataProviderCo
} else {
Log.d(TAG, "addSosServerConfig: NOT excluding video");
}
- if (!prefs.getBoolean("ble_enable", false)
- || !prefs.getStringSet("ble_location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
- sensorName = "BLEBeacon";
- dataProviderConf.excludedOutputs.add(sensorName);
- sensorName = "BLEBeaconLocation";
- dataProviderConf.excludedOutputs.add(sensorName);
- sensorName = "NearestBeacon";
- dataProviderConf.excludedOutputs.add(sensorName);
- }
+ // Add BLE back in
+// if (!prefs.getBoolean("ble_enable", false)
+// || !prefs.getStringSet("ble_location_options", Collections.emptySet()).contains("STORE_LOCAL")) {
+// sensorName = "BLEBeacon";
+// dataProviderConf.excludedOutputs.add(sensorName);
+// sensorName = "BLEBeaconLocation";
+// dataProviderConf.excludedOutputs.add(sensorName);
+// sensorName = "NearestBeacon";
+// dataProviderConf.excludedOutputs.add(sensorName);
+// }
sosConf.dataProviders.add(dataProviderConf);
}
From 333127d0fdd3e622c1221d9fa9878ae2f1108270 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Wed, 29 Sep 2021 14:05:04 -0500
Subject: [PATCH 189/207] Add mock for Status View and add Camera Selection UI
elements
---
sensorhub-android-app/AndroidManifest.xml | 20 ++--
sensorhub-android-app/build.gradle | 9 ++
.../res/layout/activity_app_status.xml | 100 ++++++++++++++++++
sensorhub-android-app/res/menu/main.xml | 8 +-
sensorhub-android-app/res/values/strings.xml | 2 +
.../res/values/strings_app_status.xml | 22 ++++
.../sensorhub/android/AppStatusActivity.java | 13 +++
.../org/sensorhub/android/MainActivity.java | 3 +
.../android/UserSettingsActivity.java | 48 ++++++++-
9 files changed, 216 insertions(+), 9 deletions(-)
create mode 100644 sensorhub-android-app/res/layout/activity_app_status.xml
create mode 100644 sensorhub-android-app/res/values/strings_app_status.xml
create mode 100644 sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java
diff --git a/sensorhub-android-app/AndroidManifest.xml b/sensorhub-android-app/AndroidManifest.xml
index 526b039f..c732090d 100644
--- a/sensorhub-android-app/AndroidManifest.xml
+++ b/sensorhub-android-app/AndroidManifest.xml
@@ -6,8 +6,12 @@
-
-
+
+
@@ -28,9 +32,6 @@
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/AppTheme">
-
-
-
+
+
+
+
-
diff --git a/sensorhub-android-app/build.gradle b/sensorhub-android-app/build.gradle
index b0a35a03..140bbdbb 100644
--- a/sensorhub-android-app/build.gradle
+++ b/sensorhub-android-app/build.gradle
@@ -14,6 +14,12 @@ dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
+ implementation 'com.android.support:appcompat-v7:26.1.0'
+ implementation 'com.android.support:design:26.1.0'
+ implementation 'com.android.support.constraint:constraint-layout:2.0.4'
+ implementation 'android.arch.navigation:navigation-fragment:1.0.0'
+ implementation 'android.arch.navigation:navigation-ui:1.0.0'
+ implementation 'com.android.support:support-v4:26.1.0'
// implementation project(path: ':sensorhub-android-sos-ipc')
// implementation project(path: ':sensorhub-storage-h2')
}
@@ -52,5 +58,8 @@ android {
lintOptions {
abortOnError false
}
+ buildFeatures {
+ viewBinding true
+ }
}
diff --git a/sensorhub-android-app/res/layout/activity_app_status.xml b/sensorhub-android-app/res/layout/activity_app_status.xml
new file mode 100644
index 00000000..2c6e3302
--- /dev/null
+++ b/sensorhub-android-app/res/layout/activity_app_status.xml
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sensorhub-android-app/res/menu/main.xml b/sensorhub-android-app/res/menu/main.xml
index 673f610b..41eacb89 100644
--- a/sensorhub-android-app/res/menu/main.xml
+++ b/sensorhub-android-app/res/menu/main.xml
@@ -21,9 +21,15 @@
android:title="@string/action_stop"/>
+
+
diff --git a/sensorhub-android-app/res/values/strings.xml b/sensorhub-android-app/res/values/strings.xml
index 0fb0bc07..4ba1f8a0 100644
--- a/sensorhub-android-app/res/values/strings.xml
+++ b/sensorhub-android-app/res/values/strings.xml
@@ -5,6 +5,7 @@
SettingsStart SmartHubStop SmartHub
+ App StatusAboutStart ProxyStop Proxy
@@ -191,4 +192,5 @@
Enter resource idEnter resource label
+
diff --git a/sensorhub-android-app/res/values/strings_app_status.xml b/sensorhub-android-app/res/values/strings_app_status.xml
new file mode 100644
index 00000000..3e5941bb
--- /dev/null
+++ b/sensorhub-android-app/res/values/strings_app_status.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+ App Status
+
+
+ Initializing
+ Initialized
+ Starting
+ Started
+ Stopping
+ Stopped
+ Unknown
+
+
+ SOS Service Status
+ HTTP Server Status
+ Android Sensor Status
+ Android Sensor Storage Status
+
\ No newline at end of file
diff --git a/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java b/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java
new file mode 100644
index 00000000..d31ca070
--- /dev/null
+++ b/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java
@@ -0,0 +1,13 @@
+package org.sensorhub.android;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+public class AppStatusActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_app_status);
+ }
+}
\ No newline at end of file
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 0b97613d..4036df72 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -501,6 +501,9 @@ else if (id == R.id.action_stop)
else if (id == R.id.action_about)
{
showAboutPopup();
+ }else if(id == R.id.action_status){
+ startActivity(new Intent(this, AppStatusActivity.class));
+ return true;
}
return super.onOptionsItemSelected(item);
diff --git a/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java b/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
index 57c9c5a7..a2a0dec5 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
@@ -29,14 +29,19 @@
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
+import android.support.v7.view.menu.ListMenuPresenter;
import android.text.InputType;
+import android.text.PrecomputedText;
+import android.util.Log;
import android.widget.BaseAdapter;
import org.sensorhub.impl.sensor.android.video.VideoEncoderConfig;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.List;
+import java.util.prefs.Preferences;
public class UserSettingsActivity extends PreferenceActivity
@@ -280,6 +285,9 @@ public void onCreate(Bundle savedInstanceState)
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class VideoPreferenceFragment extends PreferenceFragment
{
+ ArrayList frameRateList = new ArrayList<>();
+ ArrayList resList = new ArrayList<>();
+
@Override
public void onCreate(Bundle savedInstanceState)
{
@@ -287,15 +295,34 @@ public void onCreate(Bundle savedInstanceState)
addPreferencesFromResource(R.xml.pref_video);
PreferenceScreen videoOptsScreen = getPreferenceScreen();
+
+ // Create camera selection preference
+ ArrayList cameras = new ArrayList<>();
+ for(int i = 0; i < Camera.getNumberOfCameras(); i++)
+ {
+ Camera.CameraInfo info = new Camera.CameraInfo();
+ Camera.getCameraInfo(i, info);
+ cameras.add(Integer.toString(i));
+ }
+ ListPreference cameraSelectList = new ListPreference(videoOptsScreen.getContext());
+ cameraSelectList.setKey("camera_select");
+ cameraSelectList.setTitle("Selected Camera");
+ cameraSelectList.setEntries(cameras.toArray(new String[0]));
+ cameraSelectList.setEntryValues(cameras.toArray(new String[0]));
+// cameraSelectList.setDefaultValue(0);
+ bindPreferenceSummaryToValue(cameraSelectList);
+ videoOptsScreen.addPreference(cameraSelectList);
+
bindPreferenceSummaryToValue(findPreference("video_codec"));
+ // TODO: verify that this works in cases where a camera might not be available, and also works on the default value
// get possible video capture frame rates and sizes
Camera camera = Camera.open(0);
Camera.Parameters camParams = camera.getParameters();
- ArrayList frameRateList = new ArrayList<>();
+// ArrayList frameRateList = new ArrayList<>();
for (int frameRate : camParams.getSupportedPreviewFrameRates())
frameRateList.add(Integer.toString(frameRate));
- ArrayList resList = new ArrayList<>();
+// ArrayList resList = new ArrayList<>();
for (Camera.Size imgSize : camParams.getSupportedPreviewSizes())
resList.add(imgSize.width + "x" + imgSize.height);
camera.release();
@@ -354,6 +381,23 @@ public void onCreate(Bundle savedInstanceState)
presetIndexes.add("AUTO");
selectedPresetList.setEntries(presetNames.toArray(new String[0]));
selectedPresetList.setEntryValues(presetIndexes.toArray(new String[0]));
+
+ // Setup Camera Listener
+ cameraSelectList.setOnPreferenceChangeListener((preference, newValue) -> {
+ Log.d("CAMERA_SELECT", "New Camera Selected: " + newValue);
+ updateCameraSettings(Integer.parseInt((String) newValue));
+ return true;
+ });
+ }
+
+ protected void updateCameraSettings(Integer cameraId){
+ Camera camera = Camera.open(cameraId);
+ Camera.Parameters camParams = camera.getParameters();
+ for (int frameRate : camParams.getSupportedPreviewFrameRates())
+ frameRateList.add(Integer.toString(frameRate));
+ for (Camera.Size imgSize : camParams.getSupportedPreviewSizes())
+ resList.add(imgSize.width + "x" + imgSize.height);
+ camera.release();
}
}
From 929882836f2f560dd914f1bccbeafd80969bf86e Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 30 Sep 2021 15:51:09 -0500
Subject: [PATCH 190/207] selecting other cameras works, though without
properly orienting the preview for front facing sensors
---
.../org/sensorhub/android/MainActivity.java | 7 +++++--
.../sensor/android/AndroidSensorsConfig.java | 8 +++++---
.../sensor/android/AndroidSensorsDriver.java | 20 +++++++++++--------
.../android/video/AndroidCameraOutput.java | 8 +++++++-
4 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 4036df72..7a802570 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -229,8 +229,11 @@ public boolean verify(String arg0, SSLSession arg1) {
sensorsConfig.activateOrientationEuler = prefs.getBoolean("orient_euler_enabled", false);
sensorsConfig.activateGpsLocation = prefs.getBoolean("gps_enabled", false);
sensorsConfig.activateNetworkLocation = prefs.getBoolean("netloc_enabled", false);
- sensorsConfig.activateBackCamera = prefs.getBoolean("cam_enabled", false);
- if (sensorsConfig.activateBackCamera || sensorsConfig.activateFrontCamera)
+ sensorsConfig.enableCamera = prefs.getBoolean("cam_enabled", false);
+ sensorsConfig.selectedCameraId = Integer.parseInt(prefs.getString("camera_select", "0"));
+ /*if (sensorsConfig.activateBackCamera || sensorsConfig.activateFrontCamera)
+ showVideo = true;*/
+ if (sensorsConfig.enableCamera)
showVideo = true;
// video settings
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsConfig.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsConfig.java
index eb505e95..4b835421 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsConfig.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsConfig.java
@@ -39,16 +39,18 @@ public class AndroidSensorsConfig extends SensorConfig
public boolean activateOrientationEuler = true;
public boolean activateGpsLocation = true;
public boolean activateNetworkLocation = false;
+ public int selectedCameraId = 0;
public boolean activateBackCamera = false;
public boolean activateFrontCamera = false;
+ public boolean enableCamera = false;
public VideoEncoderConfig videoConfig = new VideoEncoderConfig();
public boolean outputVideoRoll = false;
-
+
public String deviceName;
public String runName;
public String runDescription;
-
-
+
+
public AndroidSensorsConfig()
{
this.moduleClass = AndroidSensorsDriver.class.getCanonicalName();
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
index d1e1e4dc..a8e191cb 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/AndroidSensorsDriver.java
@@ -160,6 +160,8 @@ public void start() throws SensorException
@SuppressWarnings("deprecation")
protected void createCameraOutputs(Context androidContext) throws SensorException
{
+ int selectedCameraId = config.selectedCameraId;
+
/*if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP)
{
CameraManager cameraManager = (CameraManager)androidContext.getSystemService(Context.CAMERA_SERVICE);
@@ -188,31 +190,33 @@ protected void createCameraOutputs(Context androidContext) throws SensorExceptio
for (int cameraId = 0; cameraId < android.hardware.Camera.getNumberOfCameras(); cameraId++)
{
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
- android.hardware.Camera.getCameraInfo(cameraId, info);
+// android.hardware.Camera.getCameraInfo(cameraId, info);
+ android.hardware.Camera.getCameraInfo(selectedCameraId, info);
- if ( (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK && config.activateBackCamera) ||
- (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT && config.activateFrontCamera))
+ /*if ( (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK && config.activateBackCamera) ||
+ (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT && config.activateFrontCamera))*/
+ if(config.enableCamera)
{
SurfaceTexture camPreviewTexture = SensorHubService.getVideoTexture();
if (VideoEncoderConfig.JPEG_CODEC.equals(config.videoConfig.codec)) {
- useCamera(new AndroidCameraOutputMJPEG(this, cameraId, camPreviewTexture), cameraId);
+ useCamera(new AndroidCameraOutputMJPEG(this, selectedCameraId, camPreviewTexture), selectedCameraId);
break;
}
else if (VideoEncoderConfig.H264_CODEC.equals(config.videoConfig.codec)) {
- useCamera(new AndroidCameraOutputH264(this, cameraId, camPreviewTexture), cameraId);
+ useCamera(new AndroidCameraOutputH264(this, selectedCameraId, camPreviewTexture), selectedCameraId);
// try a break to test
break;
}
else if (VideoEncoderConfig.H265_CODEC.equals(config.videoConfig.codec)) {
- useCamera(new AndroidCameraOutputH265(this, cameraId, camPreviewTexture), cameraId);
+ useCamera(new AndroidCameraOutputH265(this, selectedCameraId, camPreviewTexture), selectedCameraId);
break;
}
else if (VideoEncoderConfig.VP9_CODEC.equals(config.videoConfig.codec)) {
- useCamera(new AndroidCameraOutputVP9(this, cameraId, camPreviewTexture), cameraId);
+ useCamera(new AndroidCameraOutputVP9(this, selectedCameraId, camPreviewTexture), selectedCameraId);
break;
}
else if (VideoEncoderConfig.VP8_CODEC.equals(config.videoConfig.codec)) {
- useCamera(new AndroidCameraOutputVP8(this, cameraId, camPreviewTexture), cameraId);
+ useCamera(new AndroidCameraOutputVP8(this, selectedCameraId, camPreviewTexture), selectedCameraId);
break;
}
else
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
index c8240a54..51b8a161 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
@@ -228,7 +228,13 @@ protected void initVideoCapture(Camera.CameraInfo info) throws SensorException {
camParams.setPreviewSize(imgWidth, imgHeight);
camParams.setVideoStabilization(camParams.isVideoStabilizationSupported());
camParams.setPreviewFormat(ImageFormat.NV21);
- camParams.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
+
+ // TODO: Do we need to add focus mode selection to UI? Do some cameras not support fixed? Is this a problem we wouldn't have with Camera2?
+ if(camParams.getSupportedFocusModes().contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
+ camParams.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
+ }else{
+ camParams.setFocusMode(Parameters.FOCUS_MODE_FIXED);
+ }
camParams.setPreviewFrameRate(frameRate);
camera.setParameters(camParams);
log.info("Fps ranges: {}", Arrays.deepToString(camParams.getSupportedPreviewFpsRange().toArray(new int[0][])));
From 2b1066dc75d443959bf2a94e478556e3e389f5da Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 30 Sep 2021 16:02:34 -0500
Subject: [PATCH 191/207] Force camera preview orientation to 90 degrees
---
.../impl/sensor/android/video/AndroidCameraOutput.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
index 51b8a161..709b336b 100644
--- a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/video/AndroidCameraOutput.java
@@ -247,7 +247,9 @@ protected void initVideoCapture(Camera.CameraInfo info) throws SensorException {
camera.addCallbackBuffer(imgBuf1);
camera.addCallbackBuffer(imgBuf2);
camera.setPreviewCallbackWithBuffer(AndroidCameraOutput.this);
- camera.setDisplayOrientation(info.orientation);
+// camera.setDisplayOrientation(info.orientation);
+ // TODO: need to test with more devices, Pixel 3a and Samsung Galaxy S20+ both accept this for all known cameras
+ camera.setDisplayOrientation(90);
cameraOrientation = info.orientation;
}
catch (Exception e)
From d13f2861b2065b01c735ad648a2339632029e830 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Tue, 5 Oct 2021 15:50:30 -0500
Subject: [PATCH 192/207] Add prompt for permissions
---
.../src/org/sensorhub/android/MainActivity.java | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 7a802570..943108ad 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -16,6 +16,7 @@
import static android.content.ContentValues.TAG;
+import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
@@ -459,6 +460,15 @@ protected void onCreate(Bundle savedInstanceState)
displayHandler = new Handler(Looper.getMainLooper());
setupBroadcastReceivers();
+
+ //Check for necessary permissions
+ if(checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED){
+ requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 1);
+ }
+ if(checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED){
+ requestPermissions(new String[] {Manifest.permission.CAMERA}, 1);
+ }
+ // Does app actually need storage permissions now?
}
From 8f8dd8e761f51302e57be80f7fb2f18bf1aaf24a Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 7 Oct 2021 00:22:52 -0500
Subject: [PATCH 193/207] App Status screen will show basic status of modules
---
.../sensorhub/android/AppStatusActivity.java | 22 ++++++++
.../org/sensorhub/android/MainActivity.java | 52 ++++++++++++++++++-
2 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java b/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java
index d31ca070..85d29359 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/AppStatusActivity.java
@@ -1,7 +1,11 @@
package org.sensorhub.android;
+import android.content.Context;
+import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
+import android.util.Log;
+import android.widget.TextView;
public class AppStatusActivity extends AppCompatActivity {
@@ -9,5 +13,23 @@ public class AppStatusActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_status);
+
+ Intent intent = getIntent();
+ Context appContext = getApplicationContext();
+
+ String sosStatus = intent.getStringExtra("sosService");
+ String httpStatus = intent.getStringExtra("httpStatus");
+ String sensorStatus = intent.getStringExtra("androidSensorStatus");
+ String sensorStorageStatus = intent.getStringExtra("sensorStorageStatus");
+
+ TextView sosStatusView = (TextView) findViewById(R.id.sos_service_state);
+ TextView httpStatusView = (TextView) findViewById(R.id.http_service_state);
+ TextView sensorStatusView = (TextView) findViewById(R.id.sensor_service_state);
+ TextView storageStatusView = (TextView) findViewById(R.id.storage_service_state);
+
+ sosStatusView.setText(sosStatus);
+ httpStatusView.setText(httpStatus);
+ sensorStatusView.setText(sensorStatus);
+ storageStatusView.setText(sensorStorageStatus);
}
}
\ No newline at end of file
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 943108ad..ece9f8b9 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -56,8 +56,11 @@
import org.sensorhub.android.comm.ble.BleNetwork;
import org.sensorhub.api.common.Event;
import org.sensorhub.api.common.IEventListener;
+import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.api.data.IStreamingDataInterface;
+import org.sensorhub.api.module.IModule;
import org.sensorhub.api.module.IModuleConfigRepository;
+import org.sensorhub.api.module.ModuleConfig;
import org.sensorhub.api.module.ModuleEvent;
import org.sensorhub.api.sensor.SensorConfig;
import org.sensorhub.impl.client.sost.SOSTClient;
@@ -65,6 +68,7 @@
import org.sensorhub.impl.client.sost.SOSTClientConfig;
import org.sensorhub.impl.driver.flir.FlirOneCameraConfig;
import org.sensorhub.impl.module.InMemoryConfigDb;
+import org.sensorhub.impl.module.ModuleRegistry;
import org.sensorhub.impl.persistence.GenericStreamStorage;
import org.sensorhub.impl.persistence.MaxAgeAutoPurgeConfig;
import org.sensorhub.impl.persistence.StreamStorageConfig;
@@ -89,6 +93,7 @@
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@@ -514,8 +519,51 @@ else if (id == R.id.action_stop)
else if (id == R.id.action_about)
{
showAboutPopup();
- }else if(id == R.id.action_status){
- startActivity(new Intent(this, AppStatusActivity.class));
+ }
+ else if(id == R.id.action_status)
+ {
+ Intent statusIntent = new Intent(this, AppStatusActivity.class);
+ if(boundService.sensorhub != null) {
+ ModuleRegistry moduleRegistry = boundService.sensorhub.getModuleRegistry();
+ Collection modules = moduleRegistry.getAvailableModules();
+
+ for (ModuleConfig moduleConf: modules) {
+ IModule module = null;
+ try {
+ module = moduleRegistry.getModuleById(moduleConf.id);
+ String status = module.getCurrentState().name();
+
+ switch (moduleConf.id){
+ case "HTTP_SERVER_0":
+ statusIntent.putExtra("httpStatus", status);
+ break;
+ case "SOS_SERVICE":
+ statusIntent.putExtra("sosService", status);
+ break;
+ case "ANDROID_SENSORS":
+ statusIntent.putExtra("androidSensorStatus", status);
+ break;
+ case "ANDROID_SENSORS#storage":
+ statusIntent.putExtra("sensorStorageStatus", status);
+ break;
+ }
+
+ } catch (SensorHubException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }else{
+ statusIntent.putExtra("sosService", "Stopped");
+ statusIntent.putExtra("httpStatus", "Stopped");
+ statusIntent.putExtra("androidSensorStatus", "Stopped");
+ statusIntent.putExtra("sensorStorageStatus", "Stopped");
+ }
+
+// statusIntent.putExtra("boundService", boundService);
+
+
+ startActivity(statusIntent);
return true;
}
From cef1d891395ccbaf5e9cd9a53a0cb21f2f55f99a Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 7 Oct 2021 00:26:48 -0500
Subject: [PATCH 194/207] improve status text alignment
---
sensorhub-android-app/res/layout/activity_app_status.xml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/sensorhub-android-app/res/layout/activity_app_status.xml b/sensorhub-android-app/res/layout/activity_app_status.xml
index 2c6e3302..f54bffdd 100644
--- a/sensorhub-android-app/res/layout/activity_app_status.xml
+++ b/sensorhub-android-app/res/layout/activity_app_status.xml
@@ -20,7 +20,9 @@
android:id="@+id/sos_service_state"
android:layout_width="0dp"
android:layout_height="0dp"
+ android:padding="10dp"
android:text="TextView"
+ android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="@+id/sos_service_status_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
@@ -42,7 +44,9 @@
android:id="@+id/http_service_state"
android:layout_width="0dp"
android:layout_height="0dp"
+ android:padding="10dp"
android:text="TextView"
+ android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="@+id/http_server_status_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
@@ -65,7 +69,9 @@
android:id="@+id/sensor_service_state"
android:layout_width="0dp"
android:layout_height="0dp"
+ android:padding="10dp"
android:text="TextView"
+ android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="@+id/android_sensor_status_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
@@ -89,7 +95,9 @@
android:id="@+id/storage_service_state"
android:layout_width="0dp"
android:layout_height="0dp"
+ android:padding="10dp"
android:text="TextView"
+ android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="@+id/storage_service_status_label"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
From 4a1c47e374156aba7d28e92807d654fc5ca3974b Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 7 Oct 2021 00:29:19 -0500
Subject: [PATCH 195/207] change status text to N/A when the hub has not been
created or is otherwise null
---
.../src/org/sensorhub/android/MainActivity.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index ece9f8b9..57f64c63 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -554,10 +554,10 @@ else if(id == R.id.action_status)
}
}else{
- statusIntent.putExtra("sosService", "Stopped");
- statusIntent.putExtra("httpStatus", "Stopped");
- statusIntent.putExtra("androidSensorStatus", "Stopped");
- statusIntent.putExtra("sensorStorageStatus", "Stopped");
+ statusIntent.putExtra("sosService", "N/A");
+ statusIntent.putExtra("httpStatus", "N/A");
+ statusIntent.putExtra("androidSensorStatus", "N/A");
+ statusIntent.putExtra("sensorStorageStatus", "N/A");
}
// statusIntent.putExtra("boundService", boundService);
From 3ee1dca80e1595539e7bfa65552a7b1113aca4ef Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 7 Oct 2021 17:43:52 -0500
Subject: [PATCH 196/207] add back support for showing the ip address of the
android device in general preferences
---
.../android/UserSettingsActivity.java | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java b/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
index a2a0dec5..b45f3fb4 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/UserSettingsActivity.java
@@ -19,6 +19,7 @@
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.hardware.Camera;
+import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.EditTextPreference;
@@ -37,7 +38,11 @@
import org.sensorhub.impl.sensor.android.video.VideoEncoderConfig;
+import java.math.BigInteger;
+import java.net.InetAddress;
import java.net.URL;
+import java.net.UnknownHostException;
+import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
@@ -158,6 +163,26 @@ public void onCreate(Bundle savedInstanceState)
bindPreferenceSummaryToValue(findPreference("device_name"));
bindPreferenceSummaryToValue(findPreference("sos_uri"));
bindPreferenceSummaryToValue(findPreference("sos_username"));
+
+ WifiManager wifiManager = (WifiManager) getActivity().getApplicationContext().getSystemService(WIFI_SERVICE);
+ int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
+
+ // Convert little-endian to big-endianif needed
+ if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
+ ipAddress = Integer.reverseBytes(ipAddress);
+ }
+
+ byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray();
+
+ String ipAddressString;
+ try {
+ ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress();
+ } catch (UnknownHostException ex) {
+ ipAddressString = "Unable to get IP Address";
+ }
+
+ Preference ipAddressLabel = getPreferenceScreen().findPreference("nop_ipAddress");
+ ipAddressLabel.setSummary(ipAddressString);
}
}
From 77544bd5fb954cf84bc55244ba4404a78d4ac67c Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Thu, 7 Oct 2021 20:26:54 -0500
Subject: [PATCH 197/207] move back to using sosService instead of with IPC by
default
---
.../src/org/sensorhub/android/MainActivity.java | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
index 57f64c63..76cef047 100644
--- a/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
+++ b/sensorhub-android-app/src/org/sensorhub/android/MainActivity.java
@@ -289,9 +289,13 @@ public boolean verify(String arg0, SSLSession arg1) {
sensorhubConfig.add(serverConfig);
// SOS Config
- SOSServiceConfig sosConfig = new SOSServiceWithIPCConfig();
+// SOSServiceConfig sosConfig = new SOSServiceWithIPCConfig();
+// sosConfig.moduleClass = SOSServiceWithIPC.class.getCanonicalName();
+// ((SOSServiceWithIPCConfig) sosConfig).androidContext = this.getApplicationContext();
+
+ // We don't need android context unless we're doing IPC things
+ SOSServiceConfig sosConfig = new SOSServiceConfig();
sosConfig.moduleClass = SOSServiceWithIPC.class.getCanonicalName();
- ((SOSServiceWithIPCConfig) sosConfig).androidContext = this.getApplicationContext();
sosConfig.id = "SOS_SERVICE";
sosConfig.name = "SOS Service";
sosConfig.autoStart = true;
From 8d95960fec0b541bf63d9c0d3781beb378b73ee0 Mon Sep 17 00:00:00 2001
From: Ian Patterson
Date: Fri, 15 Oct 2021 17:04:42 -0500
Subject: [PATCH 198/207] start bringing in files from audio support branch
---
sensorhub-android-app/AndroidManifest.xml | 1 +
.../android/audio/AndroidAudioOutput.java | 400 ++++++++++++++++++
.../android/audio/AndroidAudioOutputAAC.java | 115 +++++
.../android/audio/AndroidAudioOutputOPUS.java | 87 ++++
.../android/audio/AudioEncoderConfig.java | 40 ++
5 files changed, 643 insertions(+)
create mode 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
create mode 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputAAC.java
create mode 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputOPUS.java
create mode 100644 sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AudioEncoderConfig.java
diff --git a/sensorhub-android-app/AndroidManifest.xml b/sensorhub-android-app/AndroidManifest.xml
index c732090d..e6c8d7b7 100644
--- a/sensorhub-android-app/AndroidManifest.xml
+++ b/sensorhub-android-app/AndroidManifest.xml
@@ -23,6 +23,7 @@
+
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
new file mode 100644
index 00000000..86a34e60
--- /dev/null
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutput.java
@@ -0,0 +1,400 @@
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android.audio;
+
+import android.graphics.ImageFormat;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.media.AudioFormat;
+import android.media.AudioRecord;
+import android.media.MediaCodec;
+import android.media.MediaCodec.BufferInfo;
+import android.media.MediaRecorder;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+
+import net.opengis.swe.v20.BinaryBlock;
+import net.opengis.swe.v20.BinaryComponent;
+import net.opengis.swe.v20.BinaryEncoding;
+import net.opengis.swe.v20.ByteEncoding;
+import net.opengis.swe.v20.ByteOrder;
+import net.opengis.swe.v20.DataBlock;
+import net.opengis.swe.v20.DataComponent;
+import net.opengis.swe.v20.DataEncoding;
+import net.opengis.swe.v20.DataRecord;
+import net.opengis.swe.v20.DataStream;
+import net.opengis.swe.v20.DataType;
+import net.opengis.swe.v20.Quantity;
+
+import org.sensorhub.algo.vecmath.Vect3d;
+import org.sensorhub.api.sensor.SensorDataEvent;
+import org.sensorhub.api.sensor.SensorException;
+import org.sensorhub.impl.sensor.AbstractSensorOutput;
+import org.sensorhub.impl.sensor.android.AndroidSensorsDriver;
+import org.sensorhub.impl.sensor.android.IAndroidOutput;
+import org.sensorhub.impl.sensor.android.video.VideoEncoderConfig;
+import org.sensorhub.impl.sensor.videocam.VideoCamHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.vast.cdm.common.CDMException;
+import org.vast.data.AbstractDataBlock;
+import org.vast.data.DataBlockMixed;
+import org.vast.swe.SWEConstants;
+import org.vast.swe.SWEHelper;
+import org.vast.swe.helper.GeoPosHelper;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+
+/**
+ *
+ * Implementation of data interface capturing audio data using Android
+ * AudioRecord API. See https://www.codota.com/code/java/classes/android.media.AudioRecord
+ *
+ *
+ * @author Alex Robin
+ * @since Mar 22, 2021
+ */
+@SuppressWarnings("deprecation")
+public abstract class AndroidAudioOutput extends AbstractSensorOutput implements IAndroidOutput
+{
+ // keep logger name short because in LogCat it's max 23 chars
+ static final Logger log = LoggerFactory.getLogger(AndroidAudioOutput.class.getSimpleName());
+
+ DataComponent dataStruct;
+ DataEncoding dataEncoding;
+ int sampleRateHz = 11025;
+ int pcmEncoding = AudioFormat.ENCODING_PCM_16BIT;
+ int numSamplesPerRecord;
+ int bytesPerSample;
+ int bytesPerRecord;
+ int bitrate = 64 * 1000; // bits/s
+
+ Looper bgLooper;
+ AudioRecord audioRecord;
+ long systemTimeOffset = -1L;
+ long lastRecordTime = 0;
+ byte[] codecInfoData;
+ MediaCodec mCodec;
+ BufferInfo bufferInfo = new BufferInfo();
+ int packetHeaderSize = 0;
+
+ protected abstract String getCodecName();
+
+ protected abstract void initCodec(int inputBufferSize) throws SensorException;
+
+ protected abstract void addPacketHeader(byte[] packet, int packetLen);
+
+
+ protected AndroidAudioOutput(AndroidSensorsDriver parentModule, String name) throws SensorException
+ {
+ super(name, parentModule);
+
+ // init audio recorder and codec
+ initAudio();
+ initCodec(bytesPerRecord);
+ initOutputStructure();
+ }
+
+
+ protected void initOutputStructure()
+ {
+ // create SWE Common data structure and encoding
+ SWEHelper swe = new SWEHelper();
+ String numSamplesId = "NUM_SAMPLES";
+ dataStruct = swe.createRecord()
+ .name(getName())
+ .definition(SWEHelper.getPropertyUri("AudioFrame"))
+ .addField("time", swe.createTime().asPhenomenonTimeIsoUTC().build())
+ .addField("sampleRate", swe.createQuantity()
+ .label("Sample Rate")
+ .description("Number of audio samples per second")
+ .definition(SWEHelper.getQudtUri("DataRate"))
+ .uomCode("Hz"))
+ .addField("numSamples", swe.createCount()
+ .id(numSamplesId)
+ .label("Num Samples")
+ .description("Number of audio samples packaged in this record"))
+ .addField("samples", swe.createArray()
+ .withVariableSize(numSamplesId)
+ .withElement("sample", swe.createCount()
+ .label("Audio Sample")
+ .definition(SWEConstants.DEF_DN)
+ .dataType(DataType.SHORT))
+ .build())
+ .build();
+
+ //////////////////////////
+ // binary encoding spec //
+ //////////////////////////
+ BinaryEncoding dataEnc = swe.newBinaryEncoding();
+ dataEnc.setByteEncoding(ByteEncoding.RAW);
+ dataEnc.setByteOrder(ByteOrder.BIG_ENDIAN);
+ BinaryComponent comp;
+
+ // time stamp
+ comp = swe.newBinaryComponent();
+ comp.setRef("/" + dataStruct.getComponent(0).getName());
+ comp.setCdmDataType(DataType.DOUBLE);
+ dataEnc.addMemberAsComponent(comp);
+
+ // sample rate
+ comp = swe.newBinaryComponent();
+ comp.setRef("/" + dataStruct.getComponent(1).getName());
+ comp.setCdmDataType(DataType.INT);
+ dataEnc.addMemberAsComponent(comp);
+
+ // num samples
+ comp = swe.newBinaryComponent();
+ comp.setRef("/" + dataStruct.getComponent(2).getName());
+ comp.setCdmDataType(DataType.INT);
+ dataEnc.addMemberAsComponent(comp);
+
+ // audio codec
+ BinaryBlock compressedBlock = swe.newBinaryBlock();
+ compressedBlock.setRef("/" + dataStruct.getComponent(3).getName());
+ compressedBlock.setCompression(getCodecName());
+ dataEnc.addMemberAsBlock(compressedBlock);
+
+ try
+ {
+ SWEHelper.assignBinaryEncoding(dataStruct, dataEnc);
+ }
+ catch (CDMException e)
+ {
+ throw new RuntimeException("Invalid binary encoding configuration", e);
+ };
+
+ this.dataEncoding = dataEnc;
+ }
+
+
+ protected void initAudio() throws SensorException
+ {
+ AudioEncoderConfig audioConfig = parentSensor.getConfiguration().audioConfig;
+ sampleRateHz = audioConfig.sampleRate;
+ bitrate = audioConfig.bitRate * 1000;
+
+ if (numSamplesPerRecord <= 0)
+ numSamplesPerRecord = (int)(sampleRateHz/10);
+ bytesPerSample = (pcmEncoding == AudioFormat.ENCODING_PCM_8BIT) ? 1 : 2;
+ bytesPerRecord = numSamplesPerRecord*bytesPerSample;
+
+ // create audio recorder object
+ // we use an internal buffer twice as big as the read buffer
+ // so we have time to compress a chunk while we're recording the next one
+ audioRecord = new AudioRecord(
+ MediaRecorder.AudioSource.MIC,
+ sampleRateHz,
+ AudioFormat.CHANNEL_IN_MONO,
+ pcmEncoding,
+ bytesPerRecord*2);
+ }
+
+
+ @Override
+ public void start(Handler eventHandler) throws SensorException
+ {
+ try
+ {
+ // start codec
+ if (mCodec != null)
+ mCodec.start();
+
+ // reset time
+ lastRecordTime = 0;
+ systemTimeOffset = -1;
+
+ // read audio samples in background thread
+ Thread bgThread = new Thread() {
+ public void run()
+ {
+ try
+ {
+ byte[] buffer = new byte[numSamplesPerRecord*2]; // 16 bits samples
+ audioRecord.startRecording();
+
+ while (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED) {
+ readAndEncodeAudioData();
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+ };
+ bgThread.start();
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot start codec " + mCodec.getName(), e);
+ }
+ }
+
+
+ private void readAndEncodeAudioData()
+ {
+ // get next available buffer from codec
+ int inputBufferIndex = mCodec.dequeueInputBuffer(0);
+ if (inputBufferIndex >= 0)
+ {
+ ByteBuffer inputBuffer = mCodec.getInputBuffer(inputBufferIndex);
+ inputBuffer.clear();
+
+ int readBytes = audioRecord.read(inputBuffer, bytesPerRecord);
+ log.debug(lastRecordTime + ": " + readBytes + " audio bytes read");
+ mCodec.queueInputBuffer(inputBufferIndex, 0, readBytes, lastRecordTime, 0);
+ lastRecordTime += (numSamplesPerRecord * 1000000) / sampleRateHz; // in µs
+
+ encode();
+ }
+ }
+
+
+ private void encode()
+ {
+ int outputBufferIndex;
+
+ do {
+ outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 0);
+ if (outputBufferIndex >= 0) {
+ ByteBuffer outBuffer = mCodec.getOutputBuffer(outputBufferIndex);
+ int outDataSize = outBuffer.remaining();
+ log.debug(bufferInfo.presentationTimeUs + ": " + outDataSize + " compressed audio bytes");
+ int outDataOffset = packetHeaderSize;
+
+ // create buffer to hold packet header + data
+ byte[] outData = new byte[outDataSize + outDataOffset];
+
+ // copy encoded data
+ outBuffer.get(outData, outDataOffset, outDataSize);
+ addPacketHeader(outData, outDataSize);
+
+ // release output buffer
+ mCodec.releaseOutputBuffer(outputBufferIndex, false);
+
+ // send it to output (but skip codec config bytes)
+ if (bufferInfo.flags != MediaCodec.BUFFER_FLAG_CODEC_CONFIG)
+ sendCompressedData(bufferInfo.presentationTimeUs, outData);
+ }
+ }
+ while (outputBufferIndex >= 0);
+ }
+
+
+ protected void sendCompressedData(long timeStamp, byte[] compressedData)
+ {
+ // generate new data record
+ DataBlock newRecord;
+ if (latestRecord == null)
+ newRecord = dataStruct.createDataBlock();
+ else
+ newRecord = latestRecord.renew();
+
+ // set time stamp
+ int idx = 0;
+ double samplingTime = getJulianTimeStamp(timeStamp);
+ newRecord.setDoubleValue(idx++, samplingTime);
+ newRecord.setIntValue(idx++, sampleRateHz);
+ newRecord.setIntValue(idx++, numSamplesPerRecord);
+
+ // set encoded data
+ AbstractDataBlock audioData = ((DataBlockMixed) newRecord).getUnderlyingObject()[idx++];
+ audioData.setUnderlyingObject(compressedData);
+
+ // send event
+ latestRecord = newRecord;
+ latestRecordTime = System.currentTimeMillis();
+ eventHandler.publishEvent(new SensorDataEvent(latestRecordTime, this, latestRecord));
+ }
+
+
+ @Override
+ public void stop()
+ {
+ if (audioRecord != null)
+ {
+ audioRecord.stop();
+ audioRecord = null;
+ }
+
+ if (mCodec != null)
+ {
+ mCodec.stop();
+ mCodec.release();
+ }
+
+ if (bgLooper != null)
+ {
+ bgLooper.quit();
+ bgLooper = null;
+ }
+ }
+
+
+ @Override
+ public double getAverageSamplingPeriod()
+ {
+ return numSamplesPerRecord/(double)sampleRateHz;
+ }
+
+
+ @Override
+ public DataComponent getRecordDescription()
+ {
+ return dataStruct;
+ }
+
+
+ @Override
+ public DataEncoding getRecommendedEncoding()
+ {
+ return dataEncoding;
+ }
+
+
+ @Override
+ public DataBlock getLatestRecord()
+ {
+ return latestRecord;
+ }
+
+
+ @Override
+ public long getLatestRecordTime()
+ {
+ return latestRecordTime;
+ }
+
+
+ protected double getJulianTimeStamp(long sensorTimeStampUs)
+ {
+ long sensorTimeMillis = sensorTimeStampUs / 1000;
+
+ if (systemTimeOffset < 0)
+ systemTimeOffset = System.currentTimeMillis() - sensorTimeMillis;
+
+ return (systemTimeOffset + sensorTimeMillis) / 1000.;
+ }
+}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputAAC.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputAAC.java
new file mode 100644
index 00000000..3772f617
--- /dev/null
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputAAC.java
@@ -0,0 +1,115 @@
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android.audio;
+
+import android.graphics.SurfaceTexture;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+
+import org.sensorhub.api.sensor.SensorException;
+import org.sensorhub.impl.sensor.android.AndroidSensorsDriver;
+
+
+/**
+ *
+ * Implementation of data interface capturing audio data and compressing it
+ * using AAC codec.
+ *
+ *
+ * @author Alex Robin
+ * @since March 22, 2021
+ */
+@SuppressWarnings("deprecation")
+public class AndroidAudioOutputAAC extends AndroidAudioOutput
+{
+ private static final String CODEC_NAME = "AAC";
+ private static int[] ADTS_FREQ_TABLE = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 };
+
+ int adtsFreqIdx;
+
+
+ public AndroidAudioOutputAAC(AndroidSensorsDriver parentModule) throws SensorException
+ {
+ super(parentModule, "audio" + "_" + CODEC_NAME);
+ }
+
+ @Override
+ protected String getCodecName()
+ {
+ return CODEC_NAME;
+ }
+
+ @Override
+ protected void initCodec(int inputBufferSize) throws SensorException
+ {
+ try {
+ final String audioCodec = MediaFormat.MIMETYPE_AUDIO_AAC;
+ mCodec = MediaCodec.createEncoderByType(audioCodec);
+ MediaFormat mediaFormat = MediaFormat.createAudioFormat(audioCodec, sampleRateHz, 1);
+ mediaFormat.setInteger("pcm-encoding", pcmEncoding);
+ mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, inputBufferSize);
+ mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+ mediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
+ mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
+ mCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+ log.debug("MediaCodec initialized");
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot initialize codec " + mCodec.getName(), e);
+ }
+ }
+
+
+ @Override
+ protected void initAudio() throws SensorException
+ {
+ // ADTS always includes 1024 samples per packet so align record size to that
+ this.numSamplesPerRecord = 1024;
+ super.initAudio();
+
+ // set ADTS packet header size
+ packetHeaderSize = 7;
+
+ // compute sample rate index to be used in ADTS headers
+ adtsFreqIdx = -1;
+ for (int i = 0; i < ADTS_FREQ_TABLE.length; i++)
+ {
+ if (ADTS_FREQ_TABLE[i] == sampleRateHz)
+ adtsFreqIdx = i;
+ }
+ if (adtsFreqIdx < 0)
+ throw new SensorException("Unsupported sample rate for AAC: " + sampleRateHz);
+ }
+
+
+ protected void addPacketHeader(byte[] packet, int dataLen)
+ {
+ int profile = 2; // AAC LC
+ int freqIdx = adtsFreqIdx;
+ int chanCfg = 1; // mono
+ int frameLen = dataLen + packetHeaderSize;
+
+ // fill in ADTS data
+ packet[0] = (byte)0xFF;
+ packet[1] = (byte)0xF1;
+ packet[2] = (byte)(((profile - 1) << 6) + (freqIdx << 2) +(chanCfg >> 2));
+ packet[3] = (byte)(((chanCfg & 3) << 6) + (frameLen >> 11));
+ packet[4] = (byte)((frameLen & 0x7FF) >> 3);
+ packet[5] = (byte)(((frameLen & 7) << 5) + 0x1F);
+ packet[6] = (byte)0xFC;
+ }
+}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputOPUS.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputOPUS.java
new file mode 100644
index 00000000..588e3e8b
--- /dev/null
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AndroidAudioOutputOPUS.java
@@ -0,0 +1,87 @@
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android.audio;
+
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaFormat;
+
+import org.sensorhub.api.sensor.SensorException;
+import org.sensorhub.impl.sensor.android.AndroidSensorsDriver;
+
+
+/**
+ *
+ * Implementation of data interface capturing audio data and compressing it
+ * using the Opus codec.
+ *
+ *
+ * @author Alex Robin
+ * @since March 29, 2021
+ */
+@SuppressWarnings("deprecation")
+public class AndroidAudioOutputOPUS extends AndroidAudioOutput
+{
+ private static final String CODEC_NAME = "OPUS";
+
+ int adtsFreqIdx;
+
+
+ public AndroidAudioOutputOPUS(AndroidSensorsDriver parentModule) throws SensorException
+ {
+ super(parentModule, "audio" + "_" + CODEC_NAME);
+ }
+
+ @Override
+ protected String getCodecName()
+ {
+ return CODEC_NAME;
+ }
+
+ @Override
+ protected void initCodec(int inputBufferSize) throws SensorException
+ {
+ try {
+ final String audioCodec = MediaFormat.MIMETYPE_AUDIO_OPUS;
+ mCodec = MediaCodec.createEncoderByType(audioCodec);
+ MediaFormat mediaFormat = MediaFormat.createAudioFormat(audioCodec, sampleRateHz, 1);
+ mediaFormat.setInteger("pcm-encoding", pcmEncoding);
+ mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, inputBufferSize);
+ mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+ mediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
+ mCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+ log.debug("MediaCodec initialized");
+ }
+ catch (Exception e)
+ {
+ throw new SensorException("Cannot initialize codec " + mCodec.getName(), e);
+ }
+ }
+
+
+ @Override
+ protected void initAudio() throws SensorException
+ {
+ super.initAudio();
+
+ // no header for opus
+ packetHeaderSize = 0;
+ }
+
+
+ protected void addPacketHeader(byte[] packet, int dataLen)
+ {
+ }
+}
diff --git a/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AudioEncoderConfig.java b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AudioEncoderConfig.java
new file mode 100644
index 00000000..7525b4a5
--- /dev/null
+++ b/sensorhub-driver-android/src/main/java/org/sensorhub/impl/sensor/android/audio/AudioEncoderConfig.java
@@ -0,0 +1,40 @@
+/***************************** BEGIN LICENSE BLOCK ***************************
+
+The contents of this file are subject to the Mozilla Public License, v. 2.0.
+If a copy of the MPL was not distributed with this file, You can obtain one
+at http://mozilla.org/MPL/2.0/.
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the License.
+
+Copyright (C) 2012-2015 Sensia Software LLC. All Rights Reserved.
+
+******************************* END LICENSE BLOCK ***************************/
+
+package org.sensorhub.impl.sensor.android.audio;
+
+
+/**
+ *
+ * Configuration of audio encoding parameters
+ *