Merge branch 'master' into live-activity-data

This commit is contained in:
cpfeiffer 2015-09-05 00:15:49 +02:00
commit 5f993c0049
7 changed files with 95 additions and 48 deletions

View File

@ -2,6 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
import android.app.Activity; import android.app.Activity;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -215,6 +216,12 @@ public class DebugActivity extends Activity {
} }
private void testNotification() { private void testNotification() {
Intent notificationIntent = new Intent(getApplicationContext(), DebugActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
notificationIntent, 0);
NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder ncomp = new NotificationCompat.Builder(this); NotificationCompat.Builder ncomp = new NotificationCompat.Builder(this);
ncomp.setContentTitle(getString(R.string.test_notification)); ncomp.setContentTitle(getString(R.string.test_notification));
@ -222,6 +229,7 @@ public class DebugActivity extends Activity {
ncomp.setTicker(getString(R.string.this_is_a_test_notification_from_gadgetbridge)); ncomp.setTicker(getString(R.string.this_is_a_test_notification_from_gadgetbridge));
ncomp.setSmallIcon(R.drawable.ic_notification); ncomp.setSmallIcon(R.drawable.ic_notification);
ncomp.setAutoCancel(true); ncomp.setAutoCancel(true);
ncomp.setContentIntent(pendingIntent);
nManager.notify((int) System.currentTimeMillis(), ncomp.build()); nManager.notify((int) System.currentTimeMillis(), ncomp.build());
} }

View File

@ -1,6 +1,8 @@
package nodomain.freeyourgadget.gadgetbridge.adapter; package nodomain.freeyourgadget.gadgetbridge.adapter;
import android.content.Context; import android.content.Context;
import android.graphics.Color;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -61,9 +63,15 @@ public class GBDeviceAdapter extends ArrayAdapter<GBDevice> {
if (batteryLevel != GBDevice.BATTERY_UNKNOWN) { if (batteryLevel != GBDevice.BATTERY_UNKNOWN) {
batteryStatusLabel.setText("BAT: " + device.getBatteryLevel() + "%"); batteryStatusLabel.setText("BAT: " + device.getBatteryLevel() + "%");
BatteryState batteryState = device.getBatteryState(); BatteryState batteryState = device.getBatteryState();
if (BatteryState.BATTERY_CHARGING.equals(batteryState) || if (BatteryState.BATTERY_LOW.equals(batteryState)) {
BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) { batteryStatusLabel.setTextColor(Color.RED);
batteryStatusLabel.append(" CHG"); } else {
batteryStatusLabel.setTextColor(ContextCompat.getColor(getContext(), R.color.secondarytext));
if (BatteryState.BATTERY_CHARGING.equals(batteryState) ||
BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) {
batteryStatusLabel.append(" CHG");
}
} }
} else { } else {
batteryStatusLabel.setText(""); batteryStatusLabel.setText("");

View File

@ -129,6 +129,7 @@ public class NotificationListener extends NotificationListenerService {
source.equals("com.android.systemui") || source.equals("com.android.systemui") ||
source.equals("com.android.dialer") || source.equals("com.android.dialer") ||
source.equals("com.android.mms") || source.equals("com.android.mms") ||
source.equals("com.moez.QKSMS") ||
source.equals("com.cyanogenmod.eleven") || source.equals("com.cyanogenmod.eleven") ||
source.equals("com.fsck.k9")) { source.equals("com.fsck.k9")) {
return; return;

View File

@ -9,7 +9,11 @@ import android.preference.PreferenceManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.GregorianCalendar;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
public class TimeChangeReceiver extends BroadcastReceiver { public class TimeChangeReceiver extends BroadcastReceiver {
@ -22,7 +26,8 @@ public class TimeChangeReceiver extends BroadcastReceiver {
final String action = intent.getAction(); final String action = intent.getAction();
if (sharedPrefs.getBoolean("datetime_synconconnect", true) && (action.equals(Intent.ACTION_TIME_CHANGED) || action.equals(Intent.ACTION_TIMEZONE_CHANGED))) { if (sharedPrefs.getBoolean("datetime_synconconnect", true) && (action.equals(Intent.ACTION_TIME_CHANGED) || action.equals(Intent.ACTION_TIMEZONE_CHANGED))) {
LOG.info("Time or Timezone changed, syncing with device"); Date newTime = GregorianCalendar.getInstance().getTime();
LOG.info("Time or Timezone changed, syncing with device: " + DateTimeUtils.formatDate(newTime) + " (" + newTime.toGMTString() + "), " + intent.getAction());
GBApplication.deviceService().onSetTime(); GBApplication.deviceService().onSetTime();
} }
} }

View File

@ -3,9 +3,10 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle;
import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic;
import java.text.DateFormat;
import java.util.Date; import java.util.Date;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
/** /**
* The Bluedroid implementation only allows performing one GATT request at a time. * The Bluedroid implementation only allows performing one GATT request at a time.
* As they are asynchronous anyway, we encapsulate every GATT request (read and write) * As they are asynchronous anyway, we encapsulate every GATT request (read and write)
@ -50,7 +51,7 @@ public abstract class BtLEAction {
} }
protected String getCreationTime() { protected String getCreationTime() {
return DateFormat.getTimeInstance().format(new Date(creationTimestamp)); return DateTimeUtils.formatDateTime(new Date(creationTimestamp));
} }
public String toString() { public String toString() {

View File

@ -432,22 +432,31 @@ public class PebbleProtocol extends GBDeviceProtocol {
} }
private static byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, byte type, boolean hasHandle) { private static byte[] encodeExtensibleNotification(int id, int timestamp, String title, String subtitle, String body, byte type, boolean hasHandle) {
final short ACTION_LENGTH_MIN = 10;
String[] parts = {title, subtitle, body}; String[] parts = {title, subtitle, body};
// Calculate length first // Calculate length first
String actionstring; byte actions_count;
byte action_id; short actions_length;
String dismiss_string;
String open_string = "Open on phone";
byte dismiss_action_id;
if (hasHandle) { if (hasHandle) {
actionstring = "dismiss"; actions_count = 2;
action_id = 0x02; dismiss_string = "Dismiss";
dismiss_action_id = 0x02;
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.length() + open_string.length());
} else { } else {
actionstring = "dismiss all"; actions_count = 1;
action_id = 0x03; dismiss_string = "Dismiss all";
dismiss_action_id = 0x03;
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.length() + open_string.length());
} }
byte attributes_count = 0; byte attributes_count = 0;
int length = 21 + 10 + actionstring.length(); //+ 19 int length = 21 + 10 + actions_length;
if (parts != null) { if (parts != null) {
for (String s : parts) { for (String s : parts) {
if (s == null || s.equals("")) { if (s == null || s.equals("")) {
@ -474,8 +483,8 @@ public class PebbleProtocol extends GBDeviceProtocol {
buf.putInt(0x00000000); // ANCS id buf.putInt(0x00000000); // ANCS id
buf.putInt(timestamp); buf.putInt(timestamp);
buf.put((byte) 0x01); // layout - ? buf.put((byte) 0x01); // layout - ?
buf.put(attributes_count); // length attributes buf.put(attributes_count);
buf.put((byte) 1); // len actions buf.put(actions_count);
byte attribute_id = 0; byte attribute_id = 0;
// Encode Pascal-Style Strings // Encode Pascal-Style Strings
@ -494,23 +503,24 @@ public class PebbleProtocol extends GBDeviceProtocol {
} }
} }
// ACTION
buf.put(action_id);
buf.put((byte) 0x04); // dismiss action
buf.put((byte) 0x01); // number attributes
buf.put((byte) 0x01); // attribute id (title)
buf.putShort((short) actionstring.length());
buf.put(actionstring.getBytes());
/* // dismiss action
buf.put((byte) 0x01); // id buf.put(dismiss_action_id);
buf.put((byte) 0x02); // generic action buf.put((byte) 0x04); // dismiss
buf.put((byte) 0x01); // number attributes buf.put((byte) 0x01); // number attributes
buf.put((byte) 0x01); // attribute id (title) buf.put((byte) 0x01); // attribute id (title)
actionstring = "open on phone"; buf.putShort((short) dismiss_string.length());
buf.putShort((short) actionstring.length()); buf.put(dismiss_string.getBytes());
buf.put(actionstring.getBytes());
*/ // open action
if (hasHandle) {
buf.put((byte) 0x01);
buf.put((byte) 0x02); // dissmiss - FIXME: find out how to answer to 2.x generic actions
buf.put((byte) 0x01); // number attributes
buf.put((byte) 0x01); // attribute id (title)
buf.putShort((short) open_string.length());
buf.put(open_string.getBytes());
}
return buf.array(); return buf.array();
} }
@ -547,6 +557,9 @@ public class PebbleProtocol extends GBDeviceProtocol {
} }
private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, byte type, boolean hasHandle) { private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, byte type, boolean hasHandle) {
final short NOTIFICATION_PIN_LENGTH = 46;
final short ACTION_LENGTH_MIN = 10;
String[] parts = {title, subtitle, body}; String[] parts = {title, subtitle, body};
int icon_id = 0x80000000 | 1; int icon_id = 0x80000000 | 1;
@ -558,23 +571,24 @@ public class PebbleProtocol extends GBDeviceProtocol {
icon_id = 0x80000000 | 45; icon_id = 0x80000000 | 45;
} }
// Calculate length first // Calculate length first
byte actions_count;
String actionstring; short actions_length;
byte action_id; String dismiss_string;
String open_string = "Open on phone";
byte dismiss_action_id;
if (hasHandle) { if (hasHandle) {
actionstring = "dismiss"; actions_count = 2;
action_id = 0x02; dismiss_string = "Dismiss";
dismiss_action_id = 0x02;
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.length() + open_string.length());
} else { } else {
actionstring = "dismiss all"; actions_count = 1;
action_id = 0x03; dismiss_string = "Dismiss all";
dismiss_action_id = 0x03;
actions_length = (short) (ACTION_LENGTH_MIN * actions_count + dismiss_string.length() + open_string.length());
} }
final short NOTIFICATION_PIN_LENGTH = 46;
short actions_length = (short) (10 + actionstring.length());
byte attributes_count = 1; // icon byte attributes_count = 1; // icon
byte actions_count = 1; // dismiss
short attributes_length = (short) (7 + actions_length); // icon short attributes_length = (short) (7 + actions_length); // icon
if (parts != null) { if (parts != null) {
for (String s : parts) { for (String s : parts) {
@ -599,7 +613,6 @@ public class PebbleProtocol extends GBDeviceProtocol {
buf.putLong(uuid.getMostSignificantBits()); buf.putLong(uuid.getMostSignificantBits());
buf.putInt((int) (uuid.getLeastSignificantBits() >>> 32)); buf.putInt((int) (uuid.getLeastSignificantBits() >>> 32));
buf.putInt(id); buf.putInt(id);
LOG.info("id " + id);
buf.order(ByteOrder.LITTLE_ENDIAN); buf.order(ByteOrder.LITTLE_ENDIAN);
buf.putInt(timestamp); // 32-bit timestamp buf.putInt(timestamp); // 32-bit timestamp
buf.putShort((short) 0); // duration buf.putShort((short) 0); // duration
@ -631,15 +644,23 @@ public class PebbleProtocol extends GBDeviceProtocol {
buf.putShort((short) 4); // length of int buf.putShort((short) 4); // length of int
buf.putInt(icon_id); buf.putInt(icon_id);
// ACTION // dismiss action
buf.put(action_id); buf.put(dismiss_action_id);
buf.put((byte) 0x02); // generic action, dismiss did not do anything buf.put((byte) 0x02); // generic action, dismiss did not do anything
buf.put((byte) 0x01); // number attributes buf.put((byte) 0x01); // number attributes
buf.put((byte) 0x01); // attribute id (title) buf.put((byte) 0x01); // attribute id (title)
buf.putShort((short) dismiss_string.length());
buf.put(dismiss_string.getBytes());
buf.putShort((short) actionstring.length()); // open action
buf.put(actionstring.getBytes()); if (hasHandle) {
buf.put((byte) 0x01);
buf.put((byte) 0x02); // generic action
buf.put((byte) 0x01); // number attributes
buf.put((byte) 0x01); // attribute id (title)
buf.putShort((short) open_string.length());
buf.put(open_string.getBytes());
}
return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array()); return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array());
} }
@ -1151,7 +1172,6 @@ public class PebbleProtocol extends GBDeviceProtocol {
long uuid_high = buf.getLong(); long uuid_high = buf.getLong();
long uuid_low = buf.getLong(); long uuid_low = buf.getLong();
int id = (int) (uuid_low & 0xffffffff); int id = (int) (uuid_low & 0xffffffff);
LOG.info("id " + id);
byte action = buf.get(); byte action = buf.get();
if (action >= 0x01 && action <= 0x03) { if (action >= 0x01 && action <= 0x03) {
GBDeviceEventNotificationControl dismissNotification = new GBDeviceEventNotificationControl(); GBDeviceEventNotificationControl dismissNotification = new GBDeviceEventNotificationControl();

View File

@ -12,6 +12,10 @@ import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
public class DateTimeUtils { public class DateTimeUtils {
public static String formatDateTime(Date date) {
return DateUtils.formatDateTime(GBApplication.getContext(), date.getTime(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME);
}
public static String formatDate(Date date) { public static String formatDate(Date date) {
return DateUtils.formatDateTime(GBApplication.getContext(), date.getTime(), DateUtils.FORMAT_SHOW_DATE); return DateUtils.formatDateTime(GBApplication.getContext(), date.getTime(), DateUtils.FORMAT_SHOW_DATE);
// long dateMillis = date.getTime(); // long dateMillis = date.getTime();