OSDN Git Service

ダイアログ表示の枠組みを作る。(OK, Cancelボタンの位置)
[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.os.Bundle;
7 import android.os.Vibrator;
8 import android.preference.PreferenceManager;
9 import android.provider.Settings;
10 import android.support.wearable.activity.WearableActivity;
11 import android.util.Log;
12 import android.widget.ImageButton;
13 import android.widget.TextView;
14 import android.Manifest;
15 import android.content.pm.PackageManager;
16 import android.support.v4.app.ActivityCompat;
17 import android.support.v4.content.ContextCompat;
18
19 import jp.sfjp.gokigen.a01c.liveview.CameraLiveImageView;
20 import jp.sfjp.gokigen.a01c.liveview.CameraLiveViewListenerImpl;
21 import jp.sfjp.gokigen.a01c.liveview.dialog.FavoriteSettingSelectionDialog;
22 import jp.sfjp.gokigen.a01c.liveview.dialog.IDialogDismissedNotifier;
23 import jp.sfjp.gokigen.a01c.liveview.dialog.IDialogDrawer;
24 import jp.sfjp.gokigen.a01c.olycamerawrapper.dispatcher.FeatureDispatcher;
25 import jp.sfjp.gokigen.a01c.liveview.ICameraStatusReceiver;
26 import jp.sfjp.gokigen.a01c.liveview.IMessageDrawer;
27 import jp.sfjp.gokigen.a01c.liveview.OlyCameraLiveViewOnTouchListener;
28 import jp.sfjp.gokigen.a01c.olycamerawrapper.IOlyCameraCoordinator;
29 import jp.sfjp.gokigen.a01c.olycamerawrapper.OlyCameraCoordinator;
30 import jp.sfjp.gokigen.a01c.preference.IPreferenceCameraPropertyAccessor;
31
32 /**
33  *   メインのActivity
34  *
35  */
36 public class MainActivity extends WearableActivity implements  IChangeScene, IShowInformation, ICameraStatusReceiver, IDialogDismissedNotifier
37 {
38     private final String TAG = toString();
39     static final int REQUEST_NEED_PERMISSIONS = 1010;
40     static final int COMMAND_MY_PROPERTY = 0x00000100;
41
42     private CameraLiveImageView liveView = null;
43     private IOlyCameraCoordinator coordinator = null;
44     private IMessageDrawer messageDrawer = null;
45     private OlyCameraLiveViewOnTouchListener listener = null;
46     private FavoriteSettingSelectionDialog selectionDialog = null;
47     private Vibrator vibrator = null;
48     private boolean cameraDisconnectedHappened = false;
49     private boolean ambientMode = false;
50
51     /**
52      *
53      */
54     @Override
55     protected void onCreate(Bundle savedInstanceState)
56     {
57         super.onCreate(savedInstanceState);
58         Log.v(TAG, "onCreate()");
59
60         // Ambientモードを許してみる...
61         setAmbientEnabled();
62
63         //  画面全体の設定
64         setContentView(R.layout.activity_main);
65
66         // WiFIアクセス権のオプトイン
67         if ((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)||
68                 (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED)||
69                 (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) != PackageManager.PERMISSION_GRANTED)||
70                 (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)||
71                 (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_SETTINGS) != PackageManager.PERMISSION_GRANTED)||
72                 (ContextCompat.checkSelfPermission(this, Manifest.permission.WAKE_LOCK) != PackageManager.PERMISSION_GRANTED)||
73                 (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED)||
74                 (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED))
75         {
76             ActivityCompat.requestPermissions(this,
77                     new String[]{
78                             Manifest.permission.ACCESS_NETWORK_STATE,
79                             Manifest.permission.ACCESS_WIFI_STATE,
80                             Manifest.permission.CHANGE_WIFI_STATE,
81                             Manifest.permission.CHANGE_NETWORK_STATE,
82                             Manifest.permission.WRITE_SETTINGS,
83                             Manifest.permission.WAKE_LOCK,
84                             Manifest.permission.INTERNET,
85                     },
86                     REQUEST_NEED_PERMISSIONS);
87         }
88
89         if (!hasGps())
90         {
91             // GPS機能が搭載されていない場合...
92             Log.d(TAG, "This hardware doesn't have GPS.");
93             // Fall back to functionality that does not use location or
94             // warn the user that location function is not available.
95         }
96
97         // バイブレータをつかまえる
98         vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
99
100         setupCameraCoordinator();
101         setupInitialButtonIcons();
102         setupActionListener();
103     }
104
105     /**
106      *
107      */
108     @Override
109     protected void onResume()
110     {
111         super.onResume();
112         Log.v(TAG, "onResume()");
113     }
114
115     /**
116      *
117      */
118     @Override
119     protected void onPause()
120     {
121         super.onPause();
122         Log.v(TAG, "onPause()");
123     }
124
125     /**
126      *
127      *
128      */
129     @Override
130     public void onStart()
131     {
132         super.onStart();
133         Log.v(TAG, "onStart()");
134     }
135
136     /**
137      *
138      *
139      */
140     @Override
141     public void onStop()
142     {
143         super.onStop();
144         Log.v(TAG, "onStop()");
145         exitApplication();
146     }
147
148     /**
149      *
150      *
151      */
152      @Override
153      public void onEnterAmbient(Bundle ambientDetails)
154      {
155          super.onEnterAmbient(ambientDetails);
156          Log.v(TAG, "onEnterAmbient()");
157          ambientMode =true;
158      }
159
160     /**
161      *
162      *
163      */
164     @Override
165     public void onExitAmbient()
166     {
167         super.onExitAmbient();
168         Log.v(TAG, "onExitAmbient()");
169         ambientMode = false;
170     }
171
172     /**
173      *
174      *
175      */
176     @Override
177     public void onUpdateAmbient()
178     {
179         super.onUpdateAmbient();
180         Log.v(TAG, "onUpdateAmbient()");
181     }
182
183     /**
184      *   ボタンが押された、画面がタッチされた、、は、リスナクラスで処理するよう紐づける
185      *
186      */
187     private void setupActionListener()
188     {
189         final ImageButton btn1 = (ImageButton) findViewById(R.id.btn_1);
190         btn1.setOnClickListener(listener);
191         btn1.setOnLongClickListener(listener);
192
193         final ImageButton btn2 = (ImageButton) findViewById(R.id.btn_2);
194         btn2.setOnClickListener(listener);
195         btn2.setOnLongClickListener(listener);
196
197         final ImageButton btn3 = (ImageButton) findViewById(R.id.btn_3);
198         btn3.setOnClickListener(listener);
199         btn3.setOnLongClickListener(listener);
200
201         final ImageButton btn4 = (ImageButton) findViewById(R.id.btn_4);
202         btn4.setOnClickListener(listener);
203         btn4.setOnLongClickListener(listener);
204
205         final ImageButton btn5 = (ImageButton) findViewById(R.id.btn_5);
206         btn5.setOnClickListener(listener);
207         btn5.setOnLongClickListener(listener);
208
209         final ImageButton btn6 = (ImageButton) findViewById(R.id.btn_6);
210         btn6.setOnClickListener(listener);
211         btn6.setOnLongClickListener(listener);
212
213         final TextView textArea1 = (TextView) findViewById(R.id.text_1);
214         textArea1.setOnClickListener(listener);
215         textArea1.setOnLongClickListener(listener);
216
217         final TextView textArea2 = (TextView) findViewById(R.id.text_2);
218         textArea2.setOnClickListener(listener);
219         textArea2.setOnLongClickListener(listener);
220
221         final TextView textArea3 = (TextView) findViewById(R.id.text_3);
222         textArea3.setOnClickListener(listener);
223         textArea3.setOnLongClickListener(listener);
224
225         final TextView textArea4 = (TextView) findViewById(R.id.text_4);
226         textArea4.setOnClickListener(listener);
227         textArea4.setOnLongClickListener(listener);
228
229         if (liveView == null)
230         {
231             liveView = (CameraLiveImageView) findViewById(R.id.liveview);
232         }
233         liveView.setOnTouchListener(listener);
234         messageDrawer = liveView.getMessageDrawer();
235         messageDrawer.setLevelGauge(coordinator.getLevelGauge());
236     }
237
238     /**
239      *   ボタンアイコンの初期設定
240      *
241      */
242     private void setupInitialButtonIcons()
243     {
244         if (coordinator != null)
245         {
246             int resId;
247             SharedPreferences preferences = android.support.v7.preference.PreferenceManager.getDefaultSharedPreferences(this);
248             if (preferences.getBoolean(IPreferenceCameraPropertyAccessor.SHOW_GRID_STATUS, true))
249             {
250                 // ボタンをGrid OFFアイコンにする
251                 resId = R.drawable.btn_ic_grid_off;
252             }
253             else
254             {
255                 // ボタンをGrid ONアイコンにする
256                 resId = R.drawable.btn_ic_grid_on;
257             }
258             setButtonDrawable(IShowInformation.BUTTON_1, resId);
259         }
260     }
261
262     /**
263      *   Intentを使ってWiFi設定画面を開く
264      *
265      */
266     private boolean launchWifiSettingScreen()
267     {
268         try
269         {
270             // Wifi 設定画面を表示する... (SONY Smart Watch 3では開かないけど...)
271             startActivity(new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"));
272             return (true);
273         }
274         catch (android.content.ActivityNotFoundException ex)
275         {
276             Log.v(TAG, "android.content.ActivityNotFoundException... " + "com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS");
277             try
278             {
279                 // SONY Smart Watch 3で開く場合のIntent...
280                 Intent intent = new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS");
281                 intent.setClassName("com.google.android.apps.wearable.settings", "com.google.android.clockwork.settings.wifi.WifiSettingsActivity");
282                 startActivity(intent);
283                 return (true);
284             }
285             catch (android.content.ActivityNotFoundException ex2)
286             {
287                 try
288                 {
289                     // Wifi 設定画面を表示する...普通のAndroidの場合
290                     startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
291                     return (true);
292                 }
293                 catch (Exception ee)
294                 {
295                     ee.printStackTrace();
296                 }
297             }
298             catch (Exception e)
299             {
300                 e.printStackTrace();
301             }
302         }
303         catch (Exception e2)
304         {
305             e2.printStackTrace();
306         }
307         return (false);
308     }
309
310     /**
311      *   Olympus Cameraクラスとのやりとりをするクラスを準備する
312      *   (カメラとの接続も、ここでスレッドを起こして開始する)
313      */
314     private void setupCameraCoordinator()
315     {
316         if (liveView == null)
317         {
318             liveView = (CameraLiveImageView) findViewById(R.id.liveview);
319         }
320         coordinator = null;
321         coordinator = new OlyCameraCoordinator(this, liveView, this, this);
322         coordinator.setLiveViewListener(new CameraLiveViewListenerImpl(liveView));
323         listener = new OlyCameraLiveViewOnTouchListener(this, new FeatureDispatcher(this, coordinator, liveView), this);
324         selectionDialog = new FavoriteSettingSelectionDialog(coordinator.getCameraPropertyLoadSaveOperations(), this);
325         connectToCamera();
326     }
327
328     /**
329      *   カメラと接続する
330      *
331      */
332     private void connectToCamera()
333     {
334         Thread thread = new Thread(new Runnable()
335         {
336             @Override
337             public void run()
338             {
339                 coordinator.getConnectionInterface().connect();
340             }
341         });
342         try
343         {
344             thread.start();
345         }
346         catch (Exception e)
347         {
348             e.printStackTrace();
349         }
350     }
351
352     /**
353      *   カメラの電源をOFFいして、アプリを抜ける処理
354      *
355      */
356     @Override
357     public void exitApplication()
358     {
359         Log.v(TAG, "exitApplication()");
360         if (ambientMode)
361         {
362             // アンビエントモードの時(≒自分でアプリを終了しなかったとき)は、何もしない
363             // (接続したままとする)
364             Log.v(TAG, "keep liveview.");
365             return;
366         }
367
368         // ライブビューを停止させる
369         coordinator.stopLiveView();
370
371         //  パラメータを確認し、カメラの電源を切る
372         if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(IPreferenceCameraPropertyAccessor.EXIT_APPLICATION_WITH_DISCONNECT, true))
373         {
374             Log.v(TAG, "Shutdown camera...");
375
376             // カメラの電源をOFFにする
377             coordinator.getConnectionInterface().disconnect(true);
378         }
379         //finish();
380         //finishAndRemoveTask();
381         //android.os.Process.killProcess(android.os.Process.myPid());
382     }
383
384     /**
385      *   接続機能を確認する
386      */
387     @Override
388     public boolean checkConnectionFeature(int id)
389     {
390         boolean ret = false;
391         if (id == 0)
392         {
393             // Wifi 設定画面を開く
394             ret = launchWifiSettingScreen();
395         }
396         return (ret);
397     }
398
399     /**
400      *   画面をタッチした場所を受信する
401      *
402      * @param posX  X座標位置 (0.0f - 1.0f)
403      * @param posY  Y座標位置 (0.0f - 1.0f)
404      * @return true / false
405      */
406     @Override
407     public boolean touchedPosition(float posX, float posY)
408     {
409         Log.v(TAG, "touchedPosition (" + posX + ", " + posY);
410         return ((liveView != null)&&(liveView.touchedPosition(posX, posY)));
411     }
412
413     /**
414      *   接続状態を見る or 再接続する
415      */
416     @Override
417     public boolean showConnectionStatus()
418     {
419         if ((listener.isEnabledOperation() == IShowInformation.operation.ONLY_CONNECT)&&(cameraDisconnectedHappened))
420         {
421             // カメラが切断されたとき、再接続を指示する
422             connectToCamera();
423             cameraDisconnectedHappened = false;
424             return (true);
425         }
426         return (false);
427     }
428
429     /**
430      *
431      */
432     @Override
433     public void onStatusNotify(String message)
434     {
435         setMessage(IShowInformation.AREA_C, Color.WHITE, message);
436     }
437
438     /**
439      *
440      */
441     @Override
442     public void onCameraConnected()
443     {
444         Log.v(TAG, "onCameraConnected()");
445
446         // ライブビューの開始 & タッチ/ボタンの操作を可能にする
447         coordinator.startLiveView();
448         coordinator.setRecViewMode(false);
449         listener.setEnableOperation(operation.ENABLE);
450         setMessage(IShowInformation.AREA_C, Color.WHITE, "");
451         coordinator.updateStatusAll();
452     }
453
454     /**
455      *   カメラとの接続が切れたとき...何もしない
456      *
457      */
458     @Override
459     public void onCameraDisconnected()
460     {
461         Log.v(TAG, "onCameraDisconnected()");
462         setMessage(IShowInformation.AREA_C, Color.YELLOW, getString(R.string.camera_disconnected));
463         listener.setEnableOperation(operation.ONLY_CONNECT);
464         cameraDisconnectedHappened = true;
465     }
466
467     /**
468      *  カメラに例外発生
469      */
470     @Override
471     public void onCameraOccursException(String message, Exception e)
472     {
473         Log.v(TAG, "onCameraOccursException()");
474         setMessage(IShowInformation.AREA_C, Color.YELLOW, message);
475         listener.setEnableOperation(operation.ONLY_CONNECT);
476         cameraDisconnectedHappened = true;
477     }
478
479     /**s
480      *   メッセージの表示
481      *
482      * @param area    表示エリア (AREA_1 ~ AREA_6, AREA_C)
483      * @param color  表示色
484      * @param message 表示するメッセージ
485      */
486     @Override
487     public void setMessage(final int area, final int color, final String message)
488     {
489         int id = 0;
490         switch (area)
491         {
492             case IShowInformation.AREA_1:
493                 id = R.id.text_1;
494                 break;
495             case IShowInformation.AREA_2:
496                 id = R.id.text_2;
497                 break;
498             case IShowInformation.AREA_3:
499                 id = R.id.text_3;
500                 break;
501             case IShowInformation.AREA_4:
502                 id = R.id.text_4;
503                 break;
504             case IShowInformation.AREA_NONE:
505             default:
506                 // unknown
507                 break;
508         }
509         if (messageDrawer != null)
510         {
511             if (area == IShowInformation.AREA_C)
512             {
513                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTER, color, IMessageDrawer.SIZE_LARGE, message);
514                 return;
515             }
516             if (area == IShowInformation.AREA_5)
517             {
518                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPLEFT, color, IMessageDrawer.SIZE_STD, message);
519                 return;
520             }
521             if (area == IShowInformation.AREA_6)
522             {
523                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWLEFT, color, IMessageDrawer.SIZE_STD, message);
524                 return;
525             }
526             if (area == IShowInformation.AREA_7)
527             {
528                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPRIGHT, color, IMessageDrawer.SIZE_STD, message);
529                 return;
530             }
531             if (area == IShowInformation.AREA_8)
532             {
533                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWRIGHT, color, IMessageDrawer.SIZE_STD, message);
534                 return;
535             }
536             if (area == IShowInformation.AREA_9)
537             {
538                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPCENTER, color, IMessageDrawer.SIZE_STD, message);
539                 return;
540             }
541             if (area == IShowInformation.AREA_A)
542             {
543                 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWCENTER, color, IMessageDrawer.SIZE_STD, message);
544                 return;
545             }
546
547             if (id == 0)
548             {
549                 // 描画エリアが不定の場合...
550                 return;
551             }
552         }
553
554         final int areaId = id;
555         runOnUiThread(new Runnable()
556         {
557              @Override
558              public void run() {
559                  final TextView textArea = (TextView) findViewById(areaId);
560                  textArea.setTextColor(color);
561                  textArea.setText(message);
562                  textArea.invalidate();
563              }
564         });
565     }
566
567     /**
568      *   ボタンの表示イメージを変更する
569      *
570      * @param button  ボタンの場所
571      * @param labelId 変更する内容
572      */
573     @Override
574     public void setButtonDrawable(final int button, final int labelId)
575     {
576         int id;
577         switch (button)
578         {
579             case IShowInformation.BUTTON_1:
580                 id = R.id.btn_1;
581                 break;
582             case IShowInformation.BUTTON_2:
583                 id = R.id.btn_2;
584                 break;
585             case IShowInformation.BUTTON_3:
586                 id = R.id.btn_3;
587                 break;
588             case IShowInformation.BUTTON_4:
589                 id = R.id.btn_4;
590                 break;
591             case IShowInformation.BUTTON_5:
592                 id = R.id.btn_5;
593                 break;
594             case IShowInformation.BUTTON_6:
595             default:
596                 id = R.id.btn_6;
597                 break;
598         }
599
600         final int areaId = id;
601         runOnUiThread(new Runnable()
602         {
603             @Override
604             public void run() {
605                 final ImageButton button = (ImageButton) findViewById(areaId);
606                 button.setImageDrawable(getDrawable(labelId));
607                 button.invalidate();
608             }
609         });
610     }
611
612     /**
613      *
614      * @return true GPS搭載, false GPS非搭載
615      */
616     private boolean hasGps()
617     {
618         return (getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS));
619     }
620
621     /**
622      *
623      *
624      */
625     @Override
626     public void vibrate(final int vibratePattern)
627     {
628         try
629         {
630             if ((vibrator == null)||(!vibrator.hasVibrator()))
631             {
632                 return;
633             }
634
635             Thread thread = new Thread(new Runnable() {
636                 @Override
637                 public void run() {
638                     switch (vibratePattern)
639                     {
640                         case IShowInformation.VIBRATE_PATTERN_SIMPLE_LONGLONG:
641                             vibrator.vibrate(300);
642                             break;
643                         case IShowInformation.VIBRATE_PATTERN_SIMPLE_LONG:
644                             vibrator.vibrate(150);
645                             break;
646                         case IShowInformation.VIBRATE_PATTERN_SIMPLE_MIDDLE:
647                             vibrator.vibrate(75);
648                             break;
649                         case IShowInformation.VIBRATE_PATTERN_SIMPLE_SHORT:
650                             vibrator.vibrate(20);
651                             break;
652                         case IShowInformation.VIBRATE_PATTERN_SHORT_DOUBLE:
653                             long[] pattern = { 10, 25, 20, 25, 0 };
654                             vibrator.vibrate(pattern, -1);
655                             break;
656                         case IShowInformation.VIBRATE_PATTERN_NONE:
657                         default:
658                             // ぶるぶるしない
659                             break;
660                     }
661                 }
662             });
663             thread.start();
664         }
665         catch (Exception e)
666         {
667             e.printStackTrace();
668         }
669     }
670
671     @Override
672     public void setEnabledOperation(IShowInformation.operation operation)
673     {
674         if (listener != null)
675         {
676             listener.setEnableOperation(operation);
677         }
678     }
679
680     /**
681      *   「お気に入り設定」表示画面を開く
682      *
683      */
684     @Override
685     public void showFavoriteSettingsDialog()
686     {
687 /*
688         // お気に入り設定画面を開く...
689         LoadSaveMyCameraPropertyDialog dialog = new LoadSaveMyCameraPropertyDialog();
690         dialog.setTargetFragment(this, COMMAND_MY_PROPERTY);
691         dialog.setPropertyOperationsHolder(coordinator.getCameraPropertyLoadSaveOperations());
692         dialog.show(this, "my_dialog");
693 */
694 /*
695         //  コマンドの実行確認ダイアログ... 動かん。。
696         ConfirmationDialog dialog = new ConfirmationDialog(this);
697         dialog.show(R.string.title_my_settings, R.string.message_none, new ConfirmationDialog.Callback()
698         {
699             @Override
700             public void confirm()
701             {
702                 vibrate(IShowInformation.VIBRATE_PATTERN_SIMPLE_LONGLONG);
703             }
704         });
705 */
706         if ((liveView != null)&&(listener != null)&&(listener.isEnabledOperation() != operation.ONLY_CONNECT))
707         {
708             listener.setEnableOperation(operation.ENABLE_ONLY_TOUCHED_POSITION);
709             liveView.showDialog(selectionDialog);
710         }
711     }
712
713     /**
714      *   「お気に入り設定」表示画面を閉じる
715      *
716      */
717     @Override
718     public void dialogDismissed(boolean isExecuted)
719     {
720         if ((liveView != null)&&(listener != null))
721         {
722             liveView.hideDialog();
723             listener.setEnableOperation(operation.ENABLE);
724
725         }
726     }
727 }