1 package jp.sfjp.gokigen.a01c;
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;
18 import androidx.appcompat.app.AppCompatActivity;
19 import androidx.core.app.ActivityCompat;
20 import androidx.core.content.ContextCompat;
22 import jp.sfjp.gokigen.a01c.liveview.CameraLiveImageView;
23 import jp.sfjp.gokigen.a01c.liveview.CameraLiveViewListenerImpl;
24 import jp.sfjp.gokigen.a01c.liveview.dialog.FavoriteSettingSelectionDialog;
25 import jp.sfjp.gokigen.a01c.liveview.dialog.IDialogDismissedNotifier;
26 import jp.sfjp.gokigen.a01c.olycamerawrapper.dispatcher.FeatureDispatcher;
27 import jp.sfjp.gokigen.a01c.liveview.ICameraStatusReceiver;
28 import jp.sfjp.gokigen.a01c.liveview.IMessageDrawer;
29 import jp.sfjp.gokigen.a01c.liveview.OlyCameraLiveViewOnTouchListener;
30 import jp.sfjp.gokigen.a01c.olycamerawrapper.IOlyCameraCoordinator;
31 import jp.sfjp.gokigen.a01c.olycamerawrapper.OlyCameraCoordinator;
32 import jp.sfjp.gokigen.a01c.preference.IPreferenceCameraPropertyAccessor;
38 public class MainActivity extends AppCompatActivity implements IChangeScene, IShowInformation, ICameraStatusReceiver, IDialogDismissedNotifier
40 private final String TAG = toString();
41 static final int REQUEST_NEED_PERMISSIONS = 1010;
42 //static final int COMMAND_MY_PROPERTY = 0x00000100;
44 private PowerManager powerManager = null;
45 private CameraLiveImageView liveView = null;
46 private IOlyCameraCoordinator coordinator = null;
47 private IMessageDrawer messageDrawer = null;
48 private OlyCameraLiveViewOnTouchListener listener = null;
49 private FavoriteSettingSelectionDialog selectionDialog = null;
50 private Vibrator vibrator = null;
51 private boolean cameraDisconnectedHappened = false;
52 //private boolean ambientMode = false;
58 protected void onCreate(Bundle savedInstanceState)
60 super.onCreate(savedInstanceState);
61 Log.v(TAG, "onCreate()");
63 // Ambientモードを許してみる...
64 //setAmbientEnabled();
67 setContentView(R.layout.activity_main);
70 if ((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)||
71 (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_WIFI_STATE) != PackageManager.PERMISSION_GRANTED)||
72 (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) != PackageManager.PERMISSION_GRANTED)||
73 (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED)||
74 (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_SETTINGS) != PackageManager.PERMISSION_GRANTED)||
75 (ContextCompat.checkSelfPermission(this, Manifest.permission.WAKE_LOCK) != PackageManager.PERMISSION_GRANTED)||
76 (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED)||
77 (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED))
79 ActivityCompat.requestPermissions(this,
81 Manifest.permission.ACCESS_NETWORK_STATE,
82 Manifest.permission.ACCESS_WIFI_STATE,
83 Manifest.permission.CHANGE_WIFI_STATE,
84 Manifest.permission.CHANGE_NETWORK_STATE,
85 Manifest.permission.WRITE_SETTINGS,
86 Manifest.permission.WAKE_LOCK,
87 Manifest.permission.INTERNET,
89 REQUEST_NEED_PERMISSIONS);
96 // GPS機能が搭載されていない場合...
97 Log.d(TAG, "This hardware doesn't have GPS.");
98 // Fall back to functionality that does not use location or
99 // warn the user that location function is not available.
103 vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
106 powerManager = (PowerManager) getSystemService(POWER_SERVICE);
108 setupCameraCoordinator();
109 setupInitialButtonIcons();
110 setupActionListener();
122 protected void onResume()
125 Log.v(TAG, "onResume()");
132 protected void onPause()
135 Log.v(TAG, "onPause()");
143 public void onStart()
146 Log.v(TAG, "onStart()");
157 Log.v(TAG, "onStop()");
163 public void onEnterAmbient(Bundle ambientDetails)
165 super.onEnterAmbient(ambientDetails);
166 Log.v(TAG, "onEnterAmbient()");
171 public void onExitAmbient()
173 super.onExitAmbient();
174 Log.v(TAG, "onExitAmbient()");
179 public void onUpdateAmbient()
181 super.onUpdateAmbient();
182 Log.v(TAG, "onUpdateAmbient()");
187 * ボタンが押された、画面がタッチされた、、は、リスナクラスで処理するよう紐づける
190 private void setupActionListener()
194 final ImageButton btn1 = findViewById(R.id.btn_1);
195 btn1.setOnClickListener(listener);
196 btn1.setOnLongClickListener(listener);
198 final ImageButton btn2 = findViewById(R.id.btn_2);
199 btn2.setOnClickListener(listener);
200 btn2.setOnLongClickListener(listener);
202 final ImageButton btn3 = findViewById(R.id.btn_3);
203 btn3.setOnClickListener(listener);
204 btn3.setOnLongClickListener(listener);
206 final ImageButton btn4 = findViewById(R.id.btn_4);
207 btn4.setOnClickListener(listener);
208 btn4.setOnLongClickListener(listener);
210 final ImageButton btn5 = findViewById(R.id.btn_5);
211 btn5.setOnClickListener(listener);
212 btn5.setOnLongClickListener(listener);
214 final ImageButton btn6 = findViewById(R.id.btn_6);
215 btn6.setOnClickListener(listener);
216 btn6.setOnLongClickListener(listener);
218 final TextView textArea1 = findViewById(R.id.text_1);
219 textArea1.setOnClickListener(listener);
220 textArea1.setOnLongClickListener(listener);
222 final TextView textArea2 = findViewById(R.id.text_2);
223 textArea2.setOnClickListener(listener);
224 textArea2.setOnLongClickListener(listener);
226 final TextView textArea3 = findViewById(R.id.text_3);
227 textArea3.setOnClickListener(listener);
228 textArea3.setOnLongClickListener(listener);
230 final TextView textArea4 = findViewById(R.id.text_4);
231 textArea4.setOnClickListener(listener);
232 textArea4.setOnLongClickListener(listener);
234 if (liveView == null)
236 liveView = findViewById(R.id.liveview);
238 liveView.setOnTouchListener(listener);
239 messageDrawer = liveView.getMessageDrawer();
240 messageDrawer.setLevelGauge(coordinator.getLevelGauge());
252 private void setupInitialButtonIcons()
256 if (coordinator != null)
259 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
260 if (preferences.getBoolean(IPreferenceCameraPropertyAccessor.SHOW_GRID_STATUS, true)) {
261 // ボタンをGrid OFFアイコンにする
262 resId = R.drawable.btn_ic_grid_off;
264 // ボタンをGrid ONアイコンにする
265 resId = R.drawable.btn_ic_grid_on;
267 setButtonDrawable(IShowInformation.BUTTON_1, resId);
277 * Intentを使ってWiFi設定画面を開く
280 private boolean launchWifiSettingScreen()
282 Log.v(TAG, "launchWifiSettingScreen()");
285 // Wifi 設定画面を表示する... (SONY Smart Watch 3では開かないけど...)
286 startActivity(new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS"));
293 Log.v(TAG, "launchWifiSettingScreen() : ACTION_WIFI_SETTINGS");
294 startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
299 Log.v(TAG, "android.content.ActivityNotFoundException... " + "com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS");
302 // SONY Smart Watch 3で開く場合のIntent...
303 Intent intent = new Intent("com.google.android.clockwork.settings.connectivity.wifi.ADD_NETWORK_SETTINGS");
304 intent.setClassName("com.google.android.apps.wearable.settings", "com.google.android.clockwork.settings.wifi.WifiSettingsActivity");
305 startActivity(intent);
308 catch (Exception ex2)
312 // Wifi 設定画面を表示する...普通のAndroidの場合
313 startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
318 ee.printStackTrace();
321 // LG G Watch Rで開く場合のIntent...
322 Intent intent = new Intent("android.intent.action.MAIN");
323 intent.setClassName("com.google.android.apps.wearable.settings", "com.google.android.clockwork.settings.MainSettingsActivity");
324 startActivity(intent);
327 catch (android.content.ActivityNotFoundException ex3)
329 ex3.printStackTrace();
339 * Olympus Cameraクラスとのやりとりをするクラスを準備する
340 * (カメラとの接続も、ここでスレッドを起こして開始する)
342 private void setupCameraCoordinator()
346 if (liveView == null) {
347 liveView = findViewById(R.id.liveview);
350 coordinator = new OlyCameraCoordinator(this, liveView, this, this);
351 coordinator.setLiveViewListener(new CameraLiveViewListenerImpl(liveView));
352 listener = new OlyCameraLiveViewOnTouchListener(this, new FeatureDispatcher(this, this, coordinator, liveView), this);
353 selectionDialog = new FavoriteSettingSelectionDialog(this, coordinator.getCameraPropertyLoadSaveOperations(), this);
366 private void connectToCamera()
368 Thread thread = new Thread(new Runnable()
373 coordinator.getConnectionInterface().connect();
387 * カメラの電源をOFFいして、アプリを抜ける処理
391 public void exitApplication()
395 Log.v(TAG, "exitApplication()");
399 // アンビエントモードの時(≒自分でアプリを終了しなかったとき)は、何もしない
401 Log.v(TAG, "keep liveview.");
406 // パワーマネージャを確認し、interactive modeではない場合は、ライブビューも止めず、カメラの電源も切らない
407 if ((powerManager != null) && (!powerManager.isInteractive()))
409 Log.v(TAG, "not interactive, keep liveview.");
414 coordinator.stopLiveView();
416 // パラメータを確認し、カメラの電源を切る
417 if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(IPreferenceCameraPropertyAccessor.EXIT_APPLICATION_WITH_DISCONNECT, true))
419 Log.v(TAG, "Shutdown camera...");
422 coordinator.getConnectionInterface().disconnect(true);
425 //finishAndRemoveTask();
426 //android.os.Process.killProcess(android.os.Process.myPid());
438 public boolean checkConnectionFeature(int id)
444 ret = launchWifiSettingScreen();
452 * @param posX X座標位置 (0.0f - 1.0f)
453 * @param posY Y座標位置 (0.0f - 1.0f)
454 * @return true / false
457 public boolean touchedPosition(float posX, float posY)
459 Log.v(TAG, "touchedPosition (" + posX + ", " + posY);
460 return ((liveView != null)&&(liveView.touchedPosition(posX, posY)));
467 public boolean showConnectionStatus()
471 if ((listener.isEnabledOperation() == IShowInformation.operation.ONLY_CONNECT) && (cameraDisconnectedHappened)) {
472 // カメラが切断されたとき、再接続を指示する
474 cameraDisconnectedHappened = false;
489 public void onStatusNotify(String message)
491 setMessage(IShowInformation.AREA_C, Color.WHITE, message);
498 public void onCameraConnected()
500 Log.v(TAG, "onCameraConnected()");
503 // ライブビューの開始 & タッチ/ボタンの操作を可能にする
504 coordinator.startLiveView();
505 coordinator.setRecViewMode(false);
506 listener.setEnableOperation(operation.ENABLE);
507 setMessage(IShowInformation.AREA_C, Color.WHITE, "");
508 coordinator.updateStatusAll();
517 * カメラとの接続が切れたとき...何もしない
521 public void onCameraDisconnected()
523 Log.v(TAG, "onCameraDisconnected()");
526 setMessage(IShowInformation.AREA_C, Color.YELLOW, getString(R.string.camera_disconnected));
527 listener.setEnableOperation(operation.ONLY_CONNECT);
528 cameraDisconnectedHappened = true;
540 public void onCameraOccursException(String message, Exception e)
542 Log.v(TAG, "onCameraOccursException()");
545 setMessage(IShowInformation.AREA_C, Color.YELLOW, message);
546 listener.setEnableOperation(operation.ONLY_CONNECT);
547 cameraDisconnectedHappened = true;
552 ee.printStackTrace();
559 * @param area 表示エリア (AREA_1 ~ AREA_6, AREA_C)
561 * @param message 表示するメッセージ
564 public void setMessage(final int area, final int color, final String message)
569 case IShowInformation.AREA_1:
572 case IShowInformation.AREA_2:
575 case IShowInformation.AREA_3:
578 case IShowInformation.AREA_4:
581 case IShowInformation.AREA_NONE:
586 if (messageDrawer != null)
588 if (area == IShowInformation.AREA_C)
590 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTER, color, IMessageDrawer.SIZE_LARGE, message);
593 if (area == IShowInformation.AREA_5)
595 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPLEFT, color, IMessageDrawer.SIZE_STD, message);
598 if (area == IShowInformation.AREA_6)
600 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWLEFT, color, IMessageDrawer.SIZE_STD, message);
603 if (area == IShowInformation.AREA_7)
605 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPRIGHT, color, IMessageDrawer.SIZE_STD, message);
608 if (area == IShowInformation.AREA_8)
610 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWRIGHT, color, IMessageDrawer.SIZE_STD, message);
613 if (area == IShowInformation.AREA_9)
615 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.UPCENTER, color, IMessageDrawer.SIZE_STD, message);
618 if (area == IShowInformation.AREA_A)
620 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.LOWCENTER, color, IMessageDrawer.SIZE_STD, message);
623 if (area == IShowInformation.AREA_B)
625 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTERLEFT, color, IMessageDrawer.SIZE_STD, message);
628 if (area == IShowInformation.AREA_D)
630 messageDrawer.setMessageToShow(IMessageDrawer.MessageArea.CENTERRIGHT, color, IMessageDrawer.SIZE_STD, message);
641 final int areaId = id;
642 runOnUiThread(new Runnable()
647 final TextView textArea = findViewById(areaId);
648 if (textArea != null)
650 textArea.setTextColor(color);
651 textArea.setText(message);
652 textArea.invalidate();
661 * @param button ボタンの場所
662 * @param labelId 変更する内容
665 public void setButtonDrawable(final int button, final int labelId)
670 case IShowInformation.BUTTON_1:
673 case IShowInformation.BUTTON_2:
676 case IShowInformation.BUTTON_3:
679 case IShowInformation.BUTTON_4:
682 case IShowInformation.BUTTON_5:
685 case IShowInformation.BUTTON_6:
691 final int areaId = id;
692 runOnUiThread(new Runnable()
699 final ImageButton button = findViewById(areaId);
700 final Drawable drawTarget = ContextCompat.getDrawable(getApplicationContext(), labelId);
703 button.setImageDrawable(drawTarget);
717 * @return true GPS搭載, false GPS非搭載
719 private boolean hasGps()
721 return (getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS));
729 public void vibrate(final int vibratePattern)
733 if ((vibrator == null)||(!vibrator.hasVibrator()))
738 Thread thread = new Thread(new Runnable() {
741 switch (vibratePattern)
743 case IShowInformation.VIBRATE_PATTERN_SIMPLE_LONGLONG:
744 vibrator.vibrate(300);
746 case IShowInformation.VIBRATE_PATTERN_SIMPLE_LONG:
747 vibrator.vibrate(150);
749 case IShowInformation.VIBRATE_PATTERN_SIMPLE_MIDDLE:
750 vibrator.vibrate(80);
752 case IShowInformation.VIBRATE_PATTERN_SIMPLE_SHORT:
753 vibrator.vibrate(30);
755 case IShowInformation.VIBRATE_PATTERN_SHORT_DOUBLE:
756 long[] pattern = { 10, 35, 30, 35, 0 };
757 vibrator.vibrate(pattern, -1);
759 case IShowInformation.VIBRATE_PATTERN_NONE:
775 public void setEnabledOperation(IShowInformation.operation operation)
777 if (listener != null)
779 listener.setEnableOperation(operation);
788 public void showFavoriteSettingsDialog()
790 if ((liveView != null)&&(listener != null)&&(listener.isEnabledOperation() != operation.ONLY_CONNECT))
792 listener.setEnableOperation(operation.ENABLE_ONLY_TOUCHED_POSITION);
793 liveView.showDialog(selectionDialog);
802 public void dialogDismissed(boolean isExecuted)
806 if ((liveView != null) && (listener != null))
808 liveView.hideDialog();
809 listener.setEnableOperation(operation.ENABLE);