Receive SMS the proper way, filter them out in the generic NotificationListener.

This commit is contained in:
Andreas Shimokawa 2015-01-24 12:21:15 +01:00
parent 070c6db5ed
commit 94c73ef20e
6 changed files with 81 additions and 18 deletions

View File

@ -11,13 +11,24 @@ Right now this is in very early testing stages and only supports the Pebble.
USE IT AT YOUR OWN RISK. It will problably not work. And if it works it will
annoy you more than it helps you ;)
Known Visible Issues:
Features:
* Notification for incoming calls with caller name and number
* SMS notification with sender name
* Generic Notificaions (android system and telephony notifications filtered out)
* No special notifications, EVERYTHING will be send as a Chat/SMS message
Known Issues:
* Can't reject or hang up phone calls yet
* Phone calls that are taken or rejected both count as rejected to make the
Pebble stop vibrating. (No in-call display yet)
* No outgoing call support (No in-call display yet)
* Complex notifications (eg. K-9 Mail) do not work yet, maybe we should implement
special K-9 Mail support? Or just support taking complex notificaion apart?
* Notifications are not properly queued, if two arrive at about the same time,
one of them will get lost (TODO: confirm)
* Android 4.4+ only, we can only change this by implementing an
AccessibiltyService. Don't know if it is worth the hassle.
* Android 4.4+ only, we can only change this by not handling generic
notifications or by using AccessibiltyService. Don't know if it is worth the
hassle.
Apart from that there are many internal design flaws which we will discuss using
the issue tracker.
the issue tracker.

View File

@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
@ -38,5 +39,10 @@
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
<receiver android:name=".SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -33,8 +33,10 @@ public class BluetoothCommunicationService extends Service {
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.start";
public static final String ACTION_STOP
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.stop";
public static final String ACTION_SENDMESSAGE
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.sendmessage";
public static final String ACTION_NOTIFICATION_GENERIC
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.notification_generic";
public static final String ACTION_NOTIFICATION_SMS
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.notification_sms";
public static final String ACTION_INCOMINGCALL
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.incomingcall";
public static final String ACTION_SETTIME
@ -121,11 +123,20 @@ public class BluetoothCommunicationService extends Service {
stopForeground(true);
stopSelf();
} else if (intent.getAction().equals(ACTION_SENDMESSAGE)) {
} else if (intent.getAction().equals(ACTION_NOTIFICATION_GENERIC)) {
String title = intent.getStringExtra("notification_title");
String content = intent.getStringExtra("notification_content");
String body = intent.getStringExtra("notification_body");
if (mBtSocketIoThread != null) {
byte[] msg = PebbleProtocol.encodeSMS(title, content);
byte[] msg = PebbleProtocol.encodeSMS(title, body);
mBtSocketIoThread.write(msg);
}
} else if (intent.getAction().equals(ACTION_NOTIFICATION_SMS)) {
String sender = intent.getStringExtra("notification_sender");
String body = intent.getStringExtra("notification_body");
String senderName = getContactDisplayNameByNumber(sender);
if (mBtSocketIoThread != null) {
byte[] msg = PebbleProtocol.encodeSMS(senderName, body);
mBtSocketIoThread.write(msg);
}
} else if (intent.getAction().equals(ACTION_INCOMINGCALL)) {

View File

@ -48,9 +48,9 @@ public class ControlCenter extends ActionBarActivity {
@Override
public void onClick(View v) {
Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class);
startIntent.setAction(BluetoothCommunicationService.ACTION_SENDMESSAGE);
startIntent.setAction(BluetoothCommunicationService.ACTION_NOTIFICATION_GENERIC);
startIntent.putExtra("notification_title", editTitle.getText().toString());
startIntent.putExtra("notification_content", editContent.getText().toString());
startIntent.putExtra("notification_body", editContent.getText().toString());
startService(startIntent);
}
});

View File

@ -30,10 +30,15 @@ public class NotificationListener extends NotificationListenerService {
* Hope it does not filter out too much, we will see...
*/
String source = sbn.getPackageName();
if (source.equals("android") || source.equals("com.android.dialer"))
return;
Log.i(TAG, source);
Log.i(TAG, sbn.getPackageName());
if (source.equals("android") ||
source.equals("com.android.dialer") ||
source.equals("com.android.mms")) {
return;
}
Log.i(TAG, "Processing notification from source " + source);
Bundle extras = notification.extras;
String title = extras.getString(Notification.EXTRA_TITLE);
@ -41,12 +46,11 @@ public class NotificationListener extends NotificationListenerService {
if (extras.containsKey(Notification.EXTRA_TEXT))
content = extras.getString(Notification.EXTRA_TEXT);
if (content != null) {
Intent startIntent = new Intent(NotificationListener.this, BluetoothCommunicationService.class);
startIntent.setAction(BluetoothCommunicationService.ACTION_SENDMESSAGE);
startIntent.setAction(BluetoothCommunicationService.ACTION_NOTIFICATION_GENERIC);
startIntent.putExtra("notification_title", title);
startIntent.putExtra("notification_content", content);
startIntent.putExtra("notification_body", content);
startService(startIntent);
}
}

View File

@ -0,0 +1,31 @@
package nodomain.freeyourgadget.gadgetbridge;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
public class SMSReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdus.length; i++) {
byte[] pdu = (byte[]) pdus[i];
SmsMessage message = SmsMessage.createFromPdu(pdu);
String body = message.getDisplayMessageBody();
String sender = message.getOriginatingAddress();
if (sender != null && body != null) {
Intent startIntent = new Intent(context, BluetoothCommunicationService.class);
startIntent.setAction(BluetoothCommunicationService.ACTION_NOTIFICATION_SMS);
startIntent.putExtra("notification_sender", sender);
startIntent.putExtra("notification_body", body);
context.startService(startIntent);
}
}
}
}
}