diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt index b2ae16986a..5b2fc2da8f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt @@ -202,7 +202,8 @@ object AutomationPlugin : PluginBase(PluginDescription() ActionStopTempTarget(), ActionNotification(), ActionProfileSwitchPercent(), - ActionProfileSwitch() + ActionProfileSwitch(), + ActionSendSMS() ) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.java new file mode 100644 index 0000000000..f8afafca75 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.java @@ -0,0 +1,88 @@ +package info.nightscout.androidaps.plugins.general.automation.actions; + +import android.widget.LinearLayout; + +import com.google.common.base.Optional; + +import org.json.JSONException; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.general.automation.elements.InputString; +import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement; +import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder; +import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.utils.JsonHelper; + +public class ActionSendSMS extends Action { + + public InputString text = new InputString(); + + @Override + public int friendlyName() { + return R.string.sendsmsactiondescription; + } + + @Override + public String shortDescription() { + return MainApp.gs(R.string.sendsmsactionlabel, text.getValue()); + } + + @Override + public void doAction(Callback callback) { + boolean result = SmsCommunicatorPlugin.getPlugin().sendNotificationToAllNumbers(text.getValue()); + if (callback != null) + callback.result(new PumpEnactResult().success(result).comment(result ? R.string.ok : R.string.danar_error)).run(); + + } + + @Override + public Optional icon() { + return Optional.of(R.drawable.ic_notifications); + } + + @Override + public String toJSON() { + JSONObject o = new JSONObject(); + JSONObject data = new JSONObject(); + try { + data.put("text", text.getValue()); + o.put("type", this.getClass().getName()); + o.put("data", data); + } catch (JSONException e) { + e.printStackTrace(); + } + return o.toString(); + } + + @Override + public Action fromJSON(String data) { + try { + JSONObject o = new JSONObject(data); + text.setValue(JsonHelper.safeGetString(o, "text")); + } catch (JSONException e) { + e.printStackTrace(); + } + return this; + } + + @Override + public boolean hasDialog() { + return true; + } + + @Override + public void generateDialog(LinearLayout root) { + + new LayoutBuilder() + .add(new LabelWithElement(MainApp.gs(R.string.sendsmsactiontext), "", text)) + .build(root); + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java index 6e8b07499a..28b0abd33d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java @@ -33,11 +33,12 @@ public class Notification { public static final int OLD_NSCLIENT = 8; public static final int OLD_NS = 9; public static final int INVALID_PHONE_NUMBER = 10; - public static final int APPROACHING_DAILY_LIMIT = 11; - public static final int NSCLIENT_NO_WRITE_PERMISSION = 12; - public static final int MISSING_SMS_PERMISSION = 13; - public static final int PUMPERROR = 14; - public static final int WRONGSERIALNUMBER = 15; + public static final int INVALID_MESSAGE_BODY = 11; + public static final int APPROACHING_DAILY_LIMIT = 12; + public static final int NSCLIENT_NO_WRITE_PERMISSION = 13; + public static final int MISSING_SMS_PERMISSION = 14; + public static final int PUMPERROR = 15; + public static final int WRONGSERIALNUMBER = 16; public static final int NSANNOUNCEMENT = 18; public static final int NSALARM = 19; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 1304c00eb6..d1494e6033 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -737,11 +737,13 @@ public class SmsCommunicatorPlugin extends PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); } - public void sendNotificationToAllNumbers(String text) { + public boolean sendNotificationToAllNumbers(String text) { + boolean result = true; for (int i = 0; i < allowedNumbers.size(); i++) { Sms sms = new Sms(allowedNumbers.get(i), text); - sendSMS(sms); + result = result && sendSMS(sms); } + return result; } private void sendSMSToAllNumbers(Sms sms) { @@ -751,7 +753,7 @@ public class SmsCommunicatorPlugin extends PluginBase { } } - void sendSMS(Sms sms) { + boolean sendSMS(Sms sms) { SmsManager smsManager = SmsManager.getDefault(); sms.text = stripAccents(sms.text); @@ -768,13 +770,22 @@ public class SmsCommunicatorPlugin extends PluginBase { messages.add(sms); } catch (IllegalArgumentException e) { - Notification notification = new Notification(Notification.INVALID_PHONE_NUMBER, MainApp.gs(R.string.smscommunicator_invalidphonennumber), Notification.NORMAL); - RxBus.INSTANCE.send(new EventNewNotification(notification)); + if (e.getMessage().equals("Invalid message body")) { + Notification notification = new Notification(Notification.INVALID_MESSAGE_BODY, MainApp.gs(R.string.smscommunicator_messagebody), Notification.NORMAL); + RxBus.INSTANCE.send(new EventNewNotification(notification)); + return false; + } else { + Notification notification = new Notification(Notification.INVALID_PHONE_NUMBER, MainApp.gs(R.string.smscommunicator_invalidphonennumber), Notification.NORMAL); + RxBus.INSTANCE.send(new EventNewNotification(notification)); + return false; + } } catch (java.lang.SecurityException e) { Notification notification = new Notification(Notification.MISSING_SMS_PERMISSION, MainApp.gs(R.string.smscommunicator_missingsmspermission), Notification.NORMAL); RxBus.INSTANCE.send(new EventNewNotification(notification)); + return false; } MainApp.bus().post(new EventSmsCommunicatorUpdateGui()); + return true; } private String generatePasscode() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fc6c37ea5e..775e8728af 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1578,6 +1578,9 @@ Last connection to pump Last connection to pump [minutes ago] Last connection to pump %1$s %2$s min ago + Send SMS: %1$s + Send SMS to all numbers in preferences + Send SMS with text %2$+.2fU]]> @@ -1595,5 +1598,6 @@ Close Increasing max basal value because setting is lower than your max basal in profile + Invalid message body diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMSTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMSTest.java new file mode 100644 index 0000000000..4db3d79dc5 --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMSTest.java @@ -0,0 +1,87 @@ +package info.nightscout.androidaps.plugins.general.automation.actions; + +import android.telephony.SmsManager; + +import com.google.common.base.Optional; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import info.AAPSMocker; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.R; +import info.nightscout.androidaps.plugins.general.automation.elements.InputString; +import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.utils.SP; + +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.mockStatic; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, SP.class, SmsManager.class}) +public class ActionSendSMSTest { + private ActionSendSMS actionSendSMS; + + @Test + public void friendlyNameTest() { + Assert.assertEquals(R.string.sendsmsactiondescription, actionSendSMS.friendlyName()); + } + + @Test + public void shortDescriptionTest() { + actionSendSMS = new ActionSendSMS(); + Assert.assertEquals(null, actionSendSMS.shortDescription()); // not mocked + } + + @Test + public void iconTest() { + Assert.assertEquals(Optional.of(R.drawable.ic_notifications), actionSendSMS.icon()); + } + + @Test + public void doActionTest() { + actionSendSMS.text = new InputString().setValue("Asd"); + actionSendSMS.doAction(new Callback() { + @Override + public void run() { + Assert.assertTrue(result.success); + } + }); + } + + @Test + public void hasDialogTest() { + Assert.assertTrue(actionSendSMS.hasDialog()); + } + + @Test + public void toJSONTest() { + actionSendSMS = new ActionSendSMS(); + actionSendSMS.text = new InputString().setValue("Asd"); + Assert.assertEquals("{\"data\":{\"text\":\"Asd\"},\"type\":\"info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS\"}", actionSendSMS.toJSON()); + } + + @Test + public void fromJSONTest() { + actionSendSMS = new ActionSendSMS(); + actionSendSMS.fromJSON("{\"text\":\"Asd\"}"); + Assert.assertEquals("Asd", actionSendSMS.text.getValue()); + } + + @Before + public void prepareTest() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockBus(); + AAPSMocker.mockSP(); + mockStatic(SmsManager.class); + SmsManager smsManager = mock(SmsManager.class); + PowerMockito.when(SmsManager.getDefault()).thenReturn(smsManager); + PowerMockito.when(SP.getString(R.string.key_smscommunicator_allowednumbers, "")).thenReturn("1234;5678"); + actionSendSMS = new ActionSendSMS(); + } +}