diff --git a/res/values/strings.xml b/res/values/strings.xml --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -216,5 +216,7 @@ To read and write SMS from your desktop you need to give permission to SMS To see phone calls and SMS from the desktop you need to give permission to phone calls and SMS To see a contact name instead of a phone number you need to give access to the phone\'s contacts + Blocked numbers + Don\'t show calls and SMS from these numbers. Please specify one number per line diff --git a/res/xml/telephonyplugin_preferences.xml b/res/xml/telephonyplugin_preferences.xml new file mode 100644 --- /dev/null +++ b/res/xml/telephonyplugin_preferences.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file 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 @@ -25,11 +25,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.media.AudioManager; import android.os.Build; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v4.content.ContextCompat; +import android.telephony.PhoneNumberUtils; import android.telephony.SmsMessage; import android.telephony.TelephonyManager; import android.util.Log; @@ -47,63 +50,52 @@ public class TelephonyPlugin extends Plugin { - public final static String PACKAGE_TYPE_TELEPHONY = "kdeconnect.telephony"; + private final static String PACKAGE_TYPE_TELEPHONY = "kdeconnect.telephony"; public final static String PACKAGE_TYPE_TELEPHONY_REQUEST = "kdeconnect.telephony.request"; + private static final String KEY_PREF_BLOCKED_NUMBERS = "telephony_blocked_numbers"; private int lastState = TelephonyManager.CALL_STATE_IDLE; private NetworkPackage lastPackage = null; private boolean isMuted = false; - private int telephonyPermissionExplanation = R.string.telephony_permission_explanation; - private int telephonyOptionalPermissionExplanation = R.string.telephony_optional_permission_explanation; - - @Override - public String getDisplayName() { - return context.getResources().getString(R.string.pref_plugin_telephony); - } - - @Override - public String getDescription() { - return context.getResources().getString(R.string.pref_plugin_telephony_desc); - } - private final BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); //Log.e("TelephonyPlugin","Telephony event: " + action); - if("android.provider.Telephony.SMS_RECEIVED".equals(action)) { + if ("android.provider.Telephony.SMS_RECEIVED".equals(action)) { final Bundle bundle = intent.getExtras(); if (bundle == null) return; final Object[] pdus = (Object[]) bundle.get("pdus"); - ArrayList messages = new ArrayList(); + ArrayList messages = new ArrayList<>(); for (Object pdu : pdus) { // I hope, but am not sure, that the pdus array is in the order that the parts // of the SMS message should be - // If it is not, I belive the pdu contains the information necessary to put it + // If it is not, I believe the pdu contains the information necessary to put it // in order, but in my testing the order seems to be correct, so I won't worry // about it now. - messages.add(SmsMessage.createFromPdu((byte[])pdu)); + messages.add(SmsMessage.createFromPdu((byte[]) pdu)); } smsBroadcastReceived(messages); } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) { String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); - int intState = TelephonyManager.CALL_STATE_IDLE; + int intState = TelephonyManager.CALL_STATE_IDLE; if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) intState = TelephonyManager.CALL_STATE_RINGING; else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) intState = TelephonyManager.CALL_STATE_OFFHOOK; String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); - if (number == null) number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); + if (number == null) + number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); final int finalIntState = intState; final String finalNumber = number; @@ -114,16 +106,27 @@ } }; + @Override + public String getDisplayName() { + return context.getResources().getString(R.string.pref_plugin_telephony); + } + + @Override + public String getDescription() { + return context.getResources().getString(R.string.pref_plugin_telephony_desc); + } + private void callBroadcastReceived(int state, String phoneNumber) { - //Log.e("TelephonyPlugin", "callBroadcastReceived"); + if (isNumberBlocked(phoneNumber)) + return; NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_TELEPHONY); int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS); - if(permissionCheck==PackageManager.PERMISSION_GRANTED) { + if (permissionCheck == PackageManager.PERMISSION_GRANTED) { Map contactInfo = ContactsHelper.phoneNumberLookup(context, phoneNumber); @@ -147,7 +150,7 @@ } } else { - np.set("contactName", phoneNumber); + np.set("contactName", phoneNumber); } if (phoneNumber != null) { @@ -179,7 +182,7 @@ if (lastState != TelephonyManager.CALL_STATE_IDLE && lastPackage != null) { //Resend a cancel of the last event (can either be "ringing" or "talking") - lastPackage.set("isCancel","true"); + lastPackage.set("isCancel", "true"); device.sendPackage(lastPackage); if (isMuted) { @@ -202,9 +205,9 @@ //Emit a missed call notification if needed if (lastState == TelephonyManager.CALL_STATE_RINGING) { - np.set("event","missedCall"); - np.set("phoneNumber", lastPackage.getString("phoneNumber",null)); - np.set("contactName", lastPackage.getString("contactName",null)); + np.set("event", "missedCall"); + np.set("phoneNumber", lastPackage.getString("phoneNumber", null)); + np.set("contactName", lastPackage.getString("contactName", null)); device.sendPackage(np); } @@ -221,30 +224,30 @@ private void smsBroadcastReceived(ArrayList messages) { if (BuildConfig.DEBUG) { - if (!(messages.size() > 0)) - { + if (!(messages.size() > 0)) { throw new AssertionError("This method requires at least one message"); } } - //Log.e("SmsBroadcastReceived", message.toString()); - NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_TELEPHONY); - np.set("event","sms"); + np.set("event", "sms"); StringBuilder messageBody = new StringBuilder(); - for (int index = 0; index < messages.size(); index ++) { + for (int index = 0; index < messages.size(); index++) { messageBody.append(messages.get(index).getMessageBody()); } np.set("messageBody", messageBody.toString()); String phoneNumber = messages.get(0).getOriginatingAddress(); + if (isNumberBlocked(phoneNumber)) + return; + int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS); - if(permissionCheck==PackageManager.PERMISSION_GRANTED) { + if (permissionCheck == PackageManager.PERMISSION_GRANTED) { Map contactInfo = ContactsHelper.phoneNumberLookup(context, phoneNumber); if (contactInfo.containsKey("name")) { @@ -260,19 +263,17 @@ } - device.sendPackage(np); } @Override public boolean onCreate() { - //Log.e("TelephonyPlugin", "onCreate"); IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); filter.setPriority(500); filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); context.registerReceiver(receiver, filter); - permissionExplanation = telephonyPermissionExplanation; - optionalPermissionExplanation = telephonyOptionalPermissionExplanation; + permissionExplanation = R.string.telephony_permission_explanation; + optionalPermissionExplanation = R.string.telephony_optional_permission_explanation; return true; } @@ -293,12 +294,23 @@ } isMuted = true; } - //Log.e("TelephonyPlugin", "mute"); } //Do nothing return true; } + private boolean isNumberBlocked(String number) { + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); + String[] blockedNumbers = sharedPref.getString(KEY_PREF_BLOCKED_NUMBERS, "").split("\n"); + + for (String s: blockedNumbers) { + if (PhoneNumberUtils.compare(number, s)) + return true; + } + + return false; + } + @Override public String[] getSupportedPackageTypes() { return new String[]{PACKAGE_TYPE_TELEPHONY_REQUEST}; @@ -318,4 +330,9 @@ public String[] getOptionalPermissions() { return new String[]{Manifest.permission.READ_CONTACTS}; } + + @Override + public boolean hasSettings() { + return true; + } }