OSDN Git Service

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