mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-29 05:16:51 +01:00
Refactoring
The notfification APIs now use NotificationSpec as their only parameter, which contains all information (required and optional ones). We no longer have separate methods and actions for SMS/EMAIL/GENERIC anymore. The type of notification is important now, not how we received them technically.
This commit is contained in:
parent
e1ea8270ca
commit
1d41f2f8e4
@ -101,9 +101,10 @@ public class GBApplication extends Application {
|
|||||||
* when that was not successful
|
* when that was not successful
|
||||||
* If acquiring was successful, callers must call #releaseDB when they
|
* If acquiring was successful, callers must call #releaseDB when they
|
||||||
* are done (from the same thread that acquired the lock!
|
* are done (from the same thread that acquired the lock!
|
||||||
|
*
|
||||||
* @return the DBHandler
|
* @return the DBHandler
|
||||||
* @see #releaseDB()
|
|
||||||
* @throws GBException
|
* @throws GBException
|
||||||
|
* @see #releaseDB()
|
||||||
*/
|
*/
|
||||||
public static DBHandler acquireDB() throws GBException {
|
public static DBHandler acquireDB() throws GBException {
|
||||||
try {
|
try {
|
||||||
@ -118,6 +119,7 @@ public class GBApplication extends Application {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases the database lock.
|
* Releases the database lock.
|
||||||
|
*
|
||||||
* @throws IllegalMonitorStateException if the current thread is not owning the lock
|
* @throws IllegalMonitorStateException if the current thread is not owning the lock
|
||||||
* @see #acquireDB()
|
* @see #acquireDB()
|
||||||
*/
|
*/
|
||||||
|
@ -4,12 +4,15 @@ public class GBException extends Exception {
|
|||||||
public GBException(String message, Throwable cause) {
|
public GBException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBException(String message) {
|
public GBException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBException(Throwable cause) {
|
public GBException(Throwable cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GBException() {
|
public GBException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||||
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for fragments. Provides hooks that are called when
|
* Abstract base class for fragments. Provides hooks that are called when
|
||||||
* the fragment is made visible and invisible in the activity. also allows
|
* the fragment is made visible and invisible in the activity. also allows
|
||||||
* the fragment to define the title to be shown in the activity.
|
* the fragment to define the title to be shown in the activity.
|
||||||
|
*
|
||||||
* @see AbstractGBFragmentActivity
|
* @see AbstractGBFragmentActivity
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractGBFragment extends Fragment {
|
public abstract class AbstractGBFragment extends Fragment {
|
||||||
@ -25,6 +26,7 @@ public abstract class AbstractGBFragment extends Fragment {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when this fragment has been scrolled out of the activity.
|
* Called when this fragment has been scrolled out of the activity.
|
||||||
|
*
|
||||||
* @see #isVisibleInActivity()
|
* @see #isVisibleInActivity()
|
||||||
* @see #onMadeVisibleInActivity()
|
* @see #onMadeVisibleInActivity()
|
||||||
*/
|
*/
|
||||||
@ -54,6 +56,7 @@ public abstract class AbstractGBFragment extends Fragment {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal
|
* Internal
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public void onMadeVisibleInActivityInternal() {
|
public void onMadeVisibleInActivityInternal() {
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.PersistableBundle;
|
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.app.FragmentPagerAdapter;
|
import android.support.v4.app.FragmentPagerAdapter;
|
||||||
import android.support.v4.view.PagerAdapter;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base activity that supports paging through fragments by swiping.
|
* A base activity that supports paging through fragments by swiping.
|
||||||
* Subclasses will have to add a ViewPager to their layout and add something
|
* Subclasses will have to add a ViewPager to their layout and add something
|
||||||
* like this to hook it to the fragments:
|
* like this to hook it to the fragments:
|
||||||
*
|
* <p/>
|
||||||
* <pre>
|
* <pre>
|
||||||
* // Set up the ViewPager with the sections adapter.
|
* // Set up the ViewPager with the sections adapter.
|
||||||
* ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
|
* ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
|
||||||
@ -50,6 +45,7 @@ public abstract class AbstractGBFragmentActivity extends FragmentActivity {
|
|||||||
/**
|
/**
|
||||||
* Creates a PagerAdapter that will create the fragments to be used with this
|
* Creates a PagerAdapter that will create the fragments to be used with this
|
||||||
* activity. The fragments should typically extend AbstractGBFragment
|
* activity. The fragments should typically extend AbstractGBFragment
|
||||||
|
*
|
||||||
* @param fragmentManager
|
* @param fragmentManager
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -8,9 +8,9 @@ import android.view.MenuItem;
|
|||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.TimePicker;
|
import android.widget.TimePicker;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
||||||
|
|
||||||
public class AlarmDetails extends Activity {
|
public class AlarmDetails extends Activity {
|
||||||
|
|
||||||
|
@ -12,10 +12,9 @@ import java.util.HashSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.adapter.GBAlarmListAdapter;
|
import nodomain.freeyourgadget.gadgetbridge.adapter.GBAlarmListAdapter;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
||||||
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ALARMS;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ALARMS;
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
|
@ -26,6 +26,8 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
@ -70,17 +72,25 @@ public class DebugActivity extends Activity {
|
|||||||
sendSMSButton.setOnClickListener(new View.OnClickListener() {
|
sendSMSButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
GBApplication.deviceService().onSMS(getResources().getText(R.string.app_name).toString(), editContent.getText().toString());
|
NotificationSpec notificationSpec = new NotificationSpec();
|
||||||
|
notificationSpec.sender = getResources().getText(R.string.app_name).toString();
|
||||||
|
notificationSpec.body = editContent.getText().toString();
|
||||||
|
notificationSpec.type = NotificationType.SMS;
|
||||||
|
notificationSpec.id = -1;
|
||||||
|
GBApplication.deviceService().onNotification(notificationSpec);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
sendEmailButton = (Button) findViewById(R.id.sendEmailButton);
|
sendEmailButton = (Button) findViewById(R.id.sendEmailButton);
|
||||||
sendEmailButton.setOnClickListener(new View.OnClickListener() {
|
sendEmailButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
GBApplication.deviceService().onEmail(
|
NotificationSpec notificationSpec = new NotificationSpec();
|
||||||
getResources().getText(R.string.app_name).toString(),
|
notificationSpec.sender = getResources().getText(R.string.app_name).toString();
|
||||||
getResources().getText(R.string.test).toString(),
|
notificationSpec.subject = editContent.getText().toString();
|
||||||
editContent.getText().toString());
|
notificationSpec.body = editContent.getText().toString();
|
||||||
|
notificationSpec.type = NotificationType.EMAIL;
|
||||||
|
notificationSpec.id = -1;
|
||||||
|
GBApplication.deviceService().onNotification(notificationSpec);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -24,13 +24,13 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.adapter.DeviceCandidateAdapter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.adapter.DeviceCandidateAdapter;
|
|
||||||
|
|
||||||
public class DiscoveryActivity extends Activity implements AdapterView.OnItemClickListener {
|
public class DiscoveryActivity extends Activity implements AdapterView.OnItemClickListener {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryActivity.class);
|
private static final Logger LOG = LoggerFactory.getLogger(DiscoveryActivity.class);
|
||||||
|
@ -12,7 +12,6 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ListAdapter;
|
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -4,6 +4,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails;
|
|||||||
|
|
||||||
public interface InstallActivity {
|
public interface InstallActivity {
|
||||||
void setInfoText(String text);
|
void setInfoText(String text);
|
||||||
|
|
||||||
void setInstallEnabled(boolean enable);
|
void setInstallEnabled(boolean enable);
|
||||||
|
|
||||||
void clearInstallItems();
|
void clearInstallItems();
|
||||||
|
@ -12,9 +12,12 @@ public interface ChartsHost {
|
|||||||
GBDevice getDevice();
|
GBDevice getDevice();
|
||||||
|
|
||||||
void setStartDate(Date startDate);
|
void setStartDate(Date startDate);
|
||||||
|
|
||||||
void setEndDate(Date endDate);
|
void setEndDate(Date endDate);
|
||||||
|
|
||||||
Date getStartDate();
|
Date getStartDate();
|
||||||
|
|
||||||
Date getEndDate();
|
Date getEndDate();
|
||||||
|
|
||||||
void setDateInfo(String dateInfo);
|
void setDateInfo(String dateInfo);
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
public class DeviceCandidateAdapter extends ArrayAdapter<GBDeviceCandidate> {
|
public class DeviceCandidateAdapter extends ArrayAdapter<GBDeviceCandidate> {
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
|
import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
||||||
|
|
||||||
public class GBDeviceAdapter extends ArrayAdapter<GBDevice> {
|
public class GBDeviceAdapter extends ArrayAdapter<GBDevice> {
|
||||||
|
@ -10,8 +10,8 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
||||||
|
|
||||||
public class GBDeviceAppAdapter extends ArrayAdapter<GBDeviceApp> {
|
public class GBDeviceAppAdapter extends ArrayAdapter<GBDeviceApp> {
|
||||||
|
|
||||||
|
@ -12,13 +12,13 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.schema.ActivityDBCreationScript;
|
import nodomain.freeyourgadget.gadgetbridge.database.schema.ActivityDBCreationScript;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.DATABASE_NAME;
|
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.DATABASE_NAME;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_INTENSITY;
|
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_INTENSITY;
|
||||||
@ -179,7 +179,7 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
|
|||||||
}
|
}
|
||||||
ArrayList<ActivitySample> samples = new ArrayList<ActivitySample>();
|
ArrayList<ActivitySample> samples = new ArrayList<ActivitySample>();
|
||||||
final String where = "(provider=" + provider.getID() + " and timestamp>=" + timestamp_from + " and timestamp<=" + timestamp_to + getWhereClauseFor(activityTypes, provider) + ")";
|
final String where = "(provider=" + provider.getID() + " and timestamp>=" + timestamp_from + " and timestamp<=" + timestamp_to + getWhereClauseFor(activityTypes, provider) + ")";
|
||||||
LOG.info("Activity query where: "+ where);
|
LOG.info("Activity query where: " + where);
|
||||||
final String order = "timestamp";
|
final String order = "timestamp";
|
||||||
try (SQLiteDatabase db = this.getReadableDatabase()) {
|
try (SQLiteDatabase db = this.getReadableDatabase()) {
|
||||||
try (Cursor cursor = db.query(TABLE_GBACTIVITYSAMPLES, null, where, null, null, null, order)) {
|
try (Cursor cursor = db.query(TABLE_GBACTIVITYSAMPLES, null, where, null, null, null, order)) {
|
||||||
|
@ -4,9 +4,9 @@ import android.content.Context;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
public abstract class DBAccess extends AsyncTask {
|
public abstract class DBAccess extends AsyncTask {
|
||||||
private final String mTask;
|
private final String mTask;
|
||||||
|
@ -6,8 +6,8 @@ import android.database.sqlite.SQLiteOpenHelper;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
|
|
||||||
public interface DBHandler {
|
public interface DBHandler {
|
||||||
public SQLiteOpenHelper getHelper();
|
public SQLiteOpenHelper getHelper();
|
||||||
|
@ -6,9 +6,9 @@ import android.support.annotation.Nullable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies all events that GadgetBridge intends to send to the gadget device.
|
* Specifies all events that GadgetBridge intends to send to the gadget device.
|
||||||
@ -16,11 +16,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
|||||||
* Implementations need to send/encode event to the connected device.
|
* Implementations need to send/encode event to the connected device.
|
||||||
*/
|
*/
|
||||||
public interface EventHandler {
|
public interface EventHandler {
|
||||||
void onSMS(String from, String body);
|
void onNotification(NotificationSpec notificationSpec);
|
||||||
|
|
||||||
void onEmail(String from, String subject, String body);
|
|
||||||
|
|
||||||
void onGenericNotification(String title, String details, int handle, NotificationKind notificationKind);
|
|
||||||
|
|
||||||
void onSetTime();
|
void onSetTime();
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@ import android.app.Activity;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
|
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
public class UnknownDeviceCoordinator implements DeviceCoordinator {
|
public class UnknownDeviceCoordinator implements DeviceCoordinator {
|
||||||
private final UnknownSampleProvider sampleProvider;
|
private final UnknownSampleProvider sampleProvider;
|
||||||
|
@ -9,18 +9,16 @@ import android.preference.PreferenceManager;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
public class MiBandCoordinator implements DeviceCoordinator {
|
public class MiBandCoordinator implements DeviceCoordinator {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(MiBandCoordinator.class);
|
private static final Logger LOG = LoggerFactory.getLogger(MiBandCoordinator.class);
|
||||||
|
@ -13,6 +13,7 @@ public class MiBandDateConverter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* uses the standard algorithm to convert bytes received from the MiBand to a Calendar object
|
* uses the standard algorithm to convert bytes received from the MiBand to a Calendar object
|
||||||
|
*
|
||||||
* @param value
|
* @param value
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@ -25,6 +26,7 @@ public class MiBandDateConverter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* uses the standard algorithm to convert bytes received from the MiBand to a Calendar object
|
* uses the standard algorithm to convert bytes received from the MiBand to a Calendar object
|
||||||
|
*
|
||||||
* @param value
|
* @param value
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@ -46,6 +48,7 @@ public class MiBandDateConverter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* uses the standard algorithm to convert a Calendar object to a byte array to send to MiBand
|
* uses the standard algorithm to convert a Calendar object to a byte array to send to MiBand
|
||||||
|
*
|
||||||
* @param timestamp
|
* @param timestamp
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -12,7 +12,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
|
|
||||||
public class MiBandFWHelper {
|
public class MiBandFWHelper {
|
||||||
@ -48,7 +47,7 @@ public class MiBandFWHelper {
|
|||||||
throw new IOException("Firmware has a filename that looks like a Pebble app/firmware.");
|
throw new IOException("Firmware has a filename that looks like a Pebble app/firmware.");
|
||||||
}
|
}
|
||||||
|
|
||||||
try (InputStream in = new BufferedInputStream(cr.openInputStream(uri))){
|
try (InputStream in = new BufferedInputStream(cr.openInputStream(uri))) {
|
||||||
this.fw = FileUtils.readAll(in, 1024 * 1024); // 1 MB
|
this.fw = FileUtils.readAll(in, 1024 * 1024); // 1 MB
|
||||||
if (fw.length <= firmwareVersionMajor || fw[firmwareVersionMajor] != 1) {
|
if (fw.length <= firmwareVersionMajor || fw[firmwareVersionMajor] != 1) {
|
||||||
throw new IOException("Firmware major version should be 1, probably this isn't a MiBand firmware.");
|
throw new IOException("Firmware major version should be 1, probably this isn't a MiBand firmware.");
|
||||||
|
@ -13,12 +13,11 @@ import android.widget.TextView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
|
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.activities.DiscoveryActivity;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.DiscoveryActivity;
|
|
||||||
|
|
||||||
public class MiBandPairingActivity extends Activity {
|
public class MiBandPairingActivity extends Activity {
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ import android.os.Bundle;
|
|||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
|
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
|
||||||
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_GENERIC;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_GENERIC;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_INCOMING_CALL;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_INCOMING_CALL;
|
||||||
@ -15,8 +15,8 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.OR
|
|||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_PEBBLEMSG;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_PEBBLEMSG;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_SMS;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_SMS;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ADDRESS;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_ADDRESS;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_FITNESS_GOAL;
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_DONT_ACK_TRANSFER;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_DONT_ACK_TRANSFER;
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_FITNESS_GOAL;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_WEARSIDE;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MIBAND_WEARSIDE;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_USER_ALIAS;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_USER_ALIAS;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_USER_GENDER;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_USER_GENDER;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
|
package nodomain.freeyourgadget.gadgetbridge.devices.miband;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class MiBandSampleProvider implements SampleProvider {
|
public class MiBandSampleProvider implements SampleProvider {
|
||||||
public static final byte TYPE_DEEP_SLEEP = 5;
|
public static final byte TYPE_DEEP_SLEEP = 5;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
|
package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class MorpheuzSampleProvider implements SampleProvider {
|
public class MorpheuzSampleProvider implements SampleProvider {
|
||||||
// raw types
|
// raw types
|
||||||
|
@ -10,7 +10,6 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
|
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
|
||||||
|
|
||||||
public class BluetoothStateChangeReceiver extends BroadcastReceiver {
|
public class BluetoothStateChangeReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
|
@ -13,6 +13,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
|
|
||||||
public class K9Receiver extends BroadcastReceiver {
|
public class K9Receiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@ -42,9 +44,9 @@ public class K9Receiver extends BroadcastReceiver {
|
|||||||
"uri"
|
"uri"
|
||||||
};
|
};
|
||||||
|
|
||||||
String sender = "";
|
NotificationSpec notificationSpec = new NotificationSpec();
|
||||||
String subject = "";
|
notificationSpec.id = -1;
|
||||||
String preview = "";
|
notificationSpec.type = NotificationType.EMAIL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* there seems to be no way to specify the the uri in the where clause.
|
* there seems to be no way to specify the the uri in the where clause.
|
||||||
@ -57,14 +59,14 @@ public class K9Receiver extends BroadcastReceiver {
|
|||||||
do {
|
do {
|
||||||
String uri = c.getString(c.getColumnIndex("uri"));
|
String uri = c.getString(c.getColumnIndex("uri"));
|
||||||
if (uri.equals(uriWanted)) {
|
if (uri.equals(uriWanted)) {
|
||||||
sender = c.getString(c.getColumnIndex("senderAddress"));
|
notificationSpec.sender = c.getString(c.getColumnIndex("senderAddress"));
|
||||||
subject = c.getString(c.getColumnIndex("subject"));
|
notificationSpec.subject = c.getString(c.getColumnIndex("subject"));
|
||||||
preview = c.getString(c.getColumnIndex("preview"));
|
notificationSpec.body = c.getString(c.getColumnIndex("preview"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (c.moveToNext());
|
} while (c.moveToNext());
|
||||||
c.close();
|
c.close();
|
||||||
|
|
||||||
GBApplication.deviceService().onEmail(sender, subject, preview);
|
GBApplication.deviceService().onNotification(notificationSpec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@ package nodomain.freeyourgadget.gadgetbridge.externalevents;
|
|||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -22,7 +22,8 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
||||||
|
|
||||||
public class NotificationListener extends NotificationListenerService {
|
public class NotificationListener extends NotificationListenerService {
|
||||||
@ -159,47 +160,45 @@ public class NotificationListener extends NotificationListenerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set application icons for generic notifications
|
// Set application icons for generic notifications
|
||||||
NotificationKind notificationKind;
|
NotificationSpec notificationSpec = new NotificationSpec();
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case "org.mariotaku.twidere":
|
case "org.mariotaku.twidere":
|
||||||
case "com.twitter.android":
|
case "com.twitter.android":
|
||||||
case "org.andstatus.app":
|
case "org.andstatus.app":
|
||||||
case "org.mustard.android":
|
case "org.mustard.android":
|
||||||
notificationKind = NotificationKind.TWITTER;
|
notificationSpec.type = NotificationType.TWITTER;
|
||||||
break;
|
break;
|
||||||
case "com.fsck.k9":
|
case "com.fsck.k9":
|
||||||
case "com.android.email":
|
case "com.android.email":
|
||||||
notificationKind = NotificationKind.EMAIL;
|
notificationSpec.type = NotificationType.EMAIL;
|
||||||
break;
|
break;
|
||||||
case "com.moez.QKSMS":
|
case "com.moez.QKSMS":
|
||||||
notificationKind = NotificationKind.SMS;
|
notificationSpec.type = NotificationType.SMS;
|
||||||
break;
|
break;
|
||||||
case "eu.siacs.conversations":
|
case "eu.siacs.conversations":
|
||||||
notificationKind = NotificationKind.CHAT;
|
notificationSpec.type = NotificationType.CHAT;
|
||||||
break;
|
break;
|
||||||
case "org.indywidualni.fblite":
|
case "org.indywidualni.fblite":
|
||||||
notificationKind = NotificationKind.FACEBOOK;
|
notificationSpec.type = NotificationType.FACEBOOK;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
notificationKind = NotificationKind.UNDEFINED;
|
notificationSpec.type = NotificationType.UNDEFINED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("Processing notification from source " + source);
|
LOG.info("Processing notification from source " + source);
|
||||||
|
|
||||||
Bundle extras = notification.extras;
|
Bundle extras = notification.extras;
|
||||||
String title = extras.getCharSequence(Notification.EXTRA_TITLE).toString();
|
notificationSpec.title = extras.getCharSequence(Notification.EXTRA_TITLE).toString();
|
||||||
String content = null;
|
|
||||||
if (extras.containsKey(Notification.EXTRA_TEXT)) {
|
if (extras.containsKey(Notification.EXTRA_TEXT)) {
|
||||||
CharSequence contentCS = extras.getCharSequence(Notification.EXTRA_TEXT);
|
CharSequence contentCS = extras.getCharSequence(Notification.EXTRA_TEXT);
|
||||||
if (contentCS != null) {
|
if (contentCS != null) {
|
||||||
content = contentCS.toString();
|
notificationSpec.body = contentCS.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content != null) {
|
notificationSpec.id = (int) sbn.getPostTime(); //FIMXE: a truly unique id would be better
|
||||||
GBApplication.deviceService().onGenericNotification(title, content, (int) sbn.getPostTime(), notificationKind); //FIMXE: a truly unique id would be better
|
GBApplication.deviceService().onNotification(notificationSpec);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isServiceRunning() {
|
private boolean isServiceRunning() {
|
||||||
|
@ -13,7 +13,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
|
|
||||||
public class PebbleReceiver extends BroadcastReceiver {
|
public class PebbleReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@ -33,9 +34,6 @@ public class PebbleReceiver extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String title;
|
|
||||||
String body;
|
|
||||||
|
|
||||||
String messageType = intent.getStringExtra("messageType");
|
String messageType = intent.getStringExtra("messageType");
|
||||||
if (!messageType.equals("PEBBLE_ALERT")) {
|
if (!messageType.equals("PEBBLE_ALERT")) {
|
||||||
LOG.info("non PEBBLE_ALERT message type not supported");
|
LOG.info("non PEBBLE_ALERT message type not supported");
|
||||||
@ -47,24 +45,25 @@ public class PebbleReceiver extends BroadcastReceiver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotificationSpec notificationSpec = new NotificationSpec();
|
||||||
|
|
||||||
String notificationData = intent.getStringExtra("notificationData");
|
String notificationData = intent.getStringExtra("notificationData");
|
||||||
try {
|
try {
|
||||||
JSONArray notificationJSON = new JSONArray(notificationData);
|
JSONArray notificationJSON = new JSONArray(notificationData);
|
||||||
title = notificationJSON.getJSONObject(0).getString("title");
|
notificationSpec.title = notificationJSON.getJSONObject(0).getString("title");
|
||||||
body = notificationJSON.getJSONObject(0).getString("body");
|
notificationSpec.body = notificationJSON.getJSONObject(0).getString("body");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (title != null && body != null) {
|
if (notificationSpec.title != null) {
|
||||||
NotificationKind notificationKind = NotificationKind.UNDEFINED;
|
notificationSpec.type = NotificationType.UNDEFINED;
|
||||||
String sender = intent.getStringExtra("sender");
|
String sender = intent.getStringExtra("sender");
|
||||||
if ("Conversations".equals(sender)) {
|
if ("Conversations".equals(sender)) {
|
||||||
notificationKind = NotificationKind.CHAT;
|
notificationSpec.type = NotificationType.CHAT;
|
||||||
}
|
}
|
||||||
GBApplication.deviceService().onGenericNotification(title, body, -1, notificationKind);
|
GBApplication.deviceService().onNotification(notificationSpec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ import android.preference.PreferenceManager;
|
|||||||
import android.telephony.SmsMessage;
|
import android.telephony.SmsMessage;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
|
|
||||||
public class SMSReceiver extends BroadcastReceiver {
|
public class SMSReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@ -27,16 +29,20 @@ public class SMSReceiver extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NotificationSpec notificationSpec = new NotificationSpec();
|
||||||
|
notificationSpec.id = -1;
|
||||||
|
notificationSpec.type = NotificationType.SMS;
|
||||||
|
|
||||||
Bundle bundle = intent.getExtras();
|
Bundle bundle = intent.getExtras();
|
||||||
if (bundle != null) {
|
if (bundle != null) {
|
||||||
Object[] pdus = (Object[]) bundle.get("pdus");
|
Object[] pdus = (Object[]) bundle.get("pdus");
|
||||||
for (Object pdu1 : pdus) {
|
for (Object pdu1 : pdus) {
|
||||||
byte[] pdu = (byte[]) pdu1;
|
byte[] pdu = (byte[]) pdu1;
|
||||||
SmsMessage message = SmsMessage.createFromPdu(pdu);
|
SmsMessage message = SmsMessage.createFromPdu(pdu);
|
||||||
String body = message.getDisplayMessageBody();
|
notificationSpec.body = message.getDisplayMessageBody();
|
||||||
String sender = message.getOriginatingAddress();
|
notificationSpec.phoneNumber = message.getOriginatingAddress();
|
||||||
if (sender != null && body != null) {
|
if (notificationSpec.phoneNumber != null) {
|
||||||
GBApplication.deviceService().onSMS(sender, body);
|
GBApplication.deviceService().onNotification(notificationSpec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,10 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
public class GBDevice implements Parcelable {
|
public class GBDevice implements Parcelable {
|
||||||
public static final String ACTION_DEVICE_CHANGED
|
public static final String ACTION_DEVICE_CHANGED
|
||||||
|
@ -4,9 +4,9 @@ import android.bluetooth.BluetoothDevice;
|
|||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
@ -11,7 +11,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
||||||
|
|
||||||
@ -80,29 +80,16 @@ public class GBDeviceService implements DeviceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSMS(String from, String body) {
|
public void onNotification(NotificationSpec notificationSpec) {
|
||||||
Intent intent = createIntent().setAction(ACTION_NOTIFICATION_SMS)
|
Intent intent = createIntent().setAction(ACTION_NOTIFICATION)
|
||||||
.putExtra(EXTRA_NOTIFICATION_SENDER, from)
|
.putExtra(EXTRA_NOTIFICATION_PHONENUMBER, notificationSpec.phoneNumber)
|
||||||
.putExtra(EXTRA_NOTIFICATION_BODY, body);
|
.putExtra(EXTRA_NOTIFICATION_SENDER, notificationSpec.sender)
|
||||||
invokeService(intent);
|
.putExtra(EXTRA_NOTIFICATION_SUBJECT, notificationSpec.subject)
|
||||||
}
|
.putExtra(EXTRA_NOTIFICATION_TITLE, notificationSpec.title)
|
||||||
|
.putExtra(EXTRA_NOTIFICATION_BODY, notificationSpec.body)
|
||||||
@Override
|
.putExtra(EXTRA_NOTIFICATION_ID, notificationSpec.id)
|
||||||
public void onEmail(String from, String subject, String body) {
|
.putExtra(EXTRA_NOTIFICATION_TYPE, notificationSpec.type)
|
||||||
Intent intent = createIntent().setAction(ACTION_NOTIFICATION_EMAIL)
|
.putExtra(EXTRA_NOTIFICATION_SOURCENAME, notificationSpec.sourceName);
|
||||||
.putExtra(EXTRA_NOTIFICATION_SENDER, from)
|
|
||||||
.putExtra(EXTRA_NOTIFICATION_SUBJECT, subject)
|
|
||||||
.putExtra(EXTRA_NOTIFICATION_BODY, body);
|
|
||||||
invokeService(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGenericNotification(String title, String details, int handle, NotificationKind notificationKind) {
|
|
||||||
Intent intent = createIntent().setAction(ACTION_NOTIFICATION_GENERIC)
|
|
||||||
.putExtra(EXTRA_NOTIFICATION_TITLE, title)
|
|
||||||
.putExtra(EXTRA_NOTIFICATION_BODY, details)
|
|
||||||
.putExtra(EXTRA_NOTIFICATION_HANDLE, handle)
|
|
||||||
.putExtra(EXTRA_NOTIFICATION_KIND, notificationKind);
|
|
||||||
invokeService(intent);
|
invokeService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,6 @@ package nodomain.freeyourgadget.gadgetbridge.model;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|
||||||
|
|
||||||
public class ActivityAmount {
|
public class ActivityAmount {
|
||||||
private int activityKind;
|
private int activityKind;
|
||||||
private short percent;
|
private short percent;
|
||||||
|
@ -13,9 +13,8 @@ public interface DeviceService extends EventHandler {
|
|||||||
|
|
||||||
static final String ACTION_START = PREFIX + ".action.start";
|
static final String ACTION_START = PREFIX + ".action.start";
|
||||||
static final String ACTION_CONNECT = PREFIX + ".action.connect";
|
static final String ACTION_CONNECT = PREFIX + ".action.connect";
|
||||||
static final String ACTION_NOTIFICATION_GENERIC = PREFIX + ".action.notification_generic";
|
static final String ACTION_NOTIFICATION = PREFIX + ".action.notification";
|
||||||
static final String ACTION_NOTIFICATION_SMS = PREFIX + ".action.notification_sms";
|
static final String ACTION_NOTIFICATION_SMS = PREFIX + ".action.notification_sms";
|
||||||
static final String ACTION_NOTIFICATION_EMAIL = PREFIX + ".action.notification_email";
|
|
||||||
static final String ACTION_CALLSTATE = PREFIX + ".action.callstate";
|
static final String ACTION_CALLSTATE = PREFIX + ".action.callstate";
|
||||||
static final String ACTION_SETTIME = PREFIX + ".action.settime";
|
static final String ACTION_SETTIME = PREFIX + ".action.settime";
|
||||||
static final String ACTION_SETMUSICINFO = PREFIX + ".action.setmusicinfo";
|
static final String ACTION_SETMUSICINFO = PREFIX + ".action.setmusicinfo";
|
||||||
@ -32,12 +31,14 @@ public interface DeviceService extends EventHandler {
|
|||||||
static final String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms";
|
static final String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms";
|
||||||
|
|
||||||
static final String EXTRA_DEVICE_ADDRESS = "device_address";
|
static final String EXTRA_DEVICE_ADDRESS = "device_address";
|
||||||
static final String EXTRA_NOTIFICATION_TITLE = "notification_title";
|
|
||||||
static final String EXTRA_NOTIFICATION_BODY = "notification_body";
|
static final String EXTRA_NOTIFICATION_BODY = "notification_body";
|
||||||
|
static final String EXTRA_NOTIFICATION_ID = "notification_id";
|
||||||
|
static final String EXTRA_NOTIFICATION_PHONENUMBER = "notification_phonenumber";
|
||||||
static final String EXTRA_NOTIFICATION_SENDER = "notification_sender";
|
static final String EXTRA_NOTIFICATION_SENDER = "notification_sender";
|
||||||
|
static final String EXTRA_NOTIFICATION_SOURCENAME = "notification_sourcename";
|
||||||
static final String EXTRA_NOTIFICATION_SUBJECT = "notification_subject";
|
static final String EXTRA_NOTIFICATION_SUBJECT = "notification_subject";
|
||||||
static final String EXTRA_NOTIFICATION_HANDLE = "notification_handle";
|
static final String EXTRA_NOTIFICATION_TITLE = "notification_title";
|
||||||
static final String EXTRA_NOTIFICATION_KIND = "notificationKind";
|
static final String EXTRA_NOTIFICATION_TYPE = "notification_type";
|
||||||
static final String EXTRA_FIND_START = "find_start";
|
static final String EXTRA_FIND_START = "find_start";
|
||||||
static final String EXTRA_CALL_COMMAND = "call_command";
|
static final String EXTRA_CALL_COMMAND = "call_command";
|
||||||
static final String EXTRA_CALL_PHONENUMBER = "call_phonenumber";
|
static final String EXTRA_CALL_PHONENUMBER = "call_phonenumber";
|
||||||
@ -51,15 +52,18 @@ public interface DeviceService extends EventHandler {
|
|||||||
static final String EXTRA_PERFORM_PAIR = "perform_pair";
|
static final String EXTRA_PERFORM_PAIR = "perform_pair";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
void connect();
|
void connect();
|
||||||
|
|
||||||
void connect(@Nullable String deviceAddress);
|
void connect(@Nullable String deviceAddress);
|
||||||
|
|
||||||
void connect(@Nullable String deviceAddress, boolean performPair);
|
void connect(@Nullable String deviceAddress, boolean performPair);
|
||||||
|
|
||||||
void disconnect();
|
void disconnect();
|
||||||
|
|
||||||
void quit();
|
void quit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests information from the {@link DeviceCommunicationService} about the connection state,
|
* Requests information from the {@link DeviceCommunicationService} about the connection state,
|
||||||
* firmware info, etc.
|
* firmware info, etc.
|
||||||
|
@ -2,6 +2,8 @@ package nodomain.freeyourgadget.gadgetbridge.model;
|
|||||||
|
|
||||||
public interface ItemWithDetails {
|
public interface ItemWithDetails {
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
String getDetails();
|
String getDetails();
|
||||||
|
|
||||||
int getIcon();
|
int getIcon();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.model;
|
||||||
|
|
||||||
|
public class NotificationSpec {
|
||||||
|
public int id;
|
||||||
|
public String sender;
|
||||||
|
public String phoneNumber;
|
||||||
|
public String title;
|
||||||
|
public String subject;
|
||||||
|
public String body;
|
||||||
|
public NotificationType type;
|
||||||
|
public String sourceName;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.model;
|
package nodomain.freeyourgadget.gadgetbridge.model;
|
||||||
|
|
||||||
public enum NotificationKind {
|
public enum NotificationType {
|
||||||
|
|
||||||
UNDEFINED,
|
UNDEFINED,
|
||||||
|
|
@ -26,7 +26,8 @@ import java.util.UUID;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
@ -37,9 +38,7 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_DI
|
|||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FETCH_ACTIVITY_DATA;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FETCH_ACTIVITY_DATA;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FIND_DEVICE;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_FIND_DEVICE;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_INSTALL;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_INSTALL;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION_EMAIL;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION_GENERIC;
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_NOTIFICATION_SMS;
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REBOOT;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REBOOT;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_APPINFO;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_APPINFO;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_DEVICEINFO;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_REQUEST_DEVICEINFO;
|
||||||
@ -60,11 +59,13 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUS
|
|||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ARTIST;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_ARTIST;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACK;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_MUSIC_TRACK;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_BODY;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_BODY;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_HANDLE;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_ID;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_KIND;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_PHONENUMBER;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SENDER;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SENDER;
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SOURCENAME;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SUBJECT;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_SUBJECT;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TITLE;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TITLE;
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_NOTIFICATION_TYPE;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_PERFORM_PAIR;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_PERFORM_PAIR;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_URI;
|
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_URI;
|
||||||
|
|
||||||
@ -180,26 +181,20 @@ public class DeviceCommunicationService extends Service {
|
|||||||
case ACTION_REQUEST_DEVICEINFO:
|
case ACTION_REQUEST_DEVICEINFO:
|
||||||
mGBDevice.sendDeviceUpdateIntent(this);
|
mGBDevice.sendDeviceUpdateIntent(this);
|
||||||
break;
|
break;
|
||||||
case ACTION_NOTIFICATION_GENERIC: {
|
case ACTION_NOTIFICATION: {
|
||||||
String title = intent.getStringExtra(EXTRA_NOTIFICATION_TITLE);
|
NotificationSpec notificationSpec = new NotificationSpec();
|
||||||
String body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY);
|
notificationSpec.phoneNumber = intent.getStringExtra(EXTRA_NOTIFICATION_PHONENUMBER);
|
||||||
int handle = intent.getIntExtra(EXTRA_NOTIFICATION_HANDLE, -1);
|
notificationSpec.sender = intent.getStringExtra(EXTRA_NOTIFICATION_SENDER);
|
||||||
NotificationKind notificationKind = (NotificationKind) intent.getSerializableExtra(EXTRA_NOTIFICATION_KIND);
|
notificationSpec.subject = intent.getStringExtra(EXTRA_NOTIFICATION_SUBJECT);
|
||||||
mDeviceSupport.onGenericNotification(title, body, handle, notificationKind);
|
notificationSpec.title = intent.getStringExtra(EXTRA_NOTIFICATION_TITLE);
|
||||||
break;
|
notificationSpec.body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY);
|
||||||
|
notificationSpec.type = (NotificationType) intent.getSerializableExtra(EXTRA_NOTIFICATION_TYPE);
|
||||||
|
notificationSpec.id = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1);
|
||||||
|
notificationSpec.sourceName = intent.getStringExtra(EXTRA_NOTIFICATION_SOURCENAME);
|
||||||
|
if (notificationSpec.type == NotificationType.SMS && notificationSpec.phoneNumber != null) {
|
||||||
|
notificationSpec.sender = getContactDisplayNameByNumber(notificationSpec.phoneNumber);
|
||||||
}
|
}
|
||||||
case ACTION_NOTIFICATION_SMS: {
|
mDeviceSupport.onNotification(notificationSpec);
|
||||||
String sender = intent.getStringExtra(EXTRA_NOTIFICATION_SENDER);
|
|
||||||
String body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY);
|
|
||||||
String senderName = getContactDisplayNameByNumber(sender);
|
|
||||||
mDeviceSupport.onSMS(senderName, body);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ACTION_NOTIFICATION_EMAIL: {
|
|
||||||
String sender = intent.getStringExtra(EXTRA_NOTIFICATION_SENDER);
|
|
||||||
String subject = intent.getStringExtra(EXTRA_NOTIFICATION_SUBJECT);
|
|
||||||
String body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY);
|
|
||||||
mDeviceSupport.onEmail(sender, subject, body);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ACTION_REBOOT: {
|
case ACTION_REBOOT: {
|
||||||
|
@ -22,6 +22,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|||||||
public interface DeviceSupport extends EventHandler {
|
public interface DeviceSupport extends EventHandler {
|
||||||
/**
|
/**
|
||||||
* Sets all context information needed for the instance to operate.
|
* Sets all context information needed for the instance to operate.
|
||||||
|
*
|
||||||
* @param gbDevice the device to operate with
|
* @param gbDevice the device to operate with
|
||||||
* @param btAdapter the bluetooth adapter to use
|
* @param btAdapter the bluetooth adapter to use
|
||||||
* @param context the android context, e.g. to look up resources
|
* @param context the android context, e.g. to look up resources
|
||||||
@ -30,6 +31,7 @@ public interface DeviceSupport extends EventHandler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a transport-level connection is established with the device
|
* Returns whether a transport-level connection is established with the device
|
||||||
|
*
|
||||||
* @return whether the device is connected with the system running this software
|
* @return whether the device is connected with the system running this software
|
||||||
*/
|
*/
|
||||||
boolean isConnected();
|
boolean isConnected();
|
||||||
@ -40,9 +42,10 @@ public interface DeviceSupport extends EventHandler {
|
|||||||
* Returns true if a connection attempt was made. If the implementation is synchronous
|
* Returns true if a connection attempt was made. If the implementation is synchronous
|
||||||
* it may also return true if the connection was successfully established, however
|
* it may also return true if the connection was successfully established, however
|
||||||
* callers shall not rely on that.
|
* callers shall not rely on that.
|
||||||
*
|
* <p/>
|
||||||
* The actual connection state change (successful or not) will be reported via the
|
* The actual connection state change (successful or not) will be reported via the
|
||||||
* #getDevice device as a device change Intent.
|
* #getDevice device as a device change Intent.
|
||||||
|
*
|
||||||
* @see GBDevice#ACTION_DEVICE_CHANGED
|
* @see GBDevice#ACTION_DEVICE_CHANGED
|
||||||
*/
|
*/
|
||||||
boolean connect();
|
boolean connect();
|
||||||
@ -62,6 +65,7 @@ public interface DeviceSupport extends EventHandler {
|
|||||||
/**
|
/**
|
||||||
* Attempts to pair and connect this device with the gadget device. Success
|
* Attempts to pair and connect this device with the gadget device. Success
|
||||||
* will be reported via a device change Intent.
|
* will be reported via a device change Intent.
|
||||||
|
*
|
||||||
* @see GBDevice#ACTION_DEVICE_CHANGED
|
* @see GBDevice#ACTION_DEVICE_CHANGED
|
||||||
*/
|
*/
|
||||||
void pair();
|
void pair();
|
||||||
|
@ -13,8 +13,8 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps another device support instance and supports busy-checking and throttling of events.
|
* Wraps another device support instance and supports busy-checking and throttling of events.
|
||||||
@ -25,6 +25,7 @@ public class ServiceDeviceSupport implements DeviceSupport {
|
|||||||
THROTTLING,
|
THROTTLING,
|
||||||
BUSY_CHECKING,
|
BUSY_CHECKING,
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ServiceDeviceSupport.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ServiceDeviceSupport.class);
|
||||||
|
|
||||||
private static final long THROTTLING_THRESHOLD = 1000; // throttle multiple events in between one second
|
private static final long THROTTLING_THRESHOLD = 1000; // throttle multiple events in between one second
|
||||||
@ -112,27 +113,11 @@ public class ServiceDeviceSupport implements DeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSMS(String from, String body) {
|
public void onNotification(NotificationSpec notificationSpec) {
|
||||||
if (checkBusy("sms") || checkThrottle("sms")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delegate.onSMS(from, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEmail(String from, String subject, String body) {
|
|
||||||
if (checkBusy("email") || checkThrottle("email")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delegate.onEmail(from, subject, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGenericNotification(String title, String details, int handle, NotificationKind notificationKind) {
|
|
||||||
if (checkBusy("generic notification") || checkThrottle("generic notification")) {
|
if (checkBusy("generic notification") || checkThrottle("generic notification")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
delegate.onGenericNotification(title, details, handle, notificationKind);
|
delegate.onNotification(notificationSpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -14,10 +14,10 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|||||||
* Abstract base class for a BTLEOperation, i.e. an operation that does more than
|
* Abstract base class for a BTLEOperation, i.e. an operation that does more than
|
||||||
* just sending a few bytes to the device. It typically involves exchanging many messages
|
* just sending a few bytes to the device. It typically involves exchanging many messages
|
||||||
* between the mobile and the device.
|
* between the mobile and the device.
|
||||||
*
|
* <p/>
|
||||||
* One operation may execute multiple @{link Transaction transactions} with each
|
* One operation may execute multiple @{link Transaction transactions} with each
|
||||||
* multiple @{link BTLEAction actions}.
|
* multiple @{link BTLEAction actions}.
|
||||||
*
|
* <p/>
|
||||||
* This class implements GattCallback so that subclasses may override those methods
|
* This class implements GattCallback so that subclasses may override those methods
|
||||||
* to handle those events.
|
* to handle those events.
|
||||||
* Note: by default all Gatt events are forwarded to AbstractBTLEDeviceSupport, subclasses may override
|
* Note: by default all Gatt events are forwarded to AbstractBTLEDeviceSupport, subclasses may override
|
||||||
@ -33,6 +33,7 @@ public abstract class AbstractBTLEOperation<T extends AbstractBTLEDeviceSupport>
|
|||||||
/**
|
/**
|
||||||
* Delegates to the DeviceSupport instance and additionally sets this instance as the Gatt
|
* Delegates to the DeviceSupport instance and additionally sets this instance as the Gatt
|
||||||
* callback for the transaction.
|
* callback for the transaction.
|
||||||
|
*
|
||||||
* @param taskName
|
* @param taskName
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
|
@ -2,8 +2,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.btle;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.MiBandSupport;
|
|
||||||
|
|
||||||
public interface BTLEOperation {
|
public interface BTLEOperation {
|
||||||
public void perform() throws IOException;
|
public void perform() throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -207,6 +207,7 @@ public final class BtLEQueue {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Depending on certain criteria, connects to the BluetoothGatt.
|
* Depending on certain criteria, connects to the BluetoothGatt.
|
||||||
|
*
|
||||||
* @return true if a reconnection attempt was made, or false otherwise
|
* @return true if a reconnection attempt was made, or false otherwise
|
||||||
*/
|
*/
|
||||||
private boolean maybeReconnect() {
|
private boolean maybeReconnect() {
|
||||||
@ -275,7 +276,9 @@ public final class BtLEQueue {
|
|||||||
// Implements callback methods for GATT events that the app cares about. For example,
|
// Implements callback methods for GATT events that the app cares about. For example,
|
||||||
// connection change and services discovered.
|
// connection change and services discovered.
|
||||||
private final class InternalGattCallback extends BluetoothGattCallback {
|
private final class InternalGattCallback extends BluetoothGattCallback {
|
||||||
private @Nullable GattCallback mTransactionGattCallback;
|
private
|
||||||
|
@Nullable
|
||||||
|
GattCallback mTransactionGattCallback;
|
||||||
private GattCallback mExternalGattCallback;
|
private GattCallback mExternalGattCallback;
|
||||||
|
|
||||||
public InternalGattCallback(GattCallback externalGattCallback) {
|
public InternalGattCallback(GattCallback externalGattCallback) {
|
||||||
@ -449,5 +452,7 @@ public final class BtLEQueue {
|
|||||||
}
|
}
|
||||||
mTransactionGattCallback = null;
|
mTransactionGattCallback = null;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ public class Transaction {
|
|||||||
private String mName;
|
private String mName;
|
||||||
private List<BtLEAction> mActions = new ArrayList<>(4);
|
private List<BtLEAction> mActions = new ArrayList<>(4);
|
||||||
private long creationTimestamp = System.currentTimeMillis();
|
private long creationTimestamp = System.currentTimeMillis();
|
||||||
private @Nullable GattCallback gattCallback;
|
private
|
||||||
|
@Nullable
|
||||||
|
GattCallback gattCallback;
|
||||||
|
|
||||||
public Transaction(String taskName) {
|
public Transaction(String taskName) {
|
||||||
this.mName = taskName;
|
this.mName = taskName;
|
||||||
@ -57,7 +59,9 @@ public class Transaction {
|
|||||||
/**
|
/**
|
||||||
* Returns the GattCallback for this transaction, or null if none.
|
* Returns the GattCallback for this transaction, or null if none.
|
||||||
*/
|
*/
|
||||||
public @Nullable GattCallback getGattCallback() {
|
public
|
||||||
|
@Nullable
|
||||||
|
GattCallback getGattCallback() {
|
||||||
return gattCallback;
|
return gattCallback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,13 +64,16 @@ public class TransactionBuilder {
|
|||||||
/**
|
/**
|
||||||
* Sets a GattCallback instance that will be called when the transaction is executed,
|
* Sets a GattCallback instance that will be called when the transaction is executed,
|
||||||
* resulting in GattCallback events.
|
* resulting in GattCallback events.
|
||||||
|
*
|
||||||
* @param callback the callback to set, may be null
|
* @param callback the callback to set, may be null
|
||||||
*/
|
*/
|
||||||
public void setGattCallback(@Nullable GattCallback callback) {
|
public void setGattCallback(@Nullable GattCallback callback) {
|
||||||
mTransaction.setGattCallback(callback);
|
mTransaction.setGattCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable GattCallback getGattCallback() {
|
public
|
||||||
|
@Nullable
|
||||||
|
GattCallback getGattCallback() {
|
||||||
return mTransaction.getGattCallback();
|
return mTransaction.getGattCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ public class SetProgressAction extends PlainAction {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* When run, will update the progress notification.
|
* When run, will update the progress notification.
|
||||||
|
*
|
||||||
* @param text
|
* @param text
|
||||||
* @param ongoing
|
* @param ongoing
|
||||||
* @param percentage
|
* @param percentage
|
||||||
|
@ -28,8 +28,8 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
@ -54,6 +54,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.FL
|
|||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.FLASH_ORIGINAL_COLOUR;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.FLASH_ORIGINAL_COLOUR;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_GENERIC;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_GENERIC;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_K9MAIL;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_K9MAIL;
|
||||||
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_PEBBLEMSG;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_SMS;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.ORIGIN_SMS;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VIBRATION_COUNT;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VIBRATION_COUNT;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VIBRATION_DURATION;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.VIBRATION_DURATION;
|
||||||
@ -402,19 +403,22 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSMS(String from, String body) {
|
public void onNotification(NotificationSpec notificationSpec) {
|
||||||
|
// FIXME: these ORIGIN contants do not really make sense anymore
|
||||||
|
switch (notificationSpec.type) {
|
||||||
|
case SMS:
|
||||||
performPreferredNotification("sms received", ORIGIN_SMS, null);
|
performPreferredNotification("sms received", ORIGIN_SMS, null);
|
||||||
}
|
break;
|
||||||
|
case EMAIL:
|
||||||
@Override
|
|
||||||
public void onEmail(String from, String subject, String body) {
|
|
||||||
performPreferredNotification("email received", ORIGIN_K9MAIL, null);
|
performPreferredNotification("email received", ORIGIN_K9MAIL, null);
|
||||||
}
|
break;
|
||||||
|
case CHAT:
|
||||||
@Override
|
performPreferredNotification("chat message received", ORIGIN_PEBBLEMSG, null);
|
||||||
public void onGenericNotification(String title, String details, int handle, NotificationKind notificationKind) {
|
break;
|
||||||
|
default:
|
||||||
performPreferredNotification("generic notification received", ORIGIN_GENERIC, null);
|
performPreferredNotification("generic notification received", ORIGIN_GENERIC, null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSetTime() {
|
public void onSetTime() {
|
||||||
@ -598,7 +602,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
|||||||
handleBatteryInfo(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
|
handleBatteryInfo(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS);
|
||||||
} else if (MiBandService.UUID_CHARACTERISTIC_NOTIFICATION.equals(characteristicUUID)) {
|
} else if (MiBandService.UUID_CHARACTERISTIC_NOTIFICATION.equals(characteristicUUID)) {
|
||||||
handleNotificationNotif(characteristic.getValue());
|
handleNotificationNotif(characteristic.getValue());
|
||||||
} else{
|
} else {
|
||||||
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
|
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,12 +151,11 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
|
|||||||
* There are two kind of messages we currently know:
|
* There are two kind of messages we currently know:
|
||||||
* - the first one is 11 bytes long and contains metadata (how many bytes to expect, when the data starts, etc.)
|
* - the first one is 11 bytes long and contains metadata (how many bytes to expect, when the data starts, etc.)
|
||||||
* - the second one is 20 bytes long and contains the actual activity data
|
* - the second one is 20 bytes long and contains the actual activity data
|
||||||
*
|
* <p/>
|
||||||
* The first message type is parsed by this method, for every other length of the value param, bufferActivityData is called.
|
* The first message type is parsed by this method, for every other length of the value param, bufferActivityData is called.
|
||||||
* @see #bufferActivityData(byte[])
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
|
* @see #bufferActivityData(byte[])
|
||||||
*/
|
*/
|
||||||
private void handleActivityNotif(byte[] value) {
|
private void handleActivityNotif(byte[] value) {
|
||||||
if (value.length == 11) {
|
if (value.length == 11) {
|
||||||
@ -205,7 +204,7 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to store temporarily the activity data values got from the Mi Band.
|
* Method to store temporarily the activity data values got from the Mi Band.
|
||||||
*
|
* <p/>
|
||||||
* Since we expect chunks of 20 bytes each, we do not store the received bytes it the length is different.
|
* Since we expect chunks of 20 bytes each, we do not store the received bytes it the length is different.
|
||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
@ -275,7 +274,7 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Acknowledge the transfer of activity data to the Mi Band.
|
* Acknowledge the transfer of activity data to the Mi Band.
|
||||||
*
|
* <p/>
|
||||||
* After receiving data from the band, it has to be acknowledged. This way the Mi Band will delete
|
* After receiving data from the band, it has to be acknowledged. This way the Mi Band will delete
|
||||||
* the data it has on record.
|
* the data it has on record.
|
||||||
*
|
*
|
||||||
|
@ -72,21 +72,21 @@ public class UpdateFirmwareOperation extends AbstractBTLEOperation<MiBandSupport
|
|||||||
* characteristic,
|
* characteristic,
|
||||||
* These messages appear to be always 1 byte long, with values that are listed in MiBandService.
|
* These messages appear to be always 1 byte long, with values that are listed in MiBandService.
|
||||||
* It is not excluded that there are further values which are still unknown.
|
* It is not excluded that there are further values which are still unknown.
|
||||||
*
|
* <p/>
|
||||||
* Upon receiving known values that request further action by GB, the appropriate method is called.
|
* Upon receiving known values that request further action by GB, the appropriate method is called.
|
||||||
*
|
*
|
||||||
* @param value
|
* @param value
|
||||||
*/
|
*/
|
||||||
private void handleNotificationNotif(byte[] value) {
|
private void handleNotificationNotif(byte[] value) {
|
||||||
if(value.length != 1) {
|
if (value.length != 1) {
|
||||||
LOG.error("Notifications should be 1 byte long.");
|
LOG.error("Notifications should be 1 byte long.");
|
||||||
getSupport().logMessageContent(value);
|
getSupport().logMessageContent(value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (value[0]) {
|
switch (value[0]) {
|
||||||
case MiBandService.NOTIFY_FW_CHECK_SUCCESS:
|
case MiBandService.NOTIFY_FW_CHECK_SUCCESS:
|
||||||
if(firmwareInfoSent && newFirmware != null) {
|
if (firmwareInfoSent && newFirmware != null) {
|
||||||
if(sendFirmwareData(newFirmware)) {
|
if (sendFirmwareData(newFirmware)) {
|
||||||
rebootWhenBandReady = true;
|
rebootWhenBandReady = true;
|
||||||
} else {
|
} else {
|
||||||
//TODO: the firmware transfer failed, but the miband should be still functional with the old firmware. What should we do?
|
//TODO: the firmware transfer failed, but the miband should be still functional with the old firmware. What should we do?
|
||||||
@ -131,14 +131,14 @@ public class UpdateFirmwareOperation extends AbstractBTLEOperation<MiBandSupport
|
|||||||
* Prepare the MiBand to receive the new firmware data.
|
* Prepare the MiBand to receive the new firmware data.
|
||||||
* Some information about the new firmware version have to be pushed to the MiBand before sending
|
* Some information about the new firmware version have to be pushed to the MiBand before sending
|
||||||
* the actual firmare.
|
* the actual firmare.
|
||||||
*
|
* <p/>
|
||||||
* The Mi Band will send a notification after receiving these data to confirm if the metadata looks good to it.
|
* The Mi Band will send a notification after receiving these data to confirm if the metadata looks good to it.
|
||||||
* @see MiBandSupport#handleNotificationNotif
|
|
||||||
*
|
*
|
||||||
* @param currentFwVersion
|
* @param currentFwVersion
|
||||||
* @param newFwVersion
|
* @param newFwVersion
|
||||||
* @param newFwSize
|
* @param newFwSize
|
||||||
* @param checksum
|
* @param checksum
|
||||||
|
* @see MiBandSupport#handleNotificationNotif
|
||||||
*/
|
*/
|
||||||
private void sendFirmwareInfo(int currentFwVersion, int newFwVersion, int newFwSize, int checksum) throws IOException {
|
private void sendFirmwareInfo(int currentFwVersion, int newFwVersion, int newFwSize, int checksum) throws IOException {
|
||||||
byte[] fwInfo = new byte[]{
|
byte[] fwInfo = new byte[]{
|
||||||
@ -165,13 +165,13 @@ public class UpdateFirmwareOperation extends AbstractBTLEOperation<MiBandSupport
|
|||||||
/**
|
/**
|
||||||
* Method that uploads a firmware (fwbytes) to the MiBand.
|
* Method that uploads a firmware (fwbytes) to the MiBand.
|
||||||
* The firmware has to be splitted into chunks of 20 bytes each, and periodically a COMMAND_SYNC comand has to be issued to the MiBand.
|
* The firmware has to be splitted into chunks of 20 bytes each, and periodically a COMMAND_SYNC comand has to be issued to the MiBand.
|
||||||
*
|
* <p/>
|
||||||
* The Mi Band will send a notification after receiving these data to confirm if the firmware looks good to it.
|
* The Mi Band will send a notification after receiving these data to confirm if the firmware looks good to it.
|
||||||
* @see MiBandSupport#handleNotificationNotif
|
|
||||||
*
|
*
|
||||||
* @param fwbytes
|
* @param fwbytes
|
||||||
* @return whether the transfer succeeded or not. Only a BT layer exception will cause the transmission to fail.
|
* @return whether the transfer succeeded or not. Only a BT layer exception will cause the transmission to fail.
|
||||||
* */
|
* @see MiBandSupport#handleNotificationNotif
|
||||||
|
*/
|
||||||
private boolean sendFirmwareData(byte fwbytes[]) {
|
private boolean sendFirmwareData(byte fwbytes[]) {
|
||||||
int len = fwbytes.length;
|
int len = fwbytes.length;
|
||||||
final int packetLength = 20;
|
final int packetLength = 20;
|
||||||
|
@ -30,7 +30,8 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInf
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleColor;
|
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleColor;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleIconID;
|
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleIconID;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||||
|
|
||||||
@ -384,7 +385,21 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] encodeNotification(int id, String title, String subtitle, String body, byte type, boolean hasHandle, NotificationKind notificationKind) {
|
@Override
|
||||||
|
public byte[] encodeNotification(NotificationSpec notificationSpec) {
|
||||||
|
boolean hasHandle = notificationSpec.id != -1;
|
||||||
|
int id = notificationSpec.id != -1 ? notificationSpec.id : mRandom.nextInt();
|
||||||
|
String title;
|
||||||
|
String subtitle = null;
|
||||||
|
|
||||||
|
// for SMS and EMAIL that came in though SMS or K9 receiver
|
||||||
|
if (notificationSpec.sender != null) {
|
||||||
|
title = notificationSpec.sender;
|
||||||
|
subtitle = notificationSpec.subject;
|
||||||
|
} else {
|
||||||
|
title = notificationSpec.title;
|
||||||
|
}
|
||||||
|
|
||||||
Long ts = System.currentTimeMillis();
|
Long ts = System.currentTimeMillis();
|
||||||
if (!isFw3x) {
|
if (!isFw3x) {
|
||||||
ts += (SimpleTimeZone.getDefault().getOffset(ts));
|
ts += (SimpleTimeZone.getDefault().getOffset(ts));
|
||||||
@ -394,33 +409,18 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
if (isFw3x) {
|
if (isFw3x) {
|
||||||
// 3.x notification
|
// 3.x notification
|
||||||
//return encodeTimelinePin(id, (int) ((ts + 600) & 0xffffffffL), (short) 90, PebbleIconID.TIMELINE_CALENDAR, title); // really, this is just for testing
|
//return encodeTimelinePin(id, (int) ((ts + 600) & 0xffffffffL), (short) 90, PebbleIconID.TIMELINE_CALENDAR, title); // really, this is just for testing
|
||||||
return encodeBlobdbNotification(id, (int) (ts & 0xffffffffL), title, subtitle, body, type, hasHandle, notificationKind);
|
return encodeBlobdbNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, hasHandle, notificationSpec.type);
|
||||||
} else if (mForceProtocol || type != NOTIFICATION_EMAIL) {
|
} else if (mForceProtocol || notificationSpec.type != NotificationType.EMAIL) {
|
||||||
// 2.x notification
|
// 2.x notification
|
||||||
return encodeExtensibleNotification(id, (int) (ts & 0xffffffffL), title, subtitle, body, type, hasHandle);
|
return encodeExtensibleNotification(id, (int) (ts & 0xffffffffL), title, subtitle, notificationSpec.body, hasHandle);
|
||||||
} else {
|
} else {
|
||||||
// 1.x notification on FW 2.X
|
// 1.x notification on FW 2.X
|
||||||
String[] parts = {title, body, ts.toString(), subtitle};
|
String[] parts = {title, notificationSpec.body, ts.toString(), subtitle};
|
||||||
// be aware that type is at this point always NOTIFICATION_EMAIL
|
// be aware that type is at this point always NOTIFICATION_EMAIL
|
||||||
return encodeMessage(ENDPOINT_NOTIFICATION, type, 0, parts);
|
return encodeMessage(ENDPOINT_NOTIFICATION, NOTIFICATION_EMAIL, 0, parts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] encodeSMS(String from, String body) {
|
|
||||||
return encodeNotification(mRandom.nextInt(), from, null, body, NOTIFICATION_SMS, false, NotificationKind.UNDEFINED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] encodeEmail(String from, String subject, String body) {
|
|
||||||
return encodeNotification(mRandom.nextInt(), from, subject, body, NOTIFICATION_EMAIL, false, NotificationKind.UNDEFINED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] encodeGenericNotification(String title, String details, int handle, NotificationKind notificationKind) {
|
|
||||||
return encodeNotification(handle != -1 ? handle : mRandom.nextInt(), title, null, details, NOTIFICATION_UNDEFINED, handle != -1, notificationKind);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] encodeSetTime() {
|
public byte[] encodeSetTime() {
|
||||||
long ts = System.currentTimeMillis();
|
long ts = System.currentTimeMillis();
|
||||||
@ -455,7 +455,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
return encodeSetCallState("Where are you?", "Gadgetbridge", start ? ServiceCommand.CALL_INCOMING : ServiceCommand.CALL_END);
|
return encodeSetCallState("Where are you?", "Gadgetbridge", start ? ServiceCommand.CALL_INCOMING : ServiceCommand.CALL_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
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, boolean hasHandle) {
|
||||||
final short ACTION_LENGTH_MIN = 10;
|
final short ACTION_LENGTH_MIN = 10;
|
||||||
|
|
||||||
String[] parts = {title, subtitle, body};
|
String[] parts = {title, subtitle, body};
|
||||||
@ -619,7 +619,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
return encodeBlobdb(uuid, BLOBDB_INSERT, BLOBDB_PIN, buf.array());
|
return encodeBlobdb(uuid, BLOBDB_INSERT, BLOBDB_PIN, buf.array());
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, byte type, boolean hasHandle, NotificationKind notificationKind) {
|
private byte[] encodeBlobdbNotification(int id, int timestamp, String title, String subtitle, String body, boolean hasHandle, NotificationType notificationType) {
|
||||||
final short NOTIFICATION_PIN_LENGTH = 46;
|
final short NOTIFICATION_PIN_LENGTH = 46;
|
||||||
final short ACTION_LENGTH_MIN = 10;
|
final short ACTION_LENGTH_MIN = 10;
|
||||||
|
|
||||||
@ -627,17 +627,17 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
|||||||
|
|
||||||
int icon_id;
|
int icon_id;
|
||||||
byte color_id;
|
byte color_id;
|
||||||
switch (type) {
|
switch (notificationType) {
|
||||||
case NOTIFICATION_EMAIL:
|
case EMAIL:
|
||||||
icon_id = PebbleIconID.GENERIC_EMAIL;
|
icon_id = PebbleIconID.GENERIC_EMAIL;
|
||||||
color_id = PebbleColor.JaegerGreen;
|
color_id = PebbleColor.JaegerGreen;
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_SMS:
|
case SMS:
|
||||||
icon_id = PebbleIconID.GENERIC_SMS;
|
icon_id = PebbleIconID.GENERIC_SMS;
|
||||||
color_id = PebbleColor.VividViolet;
|
color_id = PebbleColor.VividViolet;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch (notificationKind) {
|
switch (notificationType) {
|
||||||
case TWITTER:
|
case TWITTER:
|
||||||
icon_id = PebbleIconID.NOTIFICATION_TWITTER;
|
icon_id = PebbleIconID.NOTIFICATION_TWITTER;
|
||||||
color_id = PebbleColor.BlueMoon;
|
color_id = PebbleColor.BlueMoon;
|
||||||
|
@ -51,6 +51,6 @@ public class WeatherNeatSupport {
|
|||||||
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
|
||||||
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
|
||||||
sendBytes.encodedBytes = encodeWeatherNeatMessage("Berlin", "22 C", "cloudy", 0);
|
sendBytes.encodedBytes = encodeWeatherNeatMessage("Berlin", "22 C", "cloudy", 0);
|
||||||
return new GBDeviceEvent[] {sendBytes};
|
return new GBDeviceEvent[]{sendBytes};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import java.util.UUID;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler;
|
import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
|
||||||
|
|
||||||
@ -108,20 +108,8 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSMS(String from, String body) {
|
public void onNotification(NotificationSpec notificationSpec) {
|
||||||
byte[] bytes = gbDeviceProtocol.encodeSMS(from, body);
|
byte[] bytes = gbDeviceProtocol.encodeNotification(notificationSpec);
|
||||||
sendToDevice(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEmail(String from, String subject, String body) {
|
|
||||||
byte[] bytes = gbDeviceProtocol.encodeEmail(from, subject, body);
|
|
||||||
sendToDevice(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGenericNotification(String title, String details, int handle, NotificationKind notificationKind) {
|
|
||||||
byte[] bytes = gbDeviceProtocol.encodeGenericNotification(title, details, handle, notificationKind);
|
|
||||||
sendToDevice(bytes);
|
sendToDevice(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,20 +3,12 @@ package nodomain.freeyourgadget.gadgetbridge.service.serial;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand;
|
||||||
|
|
||||||
public abstract class GBDeviceProtocol {
|
public abstract class GBDeviceProtocol {
|
||||||
|
|
||||||
public byte[] encodeSMS(String from, String body) {
|
public byte[] encodeNotification(NotificationSpec notificationSpec) {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] encodeEmail(String from, String subject, String body) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] encodeGenericNotification(String title, String details, int handle, NotificationKind notificationKind) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,10 @@ import java.util.List;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.UnknownDeviceCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.UnknownDeviceCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleCoordinator;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||||
|
|
||||||
public class DeviceHelper {
|
public class DeviceHelper {
|
||||||
private static DeviceHelper instance = new DeviceHelper();
|
private static DeviceHelper instance = new DeviceHelper();
|
||||||
|
@ -51,6 +51,7 @@ public class FileUtils {
|
|||||||
* Reads the contents of the given InputStream into a byte array, but does not
|
* Reads the contents of the given InputStream into a byte array, but does not
|
||||||
* read more than maxLen bytes. If the stream provides more than maxLen bytes,
|
* read more than maxLen bytes. If the stream provides more than maxLen bytes,
|
||||||
* an IOException is thrown.
|
* an IOException is thrown.
|
||||||
|
*
|
||||||
* @param in the stream to read from
|
* @param in the stream to read from
|
||||||
* @param maxLen the maximum number of bytes to read/return
|
* @param maxLen the maximum number of bytes to read/return
|
||||||
* @return the bytes read from the InputStream
|
* @return the bytes read from the InputStream
|
||||||
|
@ -355,7 +355,7 @@ public class GB {
|
|||||||
notificationIntent, 0);
|
notificationIntent, 0);
|
||||||
|
|
||||||
NotificationCompat.Builder nb = new NotificationCompat.Builder(context)
|
NotificationCompat.Builder nb = new NotificationCompat.Builder(context)
|
||||||
.setContentTitle( context.getString(R.string.notif_battery_low_title))
|
.setContentTitle(context.getString(R.string.notif_battery_low_title))
|
||||||
.setContentText(text)
|
.setContentText(text)
|
||||||
.setContentIntent(pendingIntent)
|
.setContentIntent(pendingIntent)
|
||||||
.setSmallIcon(R.drawable.ic_notification_low_battery)
|
.setSmallIcon(R.drawable.ic_notification_low_battery)
|
||||||
|
Loading…
Reference in New Issue
Block a user