diff --git a/res/values/strings.xml b/res/values/strings.xml --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2,7 +2,7 @@ Telephony notifier - Send notifications for SMS and calls + Send notifications for incoming calls Battery report Periodically report battery status Filesystem expose diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java --- a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java +++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/AppDatabase.java @@ -33,7 +33,6 @@ static final private HashSet disabledByDefault = new HashSet<>(); static { - disabledByDefault.add("com.android.messaging"); //We already have sms notifications in the telephony plugin disabledByDefault.add("com.google.android.googlequicksearchbox"); //Google Now notifications re-spawn every few minutes } diff --git a/src/org/kde/kdeconnect/Plugins/SMSPlugin/SMSPlugin.java b/src/org/kde/kdeconnect/Plugins/SMSPlugin/SMSPlugin.java --- a/src/org/kde/kdeconnect/Plugins/SMSPlugin/SMSPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/SMSPlugin/SMSPlugin.java @@ -54,8 +54,6 @@ public class SMSPlugin extends Plugin { - private final static String PACKET_TYPE_SMS_REQUEST = "kdeconnect.sms.request"; - /** * Packet used to indicate a batch of messages has been pushed from the remote device * @@ -74,23 +72,37 @@ * ... * ] */ - private final static String PACKET_TYPE_TELEPHONY_MESSAGE = "kdeconnect.telephony.message"; + private final static String PACKET_TYPE_SMS_MESSAGE = "kdeconnect.sms.messages"; + + /** + * Packet sent to request a message be sent + * + * This will almost certainly need to be replaced or augmented to support MMS, + * but be sure the Android side remains compatible with old desktop apps! + * + * The body should look like so: + * { "sendSms": true, + * "phoneNumber": "542904563213", + * "messageBody": "Hi mom!" + * } + */ + private final static String PACKET_TYPE_SMS_REQUEST = "kdeconnect.sms.request"; /** - * Packet sent to request all conversations + * Packet sent to request the most-recent message in each conversations on the device * * The request packet shall contain no body */ - public final static String PACKET_TYPE_TELEPHONY_REQUEST_CONVERSATIONS = "kdeconnect.telephony.request_conversations"; + private final static String PACKET_TYPE_SMS_REQUEST_CONVERSATIONS = "kdeconnect.sms.request_conversations"; /** * Packet sent to request all the messages in a particular conversation * * The body should contain the key "threadID" mapping to the threadID (as a string) being requested * For example: * { "threadID": 203 } */ - public final static String PACKET_TYPE_TELEPHONY_REQUEST_CONVERSATION = "kdeconnect.telephony.request_conversation"; + private final static String PACKET_TYPE_SMS_REQUEST_CONVERSATION = "kdeconnect.sms.request_conversation"; private static final String KEY_PREF_BLOCKED_NUMBERS = "telephony_blocked_numbers"; @@ -193,44 +205,49 @@ @Override public boolean onPacketReceived(NetworkPacket np) { - if (np.getType().equals(PACKET_TYPE_TELEPHONY_REQUEST_CONVERSATIONS)) { - return this.handleRequestConversations(np); - } else if (np.getType().equals(PACKET_TYPE_TELEPHONY_REQUEST_CONVERSATION)) { - return this.handleRequestConversation(np); - } - - if (np.getBoolean("sendSms")) { - String phoneNo = np.getString("phoneNumber"); - String sms = np.getString("messageBody"); - - try { - SmsManager smsManager = SmsManager.getDefault(); - ArrayList parts = smsManager.divideMessage(sms); - - // If this message turns out to fit in a single SMS, sendMultipartTextMessage - // properly handles that case - smsManager.sendMultipartTextMessage(phoneNo, null, parts, null, null); - - //TODO: Notify other end - } catch (Exception e) { - //TODO: Notify other end - Log.e("SMSPlugin", e.getMessage()); - e.printStackTrace(); - } + switch (np.getType()) { + case PACKET_TYPE_SMS_REQUEST_CONVERSATIONS: + return this.handleRequestConversations(np); + case PACKET_TYPE_SMS_REQUEST_CONVERSATION: + return this.handleRequestConversation(np); + case PACKET_TYPE_SMS_REQUEST: + // Fall through to old-style handling + // This space may be filled in differently once MMS support is implemented + case TelephonyPlugin.PACKET_TYPE_TELEPHONY_REQUEST: + if (np.getBoolean("sendSms")) { + String phoneNo = np.getString("phoneNumber"); + String sms = np.getString("messageBody"); + + try { + SmsManager smsManager = SmsManager.getDefault(); + ArrayList parts = smsManager.divideMessage(sms); + + // If this message turns out to fit in a single SMS, sendMultipartTextMessage + // properly handles that case + smsManager.sendMultipartTextMessage(phoneNo, null, parts, null, null); + + //TODO: Notify other end + } catch (Exception e) { + //TODO: Notify other end + Log.e("SMSPlugin", e.getMessage()); + e.printStackTrace(); + } + } + break; } return true; } /** * Respond to a request for all conversations *

- * Send one packet of type PACKET_TYPE_TELEPHONY_MESSAGE with the first message in all conversations + * Send one packet of type PACKET_TYPE_SMS_MESSAGE with the first message in all conversations */ - protected boolean handleRequestConversations(NetworkPacket packet) { + private boolean handleRequestConversations(NetworkPacket packet) { Map conversations = SMSHelper.getConversations(this.context); - NetworkPacket reply = new NetworkPacket(PACKET_TYPE_TELEPHONY_MESSAGE); + NetworkPacket reply = new NetworkPacket(PACKET_TYPE_SMS_MESSAGE); JSONArray messages = new JSONArray(); @@ -247,19 +264,19 @@ } reply.set("messages", messages); - reply.set("event", "batch_messages"); // Not really necessary, since this is implied by PACKET_TYPE_TELEPHONY_MESSAGE, but good for readability + reply.set("event", "batch_messages"); // Not really necessary, since this is implied by PACKET_TYPE_SMS_MESSAGE, but good for readability device.sendPacket(reply); return true; } - protected boolean handleRequestConversation(NetworkPacket packet) { + private boolean handleRequestConversation(NetworkPacket packet) { SMSHelper.ThreadID threadID = new SMSHelper.ThreadID(packet.getInt("threadID")); List conversation = SMSHelper.getMessagesInThread(this.context, threadID); - NetworkPacket reply = new NetworkPacket(PACKET_TYPE_TELEPHONY_MESSAGE); + NetworkPacket reply = new NetworkPacket(PACKET_TYPE_SMS_MESSAGE); JSONArray messages = new JSONArray(); @@ -301,14 +318,14 @@ return new String[]{ PACKET_TYPE_SMS_REQUEST, TelephonyPlugin.PACKET_TYPE_TELEPHONY_REQUEST, - PACKET_TYPE_TELEPHONY_REQUEST_CONVERSATIONS, - PACKET_TYPE_TELEPHONY_REQUEST_CONVERSATION + PACKET_TYPE_SMS_REQUEST_CONVERSATIONS, + PACKET_TYPE_SMS_REQUEST_CONVERSATION }; } @Override public String[] getOutgoingPacketTypes() { - return new String[]{PACKET_TYPE_TELEPHONY_MESSAGE}; + return new String[]{PACKET_TYPE_SMS_MESSAGE}; } @Override diff --git a/src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java b/src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java --- a/src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java @@ -68,13 +68,46 @@ * - "missedCall" - An incoming call was not answered * - "sms" - An incoming SMS message * - Note: As of this writing (15 May 2018) the SMS interface is being improved and this type of event - * is no longer the preferred way of retrieving SMS. Use PACKET_TYPE_TELEPHONY_MESSAGE instead. + * is no longer the preferred way of handling SMS. Use the packets defined by the SMS plugin instead. * * Depending on the event, other fields may be defined */ public final static String PACKET_TYPE_TELEPHONY = "kdeconnect.telephony"; + + /** + * Old-style packet sent to request a simple telephony action + * + * The two possible events used the be to request a message be sent or request the device + * silence its ringer + * + * In case an SMS was being requested, the body was like so: + * { "sendSms": true, + * "phoneNumber": "542904563213", + * "messageBody": "Hi mom!" + * } + * + * In case a ringer muted was requested, the body looked like so: + * { "action": "mute" } + * + * As of 15 May 2018, the SMS interface is being improved. Use the packets defined by the + * SMS plugin instead for SMS events + * + * Ringer mute requests are best handled by PACKET_TYPE_TELEPHONY_REQUEST_MUTE + * + * This packet type is retained for backwards-compatibility with old desktop applications, + * but support should be dropped once those applications are no longer supported. New + * applications should not use this packet type. + */ + @Deprecated public final static String PACKET_TYPE_TELEPHONY_REQUEST = "kdeconnect.telephony.request"; + /** + * Packet sent to indicate the user has requested the device mute its ringer + * + * The body should be empty + */ + public final static String PACKET_TYPE_TELEPHONY_REQUEST_MUTE = "kdeconnect.telephony.request_mute"; + private static final String KEY_PREF_BLOCKED_NUMBERS = "telephony_blocked_numbers"; private int lastState = TelephonyManager.CALL_STATE_IDLE; private NetworkPacket lastPacket = null; @@ -225,6 +258,18 @@ lastState = state; } + private void muteRinger() { + if (!isMuted) { + AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + am.setStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_MUTE, 0); + } else { + am.setStreamMute(AudioManager.STREAM_RING, true); + } + isMuted = true; + } + } + @Override public boolean onCreate() { IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); @@ -244,18 +289,16 @@ @Override public boolean onPacketReceived(NetworkPacket np) { - if (np.getString("action").equals("mute")) { - if (!isMuted) { - AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - am.setStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_MUTE, 0); - } else { - am.setStreamMute(AudioManager.STREAM_RING, true); + switch (np.getType()) { + case PACKET_TYPE_TELEPHONY_REQUEST: + if (np.getString("action").equals("mute")) { + muteRinger(); } - isMuted = true; - } + break; + case PACKET_TYPE_TELEPHONY_REQUEST_MUTE: + muteRinger(); + break; } - //Do nothing return true; } @@ -274,7 +317,8 @@ @Override public String[] getSupportedPacketTypes() { return new String[]{ - PACKET_TYPE_TELEPHONY_REQUEST + PACKET_TYPE_TELEPHONY_REQUEST, + PACKET_TYPE_TELEPHONY_REQUEST_MUTE, }; }