OSDN Git Service

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