import android.view.MotionEvent;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceDataStore;
/** カメラ状態の表示をすべて更新する **/
void updateStatusAll();
+
+ // ステータス監視のタスクを取得する
+ @Nullable ICameraStatusWatcher getStatusWatcher();
+
///** カメラの状態サマリ(のテキスト情報)を取得する **/
//String getCameraStatusSummary(ICameraStatusSummary decoder);
--- /dev/null
+package jp.sfjp.gokigen.a01c;
+
+/**
+ *
+ */
+public interface ICameraStatusUpdateNotify
+{
+ void updateCameraStatus(final String message);
+ void updateRemainBattery(final double percentage);
+
+/*
+ void updateDriveMode(String driveMode);
+ void updateAeLockState(boolean isAeLocked);
+ //void updateCameraStatus(String message);
+ void updateLevelGauge(String orientation, float roll, float pitch);
+
+ void updatedTakeMode(String mode);
+ void updatedShutterSpeed(String tv);
+ void updatedAperture(String av);
+ void updatedExposureCompensation(String xv);
+ void updatedMeteringMode(String meteringMode);
+ void updatedWBMode(String wbMode);
+ void updateFocusedStatus(boolean focused, boolean focusLocked);
+ void updateIsoSensitivity(String sv);
+ void updateWarning(String warning);
+ void updateStorageStatus(String status);
+*/
+}
--- /dev/null
+package jp.sfjp.gokigen.a01c;
+
+import androidx.annotation.NonNull;
+
+public interface ICameraStatusWatcher
+{
+ void startStatusWatch(@NonNull ICameraStatusUpdateNotify notifier);
+ void stopStatusWatch();
+}
* メインのActivity
*
*/
-public class MainActivity extends AppCompatActivity implements IChangeScene, IShowInformation, ICameraStatusReceiver, IDialogDismissedNotifier
+public class MainActivity extends AppCompatActivity implements IChangeScene, IShowInformation, ICameraStatusReceiver, IDialogDismissedNotifier, ICameraStatusUpdateNotify
{
private final String TAG = toString();
static final int REQUEST_NEED_PERMISSIONS = 1010;
// ライブビューを停止させる
currentCoordinator.stopLiveView();
+ // ステータス監視を止める
+ ICameraStatusWatcher watcher = currentCoordinator.getStatusWatcher();
+ if (watcher != null)
+ {
+ watcher.stopStatusWatch();
+ }
+
// パラメータを確認し、カメラの電源を切る
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(IPreferenceCameraPropertyAccessor.EXIT_APPLICATION_WITH_DISCONNECT, true))
{
listener.setEnableOperation(operation.ENABLE);
setMessage(IShowInformation.AREA_C, Color.WHITE, "");
currentCoordinator.updateStatusAll();
+ ICameraStatusWatcher watcher = currentCoordinator.getStatusWatcher();
+ if (watcher != null)
+ {
+ watcher.startStatusWatch(this);
+ }
}
catch (Exception e)
{
}
});
}
+
+ @Override
+ public void updateCameraStatus(String message)
+ {
+ try
+ {
+ setMessage(IShowInformation.AREA_8, Color.WHITE, message);
+ }
+ catch (Exception ee)
+ {
+ ee.printStackTrace();
+ }
+ }
+
+ @Override
+ public void updateRemainBattery(double percentageDouble)
+ {
+ int color = Color.YELLOW;
+ if (percentageDouble < 0.5d)
+ {
+ if (percentageDouble < 0.3d)
+ {
+ color = Color.RED;
+ }
+ try
+ {
+ int percentage = (int) Math.ceil(percentageDouble * 100.0d);
+ setMessage(IShowInformation.AREA_7, color, "Bat: " + percentage + "%");
+ }
+ catch (Exception ee)
+ {
+ ee.printStackTrace();
+ }
+ }
+ }
}
import android.widget.Toast;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.PreferenceDataStore;
import androidx.preference.PreferenceManager;
import jp.sfjp.gokigen.a01c.ICameraConnection;
import jp.sfjp.gokigen.a01c.ICameraController;
import jp.sfjp.gokigen.a01c.ICameraFeatureDispatcher;
+import jp.sfjp.gokigen.a01c.ICameraStatusWatcher;
import jp.sfjp.gokigen.a01c.IShowInformation;
import jp.sfjp.gokigen.a01c.R;
import jp.sfjp.gokigen.a01c.liveview.CameraLiveViewListenerImpl;
cameraStatusDisplay.updateCameraStatusAll();
}
+ @Nullable
+ @Override
+ public ICameraStatusWatcher getStatusWatcher()
+ {
+ return (null);
+ }
+
@Override
public void changeRunMode(boolean isRecording)
{
import android.view.MotionEvent
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceDataStore
-import jp.sfjp.gokigen.a01c.ICameraConnection
-import jp.sfjp.gokigen.a01c.ICameraController
-import jp.sfjp.gokigen.a01c.ICameraFeatureDispatcher
-import jp.sfjp.gokigen.a01c.IShowInformation
+import jp.sfjp.gokigen.a01c.*
import jp.sfjp.gokigen.a01c.liveview.CameraLiveViewListenerImpl
import jp.sfjp.gokigen.a01c.liveview.IAutoFocusFrameDisplay
import jp.sfjp.gokigen.a01c.liveview.ICameraStatusReceiver
import jp.sfjp.gokigen.a01c.thetacamerawrapper.operation.ThetaMovieRecordingControl
import jp.sfjp.gokigen.a01c.thetacamerawrapper.operation.ThetaOptionUpdateControl
import jp.sfjp.gokigen.a01c.thetacamerawrapper.operation.ThetaSingleShotControl
+import jp.sfjp.gokigen.a01c.thetacamerawrapper.status.ThetaCameraStatusWatcher
class ThetaCameraController(val context: AppCompatActivity, private val focusFrameDisplay: IAutoFocusFrameDisplay, private val showInformation: IShowInformation, private val receiver: ICameraStatusReceiver, private val preferences: PreferenceAccessWrapper) : ICameraController, IIndicatorControl
{
private val singleShot = ThetaSingleShotControl(sessionIdHolder, this, this)
private val movieShot = ThetaMovieRecordingControl(context, sessionIdHolder, this, showInformation, this)
private val optionSet = ThetaOptionUpdateControl(sessionIdHolder, this, this)
+ private val statusWatcher = ThetaCameraStatusWatcher()
override fun connectFinished()
{
// なにもしない
}
+ override fun getStatusWatcher(): ICameraStatusWatcher
+ {
+ return (statusWatcher)
+ }
+
override fun getCameraPropertyProvider(): IOlyCameraPropertyProvider
{
return (dummyOperation)
--- /dev/null
+package jp.sfjp.gokigen.a01c.thetacamerawrapper.status;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
+public interface ICameraStatus
+{
+ @NonNull List<String> getStatusList(final @NonNull String key);
+ @NonNull String getStatus(final @NonNull String key);
+ //void setStatus(final @NonNull String key, final @NonNull String value);
+
+
+ String THETA_BATTERY_LEVEL = "batteryLevel";
+ String THETA_CAPTURE_STATUS = "_captureStatus";
+ String THETA_RECORDING_SEC = "_recordedTime";
+ String THETA_BATTERY_STATE = "_batteryState";
+ String THETA_CURRENT_API_LEVEL = "_apiVersion";
+ String THETA_SHOOTING_FUNCTION = "_function";
+ String THETA_CAMERA_ERROR = "_cameraError";
+
+/*
+ String BATTERY = "battery";
+ String STATE = "state";
+ String FOCUS_MODE = "focusMode";
+ String AF_MODE = "AFMode";
+
+ String RESOLUTION = "reso";
+ String DRIVE_MODE = "shootMode";
+ String WHITE_BALANCE = "WBMode";
+
+ String AE = "meteringMode";
+
+ String AE_STATUS_MULTI = "multi";
+ String AE_STATUS_ESP = "ESP";
+ String AE_STATUS_SPOT = "spot";
+ String AE_STATUS_PINPOINT = "Spot";
+ String AE_STATUS_CENTER = "center";
+ String AE_STATUS_CENTER2 = "Ctr-Weighted";
+
+ String EFFECT = "effect";
+ String TAKE_MODE = "exposureMode";
+ String IMAGESIZE = "stillSize";
+ String MOVIESIZE = "movieSize";
+
+ String APERATURE = "av";
+ String SHUTTER_SPEED = "tv";
+ String ISO_SENSITIVITY = "sv";
+ String EXPREV = "xv";
+ String FLASH_XV = "flashxv";
+
+ String TAKE_MODE_MOVIE = "movie";
+ */
+}
--- /dev/null
+package jp.sfjp.gokigen.a01c.thetacamerawrapper.status
+
+import android.util.Log
+import jp.sfjp.gokigen.a01c.ICameraStatusUpdateNotify
+import jp.sfjp.gokigen.a01c.ICameraStatusWatcher
+import jp.sfjp.gokigen.a01c.thetacamerawrapper.status.ICameraStatus.*
+import jp.sfjp.gokigen.a01c.utils.SimpleHttpClient
+import org.json.JSONObject
+
+class ThetaCameraStatusWatcher : ICameraStatus, ICameraStatusWatcher
+{
+ private val httpClient = SimpleHttpClient()
+ private var whileFetching = false
+ private var currentBatteryLevel : Double = 0.0
+ private var currentCaptureStatus : String = ""
+ private var currentBatteryStatus : String = ""
+
+
+ override fun getStatusList(key: String): List<String>
+ {
+ return (ArrayList<String>())
+ }
+
+ override fun getStatus(key: String): String
+ {
+ return ("")
+ }
+
+ override fun startStatusWatch(notifier: ICameraStatusUpdateNotify)
+ {
+ if (whileFetching)
+ {
+ Log.v(TAG, "startStatusWatch() already starting.")
+ return
+ }
+ whileFetching = true
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val getStateUrl = "http://192.168.1.1/osc/state"
+ Log.v(TAG, " >>>>> START STATUS WATCH : $getStateUrl")
+ while (whileFetching)
+ {
+ val response: String? = httpClient.httpPostWithHeader(getStateUrl, "", null, "application/json;charset=utf-8", timeoutMs)
+ if (!(response.isNullOrEmpty()))
+ {
+ // ステータスデータ受信
+ checkStatus(response, notifier)
+ }
+ try
+ {
+ Thread.sleep(300)
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun checkStatus(response : String, notifier: ICameraStatusUpdateNotify)
+ {
+ try
+ {
+ //Log.v(TAG, " STATUS : $response")
+ val stateObject = JSONObject(response).getJSONObject("state")
+ try
+ {
+ val batteryLevel = stateObject.getDouble(THETA_BATTERY_LEVEL)
+ if (batteryLevel != currentBatteryLevel)
+ {
+ Log.v(TAG, " BATTERY : $currentBatteryLevel => $batteryLevel")
+ currentBatteryLevel = batteryLevel
+ notifier.updateRemainBattery(currentBatteryLevel)
+ }
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+
+ try
+ {
+ val batteryStatus = stateObject.getString(THETA_CAPTURE_STATUS)
+ if (batteryStatus != currentBatteryStatus)
+ {
+ Log.v(TAG, " BATTERY STATUS : $currentBatteryStatus => $batteryStatus")
+ currentBatteryStatus = batteryStatus
+ }
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+
+ try
+ {
+ val captureStatus = stateObject.getString(THETA_CAPTURE_STATUS)
+ if (captureStatus != currentCaptureStatus)
+ {
+ Log.v(TAG, " CAPTURE STATUS : $currentCaptureStatus -> $captureStatus")
+ if (captureStatus != "idle")
+ {
+ notifier.updateCameraStatus(captureStatus)
+ }
+ currentCaptureStatus = captureStatus
+ }
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ catch (ee : Exception)
+ {
+ ee.printStackTrace()
+ }
+ }
+
+ override fun stopStatusWatch()
+ {
+ whileFetching = false
+ }
+
+ companion object
+ {
+ private val TAG = ThetaCameraStatusWatcher::class.java.simpleName
+ private const val timeoutMs = 1500
+ }
+
+}
\ No newline at end of file