OSDN Git Service

WearableActivity廃止に伴う修正を入れたつもり。
[gokigen/JoggingTimer.git] / wear / src / main / java / net / osdn / gokigen / joggingtimer / stopwatch / MainActivity.java
1 package net.osdn.gokigen.joggingtimer.stopwatch;
2
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;
13
14 import androidx.appcompat.app.AppCompatActivity;
15 import androidx.wear.ambient.AmbientModeSupport;
16 import androidx.wear.widget.BoxInsetLayout;
17
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;
22
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 import java.util.List;
26 import java.util.Locale;
27
28 /**
29  *
30  *
31  */
32 public class MainActivity extends AppCompatActivity implements IClickCallback, MyTimerTrigger.ITimeoutReceiver, MyTimerCounter.ICounterStatusNotify, AmbientModeSupport.AmbientCallbackProvider
33 {
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;
42
43     /**
44      *
45      */
46     @Override
47     protected void onCreate(Bundle savedInstanceState)
48     {
49         super.onCreate(savedInstanceState);
50         Log.v(TAG, "onCreate()");
51
52         setContentView(R.layout.activity_main);
53
54         controller.setup(this, this, counter);
55
56         // Enables Always-on
57         //getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
58         //setAmbientEnabled();
59         try
60         {
61             AmbientModeSupport.AmbientController ambientController = AmbientModeSupport.attach(this);
62             ambientController.setAutoResumeEnabled(true);
63             //boolean isAmbient = ambientController.isAmbient();
64         }
65         catch (Exception e)
66         {
67             e.printStackTrace();
68         }
69     }
70
71     /**
72      *
73      */
74     @Override
75     protected void onResume()
76     {
77         super.onResume();
78
79         // インテントを取得する
80         Intent intent = getIntent();
81         String action = intent.getAction();
82         Log.v(TAG, "onResume() : " + action);
83
84         boolean isStartTimer = false;
85         if (action != null)
86         {
87             if (action.equals("com.google.android.wearable.action.STOPWATCH"))
88             {
89                 isStartTimer = true;
90             }
91             else if (action.equals("vnd.google.fitness.TRACK"))
92             {
93                 String activity = intent.getStringExtra("actionStatus");
94                 if ((activity != null)&&(activity.equals("ActiveActionStatus")))
95                 {
96                     isStartTimer = true;
97                 }
98             }
99         }
100         isLaptimeView = controller.getDisplayMode();
101         //Log.v(TAG, "isLaptimeView " + isLaptimeView);
102
103         controller.setupReferenceData();
104
105         if (isStartTimer)
106         {
107             // start a timer!
108             //startTimer();
109             pendingStart = true;
110         }
111     }
112
113     /**
114      *
115      */
116     @Override
117     protected void onPause()
118     {
119         super.onPause();
120         Log.v(TAG, "onPause()");
121     }
122
123     /**
124      *
125      *
126      */
127     @Override
128     public void onStart()
129     {
130         super.onStart();
131         Log.v(TAG, "onStart()");
132
133         // データベースのセットアップ
134         counter.setCallback(this);
135         controller.setupDatabase(this, false);
136     }
137
138     /**
139      *
140      *
141      */
142     @Override
143     public void onStop()
144     {
145         super.onStop();
146         Log.v(TAG, "onStop()");
147         if (stopTrigger != null)
148         {
149             stopTrigger.forceStop();
150         }
151         controller.exitApplication(this);
152     }
153
154 /*
155     @Override
156     public void onEnterAmbient(Bundle ambientDetails)
157     {
158         super.onEnterAmbient(ambientDetails);
159         Log.v(TAG, "onEnterAmbient()");
160     }
161
162     @Override
163     public void onExitAmbient()
164     {
165         super.onExitAmbient();
166         Log.v(TAG, "onExitAmbient()");
167         //updateTimerLabel();
168     }
169
170     @Override
171     public void onUpdateAmbient()
172     {
173         super.onUpdateAmbient();
174         Log.v(TAG, "onUpdateAmbient()");
175     }
176 */
177
178     /**
179      *
180      */
181     private void updateTimerLabel()
182     {
183         ITimerCounter timerCounter = counter;
184         int bgColor;
185         BoxInsetLayout insetLayout = findViewById(R.id.box_inset_layout);
186         RelativeLayout layout = findViewById(R.id.relative_main_layout);
187
188         ImageButton btn1 = findViewById(R.id.btn1);
189         ImageButton btn2 = findViewById(R.id.btn2);
190         ImageButton btn3 = findViewById(R.id.btn3);
191
192         updateMainSubCounter();
193
194         if (timerCounter.isStarted())
195         {
196             bgColor = Color.BLACK;
197             insetLayout.setBackgroundColor(bgColor);
198             insetLayout.invalidate();
199
200             layout.setBackgroundColor(bgColor);
201             layout.invalidate();
202
203             btn1.setImageResource(R.drawable.ic_flag_black_24dp);
204             btn1.setBackgroundColor(bgColor);
205
206             // チャタリング防止(ラップタイムとして、3秒以内は記録しないようボタンを消しておく)
207             long currentElapsedTime = timerCounter.getCurrentElapsedTime();
208             btn1.setVisibility((currentElapsedTime > 3000) ? View.VISIBLE : View.INVISIBLE);
209             btn1.invalidate();
210
211             btn2.setImageResource(R.drawable.ic_stop_black_24dp);
212             btn2.setBackgroundColor(bgColor);
213             btn2.setVisibility(View.VISIBLE);
214             btn2.invalidate();
215
216             btn3.setImageResource(R.drawable.ic_block_black_24dp);
217             btn3.setBackgroundColor(bgColor);
218             btn3.setVisibility(View.INVISIBLE);
219             btn3.invalidate();
220         }
221         else if (timerCounter.isReset())
222         {
223             bgColor = Color.BLACK;
224             insetLayout.setBackgroundColor(bgColor);
225             insetLayout.invalidate();
226
227             layout.setBackgroundColor(bgColor);
228             layout.invalidate();
229
230             btn1.setImageResource(R.drawable.ic_play_arrow_black_24dp);
231             btn1.setBackgroundColor(bgColor);
232             btn1.setVisibility(View.VISIBLE);
233             btn1.invalidate();
234
235             btn2.setImageResource(R.drawable.ic_format_list_bulleted_black_24dp);
236             btn2.setBackgroundColor(bgColor);
237             btn2.setVisibility(View.VISIBLE);
238             btn2.invalidate();
239
240             btn3.setImageResource(R.drawable.ic_refresh_black_24dp);
241             btn3.setBackgroundColor(bgColor);
242             btn3.setVisibility(View.INVISIBLE);
243             btn3.invalidate();
244         }
245         else
246         {
247             bgColor = Color.BLACK;
248             insetLayout.setBackgroundColor(bgColor);
249             insetLayout.invalidate();
250
251             layout.setBackgroundColor(bgColor);
252             layout.invalidate();
253
254             btn1.setImageResource(R.drawable.ic_play_arrow_black_24dp);
255             btn1.setVisibility(View.VISIBLE);
256             btn1.setBackgroundColor(bgColor);
257             btn1.invalidate();
258
259             btn2.setImageResource(R.drawable.ic_format_list_bulleted_black_24dp);
260             btn2.setVisibility(View.VISIBLE);
261             btn2.setBackgroundColor(bgColor);
262             btn2.invalidate();
263
264             btn3.setImageResource(R.drawable.ic_refresh_black_24dp);
265             btn3.setVisibility(View.VISIBLE);
266             btn3.setBackgroundColor(bgColor);
267             btn3.invalidate();
268         }
269         updateElapsedTimes();
270     }
271
272     @Override
273     public void clickedCounter()
274     {
275         // 表示順番を変える
276         isCounterLapTime = !isCounterLapTime;
277     }
278
279     /**
280      *
281      */
282     @Override
283     public void clickedBtn1()
284     {
285         startTimer();
286     }
287
288     /**
289      *
290      *
291      */
292     private void startTimer()
293     {
294         try
295         {
296             ITimerCounter timerCounter = counter;
297             LapTimeGraphView graphView = findViewById(R.id.graph_area);
298             if (timerCounter.isStarted())
299             {
300                 Log.v(TAG, "startTimer() LAP TIME");
301                 long currentElapsedTime = timerCounter.getCurrentElapsedTime();
302                 if (currentElapsedTime > 3000)  // チャタリング防止(ラップタイムとして、3秒以内は記録しないようにする)
303                 {
304                     currentLapCount++;
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 + ") ]]]");
312
313                     if (graphView != null)
314                     {
315                         graphView.notifyLapTime();
316                     }
317                 }
318             }
319             else
320             {
321                 Log.v(TAG, "startTimer() START");
322                 controller.clearTimeStamp();
323                 timerCounter.start();
324                 MyTimerTrigger trigger = new MyTimerTrigger(this, 100, timerCounter);
325                 trigger.startTimer();
326                 currentLapCount = 0;
327                 stopTrigger = trigger;
328                 controller.timerStarted(true);
329                 controller.vibrate(120);
330
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);
336
337                 if (graphView != null)
338                 {
339                     graphView.notifyStarted(startTime);
340                 }
341             }
342             updateTimerLabel();
343         }
344         catch (Exception e)
345         {
346             e.printStackTrace();
347         }
348     }
349
350     /**
351      *
352      *
353      */
354     private boolean stopTimer()
355     {
356         boolean ret = false;
357         try
358         {
359             ITimerCounter timerCounter = counter;
360             if (timerCounter.isStarted())
361             {
362                 timerCounter.stop();
363                 controller.timerStarted(false);
364                 controller.vibrate(120);
365                 controller.getDataEntry().finishTimeData(timerCounter.getStartTime(), timerCounter.getStopTime());
366
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);
372                 ret = true;
373
374                 LapTimeGraphView graphView = findViewById(R.id.graph_area);
375                 if (graphView != null)
376                 {
377                     graphView.notifyStopped();
378                 }
379             }
380             updateTimerLabel();
381         }
382         catch (Exception e)
383         {
384             e.printStackTrace();
385         }
386         return (ret);
387     }
388
389     /**
390      *
391      */
392     @Override
393     public void clickedBtn2()
394     {
395         if (!((ITimerCounter) counter).isStarted())
396         {
397             // 停止中は、記録一覧を呼び出す
398             launchListActivity();
399
400             // ぶるぶる
401             controller.vibrate(35);
402         }
403         updateTimerLabel();
404     }
405
406     /**
407      *
408      */
409     @Override
410     public void clickedBtn3()
411     {
412         ITimerCounter timerCounter = counter;
413         if (!timerCounter.isStarted())
414         {
415             timerCounter.reset();
416             controller.vibrate(50);
417             controller.clearTimeStamp();
418             currentLapCount = 0;
419             LapTimeGraphView graphView = findViewById(R.id.graph_area);
420             if (graphView != null)
421             {
422                 graphView.notifyReset();
423             }
424         }
425         updateTimerLabel();
426     }
427
428     @Override
429     public void clickedArea()
430     {
431         Log.v(TAG, "clickedArea()");
432
433     }
434
435     @Override
436     public boolean pushedBtn1()
437     {
438         return (false);
439     }
440
441     @Override
442     public boolean pushedBtn2()
443     {
444         return (stopTimer());
445     }
446
447     @Override
448     public boolean pushedBtn3()
449     {
450         return (false);
451     }
452
453     @Override
454     public boolean pushedArea()
455     {
456         isLaptimeView = !isLaptimeView;
457         controller.setDisplayMode(isLaptimeView);
458         Log.v(TAG, "pushedArea() : " + isLaptimeView);
459         changeGraphicView(isLaptimeView);
460         updateTimerLabel();
461         return (true);
462     }
463
464     /**
465      *
466      *
467      */
468     @Override
469     public void timeout()
470     {
471         try
472         {
473             runOnUiThread(this::updateTimerLabel);
474         }
475         catch (Exception e)
476         {
477             e.printStackTrace();
478         }
479     }
480
481     /**
482      *
483      *
484      */
485     private void updateMainSubCounter()
486     {
487         TextView main = findViewById(R.id.main_counter);
488         TextView sub = findViewById(R.id.sub_counter1);
489
490         ITimerCounter timerCounter = counter;
491         long time1 = timerCounter.getPastTime();
492         CharSequence str1 = TimeStringConvert.getTimeString(time1);
493         CharSequence str2 = "";
494         if (timerCounter.isStarted())
495         {
496             long time2 = timerCounter.getCurrentElapsedTime();
497             int lapCount = timerCounter.getElapsedCount();
498             if ((time2 >= 100) && (lapCount > 1))
499             {
500                 str2 =  "[" + lapCount + "] " + TimeStringConvert.getTimeString(time2);
501             }
502         }
503
504         if ((str2.length() > 0)&&(isCounterLapTime))
505         {
506             // ラップタイムの方を大きく表示する
507             main.setText(str2);
508             sub.setText(str1);
509         }
510         else
511         {
512             main.setText(str1);
513             sub.setText(str2);
514         }
515         main.invalidate();
516         sub.invalidate();
517     }
518
519     /**
520      *
521      *
522      */
523     private void updateElapsedTimes()
524     {
525         if (isLaptimeView)
526         {
527            updateElapsedTimesGraph();
528         }
529         else
530         {
531             updateElapsedTimesText();
532         }
533     }
534
535     /**
536      *
537      *
538      */
539     private void updateElapsedTimesGraph()
540     {
541         //Log.v(TAG, "updateElapsedTimesGraph()");
542         LapTimeGraphView view = findViewById(R.id.graph_area);
543         view.invalidate();
544     }
545
546     /**
547      *
548      *
549      */
550     private void updateElapsedTimesText()
551     {
552         // Log.v(TAG, "updateElapsedTimesText()");
553     }
554
555     /**
556      *  Launch ListActivity
557      *
558      */
559     private void launchListActivity()
560     {
561         Log.v(TAG, "launchListActivity()");
562         try
563         {
564             Intent intent = new Intent(this, ListActivity.class);
565             startActivity(intent);
566         }
567         catch (Exception e)
568         {
569             e.printStackTrace();
570         }
571     }
572
573     /**
574      *
575      *
576      */
577     @Override
578     protected void onUserLeaveHint()
579     {
580         Log.v(TAG, "onUserLeaveHint() " );
581         // ハードキー(ホームボタン)が押されたとき、これがひろえるが...
582     }
583
584     /**
585      *
586      *
587      */
588     @Override
589     public boolean dispatchKeyEvent(KeyEvent event)
590     {
591         Log.v(TAG, "dispatchKeyEvent() : " + event.getAction() + " (" + event.getKeyCode() + ")");
592
593         return (super.dispatchKeyEvent(event));
594     }
595
596     @Override
597     public void onPointerCaptureChanged(boolean hasCapture) {
598         super.onPointerCaptureChanged(hasCapture);
599     }
600
601     /**
602      *
603      *
604      */
605     @Override
606     public boolean onKeyDown(int keyCode, KeyEvent event)
607     {
608         Log.v(TAG, "onKeyDown() : " + event.getAction() + " (" + event.getKeyCode() + ")" + keyCode);
609         if (event.getRepeatCount() == 0)
610         {
611             if (keyCode == KeyEvent.KEYCODE_STEM_1)
612             {
613                 startTimer();
614                 return (true);
615             }
616             else if (keyCode == KeyEvent.KEYCODE_STEM_2)
617             {
618                 startTimer();
619                 return (true);
620             }
621             else if (keyCode == KeyEvent.KEYCODE_STEM_3)
622             {
623                 startTimer();
624                 return (true);
625             }
626         }
627         return (super.onKeyDown(keyCode, event));
628     }
629
630     /**
631      *
632      *
633      */
634     @Override
635     public void counterStatusChanged(final boolean forceStartTimer)
636     {
637         if (forceStartTimer)
638         {
639             try
640             {
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)
646                 {
647                     graphView.notifyLapTime();
648                 }
649             }
650             catch (Exception e)
651             {
652                 e.printStackTrace();
653             }
654         }
655
656         runOnUiThread(() -> {
657             // 自動スタート時の処理。。
658             if (pendingStart)
659             {
660                 startTimer();
661                 pendingStart = false;
662             }
663
664             // ラップタイム表示状態の更新
665             reloadLapTimeList(forceStartTimer);
666
667             // 表示ビューの切り替え
668             changeGraphicView(isLaptimeView);
669
670             // 表示のボタン状態を変更
671             updateTimerLabel();
672         });
673     }
674
675     /**
676      *
677      *
678      */
679     private void reloadLapTimeList(final boolean forceStartTimer)
680     {
681         if (!forceStartTimer)
682         {
683             return;
684         }
685
686         // Adapter と TimerCounterの整合性を確認
687         try
688         {
689             List<Long> lapTimeList;
690             lapTimeList = ((ITimerCounter) counter).getLapTimeList();
691             int lapCount = lapTimeList.size();
692             int listCount = controller.getLapTimeCount();
693             if (lapCount != listCount)
694             {
695                 Log.v(TAG, "LAP COUNT IS MISMATCH!!! lap:" + lapCount + " vs list:" + listCount);
696                 int index = 0;
697                 controller.clearTimeStamp();
698                 long prevTime = lapTimeList.get(0);
699                 for (long lapTime : lapTimeList)
700                 {
701                     index++;
702                     if (prevTime != lapTime)
703                     {
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);
708                     }
709                     prevTime = lapTime;
710                 }
711                 currentLapCount = lapCount - 1;
712             }
713         }
714         catch (Exception e)
715         {
716             e.printStackTrace();
717         }
718     }
719
720     /**
721      *
722      *
723      */
724     private void changeGraphicView(boolean isGraphics)
725     {
726         try
727         {
728             LapTimeGraphView graphView = findViewById(R.id.graph_area);
729             ListView listView = findViewById(R.id.laptime_list_area);
730             if (isGraphics)
731             {
732                 graphView.setITimerCounter(counter);
733                 graphView.setVisibility(View.VISIBLE);
734                 listView.setVisibility(View.GONE);
735             }
736             else
737             {
738                 graphView.setVisibility(View.GONE);
739                 listView.setVisibility(View.VISIBLE);
740             }
741             //controller.vibrate(30);
742         }
743         catch (Exception e)
744         {
745             e.printStackTrace();
746         }
747     }
748
749     @Override
750     public AmbientModeSupport.AmbientCallback getAmbientCallback()
751     {
752         return (new AmbientModeSupport.AmbientCallback() {
753             public void onEnterAmbient(Bundle ambientDetails)
754             {
755                 Log.v(TAG, "onEnterAmbient()");
756             }
757             public void onExitAmbient(Bundle ambientDetails)
758             {
759                 Log.v(TAG, "onExitAmbient()");
760                 //updateTimerLabel();
761             }
762         });
763     }
764 }