1 package net.osdn.gokigen.joggingtimer.stopwatch;
3 import android.content.Intent;
4 import android.graphics.Color;
5 import android.os.Bundle;
6 import android.util.Log;
7 import android.view.KeyEvent;
8 import android.view.View;
9 import android.widget.ImageButton;
10 import android.widget.ListView;
11 import android.widget.RelativeLayout;
12 import android.widget.TextView;
14 import androidx.appcompat.app.AppCompatActivity;
15 import androidx.wear.ambient.AmbientModeSupport;
16 import androidx.wear.widget.BoxInsetLayout;
18 import net.osdn.gokigen.joggingtimer.R;
19 import net.osdn.gokigen.joggingtimer.recordlist.ListActivity;
20 import net.osdn.gokigen.joggingtimer.stopwatch.graphview.LapTimeGraphView;
21 import net.osdn.gokigen.joggingtimer.utilities.TimeStringConvert;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 import java.util.List;
26 import java.util.Locale;
32 public class MainActivity extends AppCompatActivity implements IClickCallback, MyTimerTrigger.ITimeoutReceiver, MyTimerCounter.ICounterStatusNotify, AmbientModeSupport.AmbientCallbackProvider
34 private final String TAG = toString();
35 private final IWearableActivityControl controller = new WearableActivityController();
36 private final MyTimerCounter counter = new MyTimerCounter();
37 private boolean isCounterLapTime = true;
38 private boolean isLaptimeView = true;
39 private boolean pendingStart = false;
40 private int currentLapCount = 0;
41 private ITimerStopTrigger stopTrigger = null;
47 protected void onCreate(Bundle savedInstanceState)
49 super.onCreate(savedInstanceState);
50 Log.v(TAG, "onCreate()");
52 setContentView(R.layout.activity_main);
54 controller.setup(this, this, counter);
57 //getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
58 //setAmbientEnabled();
61 AmbientModeSupport.AmbientController ambientController = AmbientModeSupport.attach(this);
62 ambientController.setAutoResumeEnabled(true);
63 //boolean isAmbient = ambientController.isAmbient();
75 protected void onResume()
80 Intent intent = getIntent();
81 String action = intent.getAction();
82 Log.v(TAG, "onResume() : " + action);
84 boolean isStartTimer = false;
87 if (action.equals("com.google.android.wearable.action.STOPWATCH"))
91 else if (action.equals("vnd.google.fitness.TRACK"))
93 String activity = intent.getStringExtra("actionStatus");
94 if ((activity != null)&&(activity.equals("ActiveActionStatus")))
100 isLaptimeView = controller.getDisplayMode();
101 //Log.v(TAG, "isLaptimeView " + isLaptimeView);
103 controller.setupReferenceData();
117 protected void onPause()
120 Log.v(TAG, "onPause()");
128 public void onStart()
131 Log.v(TAG, "onStart()");
134 counter.setCallback(this);
135 controller.setupDatabase(this, false);
146 Log.v(TAG, "onStop()");
147 if (stopTrigger != null)
149 stopTrigger.forceStop();
151 controller.exitApplication(this);
156 public void onEnterAmbient(Bundle ambientDetails)
158 super.onEnterAmbient(ambientDetails);
159 Log.v(TAG, "onEnterAmbient()");
163 public void onExitAmbient()
165 super.onExitAmbient();
166 Log.v(TAG, "onExitAmbient()");
167 //updateTimerLabel();
171 public void onUpdateAmbient()
173 super.onUpdateAmbient();
174 Log.v(TAG, "onUpdateAmbient()");
181 private void updateTimerLabel()
183 ITimerCounter timerCounter = counter;
185 BoxInsetLayout insetLayout = findViewById(R.id.box_inset_layout);
186 RelativeLayout layout = findViewById(R.id.relative_main_layout);
188 ImageButton btn1 = findViewById(R.id.btn1);
189 ImageButton btn2 = findViewById(R.id.btn2);
190 ImageButton btn3 = findViewById(R.id.btn3);
192 updateMainSubCounter();
194 if (timerCounter.isStarted())
196 bgColor = Color.BLACK;
197 insetLayout.setBackgroundColor(bgColor);
198 insetLayout.invalidate();
200 layout.setBackgroundColor(bgColor);
203 btn1.setImageResource(R.drawable.ic_flag_black_24dp);
204 btn1.setBackgroundColor(bgColor);
206 // チャタリング防止(ラップタイムとして、3秒以内は記録しないようボタンを消しておく)
207 long currentElapsedTime = timerCounter.getCurrentElapsedTime();
208 btn1.setVisibility((currentElapsedTime > 3000) ? View.VISIBLE : View.INVISIBLE);
211 btn2.setImageResource(R.drawable.ic_stop_black_24dp);
212 btn2.setBackgroundColor(bgColor);
213 btn2.setVisibility(View.VISIBLE);
216 btn3.setImageResource(R.drawable.ic_block_black_24dp);
217 btn3.setBackgroundColor(bgColor);
218 btn3.setVisibility(View.INVISIBLE);
221 else if (timerCounter.isReset())
223 bgColor = Color.BLACK;
224 insetLayout.setBackgroundColor(bgColor);
225 insetLayout.invalidate();
227 layout.setBackgroundColor(bgColor);
230 btn1.setImageResource(R.drawable.ic_play_arrow_black_24dp);
231 btn1.setBackgroundColor(bgColor);
232 btn1.setVisibility(View.VISIBLE);
235 btn2.setImageResource(R.drawable.ic_format_list_bulleted_black_24dp);
236 btn2.setBackgroundColor(bgColor);
237 btn2.setVisibility(View.VISIBLE);
240 btn3.setImageResource(R.drawable.ic_refresh_black_24dp);
241 btn3.setBackgroundColor(bgColor);
242 btn3.setVisibility(View.INVISIBLE);
247 bgColor = Color.BLACK;
248 insetLayout.setBackgroundColor(bgColor);
249 insetLayout.invalidate();
251 layout.setBackgroundColor(bgColor);
254 btn1.setImageResource(R.drawable.ic_play_arrow_black_24dp);
255 btn1.setVisibility(View.VISIBLE);
256 btn1.setBackgroundColor(bgColor);
259 btn2.setImageResource(R.drawable.ic_format_list_bulleted_black_24dp);
260 btn2.setVisibility(View.VISIBLE);
261 btn2.setBackgroundColor(bgColor);
264 btn3.setImageResource(R.drawable.ic_refresh_black_24dp);
265 btn3.setVisibility(View.VISIBLE);
266 btn3.setBackgroundColor(bgColor);
269 updateElapsedTimes();
273 public void clickedCounter()
276 isCounterLapTime = !isCounterLapTime;
283 public void clickedBtn1()
292 private void startTimer()
296 ITimerCounter timerCounter = counter;
297 LapTimeGraphView graphView = findViewById(R.id.graph_area);
298 if (timerCounter.isStarted())
300 Log.v(TAG, "startTimer() LAP TIME");
301 long currentElapsedTime = timerCounter.getCurrentElapsedTime();
302 if (currentElapsedTime > 3000) // チャタリング防止(ラップタイムとして、3秒以内は記録しないようにする)
305 long lapTime = timerCounter.timeStamp();
306 long refLapTime = timerCounter.getReferenceLapTime(currentLapCount);
307 long diffTime = (refLapTime == 0) ? 0 : (currentElapsedTime - refLapTime);
308 controller.vibrate(50);
309 controller.getDataEntry().appendTimeData(lapTime);
310 controller.addTimeStamp(currentLapCount, currentElapsedTime, diffTime);
311 //Log.v(TAG, " [[[ " + currentLapCount + " lap: " + currentElapsedTime + " diff:" + diffTime + " (" + refLapTime + ") ]]]");
313 if (graphView != null)
315 graphView.notifyLapTime();
321 Log.v(TAG, "startTimer() START");
322 controller.clearTimeStamp();
323 timerCounter.start();
324 MyTimerTrigger trigger = new MyTimerTrigger(this, 100, timerCounter);
325 trigger.startTimer();
327 stopTrigger = trigger;
328 controller.timerStarted(true);
329 controller.vibrate(120);
331 Date date = new Date();
332 SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
333 String title = sdf1.format(date);
334 long startTime = timerCounter.getStartTime();
335 controller.getDataEntry().createIndex(title, startTime);
337 if (graphView != null)
339 graphView.notifyStarted(startTime);
354 private boolean stopTimer()
359 ITimerCounter timerCounter = counter;
360 if (timerCounter.isStarted())
363 controller.timerStarted(false);
364 controller.vibrate(120);
365 controller.getDataEntry().finishTimeData(timerCounter.getStartTime(), timerCounter.getStopTime());
367 int lapCount = currentLapCount + 1;
368 long currentElapsedTime = timerCounter.getLastElapsedTime() - timerCounter.getElapsedTime(currentLapCount);
369 long refLapTime = timerCounter.getReferenceLapTime(lapCount);
370 long diffTime = (refLapTime == 0) ? 0 : (currentElapsedTime - refLapTime);
371 controller.addTimeStamp(lapCount, currentElapsedTime, diffTime);
374 LapTimeGraphView graphView = findViewById(R.id.graph_area);
375 if (graphView != null)
377 graphView.notifyStopped();
393 public void clickedBtn2()
395 if (!((ITimerCounter) counter).isStarted())
398 launchListActivity();
401 controller.vibrate(35);
410 public void clickedBtn3()
412 ITimerCounter timerCounter = counter;
413 if (!timerCounter.isStarted())
415 timerCounter.reset();
416 controller.vibrate(50);
417 controller.clearTimeStamp();
419 LapTimeGraphView graphView = findViewById(R.id.graph_area);
420 if (graphView != null)
422 graphView.notifyReset();
429 public void clickedArea()
431 Log.v(TAG, "clickedArea()");
436 public boolean pushedBtn1()
442 public boolean pushedBtn2()
444 return (stopTimer());
448 public boolean pushedBtn3()
454 public boolean pushedArea()
456 isLaptimeView = !isLaptimeView;
457 controller.setDisplayMode(isLaptimeView);
458 Log.v(TAG, "pushedArea() : " + isLaptimeView);
459 changeGraphicView(isLaptimeView);
469 public void timeout()
473 runOnUiThread(this::updateTimerLabel);
485 private void updateMainSubCounter()
487 TextView main = findViewById(R.id.main_counter);
488 TextView sub = findViewById(R.id.sub_counter1);
490 ITimerCounter timerCounter = counter;
491 long time1 = timerCounter.getPastTime();
492 CharSequence str1 = TimeStringConvert.getTimeString(time1);
493 CharSequence str2 = "";
494 if (timerCounter.isStarted())
496 long time2 = timerCounter.getCurrentElapsedTime();
497 int lapCount = timerCounter.getElapsedCount();
498 if ((time2 >= 100) && (lapCount > 1))
500 str2 = "[" + lapCount + "] " + TimeStringConvert.getTimeString(time2);
504 if ((str2.length() > 0)&&(isCounterLapTime))
523 private void updateElapsedTimes()
527 updateElapsedTimesGraph();
531 updateElapsedTimesText();
539 private void updateElapsedTimesGraph()
541 //Log.v(TAG, "updateElapsedTimesGraph()");
542 LapTimeGraphView view = findViewById(R.id.graph_area);
550 private void updateElapsedTimesText()
552 // Log.v(TAG, "updateElapsedTimesText()");
556 * Launch ListActivity
559 private void launchListActivity()
561 Log.v(TAG, "launchListActivity()");
564 Intent intent = new Intent(this, ListActivity.class);
565 startActivity(intent);
578 protected void onUserLeaveHint()
580 Log.v(TAG, "onUserLeaveHint() " );
581 // ハードキー(ホームボタン)が押されたとき、これがひろえるが...
589 public boolean dispatchKeyEvent(KeyEvent event)
591 Log.v(TAG, "dispatchKeyEvent() : " + event.getAction() + " (" + event.getKeyCode() + ")");
593 return (super.dispatchKeyEvent(event));
597 public void onPointerCaptureChanged(boolean hasCapture) {
598 super.onPointerCaptureChanged(hasCapture);
606 public boolean onKeyDown(int keyCode, KeyEvent event)
608 Log.v(TAG, "onKeyDown() : " + event.getAction() + " (" + event.getKeyCode() + ")" + keyCode);
609 if (event.getRepeatCount() == 0)
611 if (keyCode == KeyEvent.KEYCODE_STEM_1)
616 else if (keyCode == KeyEvent.KEYCODE_STEM_2)
621 else if (keyCode == KeyEvent.KEYCODE_STEM_3)
627 return (super.onKeyDown(keyCode, event));
635 public void counterStatusChanged(final boolean forceStartTimer)
641 LapTimeGraphView graphView = findViewById(R.id.graph_area);
642 MyTimerTrigger trigger = new MyTimerTrigger(this, 100, counter);
643 trigger.startTimer();
644 stopTrigger = trigger;
645 if (graphView != null)
647 graphView.notifyLapTime();
656 runOnUiThread(() -> {
661 pendingStart = false;
665 reloadLapTimeList(forceStartTimer);
668 changeGraphicView(isLaptimeView);
679 private void reloadLapTimeList(final boolean forceStartTimer)
681 if (!forceStartTimer)
686 // Adapter と TimerCounterの整合性を確認
689 List<Long> lapTimeList;
690 lapTimeList = ((ITimerCounter) counter).getLapTimeList();
691 int lapCount = lapTimeList.size();
692 int listCount = controller.getLapTimeCount();
693 if (lapCount != listCount)
695 Log.v(TAG, "LAP COUNT IS MISMATCH!!! lap:" + lapCount + " vs list:" + listCount);
697 controller.clearTimeStamp();
698 long prevTime = lapTimeList.get(0);
699 for (long lapTime : lapTimeList)
702 if (prevTime != lapTime)
704 long refLapTime = counter.getReferenceLapTime(index - 1);
705 long curLapTime = lapTime - prevTime;
706 long calcRefLapTime = (refLapTime == 0) ? 0 : (curLapTime - refLapTime);
707 controller.addTimeStamp((index - 1), curLapTime, calcRefLapTime);
711 currentLapCount = lapCount - 1;
724 private void changeGraphicView(boolean isGraphics)
728 LapTimeGraphView graphView = findViewById(R.id.graph_area);
729 ListView listView = findViewById(R.id.laptime_list_area);
732 graphView.setITimerCounter(counter);
733 graphView.setVisibility(View.VISIBLE);
734 listView.setVisibility(View.GONE);
738 graphView.setVisibility(View.GONE);
739 listView.setVisibility(View.VISIBLE);
741 //controller.vibrate(30);
750 public AmbientModeSupport.AmbientCallback getAmbientCallback()
752 return (new AmbientModeSupport.AmbientCallback() {
753 public void onEnterAmbient(Bundle ambientDetails)
755 Log.v(TAG, "onEnterAmbient()");
757 public void onExitAmbient(Bundle ambientDetails)
759 Log.v(TAG, "onExitAmbient()");
760 //updateTimerLabel();