more SMS commands

This commit is contained in:
Milos Kozak 2016-09-16 14:08:26 +02:00
parent 84efccb392
commit 4378c9af14
8 changed files with 141 additions and 37 deletions

View file

@ -37,7 +37,7 @@
<ConfirmationsSetting value="0" id="Add" /> <ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" /> <ConfirmationsSetting value="0" id="Remove" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View file

@ -39,6 +39,8 @@ public class SmsCommunicatorPlugin implements PluginBase {
private static boolean fragmentEnabled = false; private static boolean fragmentEnabled = false;
private static boolean fragmentVisible = true; private static boolean fragmentVisible = true;
final long CONFIRM_TIMEOUT = 5 * 60 * 1000L;
public class Sms { public class Sms {
String phoneNumber; String phoneNumber;
String text; String text;
@ -49,6 +51,7 @@ public class SmsCommunicatorPlugin implements PluginBase {
String confirmCode; String confirmCode;
double bolusRequested = 0d; double bolusRequested = 0d;
double tempBasal = 0d;
public Sms(SmsMessage message) { public Sms(SmsMessage message) {
phoneNumber = message.getOriginatingAddress(); phoneNumber = message.getOriginatingAddress();
@ -69,6 +72,8 @@ public class SmsCommunicatorPlugin implements PluginBase {
} }
} }
Sms cancelTempBasalWaitingForConfirmation = null;
Sms tempBasalWaitingForConfirmation = null;
Sms bolusWaitingForConfirmation = null; Sms bolusWaitingForConfirmation = null;
Date lastRemoteBolusTime = new Date(0); Date lastRemoteBolusTime = new Date(0);
@ -148,8 +153,10 @@ public class SmsCommunicatorPlugin implements PluginBase {
log.debug(receivedSms.toString()); log.debug(receivedSms.toString());
String[] splited = receivedSms.text.split("\\s+"); String[] splited = receivedSms.text.split("\\s+");
double amount = 0d; Double amount = 0d;
Double tempBasal = 0d;
String passCode = ""; String passCode = "";
Sms newSms = null;
if (splited.length > 0) { if (splited.length > 0) {
switch (splited[0].toUpperCase()) { switch (splited[0].toUpperCase()) {
@ -213,66 +220,147 @@ public class SmsCommunicatorPlugin implements PluginBase {
reply = danaRPlugin.shortStatus(); reply = danaRPlugin.shortStatus();
receivedSms.processed = true; receivedSms.processed = true;
break; break;
case "BASAL":
if (splited.length > 1) {
boolean remoteCommandsAllowed = sharedPreferences.getBoolean("smscommunicator_remotecommandsallowed", false);
if (splited[1].toUpperCase().equals("CANCEL") || splited[1].toUpperCase().equals("STOP")) {
if (remoteCommandsAllowed) {
passCode = generatePasscode();
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_basalstopreplywithcode), passCode);
receivedSms.processed = true;
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
newSms.confirmCode = passCode;
resetWaitingMessages();
cancelTempBasalWaitingForConfirmation = newSms;
} else {
reply = MainApp.sResources.getString(R.string.remotebasalnotallowed);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
}
} else {
tempBasal = SafeParse.stringToDouble(splited[1]);
tempBasal = MainApp.getConfigBuilder().applyBasalConstraints(tempBasal);
if (remoteCommandsAllowed) {
passCode = generatePasscode();
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_basalreplywithcode), tempBasal, passCode);
receivedSms.processed = true;
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
newSms.tempBasal = tempBasal;
newSms.confirmCode = passCode;
resetWaitingMessages();
tempBasalWaitingForConfirmation = newSms;
} else {
reply = MainApp.sResources.getString(R.string.remotebasalnotallowed);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
}
}
}
break;
case "BOLUS": case "BOLUS":
if (new Date().getTime() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) { if (new Date().getTime() - lastRemoteBolusTime.getTime() < Constants.remoteBolusMinDistance) {
reply = MainApp.sResources.getString(R.string.remotebolusnotallowed); reply = MainApp.sResources.getString(R.string.remotebolusnotallowed);
} else if (splited.length > 1) { } else if (splited.length > 1) {
amount = SafeParse.stringToDouble(splited[1]); amount = SafeParse.stringToDouble(splited[1]);
amount = MainApp.getConfigBuilder().applyBolusConstraints(amount); amount = MainApp.getConfigBuilder().applyBolusConstraints(amount);
boolean remoteBolusingAllowed = sharedPreferences.getBoolean("smscommunicator_remotebolusingallowed", false); boolean remoteCommandsAllowed = sharedPreferences.getBoolean("smscommunicator_remotecommandsallowed", false);
if (amount > 0d && remoteBolusingAllowed) { if (amount > 0d && remoteCommandsAllowed) {
int startChar1 = 'A'; // on iphone 1st char is uppercase :) passCode = generatePasscode();
passCode = Character.toString((char) (startChar1 + Math.random() * ('z' - 'a' + 1))); reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_bolusreplywithcode), amount, passCode);
int startChar2 = Math.random() > 0.5 ? 'a' : 'A';
passCode += Character.toString((char) (startChar2 + Math.random() * ('z' - 'a' + 1)));
int startChar3 = Math.random() > 0.5 ? 'a' : 'A';
passCode += Character.toString((char) (startChar3 + Math.random() * ('z' - 'a' + 1)));
reply = String.format(MainApp.sResources.getString(R.string.replywithcode), amount, passCode);
receivedSms.processed = true; receivedSms.processed = true;
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
newSms.bolusRequested = amount;
newSms.confirmCode = passCode;
resetWaitingMessages();
bolusWaitingForConfirmation = newSms;
} else { } else {
reply = MainApp.sResources.getString(R.string.remotebolusnotallowed); reply = MainApp.sResources.getString(R.string.remotebolusnotallowed);
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
} }
} }
break; break;
default: // expect passCode here default: // expect passCode here
if (bolusWaitingForConfirmation != null && !bolusWaitingForConfirmation.processed && if (bolusWaitingForConfirmation != null && !bolusWaitingForConfirmation.processed &&
bolusWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - bolusWaitingForConfirmation.date.getTime() < 5 * 60 * 1000L) { bolusWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - bolusWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) {
bolusWaitingForConfirmation.processed = true; bolusWaitingForConfirmation.processed = true;
PumpInterface pumpInterface = MainApp.getConfigBuilder(); PumpInterface pumpInterface = MainApp.getConfigBuilder();
if (pumpInterface != null) { if (pumpInterface != null) {
danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class); danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class);
PumpEnactResult result = pumpInterface.deliverTreatment(bolusWaitingForConfirmation.bolusRequested, 0, null); PumpEnactResult result = pumpInterface.deliverTreatment(bolusWaitingForConfirmation.bolusRequested, 0, null);
if (result.success) { if (result.success) {
reply = String.format(MainApp.sResources.getString(R.string.bolusdelivered), bolusWaitingForConfirmation.bolusRequested); reply = String.format(MainApp.sResources.getString(R.string.bolusdelivered), result.bolusDelivered);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
lastRemoteBolusTime = new Date(); lastRemoteBolusTime = new Date();
} else { } else {
reply = MainApp.sResources.getString(R.string.bolusfailed); reply = MainApp.sResources.getString(R.string.bolusfailed);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus(); if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
} }
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
} }
} else if (tempBasalWaitingForConfirmation != null && !tempBasalWaitingForConfirmation.processed &&
tempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - tempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) {
tempBasalWaitingForConfirmation.processed = true;
PumpInterface pumpInterface = MainApp.getConfigBuilder();
if (pumpInterface != null) {
danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class);
PumpEnactResult result = pumpInterface.setTempBasalAbsolute(tempBasalWaitingForConfirmation.tempBasal, 30);
if (result.success) {
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalset), result.absolute, result.duration);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
} else {
reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalfailed);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
} }
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
}
} else if (cancelTempBasalWaitingForConfirmation != null && !cancelTempBasalWaitingForConfirmation.processed &&
cancelTempBasalWaitingForConfirmation.confirmCode.equals(splited[0]) && new Date().getTime() - cancelTempBasalWaitingForConfirmation.date.getTime() < CONFIRM_TIMEOUT) {
cancelTempBasalWaitingForConfirmation.processed = true;
PumpInterface pumpInterface = MainApp.getConfigBuilder();
if (pumpInterface != null) {
danaRPlugin = (DanaRPlugin) MainApp.getSpecificPlugin(DanaRPlugin.class);
PumpEnactResult result = pumpInterface.cancelTempBasal();
if (result.success) {
reply = String.format(MainApp.sResources.getString(R.string.smscommunicator_tempbasalcanceled));
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
} else {
reply = MainApp.sResources.getString(R.string.smscommunicator_tempbasalcancelfailed);
if (danaRPlugin != null) reply += "\n" + danaRPlugin.shortStatus();
}
newSms = new Sms(receivedSms.phoneNumber, reply, new Date());
}
} else {
newSms = new Sms(receivedSms.phoneNumber, MainApp.sResources.getString(R.string.smscommunicator_unknowncommand), new Date());
}
resetWaitingMessages();
break; break;
} }
} }
if (!reply.equals("")) { if (newSms != null) {
SmsManager smsManager = SmsManager.getDefault(); SmsManager smsManager = SmsManager.getDefault();
Sms newSms = new Sms(receivedSms.phoneNumber, reply, new Date()); newSms.text = stripAccents(newSms.text);
if (amount > 0d) { if (newSms.text.length() > 140) newSms.text = newSms.text.substring(0, 139);
newSms.bolusRequested = amount; smsManager.sendTextMessage(newSms.phoneNumber, null, newSms.text, null, null);
newSms.confirmCode = passCode;
bolusWaitingForConfirmation = newSms;
} else {
bolusWaitingForConfirmation = null;
newSms.processed = true;
}
smsManager.sendTextMessage(newSms.phoneNumber, null, stripAccents(newSms.text), null, null);
messages.add(newSms); messages.add(newSms);
} }
MainApp.bus().post(new EventSmsCommunicatorUpdateGui()); MainApp.bus().post(new EventSmsCommunicatorUpdateGui());
} }
private String generatePasscode() {
int startChar1 = 'A'; // on iphone 1st char is uppercase :)
String passCode = Character.toString((char) (startChar1 + Math.random() * ('z' - 'a' + 1)));
int startChar2 = Math.random() > 0.5 ? 'a' : 'A';
passCode += Character.toString((char) (startChar2 + Math.random() * ('z' - 'a' + 1)));
int startChar3 = Math.random() > 0.5 ? 'a' : 'A';
passCode += Character.toString((char) (startChar3 + Math.random() * ('z' - 'a' + 1)));
return passCode;
}
private void resetWaitingMessages() {
tempBasalWaitingForConfirmation = null;
cancelTempBasalWaitingForConfirmation = null;
bolusWaitingForConfirmation = null;
}
public static String stripAccents(String s) { public static String stripAccents(String s) {
s = Normalizer.normalize(s, Normalizer.Form.NFD); s = Normalizer.normalize(s, Normalizer.Form.NFD);
s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", ""); s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");

View file

@ -227,9 +227,8 @@
<string name="waitingforpumpresult">Изчаква резултат</string> <string name="waitingforpumpresult">Изчаква резултат</string>
<string name="smscommunicator">SMS комуникатор</string> <string name="smscommunicator">SMS комуникатор</string>
<string name="smscommunicator_allowednumbers">Позволени телефонни номера</string> <string name="smscommunicator_allowednumbers">Позволени телефонни номера</string>
<string name="smscommunicator_remotebolusingallowed">Разреши болус чрез SMS</string>
<string name="success">Успех</string> <string name="success">Успех</string>
<string name="replywithcode" formatted="false">За да доставите болус %.2fU отговорете с код %s</string> <string name="smscommunicator_bolusreplywithcode" formatted="false">За да доставите болус %.2fU отговорете с код %s</string>
<string name="remotebolusnotallowed">Отдалечен болус не е разрешен</string> <string name="remotebolusnotallowed">Отдалечен болус не е разрешен</string>
<string name="reloadprofile">Обнови профила</string> <string name="reloadprofile">Обнови профила</string>
<string name="percent">Процент</string> <string name="percent">Процент</string>

View file

@ -236,11 +236,11 @@
<string name="bolusdelivered" formatted="false">Bolus %.2fU aplikován úspěšně</string> <string name="bolusdelivered" formatted="false">Bolus %.2fU aplikován úspěšně</string>
<string name="bolusfailed">Chyba při aplikování bolusu</string> <string name="bolusfailed">Chyba při aplikování bolusu</string>
<string name="remotebolusnotallowed">Vzdálený bolus není momentálně povolen</string> <string name="remotebolusnotallowed">Vzdálený bolus není momentálně povolen</string>
<string name="replywithcode" formatted="false">K potvzení bolusu %.2fU odpověz SMS s kódem %s</string> <string name="smscommunicator_bolusreplywithcode" formatted="false">K potvzení bolusu %.2fU odpověz SMS s kódem %s</string>
<string name="smscommunicator">SMS komunikátor</string> <string name="smscommunicator">SMS komunikátor</string>
<string name="smscommunicator_allowednumbers">Povolená tel. čísla</string> <string name="smscommunicator_allowednumbers">Povolená tel. čísla</string>
<string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string> <string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string>
<string name="smscommunicator_remotebolusingallowed">Povolit posílání bolusu přes SMS</string> <string name="smscommunicator_remotecommandsallowed">Povolit posílání příkazů přes SMS</string>
<string name="waitingforpumpresult">Čekání na výsledek</string> <string name="waitingforpumpresult">Čekání na výsledek</string>
<string name="careportal_temporarytarget">Dočasný cíl</string> <string name="careportal_temporarytarget">Dočasný cíl</string>
<string name="careportal_temporarytargetcancel">Dočasný cíl konec</string> <string name="careportal_temporarytargetcancel">Dočasný cíl konec</string>
@ -306,4 +306,15 @@
<string name="smscommunicator_loophasbeenenabled">Smyčka byla povolena</string> <string name="smscommunicator_loophasbeenenabled">Smyčka byla povolena</string>
<string name="smscommunicator_loopisdisabled">Smyčka je zakázána</string> <string name="smscommunicator_loopisdisabled">Smyčka je zakázána</string>
<string name="smscommunicator_loopisenabled">Smyčka je povolena</string> <string name="smscommunicator_loopisenabled">Smyčka je povolena</string>
<string name="es_lang">Español</string>
<string name="noprofileselected">Není vybrán žádný profil</string>
<string name="openapsma_valueoutofrange" formatted="false">Hodnota %s je mimo přednastavený rozsah</string>
<string name="remotebasalnotallowed">Vzdálené posílání příkazů není povoleno</string>
<string name="smscommunicator_basalreplywithcode" formatted="false">Na spuštění bazálu %.2fU/h odpověz SMS s kódem %s</string>
<string name="smscommunicator_basalstopreplywithcode" formatted="false">Na ukončení bazálu odpověz SMS s kódem %s</string>
<string name="smscommunicator_tempbasalcanceled">Dočaný bazál zastaven</string>
<string name="smscommunicator_tempbasalcancelfailed">Rušení dočasného bazálu selhalo</string>
<string name="smscommunicator_tempbasalfailed">Spuštění dočasného bazálu selhalo</string>
<string name="smscommunicator_tempbasalset" formatted="false">Dočasný bazál %.2fU/h na %d minut spuštěn</string>
<string name="smscommunicator_unknowncommand">Neznámý příkaz nebo chybná odpověď</string>
</resources> </resources>

View file

@ -246,10 +246,9 @@
<string name="hoursago">vor h </string> <string name="hoursago">vor h </string>
<string name="smscommunicator">SMS Kommunikator</string> <string name="smscommunicator">SMS Kommunikator</string>
<string name="smscommunicator_allowednumbers">erlaubte TElefonnummern</string> <string name="smscommunicator_allowednumbers">erlaubte TElefonnummern</string>
<string name="smscommunicator_remotebolusingallowed">Fernboli via SMS zulassen</string>
<string name="syncprofiletopump_title">Nightscout Profil zur Pumpe synchronisieren</string> <string name="syncprofiletopump_title">Nightscout Profil zur Pumpe synchronisieren</string>
<string name="waitingforpumpresult">auf Pumpenergebnis warten</string> <string name="waitingforpumpresult">auf Pumpenergebnis warten</string>
<string name="nobtadapter">Kein Bluetoothadapter gefunden</string> <string name="nobtadapter">Kein Bluetoothadapter gefunden</string>
<string name="remotebolusnotallowed">Remote Bolus nicht erlaubt</string> <string name="remotebolusnotallowed">Remote Bolus nicht erlaubt</string>
<string formatted="false" name="replywithcode">Um Bolus %.2fU bitte mit %s antworten</string> <string formatted="false" name="smscommunicator_bolusreplywithcode">Um Bolus %.2fU bitte mit %s antworten</string>
</resources> </resources>

View file

@ -240,11 +240,10 @@
<string name="waitingforpumpresult">Esperando resultado</string> <string name="waitingforpumpresult">Esperando resultado</string>
<string name="smscommunicator_allowednumbers">Números de teléfono permitidos</string> <string name="smscommunicator_allowednumbers">Números de teléfono permitidos</string>
<string name="smscommunicator_allowednumbers_summary">XXXXXXXXXX +; + YYYYYYYYYY</string> <string name="smscommunicator_allowednumbers_summary">XXXXXXXXXX +; + YYYYYYYYYY</string>
<string formatted="false" name="replywithcode">Para entregar bolo% .2fU responder con código% s</string> <string formatted="false" name="smscommunicator_bolusreplywithcode">Para entregar bolo% .2fU responder con código% s</string>
<string name="bolusfailed">bolo falló</string> <string name="bolusfailed">bolo falló</string>
<string formatted="false" name="bolusdelivered">Bolo% .2fU entregado con éxito</string> <string formatted="false" name="bolusdelivered">Bolo% .2fU entregado con éxito</string>
<string formatted="false" name="bolusdelivering">Entregando% .2fU</string> <string formatted="false" name="bolusdelivering">Entregando% .2fU</string>
<string name="smscommunicator_remotebolusingallowed">Permitir bolos remotos por SMS</string>
<string name="remotebolusnotallowed">Bolo remoto no permitido</string> <string name="remotebolusnotallowed">Bolo remoto no permitido</string>
<string name="glucosetype_finger">Dedo</string> <string name="glucosetype_finger">Dedo</string>
<string name="glucosetype_sensor">Sensor</string> <string name="glucosetype_sensor">Sensor</string>

View file

@ -241,11 +241,11 @@
<string name="waitingforpumpresult">Waiting for result</string> <string name="waitingforpumpresult">Waiting for result</string>
<string name="smscommunicator_allowednumbers">Allowed phone numbers</string> <string name="smscommunicator_allowednumbers">Allowed phone numbers</string>
<string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string> <string name="smscommunicator_allowednumbers_summary">+XXXXXXXXXX;+YYYYYYYYYY</string>
<string name="replywithcode" formatted="false">To deliver bolus %.2fU reply with code %s</string> <string name="smscommunicator_bolusreplywithcode" formatted="false">To deliver bolus %.2fU reply with code %s</string>
<string name="bolusfailed">Bolus failed</string> <string name="bolusfailed">Bolus failed</string>
<string name="bolusdelivered" formatted="false">Bolus %.2fU delivered successfully</string> <string name="bolusdelivered" formatted="false">Bolus %.2fU delivered successfully</string>
<string name="bolusdelivering" formatted="false">Delivering %.2fU</string> <string name="bolusdelivering" formatted="false">Delivering %.2fU</string>
<string name="smscommunicator_remotebolusingallowed">Allow remote bolusing via SMS</string> <string name="smscommunicator_remotecommandsallowed">Allow remote commands via SMS</string>
<string name="remotebolusnotallowed">Remote bolus not allowed</string> <string name="remotebolusnotallowed">Remote bolus not allowed</string>
<string name="glucosetype_finger">Finger</string> <string name="glucosetype_finger">Finger</string>
<string name="glucosetype_sensor">Sensor</string> <string name="glucosetype_sensor">Sensor</string>
@ -311,5 +311,13 @@
<string name="smscommunicator_loopisdisabled">Loop is disabled</string> <string name="smscommunicator_loopisdisabled">Loop is disabled</string>
<string name="smscommunicator_loopisenabled">Loop is enabled</string> <string name="smscommunicator_loopisenabled">Loop is enabled</string>
<string name="openapsma_valueoutofrange" formatted="false">Value %s is out of hard limits</string> <string name="openapsma_valueoutofrange" formatted="false">Value %s is out of hard limits</string>
<string name="remotebasalnotallowed">Remote basal setting is not allowed</string>
<string name="smscommunicator_basalreplywithcode" formatted="false">To start basal %.2fU/h reply with code %s</string>
<string name="smscommunicator_tempbasalset" formatted="false">Temp basal %.2fU/h for %d min started successfully</string>
<string name="smscommunicator_tempbasalfailed">Temp basal start failed</string>
<string name="smscommunicator_basalstopreplywithcode" formatted="false">To stop temp basal reply with code %s</string>
<string name="smscommunicator_tempbasalcanceled">Temp basal canceled</string>
<string name="smscommunicator_tempbasalcancelfailed">Canceling temp basal failed</string>
<string name="smscommunicator_unknowncommand">Uknonwn command or wrong reply</string>
</resources> </resources>

View file

@ -12,8 +12,8 @@
</EditTextPreference> </EditTextPreference>
<SwitchPreference <SwitchPreference
android:defaultValue="false" android:defaultValue="false"
android:key="smscommunicator_remotebolusingallowed" android:key="smscommunicator_remotecommandsallowed"
android:title="@string/smscommunicator_remotebolusingallowed" /> android:title="@string/smscommunicator_remotecommandsallowed" />
</PreferenceCategory> </PreferenceCategory>