Quick and dirty support for incoming calls notification the Pebble way

Incoming calls are no longer send as simple notifications but properly as
incoming calls. The Pebble will vibrate until the call is taken or dismissed.

It is not yet possible to dismiss the call using the Pebble button.
This commit is contained in:
Andreas Shimokawa 2015-01-22 22:49:50 +01:00
parent 59c281c61c
commit bf6abe9672
5 changed files with 55 additions and 9 deletions

View File

@ -3,10 +3,8 @@
package="nodomain.freeyourgadget.gadgetbridge">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
@ -33,6 +31,10 @@
</service>
<service android:name=".BluetoothCommunicationService" >
</service>
<receiver android:name=".PhoneCallReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -30,7 +30,9 @@ public class BluetoothCommunicationService extends Service {
public static final String ACTION_STOP
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.stop";
public static final String ACTION_SENDMESSAGE
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.sendbluetoothmessage";
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.sendmessage";
public static final String ACTION_INCOMINGCALL
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.incomingcall";
public static final String ACTION_SETTIME
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.settime";
@ -121,6 +123,14 @@ public class BluetoothCommunicationService extends Service {
byte[] msg = PebbleProtocol.encodeSMS(title, content);
mBtSocketIoThread.write(msg);
}
} else if (intent.getAction().equals(ACTION_INCOMINGCALL)) {
String phoneNumber = intent.getStringExtra("incomingcall_phonenumber");
byte phoneState = intent.getByteExtra("incomingcall_state", (byte) 0);
if (mBtSocketIoThread != null) {
byte[] msg = PebbleProtocol.encodeIncomingCall(phoneNumber, phoneNumber, phoneState);
mBtSocketIoThread.write(msg);
}
} else if (intent.getAction().equals(ACTION_SETTIME)) {
if (mBtSocketIoThread != null) {
byte[] msg = PebbleProtocol.encodeSetTime(-1);
@ -220,7 +230,7 @@ public class BluetoothCommunicationService extends Service {
if (length == 1 && endpoint == PebbleProtocol.ENDPOINT_PHONEVERSION) {
Log.i(TAG, "Pebble asked for Phone/App Version - repLYING!");
write(PebbleProtocol.encodePhoneVersion(PebbleProtocol.PHONEVERSION_REMOTE_OS_ANDROID));
} else {
} else if (endpoint != PebbleProtocol.ENDPOINT_DATALOG) {
Log.i(TAG, "unhandled message to endpoint " + endpoint + " (" + bytes + " bytes)");
}
try {

View File

@ -5,6 +5,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
public class NotificationListener extends NotificationListenerService {
@ -28,9 +29,12 @@ public class NotificationListener extends NotificationListenerService {
* This includes keyboard selection message, usb connection messages, etc
* Hope it does not filter out too much, we will see...
*/
if (sbn.getPackageName().equals("android"))
String source = sbn.getPackageName();
if (source.equals("android") || source.equals("com.android.dialer"))
return;
Log.i(TAG, sbn.getPackageName());
Bundle extras = notification.extras;
String title = extras.getString(Notification.EXTRA_TITLE);
String content = "";

View File

@ -25,6 +25,7 @@ public class PebbleProtocol {
static final short ENDPOINT_SYSREG = 5000;
static final short ENDPOINT_FCTREG = 5001;
static final short ENDPOINT_APPMANAGER = 6000;
static final short ENDPOINT_DATALOG = 6778;
static final short ENDPOINT_RUNKEEPER = 7000;
static final short ENDPOINT_SCREENSHOT = 8000;
static final short ENDPOINT_PUTBYTES = (short) 48879;
@ -130,10 +131,10 @@ public class PebbleProtocol {
return buf.array();
}
public static byte[] encodeIncomingCall(String number, String name) {
public static byte[] encodeIncomingCall(String number, String name, byte state) {
String cookie = "000"; // That's a dirty trick to make the cookie part 4 bytes long :P
String[] parts = {cookie, number, name};
return encodeMessage(ENDPOINT_PHONECONTROL, PHONECONTROL_INCOMINGCALL, parts);
return encodeMessage(ENDPOINT_PHONECONTROL, state, parts);
}
public static byte[] encodePhoneVersion(byte os) {

View File

@ -0,0 +1,29 @@
package nodomain.freeyourgadget.gadgetbridge;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
public class PhoneCallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
byte state = 0;
if (phoneState.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
state = PebbleProtocol.PHONECONTROL_INCOMINGCALL;
} else if (phoneState.equals(TelephonyManager.EXTRA_STATE_IDLE) || phoneState.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
state = PebbleProtocol.PHONECONTROL_END;
}
if (state != 0) {
String phoneNumber = intent.hasExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) ? intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) : "";
Intent startIntent = new Intent(context, BluetoothCommunicationService.class);
startIntent.setAction(BluetoothCommunicationService.ACTION_INCOMINGCALL);
startIntent.putExtra("incomingcall_phonenumber", phoneNumber);
startIntent.putExtra("incomingcall_state", state);
context.startService(startIntent);
}
}
}