Added Georeferencing to SMS - needs a bit of tidying up as geo URIs not clickable on Android for some reason.....

This commit is contained in:
Graham Jones
2016-12-15 20:19:12 +00:00
parent 5c47f95a8f
commit 756e42892e
6 changed files with 172 additions and 9 deletions

View File

@@ -36,7 +36,8 @@ dependencies {
compile 'com.android.support:support-v4:22.2.1' compile 'com.android.support:support-v4:22.2.1'
//compile files('libs/JTransforms-3.1-with-dependencies.jar') //compile files('libs/JTransforms-3.1-with-dependencies.jar')
compile 'org.apache.commons:commons-math3:3.6.1' compile 'org.apache.commons:commons-math3:3.6.1'
// google play services used for location finding for SMS alerts.
compile 'com.google.android.gms:play-services-location:10.0.0'
} }
repositories { repositories {

View File

@@ -13,15 +13,16 @@
<uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-feature <uses-feature
android:name="android.hardware.telephony" android:name="android.hardware.telephony"
android:required="false" /> android:required="false" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application <application
android:icon="@drawable/star_of_life_48x48" android:icon="@drawable/star_of_life_48x48"

View File

@@ -0,0 +1,99 @@
package uk.org.openseizuredetector;
/**
*/
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
interface SdLocationReceiver {
public void onSdLocationReceived(Location ll);
}
public class LocationFinder implements LocationListener
{
SdLocationReceiver mSdLocationReceiver = null;
Location mLastLocation = null;
OsdUtil mUtil;
Handler mHandler;
Context mContext;
Timer mTimeoutTimer = null;
LocationManager mLocationManager = null;
LocationListener mLocationListener;
int mTimeoutPeriod = 30; // Location search timeout period in seconds.
String TAG="LocationFinder";
LocationFinder(Context context) {
mHandler = new Handler();
mUtil = new OsdUtil(context, mHandler);
mContext = context;
mLocationListener = this;
}
public Location getLastLocation() {
return mLastLocation;
}
public void getLocation(SdLocationReceiver sdLocationReceiver) {
mSdLocationReceiver = sdLocationReceiver;
// Acquire a reference to the system Location Manager
mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
// Register with the Location Manager to receive location updates using both network and GPS
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
mTimeoutTimer = new Timer();
mTimeoutTimer.schedule(new TimerTask() {
@Override
public void run() {
Log.v(TAG,"mTimeOutTimer expired - returning last location");
mUtil.showToast("mTimeOutTimer expired - returning last location");
mLocationManager.removeUpdates(mLocationListener);
mSdLocationReceiver.onSdLocationReceived(mLastLocation);
}
}, mTimeoutPeriod * 1000);
}
@Override
public void onLocationChanged(Location location) {
Log.v(TAG,"onLocationChanged - "+location.toString());
// if we do not have a last location, this is the best we have!
if (mLastLocation == null) {
mLastLocation = location;
}
// if this is more accurate than mLastLocation, store it.
if (location.getAccuracy() < mLastLocation.getAccuracy()) {
mLastLocation = location;
}
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
}

View File

@@ -26,6 +26,8 @@
package uk.org.openseizuredetector; package uk.org.openseizuredetector;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Map; import java.util.Map;
import fi.iki.elonen.NanoHTTPD; import fi.iki.elonen.NanoHTTPD;
@@ -41,6 +43,7 @@ import android.content.Intent;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.location.Location;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.ToneGenerator; import android.media.ToneGenerator;
import android.os.CountDownTimer; import android.os.CountDownTimer;
@@ -55,6 +58,7 @@ import android.os.PowerManager.WakeLock;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v7.app.NotificationCompat; import android.support.v7.app.NotificationCompat;
import android.telephony.SmsManager; import android.telephony.SmsManager;
import android.location.Location;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
@@ -76,7 +80,7 @@ import org.json.JSONArray;
* and * and
* http://developer.android.com/guide/components/services.html#ExtendingService * http://developer.android.com/guide/components/services.html#ExtendingService
*/ */
public class SdServer extends Service implements SdDataReceiver { public class SdServer extends Service implements SdDataReceiver, SdLocationReceiver {
// Notification ID // Notification ID
private int NOTIFICATION_ID = 1; private int NOTIFICATION_ID = 1;
@@ -94,6 +98,7 @@ public class SdServer extends Service implements SdDataReceiver {
private HandlerThread thread; private HandlerThread thread;
private WakeLock mWakeLock = null; private WakeLock mWakeLock = null;
private LocationFinder mLocationFinder;
public SdDataSource mSdDataSource; public SdDataSource mSdDataSource;
public SdData mSdData = null; public SdData mSdData = null;
public String mSdDataSourceName = "undefined"; // The name of the data soruce specified in the preferences. public String mSdDataSourceName = "undefined"; // The name of the data soruce specified in the preferences.
@@ -204,6 +209,11 @@ public class SdServer extends Service implements SdDataReceiver {
mUtil.showToast("Datasource " + mSdDataSourceName + " not recognised - Exiting"); mUtil.showToast("Datasource " + mSdDataSourceName + " not recognised - Exiting");
return 1; return 1;
} }
if (mSMSAlarm) {
Log.v(TAG, "Creating LocationFinder");
mLocationFinder = new LocationFinder(getApplicationContext());
}
mUtil.writeToSysLogFile("SdServer.onStartCommand() - starting SdDataSource"); mUtil.writeToSysLogFile("SdServer.onStartCommand() - starting SdDataSource");
mSdDataSource.start(); mSdDataSource.start();
@@ -572,9 +582,20 @@ public class SdServer extends Service implements SdDataReceiver {
/** /**
* Sends SMS Alarms to the telephone numbers specified in mSMSNumbers[] * Sends SMS Alarms to the telephone numbers specified in mSMSNumbers[]
* Attempts to find a better location, and sends a second SMS after location search
* complete (onLocationReceived()).
*/ */
public void sendSMSAlarm() { public void sendSMSAlarm() {
if (mSMSAlarm) { if (mSMSAlarm) {
mLocationFinder.getLocation(this);
Location loc = mLocationFinder.getLastLocation();
if (loc!=null) {
mUtil.showToast("Send SMS - last location is "
+ loc.getLongitude() + ","
+ loc.getLatitude());
} else {
mUtil.showToast("ERROR - Last Location is Null");
}
Log.v(TAG, "sendSMSAlarm() - Sending to " + mSMSNumbers.length + " Numbers"); Log.v(TAG, "sendSMSAlarm() - Sending to " + mSMSNumbers.length + " Numbers");
mUtil.writeToSysLogFile("SdServer.sendSMSAlarm()"); mUtil.writeToSysLogFile("SdServer.sendSMSAlarm()");
Time tnow = new Time(Time.getCurrentTimezone()); Time tnow = new Time(Time.getCurrentTimezone());
@@ -594,6 +615,47 @@ public class SdServer extends Service implements SdDataReceiver {
} }
} }
/**
* onSdLocationReceived - called with the best estimate location after mLocationReceiver times out.
* @param ll - location (may be null if no location found)
*/
@Override
public void onSdLocationReceived(Location ll) {
if (ll == null) {
mUtil.showToast("onSdLocationReceived() - NULL LOCATION RECEIVED");
Log.v(TAG, "onSdLocationReceived() - NULL LOCATION RECEIVED");
} else {
mUtil.showToast("onSdLocationReceived() - found location" + ll.toString());
Log.v(TAG, "onSdLocationReceived() - found location" + ll.toString());
if (mSMSAlarm) {
Log.v(TAG, "onSdLocationReceived() - Sending to " + mSMSNumbers.length + " Numbers");
mUtil.writeToSysLogFile("SdServer.sendSMSAlarm()");
Time tnow = new Time(Time.getCurrentTimezone());
tnow.setToNow();
String dateStr = tnow.format("%Y-%m-%d %H-%M-%S");
NumberFormat df = new DecimalFormat("#0.000");
String geoUri = "<a href='geo:"
+df.format(ll.getLatitude())+","+df.format(ll.getLongitude())
+";u="+df.format(ll.getAccuracy())+"'>here</a>";
SmsManager sm = SmsManager.getDefault();
for (int i = 0; i < mSMSNumbers.length; i++) {
Log.v(TAG, "sendSMSAlarm() - Sending to " + mSMSNumbers[i]);
sm.sendTextMessage(mSMSNumbers[i], null,
mSMSMsgStr + " - " +
dateStr + " - "+ geoUri,
null, null);
}
} else {
Log.v(TAG, "sendSMSAlarm() - SMS Alarms Disabled - not doing anything!");
Toast toast = Toast.makeText(getApplicationContext(),
"SMS Alarms Disabled - not doing anything!",
Toast.LENGTH_SHORT);
toast.show();
}
}
}
/** /**
* set the alarm standing flags to false to allow alarm phase to reset to current value. * set the alarm standing flags to false to allow alarm phase to reset to current value.

View File

@@ -4,7 +4,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.1.2' classpath 'com.android.tools.build:gradle:2.2.2'
} }
} }
allprojects { allprojects {

View File

@@ -1,6 +1,6 @@
#Fri Apr 08 20:56:19 BST 2016 #Mon Sep 19 21:50:42 BST 2016
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip