1 package jp.sfjp.gokigen.a01c;
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;
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;
36 public class MainActivity extends WearableActivity implements IChangeScene, IShowInformation, ICameraStatusReceiver, IDialogDismissedNotifier
38 private final String TAG = toString();
39 static final int REQUEST_NEED_PERMISSIONS = 1010;
40 //static final int COMMAND_MY_PROPERTY = 0x00000100;
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;
56 protected void onCreate(Bundle savedInstanceState)
58 super.onCreate(savedInstanceState);
59 Log.v(TAG, "onCreate()");
61 // Ambientモードを許してみる...
65 setContentView(R.layout.activity_main);
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))
77 ActivityCompat.requestPermissions(this,
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,
87 REQUEST_NEED_PERMISSIONS);
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.
99 vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
102 powerManager = (PowerManager) getSystemService(POWER_SERVICE);
104 setupCameraCoordinator();
105 setupInitialButtonIcons();
106 setupActionListener();
113 protected void onResume()
116 Log.v(TAG, "onResume()");
123 protected void onPause()
126 Log.v(TAG, "onPause()");
134 public void onStart()
137 Log.v(TAG, "onStart()");
148 Log.v(TAG, "onStop()");
157 public void onEnterAmbient(Bundle ambientDetails)
159 super.onEnterAmbient(ambientDetails);
160 Log.v(TAG, "onEnterAmbient()");
169 public void onExitAmbient()
171 super.onExitAmbient();
172 Log.v(TAG, "onExitAmbient()");
181 public void onUpdateAmbient()
183 super.onUpdateAmbient();
184 Log.v(TAG, "onUpdateAmbient()");
188 * ボタンが押された、画面がタッチされた、、は、リスナクラスで処理するよう紐づける
191 private void setupActionListener()
193 final ImageButton btn1 = findViewById(R.id.btn_1);
194 btn1.setOnClickListener(listener);
195 btn1.setOnLongClickListener(listener);
197 final ImageButton btn2 = findViewById(R.id.btn_2);
198 btn2.setOnClickListener(listener);
199 btn2.setOnLongClickListener(listener);
201 final ImageButton btn3 = findViewById(R.id.btn_3);
202 btn3.setOnClickListener(listener);
203 btn3.setOnLongClickListener(listener);
205 final ImageButton btn4 = findViewById(R.id.btn_4);
206 btn4.setOnClickListener(listener);
207 btn4.setOnLongClickListener(listener);
209 final ImageButton btn5 = findViewById(R.id.btn_5);
210 btn5.setOnClickListener(listener);
211 btn5.setOnLongClickListener(listener);
213 final ImageButton btn6 = findViewById(R.id.btn_6);
214 btn6.setOnClickListener(listener);
215 btn6.setOnLongClickListener(listener);
217 final TextView textArea1 = findViewById(R.id.text_1);
218 textArea1.setOnClickListener(listener);
219 textArea1.setOnLongClickListener(listener);
221 final TextView textArea2 = findViewById(R.id.text_2);
222 textArea2.setOnClickListener(listener);
223 textArea2.setOnLongClickListener(listener);
225 final TextView textArea3 = findViewById(R.id.text_3);
226 textArea3.setOnClickListener(listener);
227 textArea3.setOnLongClickListener(listener);
229 final TextView textArea4 = findViewById(R.id.text_4);
230 textArea4.setOnClickListener(listener);
231 textArea4.setOnLongClickListener(listener);
233 if (liveView == null)
235 liveView = findViewById(R.id.liveview);
237 liveView.setOnTouchListener(listener);
238 messageDrawer = liveView.getMessageDrawer();
239 messageDrawer.setLevelGauge(coordinator.getLevelGauge());
246 private void setupInitialButtonIcons()
248 if (coordinator != null)
251 SharedPreferences preferences = android.support.v7.preference.PreferenceManager.getDefaultSharedPreferences(this);
252 if (preferences.getBoolean(IPreferenceCameraPropertyAccessor.SHOW_GRID_STATUS, true))
254 // ボタンをGrid OFFアイコンにする
255 resId = R.drawable.btn_ic_grid_off;
259 // ボタンをGrid ONアイコンにする
260 resId = R.drawable.btn_ic_grid_on;
262 setButtonDrawable(IShowInformation.BUTTON_1, resId);
267 * Intentを使ってWiFi設定画面を開く
270 private boolean launchWifiSettingScreen()
272 Log.v(TAG, "launchWifiSettingScreen()");
275 // Wifi 設定画面を表示する... (SONY Smart Watch 3では開かないけど...)
276 startActivity(new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"));
279 catch (android.content.ActivityNotFoundException ex)
281 Log.v(TAG, "android.content.ActivityNotFoundException... " + "com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS");
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);
290 catch (android.content.ActivityNotFoundException ex2)
294 // Wifi 設定画面を表示する...普通のAndroidの場合
295 startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
300 ee.printStackTrace();
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);
309 catch (android.content.ActivityNotFoundException ex3)
311 ex3.printStackTrace();
322 e2.printStackTrace();
328 * Olympus Cameraクラスとのやりとりをするクラスを準備する
329 * (カメラとの接続も、ここでスレッドを起こして開始する)
331 private void setupCameraCoordinator()
333 if (liveView == null)
335 liveView = findViewById(R.id.liveview);
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);
349 private void connectToCamera()
351 Thread thread = new Thread(new Runnable()
356 coordinator.getConnectionInterface().connect();
370 * カメラの電源をOFFいして、アプリを抜ける処理
374 public void exitApplication()
376 Log.v(TAG, "exitApplication()");
379 // アンビエントモードの時(≒自分でアプリを終了しなかったとき)は、何もしない
381 Log.v(TAG, "keep liveview.");
385 // パワーマネージャを確認し、interactive modeではない場合は、ライブビューも止めず、カメラの電源も切らない
386 if ((powerManager != null)&&(!powerManager.isInteractive()))
388 Log.v(TAG, "not interactive, keep liveview.");
393 coordinator.stopLiveView();
395 // パラメータを確認し、カメラの電源を切る
396 if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(IPreferenceCameraPropertyAccessor.EXIT_APPLICATION_WITH_DISCONNECT, true))
398 Log.v(TAG, "Shutdown camera...");
401 coordinator.getConnectionInterface().disconnect(true);
404 //finishAndRemoveTask();
405 //android.os.Process.killProcess(android.os.Process.myPid());
412 public boolean checkConnectionFeature(int id)
418 ret = launchWifiSettingScreen();
426 * @param posX X座標位置 (0.0f - 1.0f)
427 * @param posY Y座標位置 (0.0f - 1.0f)
428 * @return true / false
431 public boolean touchedPosition(float posX, float posY)
433 Log.v(TAG, "touchedPosition (" + posX + ", " + posY);
434 return ((liveView != null)&&(liveView.touchedPosition(posX, posY)));
441 public boolean showConnectionStatus()
443 if ((listener.isEnabledOperation() == IShowInformation.operation.ONLY_CONNECT)&&(cameraDisconnectedHappened))
445 // カメラが切断されたとき、再接続を指示する
447 cameraDisconnectedHappened = false;
457 public void onStatusNotify(String message)
459 setMessage(IShowInformation.AREA_C, Color.WHITE, message);
466 public void onCameraConnected()
468 Log.v(TAG, "onCameraConnected()");
470 // ライブビューの開始 & タッチ/ボタンの操作を可能にする
471 coordinator.startLiveView();
472 coordinator.setRecViewMode(false);
473 listener.setEnableOperation(operation.ENABLE);
474 setMessage(IShowInformation.AREA_C, Color.WHITE, "");
475 coordinator.updateStatusAll();
479 * カメラとの接続が切れたとき...何もしない
483 public void onCameraDisconnected()
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;
495 public void onCameraOccursException(String message, Exception e)
497 Log.v(TAG, "onCameraOccursException()");
498 setMessage(IShowInformation.AREA_C, Color.YELLOW, message);
499 listener.setEnableOperation(operation.ONLY_CONNECT);
500 cameraDisconnectedHappened = true;
506 * @param area 表示エリア (AREA_1 ~ AREA_6, AREA_C)
508 * @param message 表示するメッセージ
511 public void setMessage(final int area, final int color, final String message)
516 case IShowInformation.AREA_1:
519 case IShowInformation.AREA_2:
522 case IShowInformation.AREA_3:
525 case IShowInformation.AREA_4:
528 case IShowInformation.AREA_NONE:
533 if (messageDrawer != null)
535 if (area == IShowInformation.AREA_C)
537 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTER, color, IMessageDrawer.SIZE_LARGE, message);
540 if (area == IShowInformation.AREA_5)
542 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPLEFT, color, IMessageDrawer.SIZE_STD, message);
545 if (area == IShowInformation.AREA_6)
547 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWLEFT, color, IMessageDrawer.SIZE_STD, message);
550 if (area == IShowInformation.AREA_7)
552 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPRIGHT, color, IMessageDrawer.SIZE_STD, message);
555 if (area == IShowInformation.AREA_8)
557 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWRIGHT, color, IMessageDrawer.SIZE_STD, message);
560 if (area == IShowInformation.AREA_9)
562 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPCENTER, color, IMessageDrawer.SIZE_STD, message);
565 if (area == IShowInformation.AREA_A)
567 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWCENTER, color, IMessageDrawer.SIZE_STD, message);
570 if (area == IShowInformation.AREA_B)
572 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTERLEFT, color, IMessageDrawer.SIZE_STD, message);
575 if (area == IShowInformation.AREA_D)
577 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTERRIGHT, color, IMessageDrawer.SIZE_STD, message);
588 final int areaId = id;
589 runOnUiThread(new Runnable()
593 final TextView textArea = findViewById(areaId);
594 textArea.setTextColor(color);
595 textArea.setText(message);
596 textArea.invalidate();
604 * @param button ボタンの場所
605 * @param labelId 変更する内容
608 public void setButtonDrawable(final int button, final int labelId)
613 case IShowInformation.BUTTON_1:
616 case IShowInformation.BUTTON_2:
619 case IShowInformation.BUTTON_3:
622 case IShowInformation.BUTTON_4:
625 case IShowInformation.BUTTON_5:
628 case IShowInformation.BUTTON_6:
634 final int areaId = id;
635 runOnUiThread(new Runnable()
639 final ImageButton button = findViewById(areaId);
640 button.setImageDrawable(getDrawable(labelId));
648 * @return true GPS搭載, false GPS非搭載
650 private boolean hasGps()
652 return (getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS));
660 public void vibrate(final int vibratePattern)
664 if ((vibrator == null)||(!vibrator.hasVibrator()))
669 Thread thread = new Thread(new Runnable() {
672 switch (vibratePattern)
674 case IShowInformation.VIBRATE_PATTERN_SIMPLE_LONGLONG:
675 vibrator.vibrate(300);
677 case IShowInformation.VIBRATE_PATTERN_SIMPLE_LONG:
678 vibrator.vibrate(150);
680 case IShowInformation.VIBRATE_PATTERN_SIMPLE_MIDDLE:
681 vibrator.vibrate(80);
683 case IShowInformation.VIBRATE_PATTERN_SIMPLE_SHORT:
684 vibrator.vibrate(30);
686 case IShowInformation.VIBRATE_PATTERN_SHORT_DOUBLE:
687 long[] pattern = { 10, 35, 30, 35, 0 };
688 vibrator.vibrate(pattern, -1);
690 case IShowInformation.VIBRATE_PATTERN_NONE:
706 public void setEnabledOperation(IShowInformation.operation operation)
708 if (listener != null)
710 listener.setEnableOperation(operation);
719 public void showFavoriteSettingsDialog()
721 if ((liveView != null)&&(listener != null)&&(listener.isEnabledOperation() != operation.ONLY_CONNECT))
723 listener.setEnableOperation(operation.ENABLE_ONLY_TOUCHED_POSITION);
724 liveView.showDialog(selectionDialog);
733 public void dialogDismissed(boolean isExecuted)
735 if ((liveView != null)&&(listener != null))
737 liveView.hideDialog();
738 listener.setEnableOperation(operation.ENABLE);