• R/O
  • HTTP
  • SSH
  • HTTPS

A01c: Commit

OPC(Olympus Air)用撮影アプリ。


Commit MetaInfo

Révisione978c5e05b4f996aa251f85170c998f94f2ca864 (tree)
l'heure2021-01-10 23:28:44
AuteurMRSa <mrsa@myad...>
CommiterMRSa

Message de Log

Thetaのプレビューまで。

Change Summary

Modification

--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/ICameraConnection.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/ICameraConnection.java
@@ -7,10 +7,17 @@ import androidx.annotation.NonNull;
77 /**
88 * カメラの接続/切断
99 *
10- * Created by MRSa on 2017/02/28.
1110 */
1211 public interface ICameraConnection
1312 {
13+ enum CameraConnectionStatus
14+ {
15+ UNKNOWN,
16+ DISCONNECTED,
17+ CONNECTING,
18+ CONNECTED
19+ };
20+
1421 // WIFI 接続系
1522 void startWatchWifiStatus(@NonNull Context context);
1623 void stopWatchWifiStatus(@NonNull Context context);
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/MainActivity.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/MainActivity.java
@@ -15,6 +15,7 @@ import android.widget.TextView;
1515 import android.Manifest;
1616 import android.content.pm.PackageManager;
1717
18+import androidx.annotation.NonNull;
1819 import androidx.appcompat.app.AppCompatActivity;
1920 import androidx.core.app.ActivityCompat;
2021 import androidx.core.content.ContextCompat;
@@ -355,8 +356,8 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS
355356 liveView = findViewById(R.id.liveview);
356357 }
357358 olyAirCoordinator = new OlyCameraCoordinator(this, liveView, this, this);
358- thetaCoordinator = new ThetaCameraController(this, liveView, this, this);
359- currentCoordinator = olyAirCoordinator; // (connectionMethod.contains(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA)) ? thetaCoordinator : olyAirCoordinator;
359+ thetaCoordinator = new ThetaCameraController(this, liveView, this, this, preferences);
360+ currentCoordinator = (connectionMethod.contains(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA)) ? thetaCoordinator : olyAirCoordinator;
360361 currentCoordinator.setLiveViewListener(new CameraLiveViewListenerImpl(liveView));
361362 listener = new CameraLiveViewOnTouchListener(this, new FeatureDispatcher(this, this, currentCoordinator, preferences, liveView), this);
362363 selectionDialog = new FavoriteSettingSelectionDialog(this, currentCoordinator.getCameraPropertyLoadSaveOperations(), this);
@@ -548,10 +549,29 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS
548549 }
549550
550551 /**
552+ * カメラと接続失敗
553+ */
554+ @Override
555+ public void onCameraConnectError(@NonNull String message)
556+ {
557+ Log.v(TAG, "onCameraOccursException()");
558+ try
559+ {
560+ setMessage(IShowInformation.AREA_C, Color.YELLOW, message);
561+ listener.setEnableOperation(operation.ONLY_CONNECT);
562+ cameraDisconnectedHappened = true;
563+ }
564+ catch (Exception ee)
565+ {
566+ ee.printStackTrace();
567+ }
568+ }
569+
570+ /**
551571 * カメラに例外発生
552572 */
553573 @Override
554- public void onCameraOccursException(String message, Exception e)
574+ public void onCameraOccursException(@NonNull String message, Exception e)
555575 {
556576 Log.v(TAG, "onCameraOccursException()");
557577 try
@@ -899,7 +919,7 @@ public class MainActivity extends AppCompatActivity implements IChangeScene, IS
899919 else
900920 {
901921 // 接続方式を Theta に切り替える
902- updateConnectionMethod(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA, olyAirCoordinator); // thetaCoordinator
922+ updateConnectionMethod(IPreferenceCameraPropertyAccessor.CONNECTION_METHOD_THETA, thetaCoordinator);
903923 }
904924 updateConnectionMethodMessage();
905925 }
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/liveview/CameraLiveImageView.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/liveview/CameraLiveImageView.java
@@ -233,49 +233,54 @@ public class CameraLiveImageView extends View implements IImageDataReceiver, IAu
233233 public void setImageData(byte[] data, Map<String, Object> metadata)
234234 {
235235 Bitmap bitmap;
236- int rotationDegrees;
236+ int rotationDegrees = 0;
237237
238- if (data != null && metadata != null)
238+ if (data != null)
239239 {
240- // Create a bitmap.
241240 try
242241 {
243242 bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
244243 }
245- catch (OutOfMemoryError e)
244+ catch (Throwable e)
246245 {
247246 e.printStackTrace();
248247 return;
249248 }
250249
251- // Acquire a rotation degree of image.
252- int orientation = ExifInterface.ORIENTATION_UNDEFINED;
253- try
250+ if (metadata != null)
254251 {
255- if (metadata.containsKey(EXIF_ORIENTATION))
252+ int orientation = ExifInterface.ORIENTATION_UNDEFINED;
253+ try
256254 {
257- orientation = Integer.parseInt((String) metadata.get(EXIF_ORIENTATION));
255+ if (metadata.containsKey(EXIF_ORIENTATION))
256+ {
257+ String degree = (String) metadata.get(EXIF_ORIENTATION);
258+ if (degree != null)
259+ {
260+ orientation = Integer.parseInt(degree);
261+ }
262+ }
263+ }
264+ catch (Exception e)
265+ {
266+ e.printStackTrace();
267+ }
268+ switch (orientation)
269+ {
270+ case ExifInterface.ORIENTATION_ROTATE_90:
271+ rotationDegrees = 90;
272+ break;
273+ case ExifInterface.ORIENTATION_ROTATE_180:
274+ rotationDegrees = 180;
275+ break;
276+ case ExifInterface.ORIENTATION_ROTATE_270:
277+ rotationDegrees = 270;
278+ break;
279+ case ExifInterface.ORIENTATION_NORMAL:
280+ default:
281+ rotationDegrees = 0;
282+ break;
258283 }
259- }
260- catch (Exception e)
261- {
262- e.printStackTrace();
263- }
264- switch (orientation)
265- {
266- case ExifInterface.ORIENTATION_ROTATE_90:
267- rotationDegrees = 90;
268- break;
269- case ExifInterface.ORIENTATION_ROTATE_180:
270- rotationDegrees = 180;
271- break;
272- case ExifInterface.ORIENTATION_ROTATE_270:
273- rotationDegrees = 270;
274- break;
275- case ExifInterface.ORIENTATION_NORMAL:
276- default:
277- rotationDegrees = 0;
278- break;
279284 }
280285 imageBitmap = bitmap;
281286 imageRotationDegrees = rotationDegrees;
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/liveview/CameraLiveViewListenerImpl.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/liveview/CameraLiveViewListenerImpl.java
@@ -16,6 +16,7 @@ import jp.co.olympus.camerakit.OLYCameraLiveViewListener;
1616 */
1717 public class CameraLiveViewListenerImpl implements OLYCameraLiveViewListener, IImageDataReceiver
1818 {
19+ private final String TAG = toString();
1920 private final IImageDataReceiver imageView;
2021
2122 /**
@@ -43,9 +44,10 @@ public class CameraLiveViewListenerImpl implements OLYCameraLiveViewListener, II
4344 @Override
4445 public void setImageData(byte[] data, Map<String, Object> metadata)
4546 {
47+ // Log.v(TAG, " setImageData len : " + data.length);
4648 if (imageView != null)
4749 {
48- imageView.setImageData(data, metadata);
50+ imageView.setImageData(data, null);
4951 }
5052 }
5153 }
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/liveview/ICameraStatusReceiver.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/liveview/ICameraStatusReceiver.java
@@ -1,5 +1,7 @@
11 package jp.sfjp.gokigen.a01c.liveview;
22
3+import androidx.annotation.NonNull;
4+
35 /**
46 *
57 *
@@ -9,5 +11,6 @@ public interface ICameraStatusReceiver
911 void onStatusNotify(String message);
1012 void onCameraConnected();
1113 void onCameraDisconnected();
12- void onCameraOccursException(String message, Exception e);
14+ void onCameraConnectError(@NonNull String message);
15+ void onCameraOccursException(@NonNull String message, Exception e);
1316 }
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/IIndicatorControl.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/IIndicatorControl.java
@@ -3,5 +3,15 @@ package jp.sfjp.gokigen.a01c.olycamerawrapper;
33
44 public interface IIndicatorControl
55 {
6+ // 撮影状態の記録
7+ enum shootingStatus
8+ {
9+ Unknown,
10+ Starting,
11+ Stopping,
12+ }
13+
614 void onAfLockUpdate(boolean isAfLocked);
15+ void onShootingStatusUpdate(shootingStatus status);
16+
717 }
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/OlyCameraCoordinator.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/olycamerawrapper/OlyCameraCoordinator.java
@@ -498,6 +498,12 @@ public class OlyCameraCoordinator implements ICameraController, IIndicatorContro
498498 }
499499
500500 @Override
501+ public void onShootingStatusUpdate(shootingStatus status)
502+ {
503+ Log.v(TAG, " ShootingStatus : " + status);
504+ }
505+
506+ @Override
501507 public OLYCamera getOLYCamera()
502508 {
503509 return (camera);
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/IThetaSessionIdNotifier.java
@@ -0,0 +1,6 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper;
2+
3+public interface IThetaSessionIdNotifier
4+{
5+ void receivedSessionId(String sessionId);
6+}
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/IThetaSessionIdProvider.java
@@ -0,0 +1,8 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper;
2+
3+import androidx.annotation.NonNull;
4+
5+public interface IThetaSessionIdProvider
6+{
7+ @NonNull String getSessionId();
8+}
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/ThetaCameraController.kt
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/ThetaCameraController.kt
@@ -10,19 +10,30 @@ import jp.sfjp.gokigen.a01c.liveview.CameraLiveViewListenerImpl
1010 import jp.sfjp.gokigen.a01c.liveview.IAutoFocusFrameDisplay
1111 import jp.sfjp.gokigen.a01c.liveview.ICameraStatusReceiver
1212 import jp.sfjp.gokigen.a01c.olycamerawrapper.ICameraRunMode
13+import jp.sfjp.gokigen.a01c.olycamerawrapper.IIndicatorControl
1314 import jp.sfjp.gokigen.a01c.olycamerawrapper.ILevelGauge
1415 import jp.sfjp.gokigen.a01c.olycamerawrapper.IZoomLensHolder
1516 import jp.sfjp.gokigen.a01c.olycamerawrapper.property.ICameraPropertyLoadSaveOperations
1617 import jp.sfjp.gokigen.a01c.olycamerawrapper.property.ILoadSaveCameraProperties
1718 import jp.sfjp.gokigen.a01c.olycamerawrapper.property.IOlyCameraPropertyProvider
19+import jp.sfjp.gokigen.a01c.preference.PreferenceAccessWrapper
20+import jp.sfjp.gokigen.a01c.thetacamerawrapper.connection.ThetaCameraConnection
21+import jp.sfjp.gokigen.a01c.thetacamerawrapper.liveview.ThetaLiveViewControl
22+import jp.sfjp.gokigen.a01c.thetacamerawrapper.operation.ThetaDummyOperation
23+import jp.sfjp.gokigen.a01c.thetacamerawrapper.operation.ThetaSingleShotControl
1824
19-class ThetaCameraController(val context : AppCompatActivity, val focusFrameDisplay : IAutoFocusFrameDisplay, val showInformation : IShowInformation, val receiver : ICameraStatusReceiver) : ICameraController
25+class ThetaCameraController(val context: AppCompatActivity, private val focusFrameDisplay: IAutoFocusFrameDisplay, private val showInformation: IShowInformation, private val receiver: ICameraStatusReceiver, private val preferences: PreferenceAccessWrapper) : ICameraController, IIndicatorControl
2026 {
21- private lateinit var listener : CameraLiveViewListenerImpl
27+ //private lateinit var listener : CameraLiveViewListenerImpl
28+ private lateinit var liveViewControl : ThetaLiveViewControl
29+ private val dummyOperation = ThetaDummyOperation()
30+ private val sessionIdHolder = ThetaSessionHolder()
31+ private val cameraConnection = ThetaCameraConnection(context, receiver, sessionIdHolder)
32+ private val singleShot = ThetaSingleShotControl(sessionIdHolder, this, this)
2233
2334 override fun setLiveViewListener(listener: CameraLiveViewListenerImpl)
2435 {
25- this.listener = listener
36+ this.liveViewControl = ThetaLiveViewControl(sessionIdHolder, listener)
2637 }
2738
2839 override fun changeLiveViewSize(size: String?)
@@ -31,97 +42,134 @@ class ThetaCameraController(val context : AppCompatActivity, val focusFrameDispl
3142 Log.v(toString(), " changeLiveViewSize: $size")
3243 }
3344
34- override fun startLiveView() {
35- TODO("Not yet implemented")
45+ override fun startLiveView()
46+ {
47+ if (::liveViewControl.isInitialized)
48+ {
49+ liveViewControl.startLiveView()
50+ }
3651 }
3752
38- override fun stopLiveView() {
39- TODO("Not yet implemented")
53+ override fun stopLiveView()
54+ {
55+ if (::liveViewControl.isInitialized)
56+ {
57+ liveViewControl.stopLiveView()
58+ }
4059 }
4160
42- override fun updateTakeMode() {
43- TODO("Not yet implemented")
61+ override fun updateTakeMode()
62+ {
63+ // なにもしない
4464 }
4565
46- override fun driveAutoFocus(event: MotionEvent?): Boolean {
47- TODO("Not yet implemented")
66+ override fun driveAutoFocus(event: MotionEvent?): Boolean
67+ {
68+ return (true)
4869 }
4970
50- override fun unlockAutoFocus() {
51- TODO("Not yet implemented")
71+ override fun unlockAutoFocus()
72+ {
73+ // なにもしない
5274 }
5375
54- override fun isContainsAutoFocusPoint(event: MotionEvent?): Boolean {
55- TODO("Not yet implemented")
76+ override fun isContainsAutoFocusPoint(event: MotionEvent?): Boolean
77+ {
78+ return (false)
5679 }
5780
58- override fun singleShot() {
59- TODO("Not yet implemented")
81+ override fun singleShot()
82+ {
83+ singleShot.singleShot(sessionIdHolder.isApiLevelV21())
6084 }
6185
62- override fun movieControl() {
63- TODO("Not yet implemented")
86+ override fun movieControl()
87+ {
88+ // TODO("Not yet implemented")
6489 }
6590
66- override fun bracketingShot(bracketingStyle: Int, bracketingCount: Int, durationSeconds: Int) {
67- TODO("Not yet implemented")
91+ override fun bracketingShot(bracketingStyle: Int, bracketingCount: Int, durationSeconds: Int)
92+ {
93+ // TODO("Not yet implemented")
6894 }
6995
70- override fun setRecViewMode(isRecViewMode: Boolean) {
71- TODO("Not yet implemented")
96+ override fun setRecViewMode(isRecViewMode: Boolean)
97+ {
98+ // なにもしない
7299 }
73100
74- override fun toggleAutoExposure() {
75- TODO("Not yet implemented")
101+ override fun toggleAutoExposure()
102+ {
103+ // なにもしない
76104 }
77105
78- override fun toggleManualFocus() {
79- TODO("Not yet implemented")
106+ override fun toggleManualFocus()
107+ {
108+ // なにもしない
80109 }
81110
82- override fun isManualFocus(): Boolean {
83- TODO("Not yet implemented")
111+ override fun isManualFocus(): Boolean
112+ {
113+ return (false)
84114 }
85115
86- override fun isAFLock(): Boolean {
87- TODO("Not yet implemented")
116+ override fun isAFLock(): Boolean
117+ {
118+ return (false)
88119 }
89120
90- override fun isAELock(): Boolean {
91- TODO("Not yet implemented")
121+ override fun isAELock(): Boolean
122+ {
123+ return (false)
92124 }
93125
94- override fun updateStatusAll() {
95- TODO("Not yet implemented")
126+ override fun updateStatusAll()
127+ {
128+ // なにもしない
96129 }
97130
98- override fun getCameraPropertyProvider(): IOlyCameraPropertyProvider {
99- TODO("Not yet implemented")
131+ override fun getCameraPropertyProvider(): IOlyCameraPropertyProvider
132+ {
133+ return (dummyOperation)
100134 }
101135
102- override fun getCameraPropertyLoadSaveOperations(): ICameraPropertyLoadSaveOperations {
103- TODO("Not yet implemented")
136+ override fun getCameraPropertyLoadSaveOperations(): ICameraPropertyLoadSaveOperations
137+ {
138+ return (dummyOperation)
104139 }
105140
106- override fun getLoadSaveCameraProperties(): ILoadSaveCameraProperties {
107- TODO("Not yet implemented")
141+ override fun getLoadSaveCameraProperties(): ILoadSaveCameraProperties
142+ {
143+ return (dummyOperation)
108144 }
109145
110- override fun getChangeRunModeExecutor(): ICameraRunMode {
111- TODO("Not yet implemented")
146+ override fun getChangeRunModeExecutor(): ICameraRunMode
147+ {
148+ return (dummyOperation)
112149 }
113150
114- override fun getConnectionInterface(): ICameraConnection {
115- TODO("Not yet implemented")
151+ override fun getConnectionInterface(): ICameraConnection
152+ {
153+ return (cameraConnection)
116154 }
117155
118- override fun getZoomLensHolder(): IZoomLensHolder {
119- TODO("Not yet implemented")
156+ override fun getZoomLensHolder(): IZoomLensHolder
157+ {
158+ return (dummyOperation)
120159 }
121160
122- override fun getLevelGauge(): ILevelGauge {
123- TODO("Not yet implemented")
161+ override fun getLevelGauge(): ILevelGauge
162+ {
163+ return (dummyOperation)
124164 }
125165
166+ override fun onAfLockUpdate(isAfLocked: Boolean)
167+ {
168+ //TODO("Not yet implemented")
169+ }
126170
127-}
\ No newline at end of file
171+ override fun onShootingStatusUpdate(status: IIndicatorControl.shootingStatus?)
172+ {
173+ //TODO("Not yet implemented")
174+ }
175+}
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/ThetaSessionHolder.kt
@@ -0,0 +1,24 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper
2+
3+class ThetaSessionHolder : IThetaSessionIdProvider, IThetaSessionIdNotifier
4+{
5+ private var sessionId : String = ""
6+
7+ override fun getSessionId(): String
8+ {
9+ return (sessionId)
10+ }
11+
12+ override fun receivedSessionId(sessionId: String?)
13+ {
14+ if (sessionId != null)
15+ {
16+ this.sessionId = sessionId
17+ }
18+ }
19+
20+ fun isApiLevelV21() : Boolean
21+ {
22+ return (!(sessionId.isNotEmpty()))
23+ }
24+}
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/connection/ThetaCameraConnectSequence.kt
@@ -0,0 +1,189 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper.connection
2+
3+import android.util.Log
4+import androidx.appcompat.app.AppCompatActivity
5+import jp.sfjp.gokigen.a01c.R
6+import jp.sfjp.gokigen.a01c.liveview.ICameraStatusReceiver
7+import jp.sfjp.gokigen.a01c.thetacamerawrapper.IThetaSessionIdNotifier
8+import jp.sfjp.gokigen.a01c.utils.SimpleHttpClient
9+import org.json.JSONObject
10+
11+class ThetaCameraConnectSequence(private val context: AppCompatActivity, private val cameraStatusReceiver: ICameraStatusReceiver, private val sessionIdNotifier: IThetaSessionIdNotifier) : Runnable
12+{
13+ private var useThetaV21 : Boolean = false
14+ private val httpClient = SimpleHttpClient()
15+
16+ override fun run()
17+ {
18+ // 使用する API Levelを決める
19+ useThetaV21 = decideApiLevel()
20+ try
21+ {
22+ Log.v(TAG,"Theta API v2.1 : $useThetaV21")
23+ if (useThetaV21)
24+ {
25+ // API Level V2.1を使用して通信する
26+ connectApiV21()
27+ }
28+ else
29+ {
30+ // API Level V2 を使用して通信する
31+ connectApiV2()
32+ }
33+ }
34+ catch (e : Exception)
35+ {
36+ e.printStackTrace()
37+ }
38+ }
39+
40+ /**
41+ *
42+ */
43+ private fun decideApiLevel() : Boolean
44+ {
45+ var apiLevelIsV21 = false
46+ try
47+ {
48+ val oscInfoUrl = "http://192.168.1.1/osc/info"
49+ val timeoutMs = 5000
50+ val response: String = httpClient.httpGet(oscInfoUrl, timeoutMs)
51+ Log.v(TAG, " $oscInfoUrl $response")
52+ if (response.isNotEmpty())
53+ {
54+ val apiLevelArray = JSONObject(response).getJSONArray("apiLevel")
55+ val size = apiLevelArray.length()
56+ for (index in 0 until size)
57+ {
58+ val api = apiLevelArray.getInt(index)
59+ if (api == 2) //if (api == 2 && useThetaV21)
60+ {
61+ apiLevelIsV21 = true
62+ }
63+ }
64+ }
65+ }
66+ catch (e: Exception)
67+ {
68+ e.printStackTrace()
69+ }
70+ return (apiLevelIsV21)
71+ }
72+
73+ /**
74+ *
75+ */
76+ private fun connectApiV2()
77+ {
78+ val commandsExecuteUrl = "http://192.168.1.1/osc/commands/execute"
79+ val startSessionData = "{\"name\":\"camera.startSession\",\"parameters\":{\"timeout\":0}}"
80+ val getStateUrl = "http://192.168.1.1/osc/state"
81+ val timeoutMs = 5000
82+ try
83+ {
84+ val response: String? = httpClient.httpPostWithHeader(commandsExecuteUrl, startSessionData, null, "application/json;charset=utf-8", timeoutMs)
85+ Log.v(TAG, " $commandsExecuteUrl $startSessionData $response")
86+
87+ val response2: String? = httpClient.httpPostWithHeader(getStateUrl, "", null, "application/json;charset=utf-8", timeoutMs)
88+ Log.v(TAG, " $getStateUrl $response2")
89+ if ((response2 != null)&&(response2.isNotEmpty()))
90+ {
91+ try
92+ {
93+ val jsonObject = JSONObject(response2)
94+ val sessionId = jsonObject.getJSONObject("state").getString("sessionId")
95+ sessionIdNotifier.receivedSessionId(sessionId)
96+ onConnectNotify()
97+ return
98+ }
99+ catch (e: Exception)
100+ {
101+ e.printStackTrace()
102+ }
103+ }
104+ // 応答なし、を応答する。
105+ onConnectError(context.getString(R.string.theta_connect_response_ng))
106+ }
107+ catch (e: Exception)
108+ {
109+ e.printStackTrace()
110+ onConnectError(e.localizedMessage)
111+ }
112+ }
113+
114+ private fun connectApiV21() {
115+ val commandsExecuteUrl = "http://192.168.1.1/osc/commands/execute"
116+ val startSessionData = "{\"name\":\"camera.startSession\",\"parameters\":{\"timeout\":0}}"
117+ val getStateUrl = "http://192.168.1.1/osc/state"
118+ val timeoutMs = 5000
119+ try {
120+ val responseS: String? = httpClient.httpPostWithHeader(commandsExecuteUrl, startSessionData, null, "application/json;charset=utf-8", timeoutMs)
121+ Log.v(TAG, " [ $httpClient ] $startSessionData ::: $responseS")
122+ val response: String? = httpClient.httpPostWithHeader(getStateUrl, "", null, null, timeoutMs)
123+ Log.v(TAG, " ($getStateUrl) $response")
124+ if ((response != null)&&(response.isNotEmpty()))
125+ {
126+ var apiLevel = 1
127+ var sessionId: String? = null
128+ val `object` = JSONObject(response)
129+ try {
130+ apiLevel = `object`.getJSONObject("state").getInt("_apiVersion")
131+ } catch (e: Exception) {
132+ e.printStackTrace()
133+ }
134+ try {
135+ sessionId = `object`.getJSONObject("state").getString("sessionId")
136+ sessionIdNotifier.receivedSessionId(sessionId)
137+ } catch (e: Exception) {
138+ e.printStackTrace()
139+ }
140+ if (apiLevel != 2) {
141+ val setApiLevelData = "{\"name\":\"camera.setOptions\",\"parameters\":{\"sessionId\" : \"$sessionId\", \"options\":{ \"clientVersion\":2}}}"
142+ val response3: String? = httpClient.httpPostWithHeader(commandsExecuteUrl, setApiLevelData, null, "application/json;charset=utf-8", timeoutMs)
143+ Log.v(TAG, " $commandsExecuteUrl $setApiLevelData $response3")
144+ }
145+ onConnectNotify()
146+ } else {
147+ onConnectError(context.getString(R.string.camera_not_found))
148+ }
149+ } catch (e: Exception)
150+ {
151+ e.printStackTrace()
152+ onConnectError(e.localizedMessage)
153+ }
154+ }
155+
156+ private fun onConnectNotify()
157+ {
158+ try
159+ {
160+ val thread = Thread { // カメラとの接続確立を通知する
161+ cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_connected))
162+ cameraStatusReceiver.onCameraConnected()
163+ Log.v(TAG, "onConnectNotify()")
164+ }
165+ thread.start()
166+ }
167+ catch (e: Exception)
168+ {
169+ e.printStackTrace()
170+ }
171+ }
172+
173+ private fun onConnectError(reason: String?)
174+ {
175+ if (reason != null)
176+ {
177+ cameraStatusReceiver.onCameraConnectError(reason)
178+ }
179+ else
180+ {
181+ cameraStatusReceiver.onCameraConnectError("")
182+ }
183+ }
184+
185+ companion object
186+ {
187+ private val TAG = ThetaCameraConnectSequence::class.java.simpleName
188+ }
189+}
\ No newline at end of file
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/connection/ThetaCameraConnection.kt
@@ -0,0 +1,166 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper.connection
2+
3+import android.content.*
4+import android.net.ConnectivityManager
5+import android.net.wifi.WifiManager
6+import android.util.Log
7+import androidx.appcompat.app.AppCompatActivity
8+import jp.sfjp.gokigen.a01c.ICameraConnection
9+import jp.sfjp.gokigen.a01c.R
10+import jp.sfjp.gokigen.a01c.liveview.ICameraStatusReceiver
11+import jp.sfjp.gokigen.a01c.thetacamerawrapper.IThetaSessionIdNotifier
12+import java.util.concurrent.Executor
13+import java.util.concurrent.Executors
14+
15+/**
16+ *
17+ */
18+class ThetaCameraConnection(private val context: AppCompatActivity, private val statusReceiver: ICameraStatusReceiver, private val sessionIdNotifier: IThetaSessionIdNotifier) : ICameraConnection
19+{
20+ private val cameraExecutor: Executor = Executors.newFixedThreadPool(1)
21+ private var connectionStatus: ICameraConnection.CameraConnectionStatus = ICameraConnection.CameraConnectionStatus.UNKNOWN
22+ private var isNetworkStatusWatching : Boolean = false
23+ private var connectionReceiver = object : BroadcastReceiver()
24+ {
25+ override fun onReceive(context: Context, intent: Intent)
26+ {
27+ onReceiveBroadcastOfConnection(context, intent)
28+ }
29+ }
30+
31+ /**
32+ *
33+ */
34+ private fun onReceiveBroadcastOfConnection(context: Context, intent: Intent)
35+ {
36+ statusReceiver.onStatusNotify(context.getString(R.string.connect_check_wifi))
37+ Log.v(TAG, context.getString(R.string.connect_check_wifi))
38+ val action = intent.action
39+ if (action == null)
40+ {
41+ Log.v(TAG, "intent.getAction() : null")
42+ return
43+ }
44+ try
45+ {
46+ if (action == ConnectivityManager.CONNECTIVITY_ACTION)
47+ {
48+ Log.v(TAG, "onReceiveBroadcastOfConnection() : CONNECTIVITY_ACTION")
49+ val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
50+ val info = wifiManager.connectionInfo
51+ if ((wifiManager.isWifiEnabled)&&(info != null))
52+ {
53+ connectToCamera()
54+ }
55+ else
56+ {
57+ if (info == null)
58+ {
59+ Log.v(TAG, "NETWORK INFO IS NULL.")
60+ }
61+ else
62+ {
63+ Log.v(TAG, "isWifiEnabled : " + wifiManager.isWifiEnabled + " NetworkId : " + info.networkId)
64+ }
65+ }
66+ }
67+ }
68+ catch (e: Exception)
69+ {
70+ Log.w(TAG, "onReceiveBroadcastOfConnection() EXCEPTION" + e.message)
71+ e.printStackTrace()
72+ }
73+ }
74+
75+ /**
76+ *
77+ */
78+ override fun startWatchWifiStatus(context: Context)
79+ {
80+ Log.v(TAG, "startWatchWifiStatus()")
81+ statusReceiver.onStatusNotify("prepare")
82+ isNetworkStatusWatching = true
83+ val filter = IntentFilter()
84+ filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
85+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
86+ context.registerReceiver(connectionReceiver, filter)
87+ }
88+
89+ /**
90+ *
91+ */
92+ override fun stopWatchWifiStatus(context: Context)
93+ {
94+ Log.v(TAG, "stopWatchWifiStatus()")
95+ isNetworkStatusWatching = false
96+ context.unregisterReceiver(connectionReceiver)
97+ disconnect(false)
98+ }
99+
100+ /**
101+ *
102+ */
103+ override fun isWatchWifiStatus(): Boolean
104+ {
105+ return (isNetworkStatusWatching)
106+ }
107+
108+ /**
109+ *
110+ */
111+ override fun disconnect(powerOff: Boolean)
112+ {
113+ Log.v(TAG, "disconnect()")
114+ disconnectFromCamera(powerOff)
115+ connectionStatus = ICameraConnection.CameraConnectionStatus.DISCONNECTED
116+ statusReceiver.onCameraDisconnected()
117+ }
118+
119+ /**
120+ *
121+ */
122+ override fun connect()
123+ {
124+ Log.v(TAG, "connect()")
125+ connectToCamera()
126+ }
127+
128+ /**
129+ * カメラとの切断処理
130+ */
131+ private fun disconnectFromCamera(powerOff: Boolean)
132+ {
133+ Log.v(TAG, "disconnectFromCamera() : $powerOff")
134+ try
135+ {
136+ cameraExecutor.execute(ThetaCameraDisconnectSequence())
137+ }
138+ catch (e: Exception)
139+ {
140+ e.printStackTrace()
141+ }
142+ }
143+
144+ /**
145+ * カメラとの接続処理
146+ */
147+ private fun connectToCamera()
148+ {
149+ Log.v(TAG, "connectToCamera()")
150+ connectionStatus = ICameraConnection.CameraConnectionStatus.CONNECTING
151+ try
152+ {
153+ cameraExecutor.execute(ThetaCameraConnectSequence(context, statusReceiver, sessionIdNotifier))
154+ }
155+ catch (e: Exception)
156+ {
157+ Log.v(TAG, "connectToCamera() EXCEPTION : " + e.message)
158+ e.printStackTrace()
159+ }
160+ }
161+
162+ companion object
163+ {
164+ private val TAG = ThetaCameraConnection::class.java.simpleName
165+ }
166+}
\ No newline at end of file
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/connection/ThetaCameraDisconnectSequence.kt
@@ -0,0 +1,12 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper.connection
2+
3+import android.util.Log
4+
5+class ThetaCameraDisconnectSequence : Runnable
6+{
7+ override fun run()
8+ {
9+ // カメラをPowerOffして接続を切る
10+ Log.v(ThetaCameraDisconnectSequence::class.java.simpleName, " Disconnect from THETA.")
11+ }
12+}
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/liveview/ThetaLiveViewControl.kt
@@ -0,0 +1,110 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper.liveview
2+
3+import android.util.Log
4+import jp.sfjp.gokigen.a01c.liveview.CameraLiveViewListenerImpl
5+import jp.sfjp.gokigen.a01c.thetacamerawrapper.IThetaSessionIdProvider
6+import jp.sfjp.gokigen.a01c.utils.SimpleLiveviewSlicer
7+
8+class ThetaLiveViewControl(private val sessionIdProvider: IThetaSessionIdProvider, private val liveViewListener: CameraLiveViewListenerImpl)
9+{
10+ private var whileFetching = false
11+
12+ fun startLiveView()
13+ {
14+ Log.v(TAG, " startLiveView()")
15+ try
16+ {
17+ val thread = Thread {
18+ try
19+ {
20+
21+ start(!(sessionIdProvider.sessionId.isEmpty()))
22+ }
23+ catch (e: Exception)
24+ {
25+ e.printStackTrace()
26+ }
27+ }
28+ thread.start()
29+ }
30+ catch (e: Exception)
31+ {
32+ e.printStackTrace()
33+ }
34+ }
35+
36+ fun stopLiveView()
37+ {
38+ Log.v(TAG, " stopLiveView()")
39+ whileFetching = false
40+ }
41+
42+ private fun start(useOscV2 : Boolean)
43+ {
44+ if (whileFetching)
45+ {
46+ Log.v(TAG, "start() already starting.")
47+ return
48+ }
49+ whileFetching = true
50+
51+ try
52+ {
53+ val thread = Thread {
54+ Log.d(TAG, "Starting retrieving streaming data from server.")
55+ val slicer = SimpleLiveviewSlicer()
56+ var continuousNullDataReceived = 0
57+ try
58+ {
59+ val streamUrl = "http://192.168.1.1/osc/commands/execute"
60+ val paramData = if (useOscV2) "{\"name\":\"camera.getLivePreview\",\"parameters\":{\"timeout\":0}}" else "{\"name\":\"camera._getLivePreview\",\"parameters\":{\"sessionId\": \"" + sessionIdProvider.getSessionId().toString() + "\"}}"
61+ Log.v(TAG, " >>>>> START THETA PREVIEW : $streamUrl $paramData")
62+
63+ // Create Slicer to open the stream and parse it.
64+ slicer.open(streamUrl, paramData, "application/json;charset=utf-8")
65+ while (whileFetching) {
66+ val payload: SimpleLiveviewSlicer.Payload? = slicer.nextPayloadForMotionJpeg()
67+ if (payload == null)
68+ {
69+ //Log.v(TAG, "Liveview Payload is null.");
70+ continuousNullDataReceived++
71+ if (continuousNullDataReceived > FETCH_ERROR_MAX)
72+ {
73+ Log.d(TAG, " FETCH ERROR MAX OVER ")
74+ break
75+ }
76+ continue
77+ }
78+ liveViewListener.setImageData(payload.jpegData, null)
79+ continuousNullDataReceived = 0
80+ }
81+ }
82+ catch (e: Exception)
83+ {
84+ e.printStackTrace()
85+ }
86+ finally
87+ {
88+ slicer.close()
89+ if (whileFetching && continuousNullDataReceived > FETCH_ERROR_MAX)
90+ {
91+ // 再度ライブビューのスタートをやってみる。
92+ whileFetching = false
93+ start(useOscV2)
94+ }
95+ }
96+ }
97+ thread.start()
98+ }
99+ catch (e: Exception)
100+ {
101+ e.printStackTrace()
102+ }
103+ }
104+
105+ companion object
106+ {
107+ private val TAG = ThetaLiveViewControl::class.java.simpleName
108+ private const val FETCH_ERROR_MAX = 30
109+ }
110+}
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/operation/ThetaDummyOperation.kt
@@ -0,0 +1,182 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper.operation
2+
3+import android.graphics.Color
4+import jp.co.olympus.camerakit.OLYCamera
5+import jp.sfjp.gokigen.a01c.olycamerawrapper.ICameraHardwareStatus
6+import jp.sfjp.gokigen.a01c.olycamerawrapper.ICameraRunMode
7+import jp.sfjp.gokigen.a01c.olycamerawrapper.ILevelGauge
8+import jp.sfjp.gokigen.a01c.olycamerawrapper.IZoomLensHolder
9+import jp.sfjp.gokigen.a01c.olycamerawrapper.property.ICameraPropertyLoadSaveOperations
10+import jp.sfjp.gokigen.a01c.olycamerawrapper.property.ILoadSaveCameraProperties
11+import jp.sfjp.gokigen.a01c.olycamerawrapper.property.IOlyCameraPropertyProvider
12+
13+class ThetaDummyOperation : ILevelGauge, IZoomLensHolder, ICameraRunMode, ILoadSaveCameraProperties, ICameraPropertyLoadSaveOperations, IOlyCameraPropertyProvider, ICameraHardwareStatus
14+{
15+ override fun getLevel(area: ILevelGauge.LevelArea?): Float {
16+ // TODO("Not yet implemented")
17+ return (1.0f)
18+ }
19+
20+ override fun getLevelColor(value: Float): Int {
21+ // TODO("Not yet implemented")
22+ return (Color.WHITE)
23+ }
24+
25+ override fun checkLevelGauge(camera: OLYCamera?) {
26+ // TODO("Not yet implemented")
27+ }
28+
29+ override fun updateLevelGaugeChecking(isWatch: Boolean) {
30+ //TODO("Not yet implemented")
31+ }
32+
33+ override fun canZoom(): Boolean {
34+ //TODO("Not yet implemented")
35+ return (false)
36+ }
37+
38+ override fun updateStatus() {
39+ //TODO("Not yet implemented")
40+ }
41+
42+ override fun getMaximumFocalLength(): Float {
43+ // TODO("Not yet implemented")
44+ return (16.0f)
45+ }
46+
47+ override fun getActualFocalLength(): Float {
48+ TODO("Not yet implemented")
49+ }
50+
51+ override fun inquireHardwareInformation(): MutableMap<String, Any> {
52+ TODO("Not yet implemented")
53+ }
54+
55+ override fun getLensMountStatus(): String {
56+ TODO("Not yet implemented")
57+ }
58+
59+ override fun getMediaMountStatus(): String {
60+ TODO("Not yet implemented")
61+ }
62+
63+ override fun getMinimumFocalLength(): Float {
64+ //TODO("Not yet implemented")
65+ return (16.0f)
66+ }
67+
68+ override fun getCurrentFocalLength(): Float {
69+ //TODO("Not yet implemented")
70+ return (16.0f)
71+ }
72+
73+ override fun driveZoomLens(targetLength: Float) {
74+ //TODO("Not yet implemented")
75+ }
76+
77+ override fun driveZoomLens(direction: Int) {
78+ //TODO("Not yet implemented")
79+ }
80+
81+ override fun isDrivingZoomLens(): Boolean {
82+ //TODO("Not yet implemented")
83+ return (false)
84+ }
85+
86+ override fun getCurrentDigitalZoomScale(): Float {
87+ //TODO("Not yet implemented")
88+ return (1.0f)
89+ }
90+
91+ override fun magnifyLiveView(scale: Int): Boolean {
92+ //TODO("Not yet implemented")
93+ return (false)
94+ }
95+
96+ override fun changeDigitalZoomScale(scale: Float, isCyclic: Boolean) {
97+ // TODO("Not yet implemented")
98+ }
99+
100+ override fun changeRunMode(isRecording: Boolean) {
101+ //TODO("Not yet implemented")
102+ }
103+
104+ override fun isRecordingMode(): Boolean {
105+ //TODO("Not yet implemented")
106+ return (true)
107+ }
108+
109+ override fun loadCameraSettings(id: String?) {
110+ //TODO("Not yet implemented")
111+ }
112+
113+ override fun saveCameraSettings(id: String?, name: String?) {
114+ //TODO("Not yet implemented")
115+ }
116+
117+ override fun saveProperties(idHeader: String?, dataName: String?) {
118+ //TODO("Not yet implemented")
119+ }
120+
121+ override fun loadProperties(idHeader: String?, dataName: String?) {
122+ //TODO("Not yet implemented")
123+ }
124+
125+ override fun getCameraPropertyNames(): MutableSet<String> {
126+ TODO("Not yet implemented")
127+ }
128+
129+ override fun getCameraPropertyValue(name: String?): String {
130+ //TODO("Not yet implemented")
131+ return ("")
132+ }
133+
134+ override fun getCameraPropertyValues(names: MutableSet<String>?): MutableMap<String, String> {
135+ TODO("Not yet implemented")
136+ }
137+
138+ override fun getCameraPropertyTitle(name: String?): String {
139+ TODO("Not yet implemented")
140+ }
141+
142+ override fun getCameraPropertyValueList(name: String?): MutableList<String> {
143+ TODO("Not yet implemented")
144+ }
145+
146+ override fun getCameraPropertyValueTitle(propertyValue: String?): String {
147+ TODO("Not yet implemented")
148+ }
149+
150+ override fun setCameraPropertyValue(name: String?, value: String?) {
151+ TODO("Not yet implemented")
152+ }
153+
154+ override fun setCameraPropertyValues(values: MutableMap<String, String>?) {
155+ TODO("Not yet implemented")
156+ }
157+
158+ override fun updateCameraPropertyUp(name: String?) {
159+ TODO("Not yet implemented")
160+ }
161+
162+ override fun updateCameraPropertyDown(name: String?) {
163+ TODO("Not yet implemented")
164+ }
165+
166+ override fun changeCameraProperty(name: String?, direction: Int) {
167+ TODO("Not yet implemented")
168+ }
169+
170+ override fun canSetCameraProperty(name: String?): Boolean {
171+ TODO("Not yet implemented")
172+ }
173+
174+ override fun isConnected(): Boolean {
175+ TODO("Not yet implemented")
176+ }
177+
178+ override fun getHardwareStatus(): ICameraHardwareStatus {
179+ TODO("Not yet implemented")
180+ }
181+
182+}
\ No newline at end of file
--- /dev/null
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/thetacamerawrapper/operation/ThetaSingleShotControl.kt
@@ -0,0 +1,141 @@
1+package jp.sfjp.gokigen.a01c.thetacamerawrapper.operation
2+
3+import android.util.Log
4+import jp.sfjp.gokigen.a01c.ICameraController
5+import jp.sfjp.gokigen.a01c.olycamerawrapper.IIndicatorControl
6+import jp.sfjp.gokigen.a01c.thetacamerawrapper.IThetaSessionIdProvider
7+import jp.sfjp.gokigen.a01c.utils.SimpleHttpClient
8+import org.json.JSONObject
9+
10+
11+class ThetaSingleShotControl(private val sessionIdProvider: IThetaSessionIdProvider, private val indicator: IIndicatorControl, private val liveViewControl: ICameraController)
12+{
13+ private val httpClient = SimpleHttpClient()
14+
15+ /**
16+ *
17+ *
18+ */
19+ fun singleShot(useThetaV21 : Boolean)
20+ {
21+ Log.v(TAG, "singleShot()")
22+ try
23+ {
24+ val thread = Thread {
25+ try
26+ {
27+ val shootUrl = "http://192.168.1.1/osc/commands/execute"
28+ val postData = if (useThetaV21) "{\"name\":\"camera.takePicture\",\"parameters\":{\"timeout\":0}}" else "{\"name\":\"camera.takePicture\",\"parameters\":{\"sessionId\": \"" + sessionIdProvider.sessionId + "\"}}"
29+ val result: String? = httpClient.httpPostWithHeader(shootUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
30+ if ((result != null)&&(result.isNotEmpty()))
31+ {
32+ Log.v(TAG, " singleShot() : $result")
33+ indicator.onShootingStatusUpdate(IIndicatorControl.shootingStatus.Starting)
34+
35+ // 画像処理が終わるまで待つ
36+ waitChangeStatus()
37+
38+ // ライブビューのの再実行を指示する
39+ indicator.onShootingStatusUpdate(IIndicatorControl.shootingStatus.Stopping)
40+ liveViewControl.stopLiveView()
41+ waitMs(300) // ちょっと待つ...
42+ liveViewControl.startLiveView()
43+ }
44+ else
45+ {
46+ Log.v(TAG, "singleShot() reply is null.")
47+ }
48+ }
49+ catch (e: Exception)
50+ {
51+ e.printStackTrace()
52+ }
53+ }
54+ thread.start()
55+ }
56+ catch (e: Exception)
57+ {
58+ e.printStackTrace()
59+ }
60+ }
61+
62+ /**
63+ * 撮影状態が変わるまで待つ。
64+ * (ただし、タイムアウト時間を超えたらライブビューを再開させる)
65+ */
66+ private fun waitChangeStatus()
67+ {
68+ val getStateUrl = "http://192.168.1.1/osc/state"
69+ val maxWaitTimeoutMs = 9000 // 最大待ち時間 (単位: ms)
70+ var fingerprint = ""
71+ try
72+ {
73+ val result: String? = httpClient.httpPost(getStateUrl, "", timeoutMs)
74+ if ((result != null)&&(result.isNotEmpty()))
75+ {
76+ val jsonObject = JSONObject(result)
77+ fingerprint = jsonObject.getString("fingerprint")
78+
79+ // 現在の状態(ログを出す)
80+ Log.v(TAG, " $getStateUrl $result ($fingerprint)")
81+ }
82+ }
83+ catch (e: Exception)
84+ {
85+ e.printStackTrace()
86+ }
87+
88+ try
89+ {
90+ val firstTime = System.currentTimeMillis()
91+ var currentTime = firstTime
92+ while (currentTime - firstTime < maxWaitTimeoutMs)
93+ {
94+ // ... 状態を見て次に進める
95+ val result: String? = httpClient.httpPost(getStateUrl, "", timeoutMs)
96+ if ((result != null)&&(result.isNotEmpty()))
97+ {
98+ val jsonObject = JSONObject(result)
99+ val currentFingerprint = jsonObject.getString("fingerprint")
100+
101+ // ログを出してみる
102+ // Log.v(TAG, " " + getStateUrl + " ( " + result + " ) " + "(" + fingerprint + " " + current_fingerprint + ")");
103+ if (fingerprint != currentFingerprint)
104+ {
105+ // fingerprintが更新された!
106+ break
107+ }
108+ Log.v(TAG, " ----- NOW PROCESSING ----- : $fingerprint")
109+ }
110+ waitMs(1000)
111+ currentTime = System.currentTimeMillis()
112+ }
113+ }
114+ catch (e: Exception)
115+ {
116+ e.printStackTrace()
117+ }
118+ }
119+
120+ /**
121+ *
122+ *
123+ */
124+ private fun waitMs(waitMs: Int)
125+ {
126+ try
127+ {
128+ Thread.sleep(waitMs.toLong())
129+ }
130+ catch (e: Exception)
131+ {
132+ e.printStackTrace()
133+ }
134+ }
135+
136+ companion object
137+ {
138+ private val TAG = ThetaSingleShotControl::class.java.simpleName
139+ private const val timeoutMs = 6000
140+ }
141+}
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/utils/SimpleHttpClient.kt
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/utils/SimpleHttpClient.kt
@@ -7,7 +7,7 @@ import java.io.*
77 import java.net.HttpURLConnection
88 import java.net.URL
99
10-class SimpleHttpClient()
10+class SimpleHttpClient
1111 {
1212 /**
1313 *
--- a/wear/src/main/java/jp/sfjp/gokigen/a01c/utils/SimpleLiveviewSlicer.java
+++ b/wear/src/main/java/jp/sfjp/gokigen/a01c/utils/SimpleLiveviewSlicer.java
@@ -4,6 +4,7 @@ package jp.sfjp.gokigen.a01c.utils;
44 import android.util.Log;
55
66 import androidx.annotation.NonNull;
7+import androidx.annotation.Nullable;
78
89 import java.io.ByteArrayOutputStream;
910 import java.io.EOFException;
@@ -351,7 +352,7 @@ public class SimpleLiveviewSlicer
351352 *
352353 *
353354 */
354- public Payload nextPayloadForMotionJpeg()
355+ public @Nullable Payload nextPayloadForMotionJpeg()
355356 {
356357 int searchIndex = 0;
357358 int[] endmarker = { 0xff, 0xd9 };
--- a/wear/src/main/res/values-ja/strings.xml
+++ b/wear/src/main/res/values-ja/strings.xml
@@ -74,4 +74,7 @@
7474 <string name="connection_method_opc">OPC</string>
7575 <string name="connection_method_theta">THETA</string>
7676
77+ <string name="theta_connect_response_ng">応答がありません。</string>
78+ <string name="camera_not_found">カメラ未発見</string>
79+
7780 </resources>
--- a/wear/src/main/res/values/strings.xml
+++ b/wear/src/main/res/values/strings.xml
@@ -72,4 +72,7 @@
7272 <string name="connection_method_opc">OPC</string>
7373 <string name="connection_method_theta">THETA</string>
7474
75+ <string name="theta_connect_response_ng">Did not receive any response.</string>
76+ <string name="camera_not_found">Not Found&#8230;</string>
77+
7578 </resources>
Afficher sur ancien navigateur de dépôt.