diff --git a/wear/build.gradle b/wear/build.gradle
index 241fedbe9a..26779263e2 100644
--- a/wear/build.gradle
+++ b/wear/build.gradle
@@ -27,6 +27,7 @@ android {
resValue "string", "label_xdrip", "AAPS"
resValue "string", "label_xdrip_large", "AAPS(Large)"
resValue "string", "label_xdrip_big_chart", "AAPS(BigChart)"
+ resValue "string", "label_xdrip_no_chart", "AAPS(NoChart)"
resValue "string", "label_xdrip_circle", "AAPS(Circle)"
resValue "string", "label_xdrip_activity", "AAPS Prefs."
resValue "string", "app_settings", "AAPS Settings"
@@ -39,6 +40,7 @@ android {
resValue "string", "label_xdrip", "AAPS"
resValue "string", "label_xdrip_large", "AAPS(Large)"
resValue "string", "label_xdrip_big_chart", "AAPS(BigChart)"
+ resValue "string", "label_xdrip_no_chart", "AAPS(NoChart)"
resValue "string", "label_xdrip_circle", "AAPS(Circle)"
resValue "string", "label_xdrip_activity", "AAPS Prefs."
resValue "string", "app_settings", "AAPS Settings"
diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml
index 8909f8a3f8..fc40e930cd 100644
--- a/wear/src/main/AndroidManifest.xml
+++ b/wear/src/main/AndroidManifest.xml
@@ -34,6 +34,24 @@
+
+
+
+
+
+
+
+
+
+
bgDataList = new ArrayList<>();
+ public ArrayList tempWatchDataList = new ArrayList<>();
+ public ArrayList basalWatchDataList = new ArrayList<>();
+ public PowerManager.WakeLock wakeLock;
+ public View layoutView;
+ private final Point displaySize = new Point();
+ private int specW, specH;
+ private int animationAngle = 0;
+ private boolean isAnimated = false;
+
+ private LocalBroadcastManager localBroadcastManager;
+ private MessageReceiver messageReceiver;
+
+ protected SharedPreferences sharedPrefs;
+ private String sgvString = "--";
+ private String externalStatusString = "no status";
+ private TextView statusView;
+ private long sgvTapTime = 0l;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE))
+ .getDefaultDisplay();
+ display.getSize(displaySize);
+ wakeLock = ((PowerManager) getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Clock");
+
+ specW = View.MeasureSpec.makeMeasureSpec(displaySize.x,
+ View.MeasureSpec.EXACTLY);
+ specH = View.MeasureSpec.makeMeasureSpec(displaySize.y,
+ View.MeasureSpec.EXACTLY);
+ sharedPrefs = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ sharedPrefs.registerOnSharedPreferenceChangeListener(this);
+ LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ layoutView = inflater.inflate(R.layout.activity_nochart, null);
+ performViewSetup();
+ }
+
+ @Override
+ protected void onLayout(WatchShape shape, Rect screenBounds, WindowInsets screenInsets) {
+ super.onLayout(shape, screenBounds, screenInsets);
+ layoutView.onApplyWindowInsets(screenInsets);
+ }
+
+ public void performViewSetup() {
+ final WatchViewStub stub = (WatchViewStub) layoutView.findViewById(R.id.watch_view_stub);
+ IntentFilter messageFilter = new IntentFilter(Intent.ACTION_SEND);
+
+ messageReceiver = new MessageReceiver();
+ localBroadcastManager = LocalBroadcastManager.getInstance(this);
+ localBroadcastManager.registerReceiver(messageReceiver, messageFilter);
+
+ stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
+ @Override
+ public void onLayoutInflated(WatchViewStub stub) {
+ mTime = (TextView) stub.findViewById(R.id.watch_time);
+ mSgv = (TextView) stub.findViewById(R.id.sgv);
+ mTimestamp = (TextView) stub.findViewById(R.id.timestamp);
+ mDelta = (TextView) stub.findViewById(R.id.delta);
+ mAvgDelta = (TextView) stub.findViewById(R.id.avgdelta);
+ mRelativeLayout = (RelativeLayout) stub.findViewById(R.id.main_layout);
+ statusView = (TextView) stub.findViewById(R.id.aps_status);
+ layoutSet = true;
+ showAgeAndStatus();
+ mRelativeLayout.measure(specW, specH);
+ mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(),
+ mRelativeLayout.getMeasuredHeight());
+ }
+ });
+ ListenerService.requestData(this);
+ wakeLock.acquire(50);
+ }
+
+ @Override
+ protected void onTapCommand(int tapType, int x, int y, long eventTime) {
+
+ int extra = mSgv!=null?(mSgv.getRight() - mSgv.getLeft())/2:0;
+
+ if (tapType == TAP_TYPE_TAP&&
+ x + extra >=mSgv.getLeft() &&
+ x - extra <= mSgv.getRight()&&
+ y >= mSgv.getTop() &&
+ y <= mSgv.getBottom()){
+ if (eventTime - sgvTapTime < 800){
+ Intent intent = new Intent(this, MainMenuActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ }
+ sgvTapTime = eventTime;
+ }
+ }
+
+ protected void onWatchModeChanged(WatchMode watchMode) {
+
+ if(lowResMode ^ isLowRes(watchMode)){ //if there was a change in lowResMode
+ lowResMode = isLowRes(watchMode);
+ setColor();
+ } else if (! sharedPrefs.getBoolean("dark", true)){
+ //in bright mode: different colours if active:
+ setColor();
+ }
+ }
+
+ private boolean isLowRes(WatchMode watchMode) {
+ return (watchMode == WatchMode.LOW_BIT) || (watchMode == WatchMode.LOW_BIT_BURN_IN) || (watchMode == WatchMode.LOW_BIT_BURN_IN);
+ }
+
+
+ @Override
+ protected WatchFaceStyle getWatchFaceStyle(){
+ return new WatchFaceStyle.Builder(this).setAcceptsTapEvents(true).build();
+ }
+
+
+
+ public int ageLevel() {
+ if(timeSince() <= (1000 * 60 * 12)) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ public double timeSince() {
+ return System.currentTimeMillis() - datetime;
+ }
+
+ public String readingAge(boolean shortString) {
+ if (datetime == 0) { return shortString?"--'":"-- Minute ago"; }
+ int minutesAgo = (int) Math.floor(timeSince()/(1000*60));
+ if (minutesAgo == 1) {
+ return minutesAgo + (shortString?"'":" Minute ago");
+ }
+ return minutesAgo + (shortString?"'":" Minutes ago");
+ }
+
+ @Override
+ public void onDestroy() {
+ if(localBroadcastManager != null && messageReceiver != null){
+ localBroadcastManager.unregisterReceiver(messageReceiver);}
+ if (sharedPrefs != null){
+ sharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
+ }
+ super.onDestroy();
+ }
+
+ static {
+ INTENT_FILTER = new IntentFilter();
+ INTENT_FILTER.addAction(Intent.ACTION_TIME_TICK);
+ INTENT_FILTER.addAction(Intent.ACTION_TIMEZONE_CHANGED);
+ INTENT_FILTER.addAction(Intent.ACTION_TIME_CHANGED);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if(layoutSet) {
+ this.mRelativeLayout.draw(canvas);
+ Log.d("onDraw", "draw");
+ }
+ }
+
+ @Override
+ protected void onTimeChanged(WatchFaceTime oldTime, WatchFaceTime newTime) {
+ if (layoutSet && (newTime.hasHourChanged(oldTime) || newTime.hasMinuteChanged(oldTime))) {
+ wakeLock.acquire(50);
+ final java.text.DateFormat timeFormat = DateFormat.getTimeFormat(NOChart.this);
+ mTime.setText(timeFormat.format(System.currentTimeMillis()));
+ showAgeAndStatus();
+
+ if(ageLevel()<=0) {
+ mSgv.setPaintFlags(mSgv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
+ } else {
+ mSgv.setPaintFlags(mSgv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
+ }
+
+ missedReadingAlert();
+ mRelativeLayout.measure(specW, specH);
+ mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(),
+ mRelativeLayout.getMeasuredHeight());
+ }
+ }
+
+ public class MessageReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Bundle bundle = intent.getBundleExtra("data");
+ if (layoutSet && bundle !=null) {
+ DataMap dataMap = DataMap.fromBundle(bundle);
+ wakeLock.acquire(50);
+ sgvLevel = dataMap.getLong("sgvLevel");
+ batteryLevel = dataMap.getInt("batteryLevel");
+ datetime = dataMap.getDouble("timestamp");
+ sgvString = dataMap.getString("sgvString");
+ mSgv.setText(dataMap.getString("sgvString"));
+
+ if(ageLevel()<=0) {
+ mSgv.setPaintFlags(mSgv.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
+ } else {
+ mSgv.setPaintFlags(mSgv.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
+ }
+
+ final java.text.DateFormat timeFormat = DateFormat.getTimeFormat(NOChart.this);
+ mTime.setText(timeFormat.format(System.currentTimeMillis()));
+
+ showAgeAndStatus();
+
+ String delta = dataMap.getString("delta");
+
+ if (delta.endsWith(" mg/dl")) {
+ mDelta.setText(delta.substring(0, delta.length() - 6));
+ } else if (delta.endsWith(" mmol/l")||delta.endsWith(" mmol")) {
+ mDelta.setText(delta.substring(0, delta.length() - 5));
+ } else {
+ mDelta.setText(delta);
+ }
+
+
+ String avgDelta = dataMap.getString("avgDelta");
+
+ if (delta.endsWith(" mg/dl")) {
+ mAvgDelta.setText(avgDelta.substring(0, avgDelta.length() - 6));
+ } else if (avgDelta.endsWith(" mmol/l")||avgDelta.endsWith(" mmol")) {
+ mAvgDelta.setText(avgDelta.substring(0, avgDelta.length() - 5));
+ } else {
+ mAvgDelta.setText(avgDelta);
+ }
+
+ mRelativeLayout.measure(specW, specH);
+ mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(),
+ mRelativeLayout.getMeasuredHeight());
+ invalidate();
+ setColor();
+
+ //start animation?
+ // dataMap.getDataMapArrayList("entries") == null -> not on "resend data".
+ if (!lowResMode && (sharedPrefs.getBoolean("animation", false) && dataMap.getDataMapArrayList("entries") == null && (sgvString.equals("100") || sgvString.equals("5.5") || sgvString.equals("5,5")))) {
+ startAnimation();
+ }
+ }
+ //status
+ bundle = intent.getBundleExtra("status");
+ if (layoutSet && bundle != null) {
+ DataMap dataMap = DataMap.fromBundle(bundle);
+ wakeLock.acquire(50);
+ externalStatusString = dataMap.getString("externalStatusString");
+
+ showAgeAndStatus();
+
+ mRelativeLayout.measure(specW, specH);
+ mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(),
+ mRelativeLayout.getMeasuredHeight());
+ invalidate();
+ setColor();
+ }
+ //basals and temps
+ bundle = intent.getBundleExtra("basals");
+ if (layoutSet && bundle != null) {
+ DataMap dataMap = DataMap.fromBundle(bundle);
+ wakeLock.acquire(500);
+
+ loadBasalsAndTemps(dataMap);
+
+ mRelativeLayout.measure(specW, specH);
+ mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(),
+ mRelativeLayout.getMeasuredHeight());
+ invalidate();
+ setColor();
+ }
+ }
+ }
+
+ private void loadBasalsAndTemps(DataMap dataMap) {
+ ArrayList temps = dataMap.getDataMapArrayList("temps");
+ if (temps != null) {
+ tempWatchDataList = new ArrayList<>();
+ for (DataMap temp : temps) {
+ TempWatchData twd = new TempWatchData();
+ twd.startTime = temp.getLong("starttime");
+ twd.startBasal = temp.getDouble("startBasal");
+ twd.endTime = temp.getLong("endtime");
+ twd.endBasal = temp.getDouble("endbasal");
+ twd.amount = temp.getDouble("amount");
+ tempWatchDataList.add(twd);
+ }
+ }
+ ArrayList basals = dataMap.getDataMapArrayList("basals");
+ if (basals != null) {
+ basalWatchDataList = new ArrayList<>();
+ for (DataMap basal : basals) {
+ BasalWatchData bwd = new BasalWatchData();
+ bwd.startTime = basal.getLong("starttime");
+ bwd.endTime = basal.getLong("endtime");
+ bwd.amount = basal.getDouble("amount");
+ basalWatchDataList.add(bwd);
+ }
+ }
+ }
+
+ private void showAgeAndStatus() {
+
+ if( mTimestamp != null){
+ mTimestamp.setText(readingAge(true));
+ }
+ boolean showAvgDelta = sharedPrefs.getBoolean("showAvgDelta", true);
+
+ if(showAvgDelta){
+ mAvgDelta.setVisibility(View.VISIBLE);
+ } else {
+ mAvgDelta.setVisibility(View.GONE);
+ }
+ statusView.setText(externalStatusString);
+ statusView.setVisibility(View.VISIBLE);
+ }
+
+ public void setColor() {
+ if(lowResMode){
+ setColorLowRes();
+ } else if (sharedPrefs.getBoolean("dark", true)) {
+ setColorDark();
+ } else {
+ setColorBright();
+ }
+
+ }
+
+
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){
+ setColor();
+ if(layoutSet){
+ showAgeAndStatus();
+ mRelativeLayout.measure(specW, specH);
+ mRelativeLayout.layout(0, 0, mRelativeLayout.getMeasuredWidth(),
+ mRelativeLayout.getMeasuredHeight());
+ }
+ invalidate();
+ }
+
+ protected void updateRainbow() {
+ animationAngle = (animationAngle + 1) % 360;
+ //Animation matrix:
+ int[] rainbow = {Color.RED, Color.YELLOW, Color.GREEN, Color.BLUE
+ , Color.CYAN};
+ Shader shader = new LinearGradient(0, 0, 0, 20, rainbow,
+ null, Shader.TileMode.MIRROR);
+ Matrix matrix = new Matrix();
+ matrix.setRotate(animationAngle);
+ shader.setLocalMatrix(matrix);
+ mSgv.getPaint().setShader(shader);
+ invalidate();
+ }
+
+ private synchronized void setIsAnimated(boolean isAnimated) {
+ this.isAnimated = isAnimated;
+ }
+
+ void startAnimation() {
+ Log.d("CircleWatchface", "start startAnimation");
+
+ Thread animator = new Thread() {
+
+
+ public void run() {
+ setIsAnimated(true);
+ for (int i = 0; i <= 8 * 1000 / 40; i++) {
+ updateRainbow();
+ try {
+ Thread.sleep(40);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ mSgv.getPaint().setShader(null);
+ setIsAnimated(false);
+ invalidate();
+ setColor();
+
+ System.gc();
+ }
+ };
+
+ animator.start();
+ }
+
+ protected void setColorLowRes() {
+ mTime.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mTime));
+ statusView.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_statusView));
+ mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background));
+ mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor));
+ mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor));
+ mAvgDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor));
+ mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_Timestamp));
+ }
+
+ protected void setColorDark() {
+ mTime.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mTime));
+ statusView.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_statusView));
+ mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background));
+ if (sgvLevel == 1) {
+ mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_highColor));
+ mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_highColor));
+ mAvgDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_highColor));
+ } else if (sgvLevel == 0) {
+ mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor));
+ mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor));
+ mAvgDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor));
+ } else if (sgvLevel == -1) {
+ mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_lowColor));
+ mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_lowColor));
+ mAvgDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_lowColor));
+ }
+
+ if (ageLevel == 1) {
+ mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_Timestamp));
+ } else {
+ mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_TimestampOld));
+ }
+ }
+
+
+ protected void setColorBright() {
+
+ if (getCurrentWatchMode() == WatchMode.INTERACTIVE) {
+ mTime.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_bigchart_time));
+ statusView.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_bigchart_status));
+ mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.light_background));
+ if (sgvLevel == 1) {
+ mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_highColor));
+ mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_highColor));
+ mAvgDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_highColor));
+ } else if (sgvLevel == 0) {
+ mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_midColor));
+ mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_midColor));
+ mAvgDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_midColor));
+ } else if (sgvLevel == -1) {
+ mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_lowColor));
+ mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_lowColor));
+ mAvgDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_lowColor));
+ }
+
+ if (ageLevel == 1) {
+ mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_mTimestamp1));
+ } else {
+ mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_mTimestamp));
+ }
+ } else {
+ setColorDark();
+ }
+ }
+
+ public void missedReadingAlert() {
+ int minutes_since = (int) Math.floor(timeSince()/(1000*60));
+ if(minutes_since >= 16 && ((minutes_since - 16) % 5) == 0) {
+ ListenerService.requestData(this); // attempt endTime recover missing data
+ }
+ }
+}
\ No newline at end of file
diff --git a/wear/src/main/res/drawable/watchface_nochart.png b/wear/src/main/res/drawable/watchface_nochart.png
new file mode 100755
index 0000000000..c0e9e67747
Binary files /dev/null and b/wear/src/main/res/drawable/watchface_nochart.png differ
diff --git a/wear/src/main/res/layout/activity_nochart.xml b/wear/src/main/res/layout/activity_nochart.xml
new file mode 100644
index 0000000000..4b7198aa78
--- /dev/null
+++ b/wear/src/main/res/layout/activity_nochart.xml
@@ -0,0 +1,12 @@
+
+
diff --git a/wear/src/main/res/layout/rect_activity_nochart.xml b/wear/src/main/res/layout/rect_activity_nochart.xml
new file mode 100644
index 0000000000..47938873b2
--- /dev/null
+++ b/wear/src/main/res/layout/rect_activity_nochart.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/wear/src/main/res/layout/round_activity_nochart.xml b/wear/src/main/res/layout/round_activity_nochart.xml
new file mode 100644
index 0000000000..47938873b2
--- /dev/null
+++ b/wear/src/main/res/layout/round_activity_nochart.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+