Tweaking SMS protocol
This commit is contained in:
@@ -610,8 +610,8 @@ public abstract class SdDataSource {
|
||||
mSdData.alarmCause = "";
|
||||
|
||||
boolean flapDetected = flapCheck();
|
||||
alarmCheck(flapDetected);
|
||||
hrCheck();
|
||||
alarmCheck(flapDetected);
|
||||
o2SatCheck();
|
||||
fallCheck();
|
||||
muteCheck();
|
||||
@@ -739,7 +739,10 @@ public abstract class SdDataSource {
|
||||
mAlarmCount += mSamplePeriod;
|
||||
|
||||
if (mAlarmCount > mAlarmTime) {
|
||||
if (mRequireHrForSeizureAlarm) {
|
||||
if (mSdData.alarmState == 2) {
|
||||
// Already in full alarm. Do not require HR confirmation again.
|
||||
mSdData.alarmState = 2;
|
||||
} else if (mRequireHrForSeizureAlarm) {
|
||||
if (hasRecentHrConfirmation()) {
|
||||
mSdData.alarmState = 2;
|
||||
mSdData.alarmCause = mSdData.alarmCause + "HR_CONFIRM ";
|
||||
@@ -753,9 +756,6 @@ public abstract class SdDataSource {
|
||||
// Existing behavior
|
||||
mSdData.alarmState = 2;
|
||||
}
|
||||
} else if (mAlarmCount > mWarnTime) {
|
||||
// warning
|
||||
mSdData.alarmState = 1;
|
||||
}
|
||||
} else {
|
||||
// If we are not in an ALARM state, revert back to WARNING, otherwise
|
||||
|
||||
@@ -125,8 +125,19 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
private boolean mMp3Alarm = false;
|
||||
private boolean mPhoneAlarm = false;
|
||||
private boolean mSMSAlarm = false;
|
||||
private boolean mFlogaEmergencyEscalation = true;
|
||||
// Emergency-services escalation SMS.
|
||||
// This is separate from the normal carer/contact SMS.
|
||||
private boolean mEmergencySmsEnabled = false;
|
||||
private boolean mEmergencySmsNotifyContacts = true;
|
||||
private String mEmergencySmsNumber = "";
|
||||
private String mEmergencySmsMessage =
|
||||
"Possible seizure emergency. The wearer may be having a tonic-clonic seizure and the alarm has remained active."; private int mEmergencySmsDelaySecs = 300;
|
||||
private EmergencySmsTimer mEmergencySmsTimer = null;
|
||||
private boolean mEmergencySmsSent = false;
|
||||
|
||||
private long mAlarmStartTime = 0;
|
||||
private String mLastLocationUrl = "";
|
||||
private String mLastAlarmDateStr = "";
|
||||
private String[] mSMSNumbers;
|
||||
private String mSMSMsgStr = "default SMS Message";
|
||||
private String mSMSFalseAlarmMsgStr = "default SMS False Alarm Message";
|
||||
@@ -657,7 +668,16 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
if ((sdData.alarmState == 2) || (sdData.alarmState == 5)) {
|
||||
sdData.alarmPhrase = "ALARM";
|
||||
sdData.alarmStanding = true;
|
||||
if (mAlarmStartTime == 0) mAlarmStartTime = System.currentTimeMillis();
|
||||
|
||||
if (mAlarmStartTime == 0) {
|
||||
mAlarmStartTime = System.currentTimeMillis();
|
||||
|
||||
Time tnow = new Time(Time.getCurrentTimezone());
|
||||
tnow.setToNow();
|
||||
mLastAlarmDateStr = tnow.format("%H:%M:%S %d/%m/%Y");
|
||||
|
||||
startEmergencySmsTimer();
|
||||
}
|
||||
if (mLogAlarms) {
|
||||
Log.v(TAG, "***ALARM*** - Logging to SD Card");
|
||||
//writeAlarmToSD();
|
||||
@@ -678,12 +698,6 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
- mSMSTime.toMillis(false))
|
||||
> 60000) {
|
||||
sendSMSAlarm();
|
||||
// Floga: escalate to emergency call if seizure longer than 5 minutes
|
||||
long alarmDurationSecs = (System.currentTimeMillis() - mAlarmStartTime) / 1000;
|
||||
if (alarmDurationSecs >= 300 && mFlogaEmergencyEscalation) {
|
||||
sendPhoneAlarm();
|
||||
Log.v(TAG, "Floga: 5 minute threshold reached - calling emergency contacts");
|
||||
}
|
||||
mSMSTime = tnow;
|
||||
} else {
|
||||
mUtil.showToast(getString(R.string.SMSAlarmAlreadySentMsg));
|
||||
@@ -1067,6 +1081,46 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private void startEmergencySmsTimer() {
|
||||
if (!mEmergencySmsEnabled) {
|
||||
Log.v(TAG, "startEmergencySmsTimer() - emergency SMS disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEmergencySmsSent) {
|
||||
Log.v(TAG, "startEmergencySmsTimer() - emergency SMS already sent");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEmergencySmsTimer != null) {
|
||||
Log.v(TAG, "startEmergencySmsTimer() - timer already running");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEmergencySmsNumber == null || mEmergencySmsNumber.trim().length() == 0) {
|
||||
Log.w(TAG, "startEmergencySmsTimer() - no emergency SMS number set");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i(TAG, "startEmergencySmsTimer() - starting emergency SMS timer for "
|
||||
+ mEmergencySmsDelaySecs + " seconds");
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
mEmergencySmsTimer =
|
||||
new EmergencySmsTimer(mEmergencySmsDelaySecs * 1000L, 1000);
|
||||
mEmergencySmsTimer.start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void stopEmergencySmsTimer() {
|
||||
if (mEmergencySmsTimer != null) {
|
||||
Log.i(TAG, "stopEmergencySmsTimer() - cancelling emergency SMS timer");
|
||||
mEmergencySmsTimer.cancel();
|
||||
mEmergencySmsTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Start the timer that will automatically re-set a latched alarm after a given period.
|
||||
@@ -1111,6 +1165,12 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
Log.i(TAG, "acceptAlarm()");
|
||||
mSdData.alarmStanding = false;
|
||||
mSdData.fallAlarmStanding = false;
|
||||
mAlarmStartTime = 0;
|
||||
mLastAlarmDateStr = "";
|
||||
mEmergencySmsSent = false;
|
||||
|
||||
stopEmergencySmsTimer();
|
||||
|
||||
mSdDataSource.acceptAlarm();
|
||||
stopLatchTimer();
|
||||
}
|
||||
@@ -1315,7 +1375,24 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
mSMSAlarm = SP.getBoolean("SMSAlarm", false);
|
||||
Log.v(TAG, "updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
||||
mUtil.writeToSysLogFile("updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
||||
mFlogaEmergencyEscalation = SP.getBoolean("FlogaEmergencyEscalation", true);
|
||||
mEmergencySmsEnabled = SP.getBoolean("EmergencySmsEnabled", false);
|
||||
mEmergencySmsNotifyContacts = SP.getBoolean("EmergencySmsNotifyContacts", true);
|
||||
mEmergencySmsNumber = SP.getString("EmergencySmsNumber", "");
|
||||
mEmergencySmsMessage = SP.getString(
|
||||
"EmergencySmsMessage",
|
||||
"Possible seizure emergency. The wearer may be having a tonic-clonic seizure and the alarm has remained active."
|
||||
);
|
||||
|
||||
try {
|
||||
String emergencyDelayStr = SP.getString("EmergencySmsDelaySecs", "300");
|
||||
mEmergencySmsDelaySecs = Integer.parseInt(emergencyDelayStr);
|
||||
} catch (Exception ex) {
|
||||
mEmergencySmsDelaySecs = 300;
|
||||
}
|
||||
|
||||
Log.v(TAG, "updatePrefs() - mEmergencySmsEnabled = " + mEmergencySmsEnabled);
|
||||
Log.v(TAG, "updatePrefs() - mEmergencySmsNumber = " + mEmergencySmsNumber);
|
||||
Log.v(TAG, "updatePrefs() - mEmergencySmsDelaySecs = " + mEmergencySmsDelaySecs);
|
||||
mPhoneAlarm = SP.getBoolean("PhoneCallAlarm", false);
|
||||
Log.v(TAG, "updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
||||
mUtil.writeToSysLogFile("updatePrefs() - mSMSAlarm = " + mSMSAlarm);
|
||||
@@ -1509,6 +1586,7 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
+ ";u=" + df.format(ll.getAccuracy()) + "'>here</a>";
|
||||
String googleUrl = "https://www.google.com/maps/place?q="
|
||||
+ ll.getLatitude() + "%2C" + ll.getLongitude();
|
||||
mLastLocationUrl = googleUrl;
|
||||
String shortUuidStr = mUuidStr.substring(mUuidStr.length() - 6);
|
||||
|
||||
String messageStr = "Location update for seizure detected at "
|
||||
@@ -1532,7 +1610,69 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
|
||||
|
||||
}
|
||||
private void sendSMSDirect(String phoneNo, String msgStr) {
|
||||
String number = phoneNo == null ? "" : phoneNo.trim();
|
||||
|
||||
if (number.length() == 0) {
|
||||
Log.w(TAG, "sendSMSDirect() - empty phone number, skipping");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i(TAG, "sendSMSDirect() - Sending to " + number);
|
||||
|
||||
try {
|
||||
SmsManager sm = SmsManager.getDefault();
|
||||
sm.sendTextMessage(number, null, msgStr, null, null);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "sendSMSDirect - Failed to send SMS Message");
|
||||
mUtil.writeToSysLogFile("sendSMSDirect - Failed to send SMS Message");
|
||||
Log.e(TAG, e.toString());
|
||||
mUtil.showToast(getString(R.string.failed_to_send_sms));
|
||||
}
|
||||
}
|
||||
private void sendEmergencySms() {
|
||||
String shortUuidStr = mUuidStr.substring(mUuidStr.length() - 6);
|
||||
|
||||
String locationPart;
|
||||
if (mLastLocationUrl != null && mLastLocationUrl.length() > 0) {
|
||||
locationPart = " Location: " + mLastLocationUrl;
|
||||
} else {
|
||||
locationPart = " Location unavailable.";
|
||||
}
|
||||
|
||||
String alarmTimePart;
|
||||
if (mLastAlarmDateStr != null && mLastAlarmDateStr.length() > 0) {
|
||||
alarmTimePart = " Alarm time: " + mLastAlarmDateStr + ".";
|
||||
} else {
|
||||
alarmTimePart = "";
|
||||
}
|
||||
|
||||
String emergencyMessage = mEmergencySmsMessage
|
||||
+ alarmTimePart
|
||||
+ " Alarm duration: "
|
||||
+ mEmergencySmsDelaySecs
|
||||
+ " seconds."
|
||||
+ locationPart
|
||||
+ " Device ID: "
|
||||
+ shortUuidStr;
|
||||
|
||||
Log.i(TAG, "sendEmergencySms() - sending emergency SMS to " + mEmergencySmsNumber);
|
||||
Log.i(TAG, "sendEmergencySms() - message: " + emergencyMessage);
|
||||
|
||||
sendSMSDirect(mEmergencySmsNumber, emergencyMessage);
|
||||
|
||||
if (mEmergencySmsNotifyContacts) {
|
||||
String contactMessage = "Emergency services have been contacted for seizure alert"
|
||||
+ alarmTimePart
|
||||
+ locationPart
|
||||
+ " Device: "
|
||||
+ shortUuidStr;
|
||||
|
||||
for (int i = 0; i < mSMSNumbers.length; i++) {
|
||||
sendSMSDirect(mSMSNumbers[i], contactMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Latch alarm in alarm state for a given period (mLatchAlarmPeriod seconds) after the alarm is raised.
|
||||
@@ -1619,7 +1759,37 @@ public class SdServer extends Service implements SdDataReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private class EmergencySmsTimer extends CountDownTimer {
|
||||
public EmergencySmsTimer(long startTime, long interval) {
|
||||
super(startTime, interval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
Log.i(TAG, "EmergencySmsTimer.onFinish()");
|
||||
|
||||
mEmergencySmsTimer = null;
|
||||
|
||||
if (mEmergencySmsSent) {
|
||||
Log.i(TAG, "EmergencySmsTimer.onFinish() - already sent");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSdData == null || !mSdData.alarmStanding) {
|
||||
Log.i(TAG, "EmergencySmsTimer.onFinish() - alarm no longer standing, not sending");
|
||||
return;
|
||||
}
|
||||
|
||||
sendEmergencySms();
|
||||
mEmergencySmsSent = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(long msRemaining) {
|
||||
Log.v(TAG, "EmergencySmsTimer.onTick() - time remaining = "
|
||||
+ msRemaining / 1000 + " sec");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Inhibit fault alarm initiation for a period to avoid spurious warning
|
||||
* beeps caused by short term network interruptions.
|
||||
|
||||
@@ -87,6 +87,41 @@
|
||||
android:summary="@string/sms_false_alarm_message_summary"
|
||||
android:title="@string/sms_false_alarm_message_title" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="Emergency Services SMS Settings">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="EmergencySmsEnabled"
|
||||
android:summary="Send a separate SMS to the emergency services test number if the seizure alarm remains active for the configured delay."
|
||||
android:title="Enable emergency services SMS" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue=""
|
||||
android:key="EmergencySmsNumber"
|
||||
android:summary="Test number for emergency services escalation. Use a project/test number, not a real emergency number."
|
||||
android:title="Emergency services test number" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="300"
|
||||
android:key="EmergencySmsDelaySecs"
|
||||
android:inputType="number"
|
||||
android:summary="Delay before emergency services SMS is sent. Use 300 for 5 minutes; use a shorter value for testing."
|
||||
android:title="Emergency SMS delay seconds" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="Possible seizure emergency. The wearer may be having a tonic-clonic seizure and the alarm has remained active."
|
||||
android:key="EmergencySmsMessage"
|
||||
android:summary="Message prefix for the emergency services SMS."
|
||||
android:title="Emergency services SMS message" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="EmergencySmsNotifyContacts"
|
||||
android:summary="Also send a follow-up SMS to normal contacts when the emergency services SMS is sent."
|
||||
android:title="Notify contacts after emergency SMS" />
|
||||
|
||||
</PreferenceCategory>
|
||||
<!--
|
||||
<PreferenceCategory android:title="Phone Call Alarm Settings">
|
||||
<CheckBoxPreference
|
||||
|
||||
Reference in New Issue
Block a user