diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d8500d4c6..0a47b33a9 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,10 +1,11 @@
+ package="nodomain.freeyourgadget.gadgetbridge" >
-
+
+
@@ -12,15 +13,16 @@
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
- android:theme="@style/AppTheme">
+ android:theme="@style/AppTheme" >
+ android:label="@string/app_name" />
+ android:label="@string/app_name" >
+
@@ -28,29 +30,46 @@
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
-
+
+
-
+
+
+
+
-
+
-
+
-
+
+
-
+
+
+
+
+
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java
index 81b8c92d4..f1cf57cc7 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java
@@ -42,8 +42,8 @@ public class BluetoothCommunicationService extends Service {
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.notification_sms";
public static final String ACTION_NOTIFICATION_EMAIL
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.notification_email";
- public static final String ACTION_INCOMINGCALL
- = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.incomingcall";
+ public static final String ACTION_CALLSTATE
+ = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.callstate";
public static final String ACTION_SETTIME
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.settime";
@@ -58,6 +58,7 @@ public class BluetoothCommunicationService extends Service {
PhoneCallReceiver.class,
SMSReceiver.class,
K9Receiver.class,
+ NotificationListener.class,
};
int newState;
@@ -180,11 +181,17 @@ public class BluetoothCommunicationService extends Service {
String body = intent.getStringExtra("notification_body");
byte[] msg = PebbleProtocol.encodeEmail(sender, subject, body);
mBtSocketIoThread.write(msg);
- } else if (intent.getAction().equals(ACTION_INCOMINGCALL)) {
- String phoneNumber = intent.getStringExtra("incomingcall_phonenumber");
- byte phoneState = intent.getByteExtra("incomingcall_state", (byte) 0);
- String callerName = getContactDisplayNameByNumber(phoneNumber);
- byte[] msg = PebbleProtocol.encodeIncomingCall(phoneNumber, callerName, phoneState);
+ } else if (intent.getAction().equals(ACTION_CALLSTATE)) {
+ byte phoneState = intent.getByteExtra("call_state", (byte) 0);
+ String phoneNumber = null;
+ if (intent.hasExtra("call_phonenumber")) {
+ phoneNumber = intent.getStringExtra("call_phonenumber");
+ }
+ String callerName = null;
+ if (phoneNumber != null) {
+ callerName = getContactDisplayNameByNumber(phoneNumber);
+ }
+ byte[] msg = PebbleProtocol.encodePhoneState(phoneNumber, callerName, phoneState);
mBtSocketIoThread.write(msg);
} else if (intent.getAction().equals(ACTION_SETTIME)) {
byte[] msg = PebbleProtocol.encodeSetTime(-1);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java
index 2aabf9c32..091de3e50 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java
@@ -14,19 +14,13 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
-import android.widget.EditText;
public class ControlCenter extends ActionBarActivity {
public static final String ACTION_QUIT
= "nodomain.freeyourgadget.gadgetbride.controlcenter.action.quit";
- Button sendButton;
- Button testNotificationButton;
Button startServiceButton;
- Button setTimeButton;
- EditText editTitle;
- EditText editContent;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -44,8 +38,6 @@ public class ControlCenter extends ActionBarActivity {
registerReceiver(mReceiver, new IntentFilter(ACTION_QUIT));
- editTitle = (EditText) findViewById(R.id.editTitle);
- editContent = (EditText) findViewById(R.id.editContent);
startServiceButton = (Button) findViewById(R.id.startServiceButton);
startServiceButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -55,35 +47,6 @@ public class ControlCenter extends ActionBarActivity {
startService(startIntent);
}
});
- sendButton = (Button) findViewById(R.id.sendButton);
- sendButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class);
- startIntent.setAction(BluetoothCommunicationService.ACTION_NOTIFICATION_GENERIC);
- startIntent.putExtra("notification_title", editTitle.getText().toString());
- startIntent.putExtra("notification_body", editContent.getText().toString());
- startService(startIntent);
- }
- });
- setTimeButton = (Button) findViewById(R.id.setTimeButton);
- setTimeButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class);
- startIntent.setAction(BluetoothCommunicationService.ACTION_SETTIME);
- startService(startIntent);
- }
- });
-
- testNotificationButton = (Button) findViewById(R.id.testNotificationButton);
- testNotificationButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- testNotification();
- }
- });
-
/*
* Ask for permission to intercept notifications on first run.
* TODO: allow re-request in preferences
@@ -131,9 +94,15 @@ public class ControlCenter extends ActionBarActivity {
//startActivity(intent);
return true;
}
+ if (id == R.id.action_debug) {
+ Intent intent = new Intent(this, DebugActivity.class);
+ startActivity(intent);
+ return true;
+ }
return super.onOptionsItemSelected(item);
}
+
@Override
protected void onDestroy() {
super.onDestroy();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/DebugActivity.java
new file mode 100644
index 000000000..9c0b975fa
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/DebugActivity.java
@@ -0,0 +1,147 @@
+package nodomain.freeyourgadget.gadgetbridge;
+
+import android.app.NotificationManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.support.v4.app.NotificationCompat;
+import android.support.v7.app.ActionBarActivity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+public class DebugActivity extends ActionBarActivity {
+ Button sendSMSButton;
+ Button sendEmailButton;
+ Button incomingCallButton;
+ Button outgoingCallButton;
+ Button startCallButton;
+ Button endCallButton;
+ Button testNotificationButton;
+ Button setTimeButton;
+ EditText editContent;
+
+ private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(ControlCenter.ACTION_QUIT)) {
+ finish();
+ }
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_debug);
+
+ registerReceiver(mReceiver, new IntentFilter(ControlCenter.ACTION_QUIT));
+
+ editContent = (EditText) findViewById(R.id.editContent);
+ sendSMSButton = (Button) findViewById(R.id.sendSMSButton);
+ sendSMSButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_NOTIFICATION_GENERIC);
+ startIntent.putExtra("notification_title", "Gadgetbridge");
+ startIntent.putExtra("notification_body", editContent.getText().toString());
+ startService(startIntent);
+ }
+ });
+ sendEmailButton = (Button) findViewById(R.id.sendEmailButton);
+ sendEmailButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_NOTIFICATION_EMAIL);
+ startIntent.putExtra("notification_sender", "Gadgetbridge");
+ startIntent.putExtra("notification_subject", "Test");
+ startIntent.putExtra("notification_body", editContent.getText().toString());
+ startService(startIntent);
+ }
+ });
+
+ incomingCallButton = (Button) findViewById(R.id.incomingCallButton);
+ incomingCallButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
+ startIntent.putExtra("call_phonenumber", editContent.getText().toString());
+ startIntent.putExtra("call_state", PebbleProtocol.PHONECONTROL_INCOMINGCALL);
+ startService(startIntent);
+ }
+ });
+ outgoingCallButton = (Button) findViewById(R.id.outgoingCallButton);
+ outgoingCallButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
+ startIntent.putExtra("call_phonenumber", editContent.getText().toString());
+ startIntent.putExtra("call_state", PebbleProtocol.PHONECONTROL_OUTGOINGCALL);
+ startService(startIntent);
+ }
+ });
+
+ startCallButton = (Button) findViewById(R.id.startCallButton);
+ startCallButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
+ startIntent.putExtra("call_state", PebbleProtocol.PHONECONTROL_START);
+ startService(startIntent);
+ }
+ });
+ endCallButton = (Button) findViewById(R.id.endCallButton);
+ endCallButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
+ startIntent.putExtra("call_state", PebbleProtocol.PHONECONTROL_END);
+ startService(startIntent);
+ }
+ });
+
+ setTimeButton = (Button) findViewById(R.id.setTimeButton);
+ setTimeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_SETTIME);
+ startService(startIntent);
+ }
+ });
+
+ testNotificationButton = (Button) findViewById(R.id.testNotificationButton);
+ testNotificationButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ testNotification();
+ }
+ });
+ }
+
+ private void testNotification() {
+ NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+ NotificationCompat.Builder ncomp = new NotificationCompat.Builder(this);
+ ncomp.setContentTitle("Test Notification");
+ ncomp.setContentText("This is a Test Notification from Gadgetbridge");
+ ncomp.setTicker("This is a Test Notification from Gadgetbridge");
+ ncomp.setSmallIcon(R.drawable.ic_launcher);
+ ncomp.setAutoCancel(true);
+ nManager.notify((int) System.currentTimeMillis(), ncomp.build());
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mReceiver);
+ }
+
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java
index e7adbb4d5..d0206cd39 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java
@@ -133,7 +133,7 @@ public class PebbleProtocol {
return buf.array();
}
- public static byte[] encodeIncomingCall(String number, String name, byte state) {
+ public static byte[] encodePhoneState(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, state, parts);
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PhoneCallReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PhoneCallReceiver.java
index 3244e801d..bb6986aa9 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PhoneCallReceiver.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PhoneCallReceiver.java
@@ -5,26 +5,61 @@ import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
+
public class PhoneCallReceiver extends BroadcastReceiver {
+ private static int mLastState = TelephonyManager.CALL_STATE_IDLE;
+ private static String mSavedNumber;
+
@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 (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
+ mSavedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
+ } else {
+ String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
+ String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
+ int state = 0;
+ if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
+ state = TelephonyManager.CALL_STATE_IDLE;
+ } else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
+ state = TelephonyManager.CALL_STATE_OFFHOOK;
+ } else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
+ state = TelephonyManager.CALL_STATE_RINGING;
+ }
- 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);
+ onCallStateChanged(context, state, number);
}
}
+ public void onCallStateChanged(Context context, int state, String number) {
+ if (mLastState == state) {
+ return;
+ }
+
+ byte pebblePhoneCommand = -1; // TODO: dont assume Pebble here
+ switch (state) {
+ case TelephonyManager.CALL_STATE_RINGING:
+ mSavedNumber = number;
+ pebblePhoneCommand = PebbleProtocol.PHONECONTROL_INCOMINGCALL;
+ break;
+ case TelephonyManager.CALL_STATE_OFFHOOK:
+ if (mLastState == TelephonyManager.CALL_STATE_RINGING) {
+ pebblePhoneCommand = PebbleProtocol.PHONECONTROL_START;
+ } else {
+ pebblePhoneCommand = PebbleProtocol.PHONECONTROL_OUTGOINGCALL;
+ }
+ break;
+ case TelephonyManager.CALL_STATE_IDLE:
+ pebblePhoneCommand = PebbleProtocol.PHONECONTROL_END;
+ break;
+ }
+ if (pebblePhoneCommand != -1) {
+ Intent startIntent = new Intent(context, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
+ startIntent.putExtra("call_phonenumber", mSavedNumber);
+ startIntent.putExtra("call_state", pebblePhoneCommand);
+ context.startService(startIntent);
+ }
+ mLastState = state;
+ }
}
diff --git a/app/src/main/res/layout/activity_controlcenter.xml b/app/src/main/res/layout/activity_controlcenter.xml
index c03600e38..cb4f86891 100644
--- a/app/src/main/res/layout/activity_controlcenter.xml
+++ b/app/src/main/res/layout/activity_controlcenter.xml
@@ -6,67 +6,13 @@
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="nodomain.freeyourgadget.gadgetbridge.ControlCenter">
-
-
-
-
-
-
-
+ android:layout_alignParentEnd="true" />
-
diff --git a/app/src/main/res/layout/activity_debug.xml b/app/src/main/res/layout/activity_debug.xml
new file mode 100644
index 000000000..8568dfe42
--- /dev/null
+++ b/app/src/main/res/layout/activity_debug.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/menu_debug.xml b/app/src/main/res/menu/menu_debug.xml
new file mode 100644
index 000000000..85b36d51a
--- /dev/null
+++ b/app/src/main/res/menu/menu_debug.xml
@@ -0,0 +1,7 @@
+
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
index 45d2280b5..19854b200 100644
--- a/app/src/main/res/menu/menu_main.xml
+++ b/app/src/main/res/menu/menu_main.xml
@@ -4,4 +4,6 @@
tools:context="nodomain.freeyourgadget.gadgetbridge.ControlCenter">
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fb1ed07b2..a897a68bb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -3,7 +3,8 @@
Gadgetbridge
Gadgetbridge Control Center
- Hello world!
Settings
+ Debug
+ Debug