OSDN Git Service

7873ba53ab91f880af517647cd959e9ce1af3336
[gokigen/A01c.git] / wear / src / main / java / jp / sfjp / gokigen / a01c / MainActivity.java
1 package jp.sfjp.gokigen.a01c;
2
3 import android.content.Intent;
4 import android.content.SharedPreferences;
5 import android.graphics.Color;
6 import android.graphics.drawable.Drawable;
7 import android.os.Bundle;
8 import android.os.PowerManager;
9 import android.os.Vibrator;
10 import android.preference.PreferenceManager;
11 import android.provider.Settings;
12 import android.util.Log;
13 import android.widget.ImageButton;
14 import android.widget.TextView;
15 import android.Manifest;
16 import android.content.pm.PackageManager;
17 import android.widget.Toast;
18
19 import androidx.annotation.NonNull;
20 import androidx.appcompat.app.AppCompatActivity;
21 import androidx.core.app.ActivityCompat;
22 import androidx.core.content.ContextCompat;
23
24 import jp.sfjp.gokigen.a01c.liveview.CameraLiveImageView;
25 import jp.sfjp.gokigen.a01c.liveview.CameraLiveViewListenerImpl;
26 import jp.sfjp.gokigen.a01c.liveview.dialog.FavoriteSettingSelectionDialog;
27 import jp.sfjp.gokigen.a01c.liveview.dialog.IDialogDismissedNotifier;
28 import jp.sfjp.gokigen.a01c.liveview.ICameraStatusReceiver;
29 import jp.sfjp.gokigen.a01c.liveview.IMessageDrawer;
30 import jp.sfjp.gokigen.a01c.liveview.CameraLiveViewOnTouchListener;
31 import jp.sfjp.gokigen.a01c.olycamerawrapper.OlyCameraCoordinator;
32 import jp.sfjp.gokigen.a01c.preference.IPreferenceCameraPropertyAccessor;
33 import jp.sfjp.gokigen.a01c.preference.PreferenceAccessWrapper;
34 import jp.sfjp.gokigen.a01c.thetacamerawrapper.ThetaCameraController;
35
36 /**
37  *   メインのActivity
38  *
39  */
40 public class MainActivity extends AppCompatActivity implements  IChangeScene, IShowInformation, ICameraStatusReceiver, IDialogDismissedNotifier, IWifiConnection
41 {
42     private final String TAG = toString();
43     static final int REQUEST_NEED_PERMISSIONS = 1010;
44     //static final int COMMAND_MY_PROPERTY = 0x00000100;
45
46     private PreferenceAccessWrapper preferences = null;
47     private PowerManager powerManager = null;
48     private CameraLiveImageView liveView = null;
49     private ICameraController currentCoordinator = null;
50     private ICameraController olyAirCoordinator = null;
51     private ICameraController thetaCoordinator = null;
52     private IMessageDrawer messageDrawer = null;
53     private CameraLiveViewOnTouchListener listener = null;
54     private FavoriteSettingSelectionDialog selectionDialog = null;
55     private Vibrator vibrator = null;
56     private boolean cameraDisconnectedHappened = false;
57     private WifiConnection wifiConnection = null;
58     //private boolean ambientMode = false;
59
60     /**
61      *
62      */
63     @Override
64     protected void onCreate(Bundle savedInstanceState)
65     {
66         super.onCreate(savedInstanceState);
67         Log.v(TAG, "onCreate()");
68
69         // Ambientモードを許してみる...
70         //setAmbientEnabled();
71
72         //  画面全体の設定
73         setContentView(R.layout.activity_main);
74
75         // WiFIアクセス権のオプトイン
76         if ((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)||
77                 (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED)||
78                 (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) != PackageManager.PERMISSION_GRANTED)||
79                 (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)||
80                 (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_SETTINGS) != PackageManager.PERMISSION_GRANTED)||
81                 (ContextCompat.checkSelfPermission(this, Manifest.permission.WAKE_LOCK) != PackageManager.PERMISSION_GRANTED)||
82                 (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED)||
83                 (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED))
84         {
85             ActivityCompat.requestPermissions(this,
86                     new String[]{
87                             Manifest.permission.ACCESS_NETWORK_STATE,
88                             Manifest.permission.ACCESS_WIFI_STATE,
89                             Manifest.permission.CHANGE_WIFI_STATE,
90                             Manifest.permission.CHANGE_NETWORK_STATE,
91                             Manifest.permission.WRITE_SETTINGS,
92                             Manifest.permission.WAKE_LOCK,
93                             Manifest.permission.INTERNET,
94                     },
95                     REQUEST_NEED_PERMISSIONS);
96         }
97
98         try
99         {
100             if (!hasGps())
101             {
102                 // GPS機能が搭載されていない場合...
103                 Log.d(TAG, "This hardware doesn't have GPS.");
104                 // Fall back to functionality that does not use location or
105                 // warn the user that location function is not available.
106             }
107
108             // バイブレータをつかまえる
109             vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
110
111             // パワーマネージャをつかまえる
112             powerManager = (PowerManager) getSystemService(POWER_SERVICE);
113
114             setupCameraCoordinator();
115             setupInitialButtonIcons();
116             setupActionListener();
117
118             wifiConnection = new WifiConnection(this, this);
119         }
120         catch (Exception e)
121         {
122             e.printStackTrace();
123         }
124     }
125
126     /**
127      *
128      */
129     @Override
130     protected void onResume()
131     {
132         super.onResume();
133         Log.v(TAG, "onResume()");
134         if (wifiConnection != null)
135         {
136             // ネットワークを要求する!
137             wifiConnection.requestNetwork();
138             wifiConnection.startWatchWifiStatus();
139         }
140     }
141
142     /**
143      *
144      */
145     @Override
146     protected void onPause()
147     {
148         super.onPause();
149         Log.v(TAG, "onPause()");
150     }
151
152     /**
153      *
154      *
155      */
156     @Override
157     public void onStart()
158     {
159         super.onStart();
160         Log.v(TAG, "onStart()");
161     }
162
163     /**
164      *
165      *
166      */
167     @Override
168     public void onStop()
169     {
170         super.onStop();
171         Log.v(TAG, "onStop()");
172         exitApplication();
173     }
174
175 /*
176      @Override
177      public void onEnterAmbient(Bundle ambientDetails)
178      {
179          super.onEnterAmbient(ambientDetails);
180          Log.v(TAG, "onEnterAmbient()");
181          ambientMode =true;
182      }
183
184     @Override
185     public void onExitAmbient()
186     {
187         super.onExitAmbient();
188         Log.v(TAG, "onExitAmbient()");
189         ambientMode = false;
190     }
191
192     @Override
193     public void onUpdateAmbient()
194     {
195         super.onUpdateAmbient();
196         Log.v(TAG, "onUpdateAmbient()");
197     }
198 */
199
200     /**
201      *   ボタンが押された、画面がタッチされた、、は、リスナクラスで処理するよう紐づける
202      *
203      */
204     private void setupActionListener()
205     {
206         try
207         {
208             final ImageButton btn1 = findViewById(R.id.btn_1);
209             btn1.setOnClickListener(listener);
210             btn1.setOnLongClickListener(listener);
211
212             final ImageButton btn2 = findViewById(R.id.btn_2);
213             btn2.setOnClickListener(listener);
214             btn2.setOnLongClickListener(listener);
215
216             final ImageButton btn3 = findViewById(R.id.btn_3);
217             btn3.setOnClickListener(listener);
218             btn3.setOnLongClickListener(listener);
219
220             final ImageButton btn4 = findViewById(R.id.btn_4);
221             btn4.setOnClickListener(listener);
222             btn4.setOnLongClickListener(listener);
223
224             final ImageButton btn5 = findViewById(R.id.btn_5);
225             btn5.setOnClickListener(listener);
226             btn5.setOnLongClickListener(listener);
227
228             final ImageButton btn6 = findViewById(R.id.btn_6);
229             btn6.setOnClickListener(listener);
230             btn6.setOnLongClickListener(listener);
231
232             final TextView textArea1 = findViewById(R.id.text_1);
233             textArea1.setOnClickListener(listener);
234             textArea1.setOnLongClickListener(listener);
235
236             final TextView textArea2 = findViewById(R.id.text_2);
237             textArea2.setOnClickListener(listener);
238             textArea2.setOnLongClickListener(listener);
239
240             final TextView textArea3 = findViewById(R.id.text_3);
241             textArea3.setOnClickListener(listener);
242             textArea3.setOnLongClickListener(listener);
243
244             final TextView textArea4 = findViewById(R.id.text_4);
245             textArea4.setOnClickListener(listener);
246             textArea4.setOnLongClickListener(listener);
247
248             if (liveView == null)
249             {
250                 liveView = findViewById(R.id.liveview);
251             }
252             liveView.setOnTouchListener(listener);
253             messageDrawer = liveView.getMessageDrawer();
254             messageDrawer.setLevelGauge(currentCoordinator.getLevelGauge());
255         }
256         catch (Exception e)
257         {
258             e.printStackTrace();
259         }
260     }
261
262     /**
263      *   ボタンアイコンの初期設定
264      *
265      */
266     private void setupInitialButtonIcons()
267     {
268         try
269         {
270             if (currentCoordinator != null)
271             {
272                 int resId;
273                 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
274                 if (preferences.getBoolean(IPreferenceCameraPropertyAccessor.SHOW_GRID_STATUS, true)) {
275                     // ボタンをGrid OFFアイコンにする
276                     resId = R.drawable.btn_ic_grid_off;
277                 } else {
278                     // ボタンをGrid ONアイコンにする
279                     resId = R.drawable.btn_ic_grid_on;
280                 }
281                 setButtonDrawable(IShowInformation.BUTTON_1, resId);
282             }
283         }
284         catch (Exception e)
285         {
286             e.printStackTrace();
287         }
288     }
289
290     /**
291      *   Intentを使ってWiFi設定画面を開く
292      *
293      */
294     private boolean launchWifiSettingScreen()
295     {
296         Log.v(TAG, "launchWifiSettingScreen()");
297         try
298         {
299             // Wifi 設定画面を表示する... (SONY Smart Watch 3では開かないけど...)
300             startActivity(new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"));
301             return (true);
302         }
303         catch (Exception ex)
304         {
305             try
306             {
307                 Log.v(TAG, "launchWifiSettingScreen() : ACTION_WIFI_SETTINGS");
308                 startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
309                 return (true);
310             }
311             catch (Exception e)
312             {
313                 Log.v(TAG, "android.content.ActivityNotFoundException... " + "com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS");
314                 try
315                 {
316                     // SONY Smart Watch 3で開く場合のIntent...
317                     Intent intent = new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS");
318                     intent.setClassName("com.google.android.apps.wearable.settings", "com.google.android.clockwork.settings.wifi.WifiSettingsActivity");
319                     startActivity(intent);
320                     return (true);
321                 }
322                 catch (Exception ex2)
323                 {
324                     try
325                     {
326                         // Wifi 設定画面を表示する...普通のAndroidの場合
327                         startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
328                         return (true);
329                     }
330                     catch (Exception ee)
331                     {
332                         ee.printStackTrace();
333                         try
334                         {
335                             // LG G Watch Rで開く場合のIntent...
336                             Intent intent = new Intent("android.intent.action.MAIN");
337                             intent.setClassName("com.google.android.apps.wearable.settings", "com.google.android.clockwork.settings.MainSettingsActivity");
338                             startActivity(intent);
339                             return (true);
340                         }
341                         catch (android.content.ActivityNotFoundException ex3)
342                         {
343                             ex3.printStackTrace();
344                         }
345                     }
346                 }
347             }
348         }
349         return (false);
350     }
351
352     /**
353      *   Olympus Cameraクラスとのやりとりをするクラスを準備する
354      *   (カメラとの接続も、ここでスレッドを起こして開始する)
355      */
356     private void setupCameraCoordinator()
357     {
358         try
359         {
360             preferences = new PreferenceAccessWrapper(this);
361             preferences.initialize();
362             String connectionMethod = preferences.getString(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD, IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_DEFAULT_VALUE);
363             if (liveView == null)
364             {
365                 liveView = findViewById(R.id.liveview);
366             }
367             olyAirCoordinator = new OlyCameraCoordinator(this, liveView, this, this);
368             thetaCoordinator = new ThetaCameraController(this, this, this);
369             currentCoordinator = (connectionMethod.contains(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA)) ? thetaCoordinator : olyAirCoordinator;
370             currentCoordinator.setLiveViewListener(new CameraLiveViewListenerImpl(liveView));
371             listener = new CameraLiveViewOnTouchListener(this, currentCoordinator.getFeatureDispatcher(this, this, currentCoordinator, preferences, liveView), this);
372             selectionDialog = new FavoriteSettingSelectionDialog(this, currentCoordinator.getCameraPropertyLoadSaveOperations(), this);
373             connectToCamera();
374         }
375         catch (Exception e)
376         {
377             e.printStackTrace();
378         }
379     }
380
381     /**
382      *   カメラと接続する
383      *
384      */
385     private void connectToCamera()
386     {
387         Thread thread = new Thread(new Runnable()
388         {
389             @Override
390             public void run()
391             {
392                 currentCoordinator.getConnectionInterface().connect();
393             }
394         });
395         try
396         {
397             thread.start();
398         }
399         catch (Exception e)
400         {
401             e.printStackTrace();
402         }
403     }
404
405     /**
406      *   カメラの電源をOFFいして、アプリを抜ける処理
407      *
408      */
409     @Override
410     public void exitApplication()
411     {
412         try
413         {
414             Log.v(TAG, "exitApplication()");
415 /*
416             if (ambientMode)
417             {
418                 // アンビエントモードの時(≒自分でアプリを終了しなかったとき)は、何もしない
419                 // (接続したままとする)
420                 Log.v(TAG, "keep liveview.");
421                 return;
422             }
423 */
424
425             // パワーマネージャを確認し、interactive modeではない場合は、ライブビューも止めず、カメラの電源も切らない
426             if ((powerManager != null) && (!powerManager.isInteractive()))
427             {
428                 Log.v(TAG, "not interactive, keep liveview.");
429                 return;
430             }
431
432             // ライブビューを停止させる
433             currentCoordinator.stopLiveView();
434
435             // ステータス監視を止める
436             ICameraStatusWatcher watcher = currentCoordinator.getStatusWatcher();
437             if (watcher != null)
438             {
439                 watcher.stopStatusWatch();
440             }
441
442             //  パラメータを確認し、カメラの電源を切る
443             if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(IPreferenceCameraPropertyAccessor.EXIT_APPLICATION_WITH_DISCONNECT, true))
444             {
445                 Log.v(TAG, "Shutdown camera...");
446
447                 // カメラの電源をOFFにする
448                 currentCoordinator.getConnectionInterface().disconnect(true);
449             }
450             //finish();
451             //finishAndRemoveTask();
452             //android.os.Process.killProcess(android.os.Process.myPid());
453         }
454         catch (Exception e)
455         {
456             e.printStackTrace();
457         }
458     }
459
460     /**
461      *   接続機能を確認する
462      */
463     @Override
464     public boolean checkConnectionFeature(int id, int btnId)
465     {
466         boolean ret = false;
467         if (id == 0)
468         {
469             // Wifi 設定画面を開く
470             ret = launchWifiSettingScreen();
471         }
472         else if (id == 1)
473         {
474             // 接続の変更を確認する
475             changeConnectionMethod();
476         }
477         return (ret);
478     }
479
480     /**
481      *   画面をタッチした場所を受信する
482      *
483      * @param posX  X座標位置 (0.0f - 1.0f)
484      * @param posY  Y座標位置 (0.0f - 1.0f)
485      * @return true / false
486      */
487     @Override
488     public boolean touchedPosition(float posX, float posY)
489     {
490         Log.v(TAG, "touchedPosition (" + posX + ", " + posY);
491         return ((liveView != null)&&(liveView.touchedPosition(posX, posY)));
492     }
493
494     /**
495      *   接続状態を見る or 再接続する
496      */
497     @Override
498     public boolean showConnectionStatus()
499     {
500         try
501         {
502             if ((listener.isEnabledOperation() == IShowInformation.operation.ONLY_CONNECT) && (cameraDisconnectedHappened)) {
503                 // カメラが切断されたとき、再接続を指示する
504                 connectToCamera();
505                 cameraDisconnectedHappened = false;
506                 return (true);
507             }
508         }
509         catch (Exception e)
510         {
511             e.printStackTrace();
512         }
513         return (false);
514     }
515
516     /**
517      *
518      */
519     @Override
520     public void onStatusNotify(String message)
521     {
522         setMessage(IShowInformation.AREA_C, Color.WHITE, message);
523     }
524
525     /**
526      *
527      */
528     @Override
529     public void onCameraConnected()
530     {
531         Log.v(TAG, "onCameraConnected()");
532         try
533         {
534             // ライブビューの開始 & タッチ/ボタンの操作を可能にする
535             currentCoordinator.connectFinished();
536             currentCoordinator.startLiveView();
537             currentCoordinator.setRecViewMode(false);
538             listener.setEnableOperation(operation.ENABLE);
539             setMessage(IShowInformation.AREA_C, Color.WHITE, "");
540             currentCoordinator.updateStatusAll();
541             ICameraStatusWatcher watcher = currentCoordinator.getStatusWatcher();
542             if (watcher != null)
543             {
544                 watcher.startStatusWatch();
545             }
546         }
547         catch (Exception e)
548         {
549             e.printStackTrace();
550         }
551     }
552
553     /**
554      *   カメラとの接続が切れたとき...何もしない
555      *
556      */
557     @Override
558     public void onCameraDisconnected()
559     {
560         Log.v(TAG, "onCameraDisconnected()");
561         try
562         {
563             setMessage(IShowInformation.AREA_C, Color.YELLOW, getString(R.string.camera_disconnected));
564             listener.setEnableOperation(operation.ONLY_CONNECT);
565             cameraDisconnectedHappened = true;
566         }
567         catch (Exception e)
568         {
569             e.printStackTrace();
570         }
571     }
572
573     /**
574      *  カメラと接続失敗
575      */
576     @Override
577     public void onCameraConnectError(@NonNull String message)
578     {
579         Log.v(TAG, "onCameraOccursException()");
580         try
581         {
582             setMessage(IShowInformation.AREA_C, Color.YELLOW, message);
583             listener.setEnableOperation(operation.ONLY_CONNECT);
584             cameraDisconnectedHappened = true;
585         }
586         catch (Exception ee)
587         {
588             ee.printStackTrace();
589         }
590     }
591
592     /**
593      *  カメラに例外発生
594      */
595     @Override
596     public void onCameraOccursException(@NonNull String message, Exception e)
597     {
598         Log.v(TAG, "onCameraOccursException()");
599         try
600         {
601             setMessage(IShowInformation.AREA_C, Color.YELLOW, message);
602             listener.setEnableOperation(operation.ONLY_CONNECT);
603             cameraDisconnectedHappened = true;
604         }
605         catch (Exception ee)
606         {
607             e.printStackTrace();
608             ee.printStackTrace();
609         }
610     }
611
612     /**s
613      *   メッセージの表示
614      *
615      * @param area    表示エリア (AREA_1 ~ AREA_6, AREA_C)
616      * @param color  表示色
617      * @param message 表示するメッセージ
618      */
619     @Override
620     public void setMessage(final int area, final int color, final String message)
621     {
622         int id = 0;
623         switch (area)
624         {
625             case IShowInformation.AREA_1:
626                 id = R.id.text_1;
627                 break;
628             case IShowInformation.AREA_2:
629                 id = R.id.text_2;
630                 break;
631             case IShowInformation.AREA_3:
632                 id = R.id.text_3;
633                 break;
634             case IShowInformation.AREA_4:
635                 id = R.id.text_4;
636                 break;
637             case IShowInformation.AREA_NONE:
638             default:
639                 // unknown
640                 break;
641         }
642         if (messageDrawer != null)
643         {
644             if (area == IShowInformation.AREA_C)
645             {
646                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTER, color, IMessageDrawer.SIZE_LARGE, message);
647                 return;
648             }
649             if (area == IShowInformation.AREA_5)
650             {
651                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPLEFT, color, IMessageDrawer.SIZE_STD, message);
652                 return;
653             }
654             if (area == IShowInformation.AREA_6)
655             {
656                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWLEFT, color, IMessageDrawer.SIZE_STD, message);
657                 return;
658             }
659             if (area == IShowInformation.AREA_7)
660             {
661                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPRIGHT, color, IMessageDrawer.SIZE_STD, message);
662                 return;
663             }
664             if (area == IShowInformation.AREA_8)
665             {
666                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWRIGHT, color, IMessageDrawer.SIZE_STD, message);
667                 return;
668             }
669             if (area == IShowInformation.AREA_9)
670             {
671                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPCENTER, color, IMessageDrawer.SIZE_STD, message);
672                 return;
673             }
674             if (area == IShowInformation.AREA_A)
675             {
676                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWCENTER, color, IMessageDrawer.SIZE_STD, message);
677                 return;
678             }
679             if (area == IShowInformation.AREA_B)
680             {
681                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTERLEFT, color, IMessageDrawer.SIZE_STD, message);
682                 return;
683             }
684             if (area == IShowInformation.AREA_D)
685             {
686                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTERRIGHT, color, IMessageDrawer.SIZE_STD, message);
687                 return;
688             }
689
690             if (id == 0)
691             {
692                 // 描画エリアが不定の場合...
693                 return;
694             }
695         }
696
697         final int areaId = id;
698         runOnUiThread(new Runnable()
699         {
700              @Override
701              public void run()
702              {
703                  final TextView textArea = findViewById(areaId);
704                  if (textArea != null)
705                  {
706                      textArea.setTextColor(color);
707                      textArea.setText(message);
708                      textArea.invalidate();
709                  }
710              }
711         });
712     }
713
714     /**
715      *   ボタンの表示イメージを変更する
716      *
717      * @param button  ボタンの場所
718      * @param labelId 変更する内容
719      */
720     @Override
721     public void setButtonDrawable(final int button, final int labelId)
722     {
723         int id;
724         switch (button)
725         {
726             case IShowInformation.BUTTON_1:
727                 id = R.id.btn_1;
728                 break;
729             case IShowInformation.BUTTON_2:
730                 id = R.id.btn_2;
731                 break;
732             case IShowInformation.BUTTON_3:
733                 id = R.id.btn_3;
734                 break;
735             case IShowInformation.BUTTON_4:
736                 id = R.id.btn_4;
737                 break;
738             case IShowInformation.BUTTON_5:
739                 id = R.id.btn_5;
740                 break;
741             case IShowInformation.BUTTON_6:
742             default:
743                 id = R.id.btn_6;
744                 break;
745         }
746
747         final int areaId = id;
748         runOnUiThread(new Runnable()
749         {
750             @Override
751             public void run()
752             {
753                 try
754                 {
755                     final ImageButton button = findViewById(areaId);
756                     final Drawable drawTarget = ContextCompat.getDrawable(getApplicationContext(), labelId);
757                     if (button != null)
758                     {
759                         button.setImageDrawable(drawTarget);
760                         button.invalidate();
761                     }
762                 }
763                 catch (Exception e)
764                 {
765                     e.printStackTrace();
766                 }
767             }
768         });
769     }
770
771     /**
772      *
773      * @return true GPS搭載, false GPS非搭載
774      */
775     private boolean hasGps()
776     {
777         return (getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS));
778     }
779
780     /**
781      *
782      *
783      */
784     @Override
785     public void vibrate(final int vibratePattern)
786     {
787         try
788         {
789             if ((vibrator == null)||(!vibrator.hasVibrator()))
790             {
791                 return;
792             }
793
794             Thread thread = new Thread(new Runnable() {
795                 @Override
796                 public void run() {
797                     switch (vibratePattern)
798                     {
799                         case IShowInformation.VIBRATE_PATTERN_SIMPLE_LONGLONG:
800                             vibrator.vibrate(300);
801                             break;
802                         case IShowInformation.VIBRATE_PATTERN_SIMPLE_LONG:
803                             vibrator.vibrate(150);
804                             break;
805                         case IShowInformation.VIBRATE_PATTERN_SIMPLE_MIDDLE:
806                             vibrator.vibrate(80);
807                             break;
808                         case IShowInformation.VIBRATE_PATTERN_SIMPLE_SHORT:
809                             vibrator.vibrate(30);
810                             break;
811                         case IShowInformation.VIBRATE_PATTERN_SHORT_DOUBLE:
812                             long[] pattern = { 10, 35, 30, 35, 0 };
813                             vibrator.vibrate(pattern, -1);
814                             break;
815                         case IShowInformation.VIBRATE_PATTERN_NONE:
816                         default:
817                             // ぶるぶるしない
818                             break;
819                     }
820                 }
821             });
822             thread.start();
823         }
824         catch (Exception e)
825         {
826             e.printStackTrace();
827         }
828     }
829
830     @Override
831     public void setEnabledOperation(IShowInformation.operation operation)
832     {
833         if (listener != null)
834         {
835             listener.setEnableOperation(operation);
836         }
837     }
838
839     /**
840      *   「お気に入り設定」表示画面を開く
841      *
842      */
843     @Override
844     public void showFavoriteSettingsDialog()
845     {
846         if ((liveView != null)&&(listener != null)&&(listener.isEnabledOperation() != operation.ONLY_CONNECT))
847         {
848             listener.setEnableOperation(operation.ENABLE_ONLY_TOUCHED_POSITION);
849             liveView.showDialog(selectionDialog);
850         }
851     }
852
853     @Override
854     public void showToast(final int rscId, @NonNull final String appendMessage, final int duration)
855     {
856         try
857         {
858             runOnUiThread(new Runnable() {
859                 @Override
860                 public void run() {
861                     try
862                     {
863                         String message = (rscId != 0) ? getString(rscId) + appendMessage : appendMessage;
864                         Toast.makeText(getApplicationContext(), message, duration).show();
865                     }
866                     catch (Exception e)
867                     {
868                         e.printStackTrace();
869                     }
870                 }
871             });
872
873         }
874         catch (Exception e)
875         {
876             e.printStackTrace();
877         }
878     }
879
880     @Override
881     public void invalidate()
882     {
883         try
884         {
885             runOnUiThread(new Runnable() {
886                 @Override
887                 public void run() {
888                     if (liveView != null)
889                     {
890                         liveView.invalidate();
891                     }
892                 }
893             });
894         }
895         catch (Exception e)
896         {
897             e.printStackTrace();
898         }
899     }
900
901     /**
902      *   「お気に入り設定」表示画面を閉じる
903      *
904      */
905     @Override
906     public void dialogDismissed(boolean isExecuted)
907     {
908         try
909         {
910             if ((liveView != null) && (listener != null))
911             {
912                 liveView.hideDialog();
913                 listener.setEnableOperation(operation.ENABLE);
914             }
915         }
916         catch (Exception e)
917         {
918             e.printStackTrace();
919         }
920     }
921
922     private void updateConnectionMethodMessage()
923     {
924         try
925         {
926             String connectionMethod = preferences.getString(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD, IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_DEFAULT_VALUE);
927             int methodId = (connectionMethod.contains(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA)) ? R.string.connection_method_theta : R.string.connection_method_opc;
928             setMessage(IShowInformation.AREA_7, Color.MAGENTA, getString(methodId));
929             if (liveView == null)
930             {
931                 liveView = findViewById(R.id.liveview);
932             }
933             liveView.setupInitialBackgroundImage(this);
934             liveView.invalidate();
935         }
936         catch (Exception e)
937         {
938             e.printStackTrace();
939         }
940     }
941
942     private void updateConnectionMethod(String parameter, ICameraController method)
943     {
944         try
945         {
946             currentCoordinator = method;
947             preferences.putString(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD, parameter);
948             vibrate(IShowInformation.VIBRATE_PATTERN_SHORT_DOUBLE);
949         }
950         catch (Exception e)
951         {
952             e.printStackTrace();
953         }
954     }
955
956     /**
957      *   接続方式を変更するか確認する (OPC ⇔ THETA)
958      *
959      */
960     private void changeConnectionMethod()
961     {
962         final AppCompatActivity activity = this;
963         runOnUiThread(new Runnable() {
964             @Override
965             public void run() {
966                 try
967                 {
968                     int titleId = R.string.change_title_from_opc_to_theta;
969                     int messageId = R.string.change_message_from_opc_to_theta;
970                     boolean method = false;
971                     String connectionMethod = preferences.getString(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD, IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_DEFAULT_VALUE);
972                     if (connectionMethod.contains(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA))
973                     {
974                         titleId = R.string.change_title_from_theta_to_opc;
975                         messageId = R.string.change_message_from_theta_to_opc;
976                         method = true;
977                     }
978                     final boolean isTheta = method;
979                     ConfirmationDialog confirmation = new ConfirmationDialog(activity);
980                     confirmation.show(titleId, messageId, new ConfirmationDialog.Callback() {
981                         @Override
982                         public void confirm() {
983                             Log.v(TAG, " --- CONFIRMED! --- (theta:" + isTheta + ")");
984                             if (isTheta)
985                             {
986                                 // 接続方式を OPC に切り替える
987                                 updateConnectionMethod(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_OPC, olyAirCoordinator);
988                             }
989                             else
990                             {
991                                 // 接続方式を Theta に切り替える
992                                 updateConnectionMethod(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA, thetaCoordinator);
993                             }
994                             updateConnectionMethodMessage();
995                         }
996                     });
997                 }
998                 catch (Exception e)
999                 {
1000                     e.printStackTrace();
1001                 }
1002             }
1003         });
1004     }
1005
1006     @Override
1007     public void onConnectedToWifi()
1008     {
1009         try
1010         {
1011             Log.v(TAG, "onConnectedToWifi()");
1012         }
1013         catch (Exception e)
1014         {
1015             e.printStackTrace();
1016         }
1017     }
1018 }