timmo001

Watchface.java

Aug 20th, 2016
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 25.33 KB | None | 0 0
  1. package tech.timmo.terminalwatch;
  2.  
  3. import android.annotation.SuppressLint;
  4. import android.content.BroadcastReceiver;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.IntentFilter;
  8. import android.content.SharedPreferences;
  9. import android.content.pm.PackageManager;
  10. import android.content.res.Resources;
  11. import android.graphics.Canvas;
  12. import android.graphics.Color;
  13. import android.graphics.Paint;
  14. import android.graphics.Rect;
  15. import android.os.AsyncTask;
  16. import android.os.Bundle;
  17. import android.os.Handler;
  18. import android.os.Message;
  19. import android.preference.PreferenceManager;
  20. import android.support.annotation.NonNull;
  21. import android.support.annotation.Nullable;
  22. import android.support.v4.content.ContextCompat;
  23. import android.support.wearable.watchface.CanvasWatchFaceService;
  24. import android.support.wearable.watchface.WatchFaceStyle;
  25. import android.text.format.DateFormat;
  26. import android.util.Log;
  27. import android.view.SurfaceHolder;
  28. import android.view.WindowInsets;
  29.  
  30. import com.google.android.gms.common.ConnectionResult;
  31. import com.google.android.gms.common.Scopes;
  32. import com.google.android.gms.common.api.GoogleApiClient;
  33. import com.google.android.gms.common.api.ResultCallback;
  34. import com.google.android.gms.common.api.Scope;
  35. import com.google.android.gms.common.api.Status;
  36. import com.google.android.gms.fitness.Fitness;
  37. import com.google.android.gms.fitness.data.DataPoint;
  38. import com.google.android.gms.fitness.data.DataSource;
  39. import com.google.android.gms.fitness.data.DataType;
  40. import com.google.android.gms.fitness.data.Field;
  41. import com.google.android.gms.fitness.data.Value;
  42. import com.google.android.gms.fitness.request.DataSourcesRequest;
  43. import com.google.android.gms.fitness.request.OnDataPointListener;
  44. import com.google.android.gms.fitness.request.SensorRequest;
  45. import com.google.android.gms.fitness.result.DataSourcesResult;
  46. import com.google.android.gms.wearable.DataApi;
  47. import com.google.android.gms.wearable.DataEvent;
  48. import com.google.android.gms.wearable.DataEventBuffer;
  49. import com.google.android.gms.wearable.DataItem;
  50. import com.google.android.gms.wearable.DataMap;
  51. import com.google.android.gms.wearable.DataMapItem;
  52. import com.google.android.gms.wearable.Wearable;
  53.  
  54. import java.lang.ref.WeakReference;
  55. import java.util.ArrayList;
  56. import java.util.Calendar;
  57. import java.util.TimeZone;
  58. import java.util.concurrent.TimeUnit;
  59.  
  60. import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
  61.  
  62. public class WatchFace extends CanvasWatchFaceService implements
  63.         DataApi.DataListener,
  64.         GoogleApiClient.ConnectionCallbacks,
  65.         GoogleApiClient.OnConnectionFailedListener {
  66.  
  67.     private static final String TAG = WatchFace.class.getSimpleName();
  68.     private static final long INTERACTIVE_UPDATE_RATE_MS = TimeUnit.SECONDS.toMillis(1);
  69.     private static final long GET_EXTRAS_UPDATE_RATE_MS = TimeUnit.MINUTES.toMillis(1);
  70.     private static final int MSG_UPDATE_TIME = 0;
  71.     boolean permissionsGranted;
  72.     private String user, hostname, mPhoneBatt, mCurrTemp, mHeartRate = "";
  73.     private int timeFormat, dateFormat;
  74.     private boolean period;
  75.     private GoogleApiClient googleApiClient;
  76.     private OnDataPointListener onDataPointListener;
  77.  
  78.     @Override
  79.     public void onCreate() {
  80.         super.onCreate();
  81.  
  82.         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
  83.         // Check for permissions
  84.         if (!checkPermissions() && preferences.getBoolean(Utility.PREF_FIRST_RUN, true)) {
  85.             startActivity(new Intent(WatchFace.this, WatchFacePermissionActivity.class)
  86.                     .setFlags(FLAG_ACTIVITY_NEW_TASK));
  87.         }
  88.         preferences.edit().putBoolean(Utility.PREF_FIRST_RUN, false).apply();
  89.  
  90.         permissionsGranted = checkPermissions();
  91.         Log.d(TAG, permissionsGranted ? "Permissions Granted!" : "Permissions Denied.");
  92.  
  93.         googleApiClient = new GoogleApiClient.Builder(this)
  94.                 .addApi(Wearable.API)
  95.                 .addConnectionCallbacks(this)
  96.                 .addOnConnectionFailedListener(this)
  97.                 .addApi(Fitness.SENSORS_API)
  98.                 .addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
  99.                 .build();
  100.         googleApiClient.connect();
  101.     }
  102.  
  103.     @Override
  104.     public void onDestroy() {
  105.         super.onDestroy();
  106.         Wearable.DataApi.removeListener(googleApiClient, this);
  107.         Fitness.SensorsApi.remove(
  108.                 googleApiClient,
  109.                 onDataPointListener)
  110.                 .setResultCallback(new ResultCallback<Status>() {
  111.                     @Override
  112.                     public void onResult(@NonNull Status status) {
  113.                         if (status.isSuccess()) {
  114.                             Log.i(TAG, "Listener was removed!");
  115.                         } else {
  116.                             Log.i(TAG, "Listener was not removed.");
  117.                         }
  118.                     }
  119.                 });
  120.         googleApiClient.disconnect();
  121.     }
  122.  
  123.     @Override
  124.     public void onConnected(@Nullable Bundle bundle) {
  125.         Wearable.DataApi.addListener(googleApiClient, this);
  126.         Log.i(TAG, "Connected!");
  127.  
  128.         if (permissionsGranted) {
  129.             // Now you can make calls to the Fitness APIs.
  130.             Fitness.SensorsApi.findDataSources(googleApiClient, new DataSourcesRequest.Builder()
  131.                     // At least one datatype must be specified.
  132.                     .setDataTypes(DataType.TYPE_HEART_RATE_BPM)
  133.                     // Can specify whether data type is raw or derived.
  134.                     .setDataSourceTypes(DataSource.TYPE_RAW)
  135.                     .build())
  136.                     .setResultCallback(new ResultCallback<DataSourcesResult>() {
  137.                         @Override
  138.                         public void onResult(@NonNull DataSourcesResult dataSourcesResult) {
  139.                             Log.i(TAG, "Result: " + dataSourcesResult.getStatus().toString());
  140.                             for (DataSource dataSource : dataSourcesResult.getDataSources()) {
  141.                                 Log.i(TAG, "Data source found: " + dataSource.toString());
  142.                                 Log.i(TAG, "Data Source type: " + dataSource.getDataType().getName());
  143.  
  144.                                 mHeartRate = dataSource.getDataType().equals(DataType.TYPE_HEART_RATE_BPM)
  145.                                         ? dataSource.toString() + " BPM" : "";
  146.  
  147.                                 //Let's register a listener to receive Activity data!
  148.                                 if (dataSource.getDataType().equals(DataType.TYPE_HEART_RATE_BPM)
  149.                                         && onDataPointListener == null) {
  150.                                     Log.i(TAG, "Data source for LOCATION_SAMPLE found!  Registering.");
  151.                                     registerFitnessDataListener(dataSource);
  152.                                 }
  153.                             }
  154.                         }
  155.                     });
  156.         }
  157.     }
  158.  
  159.     @Override
  160.     public void onConnectionSuspended(int i) {
  161.         // If your connection to the sensor gets lost at some point,
  162.         // you'll be able to determine the reason and react to it here.
  163.         if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
  164.             Log.i(TAG, "Connection lost.  Cause: Network Lost.");
  165.         } else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
  166.             Log.i(TAG, "Connection lost.  Reason: Service Disconnected");
  167.         }
  168.     }
  169.  
  170.     @Override
  171.     public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
  172.         Log.e(TAG, "Google Play services connection failed: " + connectionResult);
  173.     }
  174.  
  175.     @Override
  176.     public Engine onCreateEngine() {
  177.         return new Engine();
  178.     }
  179.  
  180.     @Override
  181.     public void onDataChanged(DataEventBuffer dataEvents) {
  182.         for (DataEvent event : dataEvents) {
  183.             if (event.getType() == DataEvent.TYPE_CHANGED) {
  184.                 // DataItem changed
  185.                 DataItem item = event.getDataItem();
  186.                 if (item.getUri().getPath().compareTo("/prefs") == 0) {
  187.                     DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
  188.                     updateFacePrefs(
  189.                             dataMap.getString(Utility.PREF_USER),
  190.                             dataMap.getString(Utility.PREF_HOSTNAME),
  191.                             dataMap.getInt(Utility.PREF_TIME_FORMAT),
  192.                             dataMap.getBoolean(Utility.PREF_PERIOD),
  193.                             dataMap.getInt(Utility.PREF_DATE_FORMAT)
  194.                     );
  195.                 }
  196.                 if (item.getUri().getPath().compareTo("/extras") == 0) {
  197.                     DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
  198.                     updateFaceExtras(
  199.                             dataMap.getString(Utility.EXTRA_BATT),
  200.                             dataMap.getString(Utility.EXTRA_TEMP)
  201.                             //dataMap.getString(Utility.EXTRA_HEART)
  202.                     );
  203.                 }
  204.             }
  205.             // else if (event.getType() == DataEvent.TYPE_DELETED) {
  206.             // DataItem deleted
  207.             // }
  208.         }
  209.     }
  210.  
  211.     private void updateFacePrefs(String user, String hostname,
  212.                                  int timeFormat, boolean period, int dateFormat) {
  213.         this.user = user;
  214.         this.hostname = hostname;
  215.         this.timeFormat = timeFormat;
  216.         this.period = period;
  217.         this.dateFormat = dateFormat;
  218.  
  219.         PreferenceManager.getDefaultSharedPreferences(this).edit()
  220.                 .putString(Utility.PREF_USER, user)
  221.                 .putString(Utility.PREF_HOSTNAME, hostname)
  222.                 .putInt(Utility.PREF_TIME_FORMAT, timeFormat)
  223.                 .putBoolean(Utility.PREF_PERIOD, period)
  224.                 .putInt(Utility.PREF_DATE_FORMAT, dateFormat)
  225.                 .apply();
  226.     }
  227.  
  228.     private void updateFaceExtras(String batteryLvl, String temp) { //, String mHeartRate
  229.         //TODO
  230.         mPhoneBatt = batteryLvl;
  231.         mCurrTemp = temp;
  232.     }
  233.  
  234.     private void registerFitnessDataListener(DataSource dataSource) {
  235.         onDataPointListener = new OnDataPointListener() {
  236.             @Override
  237.             public void onDataPoint(DataPoint dataPoint) {
  238.                 for (Field field : dataPoint.getDataType().getFields()) {
  239.                     Value val = dataPoint.getValue(field);
  240.                     Log.i(TAG, "Detected DataPoint field: " + field.getName());
  241.                     Log.i(TAG, "Detected DataPoint value: " + val);
  242.                 }
  243.             }
  244.         };
  245.  
  246.         Fitness.SensorsApi.add(
  247.                 googleApiClient,
  248.                 new SensorRequest.Builder()
  249.                         .setDataSource(dataSource) // Optional but recommended for custom data sets.
  250.                         .setDataType(DataType.TYPE_HEART_RATE_BPM) // Can't be omitted.
  251.                         .setSamplingRate(10, TimeUnit.SECONDS)
  252.                         .build(),
  253.                 onDataPointListener)
  254.                 .setResultCallback(new ResultCallback<Status>() {
  255.                     @Override
  256.                     public void onResult(@NonNull Status status) {
  257.                         if (status.isSuccess()) {
  258.                             Log.i(TAG, "Listener registered!");
  259.                         } else {
  260.                             Log.i(TAG, "Listener not registered.");
  261.                         }
  262.                     }
  263.                 });
  264.     }
  265.  
  266.     private boolean checkPermissions() {
  267.         int permissionCheck1 = ContextCompat.checkSelfPermission(WatchFace.this,
  268.                 Manifest.permission.ACCESS_FINE_LOCATION);
  269.         int permissionCheck2 = ContextCompat.checkSelfPermission(WatchFace.this,
  270.                 Manifest.permission.BODY_SENSORS);
  271.  
  272.         return permissionCheck1 == PackageManager.PERMISSION_GRANTED
  273.                 && permissionCheck2 == PackageManager.PERMISSION_GRANTED;
  274.     }
  275.  
  276.     private static class EngineHandler extends Handler {
  277.         private final WeakReference<WatchFace.Engine> mWeakReference;
  278.  
  279.         EngineHandler(WatchFace.Engine reference) {
  280.             mWeakReference = new WeakReference<>(reference);
  281.         }
  282.  
  283.         @Override
  284.         public void handleMessage(Message msg) {
  285.             WatchFace.Engine engine = mWeakReference.get();
  286.             if (engine != null) {
  287.                 switch (msg.what) {
  288.                     case MSG_UPDATE_TIME:
  289.                         engine.handleUpdateTimeMessage();
  290.                         break;
  291.                 }
  292.             }
  293.         }
  294.     }
  295.  
  296.     private class Engine extends CanvasWatchFaceService.Engine {
  297.         private static final int MSG_GET_EXTRAS = 1000;
  298.         private final Handler mUpdateTimeHandler = new EngineHandler(this);
  299.         private final Rect mCardBounds = new Rect();
  300.         private final Paint mPeekCardBackgroundPaint = new Paint();
  301.         private Paint mBackgroundPaint;
  302.         private Paint mTextPaint;
  303.         private Calendar calendar;
  304.         private final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() {
  305.             @Override
  306.             public void onReceive(Context context, Intent intent) {
  307.                 calendar.setTimeZone(TimeZone.getDefault());
  308.                 invalidate();
  309.             }
  310.         };
  311.         private ArrayList<String> arrayListExtras, arrayListLines;
  312.         private AsyncTask<Void, Void, ArrayList<String>> mLoadExtrasTask;
  313.         @SuppressLint("HandlerLeak")
  314.         private final Handler mGetExtrasHandler = new Handler() {
  315.             @Override
  316.             public void handleMessage(Message message) {
  317.                 switch (message.what) {
  318.                     case MSG_GET_EXTRAS:
  319.                         if (mLoadExtrasTask != null) {
  320.                             mLoadExtrasTask.cancel(true);
  321.                         }
  322.                         mLoadExtrasTask = new LoadExtrasTask();
  323.                         mLoadExtrasTask.execute();
  324.                         break;
  325.                 }
  326.             }
  327.         };
  328.  
  329.         private boolean mAmbient, mBlink;
  330.         private boolean mRegisteredTimeZoneReceiver = false;
  331.         private float mXOffset, mXOffsetExL, mXOffsetExR;
  332.         private float[] mYOffsets;
  333.         private boolean mLowBitAmbient;
  334.         private float mTextSize;
  335.  
  336.         @Override
  337.         public void onCreate(SurfaceHolder holder) {
  338.             super.onCreate(holder);
  339.  
  340.             SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(WatchFace.this);
  341.             user = preferences.getString(Utility.PREF_USER, "user");
  342.             hostname = preferences.getString(Utility.PREF_HOSTNAME, "wear");
  343.             timeFormat = preferences.getInt(Utility.PREF_TIME_FORMAT, 0);
  344.             period = preferences.getBoolean(Utility.PREF_PERIOD, DateFormat.is24HourFormat(WatchFace.this));
  345.             dateFormat = preferences.getInt(Utility.PREF_DATE_FORMAT, 0);
  346.  
  347.             setWatchFaceStyle(new WatchFaceStyle.Builder(WatchFace.this)
  348.                     .setCardPeekMode(WatchFaceStyle.PEEK_MODE_SHORT)
  349.                     .setAmbientPeekMode(WatchFaceStyle.AMBIENT_PEEK_MODE_VISIBLE)
  350.                     .setPeekOpacityMode(WatchFaceStyle.PEEK_OPACITY_MODE_TRANSLUCENT)
  351.                     .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
  352.                     .setShowSystemUiTime(false)
  353.                     .setAcceptsTapEvents(true)
  354.                     .build());
  355.  
  356.             Resources resources = WatchFace.this.getResources();
  357.  
  358.             mYOffsets = new float[]{
  359.                     resources.getDimension(R.dimen.digital_y_offset_0),
  360.                     resources.getDimension(R.dimen.digital_y_offset_1),
  361.                     resources.getDimension(R.dimen.digital_y_offset_2),
  362.                     resources.getDimension(R.dimen.digital_y_offset_3),
  363.                     resources.getDimension(R.dimen.digital_y_offset_4),
  364.                     resources.getDimension(R.dimen.digital_y_offset_5),
  365.                     resources.getDimension(R.dimen.digital_y_offset_6),
  366.                     resources.getDimension(R.dimen.digital_y_offset_7)
  367.             };
  368.  
  369.             mBackgroundPaint = new Paint();
  370.             mBackgroundPaint.setColor(getColor(R.color.background));
  371.  
  372.             mTextPaint = new Paint();
  373.             mTextPaint = createTextPaint(getColor(R.color.digital_text));
  374.  
  375.             calendar = Calendar.getInstance();
  376.  
  377.             arrayListLines = new ArrayList<>();
  378.             arrayListExtras = new ArrayList<>();
  379.             arrayListExtras.add("");
  380.             arrayListExtras.add("");
  381.             arrayListExtras.add("");
  382.             arrayListExtras.add("");
  383.         }
  384.  
  385.         @Override
  386.         public void onDestroy() {
  387.             mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
  388.             super.onDestroy();
  389.         }
  390.  
  391.         private Paint createTextPaint(int textColor) {
  392.             Paint paint = new Paint();
  393.             paint.setColor(textColor);
  394.             paint.setTypeface(Utility.getFont(WatchFace.this, 0));
  395.             //preferences.getInt(Utility.PREF_FONT, 0)));
  396.             paint.setAntiAlias(true);
  397.             return paint;
  398.         }
  399.  
  400.         @Override
  401.         public void onVisibilityChanged(boolean visible) {
  402.             super.onVisibilityChanged(visible);
  403.             if (visible) {
  404.                 registerReceiver();
  405.                 // Update time zone in case it changed while we weren't visible.
  406.                 calendar.setTimeZone(TimeZone.getDefault());
  407.                 mGetExtrasHandler.sendEmptyMessage(MSG_GET_EXTRAS);
  408.                 invalidate();
  409.             } else {
  410.                 unregisterReceiver();
  411.                 mGetExtrasHandler.removeMessages(MSG_GET_EXTRAS);
  412.                 if (mLoadExtrasTask != null) {
  413.                     mLoadExtrasTask.cancel(true);
  414.                 }
  415.             }
  416.  
  417.             // Whether the timer should be running depends on whether we're visible (as well as
  418.             // whether we're in ambient mode), so we may need to start or stop the timer.
  419.             updateTimer();
  420.         }
  421.  
  422.         private void registerReceiver() {
  423.             if (mRegisteredTimeZoneReceiver) {
  424.                 return;
  425.             }
  426.             mRegisteredTimeZoneReceiver = true;
  427.             IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
  428.             WatchFace.this.registerReceiver(mTimeZoneReceiver, filter);
  429.         }
  430.  
  431.         private void unregisterReceiver() {
  432.             if (!mRegisteredTimeZoneReceiver) {
  433.                 return;
  434.             }
  435.             mRegisteredTimeZoneReceiver = false;
  436.             WatchFace.this.unregisterReceiver(mTimeZoneReceiver);
  437.         }
  438.  
  439.         @Override
  440.         public void onApplyWindowInsets(WindowInsets insets) {
  441.             super.onApplyWindowInsets(insets);
  442.             Resources resources = WatchFace.this.getResources();
  443.             boolean isRound = insets.isRound();
  444.             mXOffset = resources.getDimension(isRound
  445.                     ? R.dimen.digital_x_offset_round
  446.                     : R.dimen.digital_x_offset);
  447.             mXOffsetExL = resources.getDimension(isRound
  448.                     ? R.dimen.digital_x_offset_ex_l_round
  449.                     : R.dimen.digital_x_offset_ex_l);
  450.             mXOffsetExR = resources.getDimension(isRound
  451.                     ? R.dimen.digital_x_offset_ex_r_round
  452.                     : R.dimen.digital_x_offset_ex_r);
  453.             mTextSize = resources.getDimension(isRound
  454.                     ? R.dimen.digital_text_size_round
  455.                     : R.dimen.digital_text_size);
  456.  
  457.             mTextPaint.setTextSize(mTextSize);
  458.         }
  459.  
  460.         @Override
  461.         public void onPropertiesChanged(Bundle properties) {
  462.             super.onPropertiesChanged(properties);
  463.             mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false);
  464.         }
  465.  
  466.         @Override
  467.         public void onTimeTick() {
  468.             super.onTimeTick();
  469.             invalidate();
  470.         }
  471.  
  472.         @Override
  473.         public void onAmbientModeChanged(boolean inAmbientMode) {
  474.             super.onAmbientModeChanged(inAmbientMode);
  475.             if (mAmbient != inAmbientMode) {
  476.                 mAmbient = inAmbientMode;
  477.                 if (mLowBitAmbient) {
  478.                     mTextPaint.setAntiAlias(!inAmbientMode);
  479.                 }
  480.                 invalidate();
  481.             }
  482.             // Whether the timer should be running depends on whether we're visible (as well as
  483.             // whether we're in ambient mode), so we may need to start or stop the timer.
  484.             updateTimer();
  485.         }
  486.  
  487.         @Override
  488.         public void onTapCommand(int tapType, int x, int y, long eventTime) {
  489.             switch (tapType) {
  490.                 case TAP_TYPE_TOUCH:
  491.                     // The user has started touching the screen.
  492.                     break;
  493.                 case TAP_TYPE_TOUCH_CANCEL:
  494.                     // The user has started a different gesture or otherwise cancelled the tap.
  495.                     break;
  496.                 case TAP_TYPE_TAP:
  497.                     // The user has completed the tap gesture.
  498.                     mBlink = false;
  499.                     invalidate();
  500.                     //updateTimer();
  501.                     break;
  502.             }
  503.             invalidate();
  504.         }
  505.  
  506.         @Override
  507.         public void onPeekCardPositionUpdate(Rect bounds) {
  508.             super.onPeekCardPositionUpdate(bounds);
  509.             //if (Log.isLoggable(TAG, Log.DEBUG)) {
  510.             //    Log.d(TAG, "onPeekCardPositionUpdate: " + bounds);
  511.             //}
  512.             if (!bounds.equals(mCardBounds)) {
  513.                 mCardBounds.set(bounds);
  514.                 invalidate();
  515.             }
  516.         }
  517.  
  518.         @Override
  519.         public void onDraw(Canvas canvas, Rect bounds) {
  520.             canvas.drawColor(Color.BLACK);
  521.             if (isInAmbientMode()) {
  522.                 canvas.drawRect(mCardBounds, mPeekCardBackgroundPaint);
  523.             }
  524.  
  525.             long now = System.currentTimeMillis();
  526.             calendar.setTimeInMillis(now);
  527.  
  528.             arrayListLines.clear();
  529.             arrayListLines.addAll(arrayListExtras);
  530.             arrayListLines.addAll(Utility.getTimeDate(
  531.                     calendar,
  532.                     user,
  533.                     hostname,
  534.                     mAmbient ? 0 : timeFormat,
  535.                     period,
  536.                     dateFormat));
  537.  
  538.             // TODO CHECK PERMS FIRST IN ONCREATE
  539.             try {
  540.                 canvas.drawText(arrayListLines.get(0), mXOffsetExL, mYOffsets[0], mTextPaint);
  541.                 canvas.drawText(arrayListLines.get(1), bounds.right - mXOffsetExR, mYOffsets[1], mTextPaint);
  542.                 canvas.drawText(arrayListLines.get(2), mXOffsetExL, mYOffsets[2], mTextPaint);
  543.                 canvas.drawText(arrayListLines.get(3), bounds.right - mXOffsetExR, mYOffsets[3], mTextPaint);
  544.             } catch (NullPointerException e) {
  545.                 Log.e(TAG, e.toString());
  546.             }
  547.             canvas.drawText(arrayListLines.get(4), mXOffset, mYOffsets[4], mTextPaint);
  548.             canvas.drawText(arrayListLines.get(5), mXOffset, mYOffsets[5], mTextPaint);
  549.             canvas.drawText(arrayListLines.get(6), mXOffset, mYOffsets[6], mTextPaint);
  550.             if (!mBlink && !mAmbient) {
  551.                 mBlink = true;
  552.                 canvas.drawText(arrayListLines.get(7), mXOffset, mYOffsets[7], mTextPaint);
  553.             } else {
  554.                 mBlink = false;
  555.                 canvas.drawText(arrayListLines.get(8), mXOffset, mYOffsets[7], mTextPaint);
  556.             }
  557.         }
  558.  
  559.         private void updateTimer() {
  560.             mUpdateTimeHandler.removeMessages(MSG_UPDATE_TIME);
  561.             if (shouldTimerBeRunning()) {
  562.                 mUpdateTimeHandler.sendEmptyMessage(MSG_UPDATE_TIME);
  563.             }
  564.         }
  565.  
  566.         private boolean shouldTimerBeRunning() {
  567.             return isVisible() && !isInAmbientMode();
  568.         }
  569.  
  570.         private void handleUpdateTimeMessage() {
  571.             invalidate();
  572.             if (shouldTimerBeRunning()) {
  573.                 long timeMs = System.currentTimeMillis();
  574.                 long delayMs = INTERACTIVE_UPDATE_RATE_MS
  575.                         - (timeMs % INTERACTIVE_UPDATE_RATE_MS);
  576.                 mUpdateTimeHandler.sendEmptyMessageDelayed(MSG_UPDATE_TIME, delayMs);
  577.             }
  578.         }
  579.  
  580.         private class LoadExtrasTask extends AsyncTask<Void, Void, ArrayList<String>> {
  581.  
  582.             @Override
  583.             protected ArrayList<String> doInBackground(Void... voids) {
  584.                 ArrayList<String> arrayListExtras = new ArrayList<>();
  585.  
  586.                 arrayListExtras.add(Utility.getBattLvl(WatchFace.this));
  587.                 arrayListExtras.add(mPhoneBatt);
  588.                 arrayListExtras.add(mCurrTemp);
  589.                 arrayListExtras.add(mHeartRate);
  590.  
  591.                 return arrayListExtras;
  592.             }
  593.  
  594.             @Override
  595.             protected void onPostExecute(ArrayList<String> arrayList) {
  596.                 if (arrayList != null) {
  597.                     arrayListExtras = arrayList;
  598.                     invalidate();
  599.                 }
  600.                 if (isVisible()) {
  601.                     mGetExtrasHandler.sendEmptyMessageDelayed(
  602.                             MSG_GET_EXTRAS, GET_EXTRAS_UPDATE_RATE_MS);
  603.                 }
  604.             }
  605.         }
  606.     }
  607. }
Add Comment
Please, Sign In to add comment