1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-28 19:45:50 +01:00

added option to track notification count with activity hand

This commit is contained in:
dakhnod 2019-10-20 01:42:31 +02:00
parent b6c744c8c6
commit 2a96f762af
6 changed files with 154 additions and 35 deletions

View File

@ -3,21 +3,17 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.IBinder;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@ -29,6 +25,8 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
@ -54,9 +52,6 @@ import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
public class ConfigActivity extends AbstractGBActivity {
@ -225,9 +220,9 @@ public class ConfigActivity extends AbstractGBActivity {
});
device = GBApplication.app().getDeviceManager().getSelectedDevice();
if(device == null || device.getType() != DeviceType.FOSSILQHYBRID){
if (device == null || device.getType() != DeviceType.FOSSILQHYBRID) {
setSettingsError("Watch not connected");
}else{
} else {
updateSettings();
}
}
@ -251,9 +246,9 @@ public class ConfigActivity extends AbstractGBActivity {
public void run() {
EditText et = findViewById(R.id.stepGoalEt);
et.setOnEditorActionListener(null);
//final String text = device.getDeviceInfo(QHybridSupport.ITEM_STEP_GOAL).getDetails();
//et.setText(text);
//et.setSelection(text.length());
final String text = device.getDeviceInfo(QHybridSupport.ITEM_STEP_GOAL).getDetails();
et.setText(text);
et.setSelection(text.length());
et.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
@ -272,16 +267,42 @@ public class ConfigActivity extends AbstractGBActivity {
}
});
if(device.getDeviceInfo(QHybridSupport.ITEM_EXTENDED_VIBRATION_SUPPORT).getDetails().equals("true")){
if (device.getDeviceInfo(QHybridSupport.ITEM_EXTENDED_VIBRATION_SUPPORT).getDetails().equals("true")) {
final int strengthProgress = (int) (Math.log(Double.parseDouble(device.getDeviceInfo(QHybridSupport.ITEM_VIBRATION_STRENGTH).getDetails()) / 25) / Math.log(2));
setSettingsEnabled(true);
SeekBar seekBar = findViewById(R.id.vibrationStrengthBar);
seekBar.setProgress(strengthProgress);
}else{
} else {
findViewById(R.id.vibrationStrengthBar).setEnabled(false);
findViewById(R.id.vibrationStrengthLayout).setAlpha(0.5f);
}
CheckBox activityHandCheckbox = findViewById(R.id.checkBoxUserActivityHand);
if (device.getDeviceInfo(QHybridSupport.ITEM_HAS_ACTIVITY_HAND).getDetails().equals("true")) {
if (device.getDeviceInfo(QHybridSupport.ITEM_USE_ACTIVITY_HAND).getDetails().equals("true")) {
activityHandCheckbox.setChecked(true);
}
activityHandCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
if(!device.getDeviceInfo(QHybridSupport.ITEM_STEP_GOAL).getDetails().equals("1000000")){
new AlertDialog.Builder(ConfigActivity.this)
.setMessage("Please set the step count to a million to activate that.")
.setPositiveButton("ok", null)
.show();
buttonView.setChecked(false);
return;
}
device.addDeviceInfo(new GenericItem(QHybridSupport.ITEM_USE_ACTIVITY_HAND, String.valueOf(checked)));
Intent intent = new Intent(QHybridSupport.QHYBRID_COMMAND_UPDATE_SETTINGS);
intent.putExtra("EXTRA_SETTING", QHybridSupport.ITEM_USE_ACTIVITY_HAND);
LocalBroadcastManager.getInstance(ConfigActivity.this).sendBroadcast(intent);
}
});
} else {
activityHandCheckbox.setEnabled(false);
activityHandCheckbox.setAlpha(0.5f);
}
}
});
}
@ -429,8 +450,8 @@ public class ConfigActivity extends AbstractGBActivity {
BroadcastReceiver fileReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
boolean error = intent.getBooleanExtra("EXTRA_ERROR",false);
if(error){
boolean error = intent.getBooleanExtra("EXTRA_ERROR", false);
if (error) {
Toast.makeText(ConfigActivity.this, "Error overwriting buttons", Toast.LENGTH_SHORT).show();
return;
}

View File

@ -629,6 +629,9 @@ public class NotificationListener extends NotificationListenerService {
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
LOG.info("Notification removed: " + sbn.getPackageName());
int originalId = (int) mNotificationHandleLookup.lookupByValue(sbn.getPostTime());
if (GBApplication.isRunningLollipopOrLater()) {
LOG.info("Notification removed: " + sbn.getPackageName() + ", category: " + sbn.getNotification().category);
if (Notification.CATEGORY_CALL.equals(sbn.getNotification().category) && activeCallPostTime == sbn.getPostTime()) {
@ -638,17 +641,14 @@ public class NotificationListener extends NotificationListenerService {
GBApplication.deviceService().onSetCallState(callSpec);
}
}
// FIXME: DISABLED for now
/*
if (shouldIgnore(sbn))
return;
Prefs prefs = GBApplication.getPrefs();
if (prefs.getBoolean("autoremove_notifications", false)) {
if (prefs.getBoolean("autoremove_notifications", true)) {
LOG.info("notification removed, will ask device to delete it");
GBApplication.deviceService().onDeleteNotification((int) sbn.getPostTime());
GBApplication.deviceService().onDeleteNotification(originalId);
}
*/
}

View File

@ -1,17 +1,14 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.util.SparseArray;
import android.widget.Toast;
@ -23,6 +20,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.NoSuchElementException;
@ -32,6 +30,7 @@ import java.util.UUID;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
@ -39,7 +38,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfig;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
@ -64,8 +62,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Pla
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.ReleaseHandsControlRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.RequestHandControlRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetCountdownSettings;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetCurrentTimeServiceRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetCurrentStepCountRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetStepGoalRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetTimeRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetVibrationStrengthRequest;
@ -93,6 +90,8 @@ public class QHybridSupport extends QHybridBaseSupport {
public static final String ITEM_VIBRATION_STRENGTH = "VIBRATION_STRENGTH";
public static final String ITEM_ACTIVITY_POINT = "ACTIVITY_POINT";
public static final String ITEM_EXTENDED_VIBRATION_SUPPORT = "EXTENDED_VIBRATION";
public static final String ITEM_HAS_ACTIVITY_HAND = "HAS_ACTIVITY_HAND";
public static final String ITEM_USE_ACTIVITY_HAND = "USE_ACTIVITY_HAND";
private static final Logger logger = LoggerFactory.getLogger(QHybridSupport.class);
@ -114,6 +113,10 @@ public class QHybridSupport extends QHybridBaseSupport {
private String modelNumber;
private boolean useActivityHand;
ArrayList<Integer> notificationStack = new ArrayList<>();
public QHybridSupport() {
super(logger);
addSupportedService(UUID.fromString("3dda0001-957f-7d4a-34a6-74696673696d"));
@ -132,6 +135,16 @@ public class QHybridSupport extends QHybridBaseSupport {
fillResponseList();
}
private boolean supportsActivityHand() {
switch (modelNumber) {
case "HL.0.0":
return false;
case "HW.0.0":
return true;
}
throw new UnsupportedOperationException();
}
private boolean supportsExtendedVibration() {
switch (modelNumber) {
case "HL.0.0":
@ -175,12 +188,22 @@ public class QHybridSupport extends QHybridBaseSupport {
private void queueWrite(Request request) {
new TransactionBuilder(request.getClass().getSimpleName()).write(getCharacteristic(request.getRequestUUID()), request.getRequestData()).queue(getQueue());
if (request instanceof FileRequest) this.fileRequest = request;
if (!request.expectsResponse()) {
try {
queueWrite(requestQueue.remove());
} catch (NoSuchElementException e) {
}
}
}
@Override
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
this.useActivityHand = GBApplication.getPrefs().getBoolean("QHYBRID_USE_ACTIVITY_HAND", false);
getDevice().addDeviceInfo(new GenericItem(ITEM_USE_ACTIVITY_HAND, String.valueOf(this.useActivityHand)));
getDevice().setNotificationIconConnected(R.drawable.ic_notification_qhybrid);
getDevice().setNotificationIconDisconnected(R.drawable.ic_notification_disconnected_qhybrid);
@ -190,6 +213,7 @@ public class QHybridSupport extends QHybridBaseSupport {
requestQueue.add(new GetCurrentStepCountRequest());
requestQueue.add(new GetVibrationStrengthRequest());
requestQueue.add(new ActivityPointGetRequest());
requestQueue.add(prepareSetTimeRequest());
requestQueue.add(new AnimationRequest());
Request initialRequest = new GetStepGoalRequest();
@ -237,6 +261,24 @@ public class QHybridSupport extends QHybridBaseSupport {
}
playNotification(config);
notificationStack.remove(Integer.valueOf(notificationSpec.getId()));
notificationStack.add(Integer.valueOf(notificationSpec.getId()));
showNotificationCountOnActivityHand();
}
@Override
public void onDeleteNotification(int id) {
super.onDeleteNotification(id);
notificationStack.remove(Integer.valueOf(id));
showNotificationCountOnActivityHand();
}
private void showNotificationCountOnActivityHand(){
if(useActivityHand){
setActivityHand(notificationStack.size() / 4.0);
}
}
private void playNotification(PackageConfig config) {
@ -245,13 +287,17 @@ public class QHybridSupport extends QHybridBaseSupport {
@Override
public void onSetTime() {
queueWrite(prepareSetTimeRequest());
}
private SetTimeRequest prepareSetTimeRequest() {
long millis = System.currentTimeMillis();
TimeZone zone = new GregorianCalendar().getTimeZone();
SetTimeRequest request = new SetTimeRequest(
(int) (millis / 1000 + timeOffset * 60),
(short) (millis % 1000),
(short) ((zone.getRawOffset() + zone.getDSTSavings()) / 60000));
queueWrite(request);
return request;
}
@Override
@ -303,7 +349,8 @@ public class QHybridSupport extends QHybridBaseSupport {
//queueWrite(new SetCountdownSettings(secs, secs + 10, (short) 120));
//queueWrite(new GetCountdownSettingsRequest());
queueWrite(new AnimationRequest());
// queueWrite(new AnimationRequest());
queueWrite(new SetCurrentStepCountRequest(1000000));
}
private void overwriteButtons() {
@ -360,6 +407,7 @@ public class QHybridSupport extends QHybridBaseSupport {
gbDevice.setName(getModelNameByModelNumber(modelNumber));
try {
gbDevice.addDeviceInfo(new GenericItem(ITEM_EXTENDED_VIBRATION_SUPPORT, String.valueOf(supportsExtendedVibration())));
gbDevice.addDeviceInfo(new GenericItem(ITEM_HAS_ACTIVITY_HAND, String.valueOf(supportsActivityHand())));
} catch (UnsupportedOperationException e) {
GB.toast("Please contact dakhnod@gmail.com\n", Toast.LENGTH_SHORT, GB.INFO);
gbDevice.addDeviceInfo(new GenericItem(ITEM_EXTENDED_VIBRATION_SUPPORT, "false"));
@ -391,10 +439,12 @@ public class QHybridSupport extends QHybridBaseSupport {
return true;
}
private String getModelNameByModelNumber(String modelNumber){
switch (modelNumber){
case "HW.0.0": return "Q Commuter";
case "HL.0.0": return "Q Activist";
private String getModelNameByModelNumber(String modelNumber) {
switch (modelNumber) {
case "HW.0.0":
return "Q Commuter";
case "HL.0.0":
return "Q Activist";
}
return "unknwon Q";
}
@ -459,6 +509,10 @@ public class QHybridSupport extends QHybridBaseSupport {
return super.onCharacteristicChanged(gatt, characteristic);
}
private void setActivityHand(double progress){
queueWrite(new SetCurrentStepCountRequest(Math.min((int)(1000000 * progress), 999999)));
}
private boolean handleFileUploadCharacteristic(BluetoothGattCharacteristic characteristic) {
if (uploadFileRequest == null) {
logger.debug("no uploadFileRequest to handle response");
@ -623,6 +677,7 @@ public class QHybridSupport extends QHybridBaseSupport {
}
private final BroadcastReceiver commandReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
@ -669,7 +724,12 @@ public class QHybridSupport extends QHybridBaseSupport {
break;
}
case ITEM_STEP_GOAL: {
queueWrite(new SetStepGoalRequest(Short.parseShort(gbDevice.getDeviceInfo(ITEM_STEP_GOAL).getDetails())));
queueWrite(new SetStepGoalRequest(Integer.parseInt(gbDevice.getDeviceInfo(ITEM_STEP_GOAL).getDetails())));
break;
}
case ITEM_USE_ACTIVITY_HAND: {
QHybridSupport.this.useActivityHand = gbDevice.getDeviceInfo(ITEM_USE_ACTIVITY_HAND).getDetails().equals("true");
GBApplication.getPrefs().getPreferences().edit().putBoolean("QHYBRID_USE_ACTIVITY_HAND", useActivityHand).apply();
break;
}
}

View File

@ -0,0 +1,22 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
import java.nio.ByteBuffer;
public class SetCurrentStepCountRequest extends Request {
public SetCurrentStepCountRequest(int steps){
super();
ByteBuffer buffer = createBuffer();
buffer.putInt(steps);
this.data = buffer.array();
}
@Override
public int getPayloadLength() {
return 6;
}
@Override
public byte[] getStartSequence() {
return new byte[]{2, 17};
}
}

View File

@ -53,4 +53,13 @@ public class LimitedQueue {
}
return null;
}
synchronized public Object lookupByValue(Object value){
for (Pair entry : list) {
if (value.equals(entry.second)) {
return entry.first;
}
}
return null;
}
}

View File

@ -70,6 +70,13 @@
android:layout_height="wrap_content"
android:text="overwrite buttons" />
<CheckBox
android:id="@+id/checkBoxUserActivityHand"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="use activity hand as notification counter" />
</LinearLayout>
<!-- <ProgressBar