From d18121a2213d951e5f611493197da705ad1f78d1 Mon Sep 17 00:00:00 2001 From: MRSa Date: Thu, 17 Oct 2019 00:28:04 +0900 Subject: [PATCH] =?utf8?q?=E6=AC=A1=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?utf8?q?=E3=83=B3=E3=81=AE=E3=81=9F=E3=82=81=E3=81=AE=E6=8B=A1=E5=BC=B5?= =?utf8?q?=E3=82=92=E9=96=8B=E5=A7=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- .../pkremote/camera/CameraInterfaceProvider.java | 63 +++ .../interfaces/control/ICameraConnection.java | 1 + .../vendor/nikon/INikonInterfaceProvider.java | 57 +++ .../nikon/wrapper/NikonInterfaceProvider.java | 233 +++++++++++ .../wrapper/playback/NikonImageObjectReceiver.java | 215 ++++++++++ .../wrapper/playback/NikonPlaybackControl.java | 257 ++++++++++++ .../olympuspen/IOlympusPenInterfaceProvider.java | 39 ++ .../operation/OlympusPenCameraPowerOff.java | 81 ++++ .../wrapper/OlympusPenInterfaceProvider.java | 193 +++++++++ .../olympuspen/wrapper/OlympusPenRunMode.java | 20 + .../OlympusPenCameraConnectSequence.java | 115 +++++ .../OlympusPenCameraDisconnectSequence.java | 53 +++ .../wrapper/connection/OlympusPenConnection.java | 278 ++++++++++++ .../wrapper/hardware/OlympusPenButtonControl.java | 13 + .../wrapper/hardware/OlympusPenHardwareStatus.java | 51 +++ .../playback/OlympusPenPlaybackControl.java | 464 +++++++++++++++++++++ .../camera/vendor/ptpip/wrapper/PtpIpRunMode.java | 2 +- .../wrapper/playback/PtpIpFullImageReceiver.java | 4 +- .../wrapper/playback/PtpIpImageContentInfo.java | 4 +- .../playback/PtpIpScreennailImageReceiver.java | 2 +- .../wrapper/playback/PtpIpSmallImageReceiver.java | 4 +- .../playback/PtpIpThumbnailImageReceiver.java | 2 +- .../preference/nikon/NikonPreferenceFragment.java | 8 +- .../olympuspen/OlympusPenPreferenceFragment.java | 313 ++++++++++++++ .../gokigen/pkremote/scene/CameraSceneUpdater.java | 5 + app/src/main/res/values-ja/arrays.xml | 2 + app/src/main/res/values/arrays.xml | 2 + app/src/main/res/xml/preferences_olympus.xml | 82 ++++ 29 files changed, 2552 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/INikonInterfaceProvider.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/NikonInterfaceProvider.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonImageObjectReceiver.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonPlaybackControl.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/IOlympusPenInterfaceProvider.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/operation/OlympusPenCameraPowerOff.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/OlympusPenInterfaceProvider.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/OlympusPenRunMode.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenCameraConnectSequence.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenCameraDisconnectSequence.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenConnection.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/hardware/OlympusPenButtonControl.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/hardware/OlympusPenHardwareStatus.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/playback/OlympusPenPlaybackControl.java create mode 100644 app/src/main/java/net/osdn/gokigen/pkremote/preference/olympuspen/OlympusPenPreferenceFragment.java create mode 100644 app/src/main/res/xml/preferences_olympus.xml diff --git a/app/build.gradle b/app/build.gradle index ff6a19f..331e3b5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,8 +6,8 @@ android { applicationId "net.osdn.gokigen.pkremote" minSdkVersion 14 targetSdkVersion 29 - versionCode 10400 - versionName "1.4.0" + versionCode 10500 + versionName "1.5.0" } buildTypes { release { diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/CameraInterfaceProvider.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/CameraInterfaceProvider.java index 97ad2df..fa04c76 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/CameraInterfaceProvider.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/CameraInterfaceProvider.java @@ -25,6 +25,7 @@ import net.osdn.gokigen.pkremote.camera.utils.CameraStatusListener; import net.osdn.gokigen.pkremote.camera.vendor.fujix.wrapper.FujiXInterfaceProvider; import net.osdn.gokigen.pkremote.camera.vendor.olympus.IOlympusInterfaceProvider; import net.osdn.gokigen.pkremote.camera.vendor.olympus.wrapper.OlympusInterfaceProvider; +import net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.OlympusPenInterfaceProvider; import net.osdn.gokigen.pkremote.camera.vendor.panasonic.wrapper.PanasonicCameraWrapper; import net.osdn.gokigen.pkremote.camera.vendor.ptpip.IPtpIpInterfaceProvider; import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.PtpIpInterfaceProvider; @@ -49,6 +50,7 @@ public class CameraInterfaceProvider implements IInterfaceProvider private final FujiXInterfaceProvider fujiX; private final PanasonicCameraWrapper panasonic; private final PtpIpInterfaceProvider ptpip; + private final OlympusPenInterfaceProvider olympuspen; private final IInformationReceiver informationReceiver; private final CameraContentsRecognizer cameraContentsRecognizer; private final AppCompatActivity context; @@ -74,6 +76,7 @@ public class CameraInterfaceProvider implements IInterfaceProvider sony = new SonyCameraWrapper(context, provider, statusListener, informationReceiver); ptpip = new PtpIpInterfaceProvider(context, provider, statusListener, informationReceiver); panasonic = new PanasonicCameraWrapper(context, provider, statusListener, informationReceiver); + olympuspen = new OlympusPenInterfaceProvider(context, provider); this.informationReceiver = informationReceiver; this.cameraContentsRecognizer = new CameraContentsRecognizer(context, this); } @@ -130,6 +133,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getPtpIpCameraConnection()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getOlyCameraConnection()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getRicohGr2CameraConnection()); @@ -172,6 +179,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getButtonControl()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getButtonControl()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getButtonControl()); @@ -214,6 +225,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getDisplayInjector()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getDisplayInjector()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getDisplayInjector()); @@ -256,6 +271,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getLiveViewControl()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getLiveViewControl()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getLiveViewControl()); @@ -298,6 +317,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getLiveViewListener()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getLiveViewListener()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getLiveViewListener()); @@ -340,6 +363,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getFocusingControl()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getFocusingControl()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getFocusingControl()); @@ -382,6 +409,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getCameraInformation()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getCameraInformation()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getCameraInformation()); @@ -424,6 +455,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getZoomLensControl()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getZoomLensControl()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getZoomLensControl()); @@ -466,6 +501,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getCaptureControl()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getCaptureControl()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getCaptureControl()); @@ -508,6 +547,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getCameraStatusListHolder()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getCameraStatusListHolder()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getCameraStatusListHolder()); @@ -550,6 +593,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getCameraStatusWatcher()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getCameraStatusWatcher()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getCameraStatusWatcher()); @@ -592,6 +639,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getPlaybackControl()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getPlaybackControl()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getPlaybackControl()); @@ -634,6 +685,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getHardwareStatus()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getHardwareStatus()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getHardwareStatus()); @@ -676,6 +731,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { return (ptpip.getCameraRunMode()); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + return (olympuspen.getCameraRunMode()); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.RICOH) { return (ricohGr2.getCameraRunMode()); @@ -763,6 +822,10 @@ public class CameraInterfaceProvider implements IInterfaceProvider { ret = ICameraConnection.CameraConnectionMethod.NIKON; } + else if (connectionMethod.contains("OLYMPUS")) + { + ret = ICameraConnection.CameraConnectionMethod.OLYMPUS; + } else // if (connectionMethod.contains("OPC")) { ret = ICameraConnection.CameraConnectionMethod.OPC; diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/interfaces/control/ICameraConnection.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/interfaces/control/ICameraConnection.java index 0de644d..59577c1 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/interfaces/control/ICameraConnection.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/interfaces/control/ICameraConnection.java @@ -18,6 +18,7 @@ public interface ICameraConnection PANASONIC, CANON, NIKON, + OLYMPUS, } enum CameraConnectionStatus diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/INikonInterfaceProvider.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/INikonInterfaceProvider.java new file mode 100644 index 0000000..8380910 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/INikonInterfaceProvider.java @@ -0,0 +1,57 @@ +package net.osdn.gokigen.pkremote.camera.vendor.nikon; + +import androidx.annotation.NonNull; + +import net.osdn.gokigen.pkremote.IInformationReceiver; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraButtonControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraRunMode; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICaptureControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IFocusingControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IZoomLensControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ICameraStatusUpdateNotify; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.IDisplayInjector; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ILiveViewControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ILiveViewListener; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IPlaybackControl; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraHardwareStatus; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraInformation; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatus; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusWatcher; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommunication; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.status.IPtpIpRunModeHolder; + +public interface INikonInterfaceProvider +{ + ICameraConnection getPtpIpCameraConnection(); + ILiveViewControl getLiveViewControl(); + ILiveViewListener getLiveViewListener(); + IFocusingControl getFocusingControl(); + ICameraInformation getCameraInformation(); + IZoomLensControl getZoomLensControl(); + ICaptureControl getCaptureControl(); + IDisplayInjector getDisplayInjector(); + + IPtpIpRunModeHolder getRunModeHolder(); + IPtpIpCommandCallback getStatusHolder(); + IPtpIpCommandPublisher getCommandPublisher(); + IPtpIpCommunication getLiveviewCommunication(); + IPtpIpCommunication getAsyncEventCommunication(); + IPtpIpCommunication getCommandCommunication(); + + ICameraStatusUpdateNotify getStatusListener(); + + ICameraStatusWatcher getCameraStatusWatcher(); + ICameraStatus getCameraStatusListHolder(); + + ICameraButtonControl getButtonControl(); + IPlaybackControl getPlaybackControl(); + ICameraHardwareStatus getHardwareStatus(); + ICameraRunMode getCameraRunMode(); + + IInformationReceiver getInformationReceiver(); + + void setAsyncEventReceiver(@NonNull IPtpIpCommandCallback receiver); +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/NikonInterfaceProvider.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/NikonInterfaceProvider.java new file mode 100644 index 0000000..764251d --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/NikonInterfaceProvider.java @@ -0,0 +1,233 @@ +package net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper; + +import android.app.Activity; +import android.util.Log; + +import androidx.annotation.NonNull; + +import net.osdn.gokigen.pkremote.IInformationReceiver; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraButtonControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraRunMode; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICaptureControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IFocusingControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IFocusingModeNotify; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IZoomLensControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.IAutoFocusFrameDisplay; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ICameraStatusUpdateNotify; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.IDisplayInjector; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.IIndicatorControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ILiveViewControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ILiveViewListener; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IPlaybackControl; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraHardwareStatus; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraInformation; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatus; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusReceiver; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusWatcher; +import net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.playback.NikonPlaybackControl; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.IPtpIpInterfaceProvider; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.operation.PtpIpZoomControl; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.PtpIpButtonControl; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.PtpIpHardwareStatus; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.PtpIpRunMode; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommunication; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.PtpIpAsyncResponseReceiver; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.PtpIpCommandPublisher; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.connection.CanonConnection; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.liveview.PtpIpLiveViewControl; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.status.IPtpIpRunModeHolder; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.status.PtpIpStatusChecker; + +public class NikonInterfaceProvider implements IPtpIpInterfaceProvider, IDisplayInjector +{ + private final String TAG = toString(); + + private static final int STREAM_PORT = 15742; // ?? + private static final int ASYNC_RESPONSE_PORT = 15741; // ?? + private static final int CONTROL_PORT = 15740; + private static final int EVENT_PORT = 15740; + private static final String CAMERA_IP = "192.168.0.1"; + + private final Activity activity; + private final PtpIpRunMode runmode; + private final PtpIpHardwareStatus hardwareStatus; + private PtpIpButtonControl ptpIpButtonControl; + private CanonConnection canonConnection; + private PtpIpCommandPublisher commandPublisher; + private PtpIpLiveViewControl liveViewControl; + private PtpIpAsyncResponseReceiver asyncReceiver; + private PtpIpZoomControl zoomControl; + //private PtpIpCaptureControl captureControl; + //private PtpIpFocusingControl focusingControl; + private PtpIpStatusChecker statusChecker; + private ICameraStatusUpdateNotify statusListener; + private NikonPlaybackControl playbackControl; + private IInformationReceiver informationReceiver; + + public NikonInterfaceProvider(@NonNull Activity context, @NonNull ICameraStatusReceiver provider, @NonNull ICameraStatusUpdateNotify statusListener, @NonNull IInformationReceiver informationReceiver) + { + this.activity = context; + commandPublisher = new PtpIpCommandPublisher(CAMERA_IP, CONTROL_PORT); + liveViewControl = new PtpIpLiveViewControl(context, CAMERA_IP, STREAM_PORT); + asyncReceiver = new PtpIpAsyncResponseReceiver(CAMERA_IP, ASYNC_RESPONSE_PORT); + statusChecker = new PtpIpStatusChecker(activity, commandPublisher, CAMERA_IP, EVENT_PORT); + canonConnection = new CanonConnection(context, provider, this, statusChecker); + zoomControl = new PtpIpZoomControl(); + this.statusListener = statusListener; + this.runmode = new PtpIpRunMode(); + this.hardwareStatus = new PtpIpHardwareStatus(); + this.ptpIpButtonControl = new PtpIpButtonControl(); + this.playbackControl = new NikonPlaybackControl(activity, this); + this.informationReceiver = informationReceiver; + } + + @Override + public void injectDisplay(IAutoFocusFrameDisplay frameDisplayer, IIndicatorControl indicator, IFocusingModeNotify focusingModeNotify) + { + Log.v(TAG, "injectDisplay()"); + //captureControl = new FujiXCaptureControl(commandPublisher, frameDisplayer); + //focusingControl = new FujiXFocusingControl(activity, commandPublisher, frameDisplayer, indicator); + } + + @Override + public ICameraConnection getPtpIpCameraConnection() + { + return (canonConnection); + } + + @Override + public ILiveViewControl getLiveViewControl() + { + return (liveViewControl); + } + + @Override + public ILiveViewListener getLiveViewListener() + { + return (liveViewControl.getLiveViewListener()); + } + + @Override + public IFocusingControl getFocusingControl() + { + return (null); + } + + @Override + public ICameraInformation getCameraInformation() + { + return null; + } + + @Override + public IZoomLensControl getZoomLensControl() + { + return (zoomControl); + } + + @Override + public ICaptureControl getCaptureControl() + { + return (null); + } + + @Override + public IDisplayInjector getDisplayInjector() + { + return (this); + } + + @Override + public IPtpIpRunModeHolder getRunModeHolder() + { + return (runmode); + } + + @Override + public IPtpIpCommandCallback getStatusHolder() { + return (statusChecker); + } + + @Override + public IPtpIpCommandPublisher getCommandPublisher() + { + return (commandPublisher); + } + + @Override + public IPtpIpCommunication getLiveviewCommunication() + { + return (liveViewControl); + } + + @Override + public IPtpIpCommunication getAsyncEventCommunication() + { + return (asyncReceiver); + } + + @Override + public IPtpIpCommunication getCommandCommunication() + { + return (commandPublisher); + } + + @Override + public ICameraStatusWatcher getCameraStatusWatcher() + { + return (statusChecker); + } + + @Override + public ICameraStatusUpdateNotify getStatusListener() + { + return (statusListener); + } + + @Override + public ICameraStatus getCameraStatusListHolder() + { + return (statusChecker); + } + + @Override + public ICameraButtonControl getButtonControl() + { + return (ptpIpButtonControl); + } + + @Override + public IPlaybackControl getPlaybackControl() + { + return (playbackControl); + } + + @Override + public ICameraHardwareStatus getHardwareStatus() + { + return (hardwareStatus); + } + + @Override + public ICameraRunMode getCameraRunMode() + { + return (runmode); + } + + @Override + public IInformationReceiver getInformationReceiver() + { + // ちょっとこの引き回しは気持ちがよくない... + return (informationReceiver); + } + + @Override + public void setAsyncEventReceiver(@NonNull IPtpIpCommandCallback receiver) + { + asyncReceiver.setEventSubscriber(receiver); + } + +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonImageObjectReceiver.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonImageObjectReceiver.java new file mode 100644 index 0000000..30acdda --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonImageObjectReceiver.java @@ -0,0 +1,215 @@ +package net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.playback; + +import android.util.Log; + +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentListCallback; +import net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.NikonInterfaceProvider; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback.PtpIpImageContentInfo; + +import java.util.ArrayList; +import java.util.List; + +import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX_2; +import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX_3; +import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_ID; +import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_INFO; +import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX; + +public class NikonImageObjectReceiver implements IPtpIpCommandCallback +{ + private final String TAG = toString(); + private final NikonInterfaceProvider provider; + private boolean isDumpLog = false; + private List imageObjectList; + private List ptpIpImageObjectList; + private ICameraContentListCallback callback = null; + private int subDirectoriesCount = -1; + private int receivedSubDirectoriesCount = -1; + + NikonImageObjectReceiver(NikonInterfaceProvider provider) + { + this.provider = provider; + this.imageObjectList = new ArrayList<>(); + this.ptpIpImageObjectList = new ArrayList<>(); + } + + @Override + public void receivedMessage(int id, byte[] rx_body) + { + try + { + IPtpIpCommandPublisher publisher = provider.getCommandPublisher(); + //SimpleLogDumper.dump_bytes(" [RX] ", rx_body); + switch (id) + { + case GET_STORAGE_ID: + // TODO: ストレージのIDを 0x00100010 で固定にしている。複数スロットある場合もあるので、このタイミングでちゃんと応答を parse してループさせる必要がある + publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_INFO, isDumpLog, 0, 0x9102, 4, 0x00010001)); + subDirectoriesCount = -1; // ここから画像取得シーケンスに入るので、、、 + break; + + case GET_STORAGE_INFO: + // TODO: (要検討) ストレージの情報を取得しているが、本当に使わなくてもよい? + publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX, isDumpLog, 0, 0x9109, 12, 0x00010001, 0xffffffff, 0x00200000)); + break; + + case GET_OBJECT_INFO_EX: + List directries = parseContentSubdirectories(rx_body, 32); + { + // サブディレクトリの情報を拾う + for (PtpIpImageContentInfo contentInfo : directries) + { + publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX_2, isDumpLog, 0, 0x9109, 12, 0x00010001, contentInfo.getId(), 0x00200000)); + } + } + break; + + case GET_OBJECT_INFO_EX_2: + List subDirectries = parseContentSubdirectories(rx_body, 32); + { + // 画像の情報を拾う + for (PtpIpImageContentInfo contentInfo : subDirectries) + { + publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX_3, isDumpLog, 0, 0x9109, 12, 0x00010001, contentInfo.getId(), 0x00200000)); + } + subDirectoriesCount = subDirectries.size(); + receivedSubDirectoriesCount = 0; + if (subDirectoriesCount <= 0) + { + // カメラの画像コンテンツが見つからなかった(サブディレクトリがなかった)...ここで画像解析終了の報告をする + callback.onCompleted(imageObjectList); + } + } + break; + + case GET_OBJECT_INFO_EX_3: + if (isDumpLog) + { + Log.v(TAG, " --- CONTENT ---"); + } + List objects = parseContentSubdirectories(rx_body, 32); + if (objects.size() > 0) + { + imageObjectList.addAll(objects); + ptpIpImageObjectList.addAll(objects); + } + receivedSubDirectoriesCount++; + if (receivedSubDirectoriesCount >= subDirectoriesCount) + { + // 全コンテンツの受信成功 + if(this.callback != null) + { + callback.onCompleted(imageObjectList); + } + } + break; + + default: + break; + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + private List parseContentSubdirectories(byte[] rx_body, int offset) + { + List result = new ArrayList<>(); + try + { + int nofObjects = (rx_body[offset] & 0xff); + nofObjects = nofObjects + ((rx_body[offset + 1] & 0xff) << 8); + nofObjects = nofObjects + ((rx_body[offset + 2] & 0xff) << 16); + nofObjects = nofObjects + ((rx_body[offset + 3] & 0xff) << 24); + + int dataIndex = offset + 4; + while (rx_body.length > dataIndex) + { + int objectSize = (rx_body[dataIndex++] & 0xff); + objectSize = objectSize + ((rx_body[dataIndex++] & 0xff) << 8); + objectSize = objectSize + ((rx_body[dataIndex++] & 0xff) << 16); + objectSize = objectSize + ((rx_body[dataIndex++] & 0xff) << 24); + objectSize = objectSize - 4; // 抽出したレングス長分減らず + + int id = (rx_body[dataIndex] & 0xff); + id = id + ((rx_body[dataIndex + 1] & 0xff) << 8); + id = id + ((rx_body[dataIndex + 2] & 0xff) << 16); + id = id + ((rx_body[dataIndex + 3] & 0xff) << 24); + + PtpIpImageContentInfo content = new PtpIpImageContentInfo(id, "", rx_body, dataIndex, objectSize); + result.add(content); + dataIndex = dataIndex + objectSize; + if (result.size() >= nofObjects) + { + // オブジェクトを全部切り出した + break; + } + } + } + catch (Exception e) + { + e.printStackTrace(); + } + return (result); + } + + @Override + public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body) + { + Log.v(TAG, "onReceiveProgress(" + currentBytes + "/" + totalBytes + ")"); + } + + @Override + public boolean isReceiveMulti() + { + return (false); + } + + PtpIpImageContentInfo getContentObject(String fileName) + { + for (PtpIpImageContentInfo contentInfo : ptpIpImageObjectList) + { + + if (fileName.matches(contentInfo.getContentName())) + { + return (contentInfo); + } + } + return (null); + } + + public void getCameraContents(ICameraContentListCallback callback) + { + this.callback = null; + try + { + ICameraConnection connection = provider.getPtpIpCameraConnection(); + if (connection.getConnectionStatus() != ICameraConnection.CameraConnectionStatus.CONNECTED) + { + Log.v(TAG, "DOES NOT CONNECT TO CAMERA."); + return; + } + + IPtpIpCommandPublisher publisher = provider.getCommandPublisher(); + if (publisher != null) + { + // オブジェクト一覧をクリアする + this.imageObjectList.clear(); + this.ptpIpImageObjectList.clear(); + publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_ID, isDumpLog, 0, 0x9101)); + this.callback = callback; + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonPlaybackControl.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonPlaybackControl.java new file mode 100644 index 0000000..823d925 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/nikon/wrapper/playback/NikonPlaybackControl.java @@ -0,0 +1,257 @@ +package net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.playback; + +import android.app.Activity; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.util.Log; + +import androidx.preference.PreferenceManager; + +import net.osdn.gokigen.pkremote.IInformationReceiver; +import net.osdn.gokigen.pkremote.R; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentListCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraFileInfo; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IContentInfoCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentListCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadThumbnailImageCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IPlaybackControl; +import net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.NikonInterfaceProvider; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.specific.CanonRequestInnerDevelopStart; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback.PtpIpFullImageReceiver; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback.PtpIpImageContentInfo; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback.PtpIpScreennailImageReceiver; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback.PtpIpSmallImageReceiver; +import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback.PtpIpThumbnailImageReceiver; +import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor; + +/** + * + * + */ +public class NikonPlaybackControl implements IPlaybackControl +{ + private final String TAG = toString(); + private final Activity activity; + private final NikonInterfaceProvider provider; + private final PtpIpFullImageReceiver fullImageReceiver; + private final PtpIpSmallImageReceiver smallImageReciever; + private String raw_suffix = "CR2"; + private boolean use_screennail_image = false; + private NikonImageObjectReceiver canonImageObjectReceiver; + + public NikonPlaybackControl(Activity activity, NikonInterfaceProvider provider) + { + this.activity = activity; + this.provider = provider; + this.fullImageReceiver = new PtpIpFullImageReceiver(activity, provider.getCommandPublisher()); + this.smallImageReciever = new PtpIpSmallImageReceiver(activity, provider.getCommandPublisher()); + canonImageObjectReceiver = new NikonImageObjectReceiver(provider); + + try + { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); + raw_suffix = preferences.getString(IPreferencePropertyAccessor.CANON_RAW_SUFFIX, IPreferencePropertyAccessor.CANON_RAW_SUFFIX_DEFAULT_VALUE); + use_screennail_image = preferences.getBoolean(IPreferencePropertyAccessor.CANON_USE_SCREENNAIL_AS_SMALL, false); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + @Override + public String getRawFileSuffix() + { + return (raw_suffix); + } + + @Override + public void downloadContentList(IDownloadContentListCallback callback) + { + // なにもしない。(未使用) + } + + @Override + public void getContentInfo(String path, String name, IContentInfoCallback callback) + { + // showFileInformation + + } + + @Override + public void updateCameraFileInfo(ICameraFileInfo info) + { + // なにもしない + } + + @Override + public void downloadContentScreennail(String path, IDownloadThumbnailImageCallback callback) + { + Log.v(TAG, " downloadContentScreennail() " + path); + + if (!use_screennail_image) + { + // Thumbnail と同じ画像を表示する + downloadContentThumbnail(path, callback); + return; + } + + try + { + int start = 0; + if (path.indexOf("/") == 0) + { + start = 1; + } + final String indexStr = path.substring(start); + PtpIpImageContentInfo content = canonImageObjectReceiver.getContentObject(indexStr); + if (content != null) + { + IPtpIpCommandPublisher publisher = provider.getCommandPublisher(); + //int storageId = content.getStorageId(); + int objectId = content.getId(); + + // 画像表示中...のメッセージを表示する + IInformationReceiver display = provider.getInformationReceiver(); + if (display != null) + { + String message = activity.getString(R.string.canon_get_image_screennail); + display.updateMessage(message, false, true, Color.LTGRAY); + } + + // 画像を取得する + PtpIpScreennailImageReceiver receiver = new PtpIpScreennailImageReceiver(activity, objectId, publisher, callback); + publisher.enqueueCommand(new CanonRequestInnerDevelopStart(receiver, objectId, true, objectId, objectId)); // 0x9141 : RequestInnerDevelopStart + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + @Override + public void downloadContentThumbnail(String path, final IDownloadThumbnailImageCallback callback) + { + try + { + int start = 0; + if (path.indexOf("/") == 0) + { + start = 1; + } + //String indexStr = path.substring(start, path.indexOf(".")); + final String indexStr = path.substring(start); + //Log.v(TAG, "downloadContentThumbnail() : [" + path + "] " + indexStr); + + PtpIpImageContentInfo content = canonImageObjectReceiver.getContentObject(indexStr); + if (content != null) + { + IPtpIpCommandPublisher publisher = provider.getCommandPublisher(); + //int storageId = content.getStorageId(); + int objectId = content.getId(); + // Log.v(TAG, "downloadContentThumbnail() " + indexStr + " [" + objectId + "] (" + storageId + ")"); + publisher.enqueueCommand(new PtpIpCommandGeneric(new PtpIpThumbnailImageReceiver(activity, callback), objectId, false, 0, 0x910a, 8, objectId, 0x00032000)); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + @Override + public void downloadContent(String path, boolean isSmallSize, IDownloadContentCallback callback) + { + try + { + int start = 0; + if (path.indexOf("/") == 0) + { + start = 1; + } + final String indexStr = path.substring(start); + PtpIpImageContentInfo content = canonImageObjectReceiver.getContentObject(indexStr); + if (content != null) + { + if (isSmallSize) + { + // スモールサイズの画像取得コマンド(シーケンス)を発行する + smallImageReciever.issueCommand(content.getId(), callback); + } + else + { + // オリジナル画像の取得コマンド(シーケンス)を発行する + fullImageReceiver.issueCommand(content.getId(), content.getOriginalSize(), callback); + } + } + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + @Override + public void getCameraContentList(final ICameraContentListCallback callback) + { + if (callback == null) + { + return; + } + + try + { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + canonImageObjectReceiver.getCameraContents(callback); + } + }); + thread.start(); + } + catch (Exception e) + { + e.printStackTrace(); + callback.onErrorOccurred(e); + } + } + + @Override + public void showPictureStarted() + { + try + { + Log.v(TAG, " showPictureStarted() "); + + IPtpIpCommandPublisher publisher = provider.getCommandPublisher(); + publisher.flushHoldQueue(); + System.gc(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + @Override + public void showPictureFinished() + { + try + { + Log.v(TAG, " showPictureFinished() "); + + IPtpIpCommandPublisher publisher = provider.getCommandPublisher(); + publisher.flushHoldQueue(); + System.gc(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/IOlympusPenInterfaceProvider.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/IOlympusPenInterfaceProvider.java new file mode 100644 index 0000000..23639f9 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/IOlympusPenInterfaceProvider.java @@ -0,0 +1,39 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen; + +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraButtonControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraRunMode; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICaptureControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IFocusingControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IZoomLensControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.IDisplayInjector; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ILiveViewControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ILiveViewListener; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IPlaybackControl; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraHardwareStatus; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraInformation; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatus; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusWatcher; + +/** + * + */ +public interface IOlympusPenInterfaceProvider +{ + ICameraConnection getOlyCameraConnection(); + ILiveViewControl getLiveViewControl(); + ILiveViewListener getLiveViewListener(); + IFocusingControl getFocusingControl(); + ICameraInformation getCameraInformation(); + IZoomLensControl getZoomLensControl(); + ICaptureControl getCaptureControl(); + ICameraButtonControl getButtonControl(); + IDisplayInjector getDisplayInjector(); + + ICameraStatus getCameraStatusListHolder(); + ICameraStatusWatcher getCameraStatusWatcher(); + IPlaybackControl getPlaybackControl(); + + ICameraHardwareStatus getHardwareStatus(); + ICameraRunMode getCameraRunMode(); +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/operation/OlympusPenCameraPowerOff.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/operation/OlympusPenCameraPowerOff.java new file mode 100644 index 0000000..f807c09 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/operation/OlympusPenCameraPowerOff.java @@ -0,0 +1,81 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.operation; + + +import android.content.Context; + +import net.osdn.gokigen.pkremote.R; +import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor; +import net.osdn.gokigen.pkremote.scene.ConfirmationDialog; +import net.osdn.gokigen.pkremote.scene.IChangeScene; + +import androidx.preference.Preference; + +/** + * Preferenceがクリックされた時に処理するクラス + * + */ +public class OlympusPenCameraPowerOff implements Preference.OnPreferenceClickListener, ConfirmationDialog.Callback +{ + private final Context context; + private final IChangeScene changeScene; + private String preferenceKey = null; + + /** + * コンストラクタ + * + */ + public OlympusPenCameraPowerOff(Context context, IChangeScene changeScene) + { + this.context = context; + this.changeScene = changeScene; + } + + /** + * クラスの準備 + * + */ + public void prepare() + { + // 何もしない + } + + /** + * + * + * @param preference クリックしたpreference + * @return false : ハンドルしない / true : ハンドルした + */ + @Override + public boolean onPreferenceClick(Preference preference) + { + if (!preference.hasKey()) + { + return (false); + } + + preferenceKey = preference.getKey(); + if (preferenceKey.contains(IPreferencePropertyAccessor.EXIT_APPLICATION)) + { + + // 確認ダイアログの生成と表示 + ConfirmationDialog dialog = ConfirmationDialog.newInstance(context); + dialog.show(R.string.dialog_title_confirmation, R.string.dialog_message_power_off, this); + return (true); + } + return (false); + } + + /** + * + * + */ + @Override + public void confirm() + { + if (preferenceKey.contains(IPreferencePropertyAccessor.EXIT_APPLICATION)) + { + // カメラの電源をOFFにしたうえで、アプリケーションを終了する。 + changeScene.exitApplication(); + } + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/OlympusPenInterfaceProvider.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/OlympusPenInterfaceProvider.java new file mode 100644 index 0000000..8c04a20 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/OlympusPenInterfaceProvider.java @@ -0,0 +1,193 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper; + +import android.app.Activity; +import android.content.SharedPreferences; + +import android.util.Log; + +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraButtonControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraRunMode; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICaptureControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IFocusingControl; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IFocusingModeNotify; +import net.osdn.gokigen.pkremote.camera.interfaces.control.IZoomLensControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.IAutoFocusFrameDisplay; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.IDisplayInjector; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.IIndicatorControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ILiveViewControl; +import net.osdn.gokigen.pkremote.camera.interfaces.liveview.ILiveViewListener; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IPlaybackControl; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraHardwareStatus; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraInformation; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatus; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusReceiver; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusWatcher; +import net.osdn.gokigen.pkremote.camera.vendor.olympuspen.IOlympusPenInterfaceProvider; +import net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.connection.OlympusPenConnection; +import net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.hardware.OlympusPenButtonControl; +import net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.hardware.OlympusPenHardwareStatus; +import net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.playback.OlympusPenPlaybackControl; +import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor; + +import androidx.annotation.NonNull; +import androidx.preference.PreferenceManager; + +/** + * + * + */ +public class OlympusPenInterfaceProvider implements IOlympusPenInterfaceProvider, IDisplayInjector +{ + private final String TAG = toString(); + //private final Activity activity; + //private final ICameraStatusReceiver provider; + private final OlympusPenConnection olympusPenConnection; + private final OlympusPenButtonControl buttonControl; + private final OlympusPenPlaybackControl playbackControl; + private final OlympusPenHardwareStatus hardwareStatus; + private final OlympusPenRunMode runMode; + + /** + * + * + */ + public OlympusPenInterfaceProvider(@NonNull Activity context, @NonNull ICameraStatusReceiver provider) + { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + //useGrCommand = preferences.getBoolean(IPreferencePropertyAccessor.USE_GR2_SPECIAL_COMMAND, true); + //pentaxCaptureAfterAf = preferences.getBoolean(IPreferencePropertyAccessor.PENTAX_CAPTURE_AFTER_AF, false); + int communicationTimeoutMs = 10000; // デフォルトは 10000ms とする + try + { + communicationTimeoutMs = Integer.parseInt(preferences.getString(IPreferencePropertyAccessor.RICOH_GET_PICS_LIST_TIMEOUT, IPreferencePropertyAccessor.RICOH_GET_PICS_LIST_TIMEOUT_DEFAULT_VALUE)) * 1000; + if (communicationTimeoutMs < 3000) + { + communicationTimeoutMs = 3000; // 最小値は 3000msとする。 + } + } + catch (Exception e) + { + e.printStackTrace(); + } + int maxCount = 3000; // デフォルトは 3000枚 とする + try + { + maxCount = Integer.parseInt(preferences.getString(IPreferencePropertyAccessor.RICOH_GET_PICS_LIST_MAX_COUNT, IPreferencePropertyAccessor.RICOH_GET_PICS_LIST_MAX_COUNT_DEFAULT_VALUE)); + if (maxCount < 300) + { + maxCount = 300; // 最小値は 300枚とする。 + } + } + catch (Exception e) + { + e.printStackTrace(); + } + + //this.activity = context; + //this.provider = provider; + olympusPenConnection = new OlympusPenConnection(context, provider); + //liveViewControl = new RicohGr2LiveViewControl(useGrCommand); + //zoomControl = new RicohGr2CameraZoomLensControl(); + buttonControl = new OlympusPenButtonControl(); + //statusChecker = new RicohGr2StatusChecker(500, useGrCommand); + playbackControl = new OlympusPenPlaybackControl(communicationTimeoutMs); + hardwareStatus = new OlympusPenHardwareStatus(); + runMode = new OlympusPenRunMode(); + } + + public void prepare() + { + Log.v(TAG, "prepare()"); + } + + @Override + public void injectDisplay(IAutoFocusFrameDisplay frameDisplayer, IIndicatorControl indicator, IFocusingModeNotify focusingModeNotify) + { + Log.v(TAG, "injectDisplay()"); + //focusControl = new RicohGr2CameraFocusControl(useGrCommand, frameDisplayer, indicator); + //captureControl = new RicohGr2CameraCaptureControl(useGrCommand, pentaxCaptureAfterAf, frameDisplayer, statusChecker); + } + + @Override + public ICameraConnection getOlyCameraConnection() + { + return (olympusPenConnection); + } + + @Override + public ILiveViewControl getLiveViewControl() + { + return (null); + } + + @Override + public ILiveViewListener getLiveViewListener() + { + return (null); + } + + @Override + public IFocusingControl getFocusingControl() + { + return (null); + } + + @Override + public ICameraInformation getCameraInformation() + { + return (null); + } + + @Override + public IZoomLensControl getZoomLensControl() + { + return (null); + } + + @Override + public ICaptureControl getCaptureControl() + { + return (null); + } + + @Override + public IDisplayInjector getDisplayInjector() { + return (this); + } + + @Override + public ICameraStatus getCameraStatusListHolder() + { + return (null); + } + + @Override + public ICameraButtonControl getButtonControl() + { + return (buttonControl); + } + + @Override + public ICameraStatusWatcher getCameraStatusWatcher() { + return (null); + } + + @Override + public IPlaybackControl getPlaybackControl() + { + return (playbackControl); + } + + @Override + public ICameraHardwareStatus getHardwareStatus() + { + return (hardwareStatus); + } + + @Override + public ICameraRunMode getCameraRunMode() + { + return (runMode); + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/OlympusPenRunMode.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/OlympusPenRunMode.java new file mode 100644 index 0000000..395385e --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/OlympusPenRunMode.java @@ -0,0 +1,20 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper; + +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraRunMode; + +public class OlympusPenRunMode implements ICameraRunMode +{ + @Override + public void changeRunMode(boolean isRecording) + { + + + + } + + @Override + public boolean isRecordingMode() + { + return (true); + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenCameraConnectSequence.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenCameraConnectSequence.java new file mode 100644 index 0000000..4a8182a --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenCameraConnectSequence.java @@ -0,0 +1,115 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.connection; + +import android.app.Activity; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +import net.osdn.gokigen.pkremote.R; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusReceiver; +import net.osdn.gokigen.pkremote.camera.utils.SimpleHttpClient; +import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor; + +import androidx.annotation.NonNull; + +class OlympusPenCameraConnectSequence implements Runnable +{ + private final String TAG = this.toString(); + private final Activity context; + private final ICameraConnection cameraConnection; + private final ICameraStatusReceiver cameraStatusReceiver; + + OlympusPenCameraConnectSequence(@NonNull Activity context, @NonNull ICameraStatusReceiver statusReceiver, @NonNull final ICameraConnection cameraConnection) + { + Log.v(TAG, "OlympusPenCameraConnectSequence"); + this.context = context; + this.cameraConnection = cameraConnection; + this.cameraStatusReceiver = statusReceiver; + } + + @Override + public void run() + { + final String areYouThereUrl = "http://192.168.0.1/v1/ping"; + final String grCommandUrl = "http://192.168.0.1/_gr"; + final int TIMEOUT_MS = 5000; + try + { + String response = SimpleHttpClient.httpGet(areYouThereUrl, TIMEOUT_MS); + Log.v(TAG, areYouThereUrl + " " + response); + if (response.length() > 0) + { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + + // 接続時、レンズロックOFF + { + final String postData = "cmd=acclock off"; + String response0 = SimpleHttpClient.httpPost(grCommandUrl, postData, TIMEOUT_MS); + Log.v(TAG, grCommandUrl + " " + response0); + } + + // 接続時、カメラの画面を消す + if (preferences.getBoolean(IPreferencePropertyAccessor.GR2_LCD_SLEEP, false)) + { + final String postData = "cmd=lcd sleep on"; + String response0 = SimpleHttpClient.httpPost(grCommandUrl, postData, TIMEOUT_MS); + Log.v(TAG, grCommandUrl + " " + response0); + } + onConnectNotify(); + } + else + { + onConnectError(context.getString(R.string.camera_not_found)); + } + } + catch (Exception e) + { + e.printStackTrace(); + onConnectError(e.getLocalizedMessage()); + } + } + + private void onConnectNotify() + { + try + { + final Thread thread = new Thread(new Runnable() + { + @Override + public void run() + { + // カメラとの接続確立を通知する + cameraStatusReceiver.onStatusNotify(context.getString(R.string.connect_connected)); + cameraStatusReceiver.onCameraConnected(); + Log.v(TAG, "onConnectNotify()"); + } + }); + thread.start(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + +/* + private void waitForAMoment(long mills) + { + if (mills > 0) + { + try { + Log.v(TAG, " WAIT " + mills + "ms"); + Thread.sleep(mills); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +*/ + + private void onConnectError(String reason) + { + cameraConnection.alertConnectingFailed(reason); + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenCameraDisconnectSequence.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenCameraDisconnectSequence.java new file mode 100644 index 0000000..3402c11 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenCameraDisconnectSequence.java @@ -0,0 +1,53 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.connection; + +import android.app.Activity; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +import net.osdn.gokigen.pkremote.camera.utils.SimpleHttpClient; +import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor; + +public class OlympusPenCameraDisconnectSequence implements Runnable +{ + private final String TAG = this.toString(); + private final Activity activity; + private final boolean powerOff; + + OlympusPenCameraDisconnectSequence(Activity activity, boolean isOff) + { + this.activity = activity; + this.powerOff = isOff; + } + + @Override + public void run() + { + // カメラをPowerOffして接続を切る + try + { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); + if (preferences.getBoolean(IPreferencePropertyAccessor.GR2_LCD_SLEEP, false)) + { + final String screenOnUrl = "http://192.168.0.1/_gr"; + final String postData = "lcd sleep off"; + final int TIMEOUT_MS = 5000; + String response = SimpleHttpClient.httpPost(screenOnUrl, postData, TIMEOUT_MS); + Log.v(TAG, screenOnUrl + " " + response); + } + + if (powerOff) + { + final String cameraPowerOffUrl = "http://192.168.0.1/v1/device/finish"; + final String postData = ""; + final int TIMEOUT_MS = 5000; + String response = SimpleHttpClient.httpPost(cameraPowerOffUrl, postData, TIMEOUT_MS); + Log.v(TAG, cameraPowerOffUrl + " " + response); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenConnection.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenConnection.java new file mode 100644 index 0000000..03b25b3 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/connection/OlympusPenConnection.java @@ -0,0 +1,278 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.connection; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.provider.Settings; + +import android.util.Log; + +import net.osdn.gokigen.pkremote.R; +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraConnection; +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusReceiver; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AlertDialog; + + +/** + * + * + */ +public class OlympusPenConnection implements ICameraConnection +{ + private final String TAG = toString(); + private final Activity context; + private final ICameraStatusReceiver statusReceiver; + private final BroadcastReceiver connectionReceiver; + //private final ConnectivityManager connectivityManager; + private final Executor cameraExecutor = Executors.newFixedThreadPool(1); + //private final Handler networkConnectionTimeoutHandler; + //private static final int MESSAGE_CONNECTIVITY_TIMEOUT = 1; + private CameraConnectionStatus connectionStatus = CameraConnectionStatus.UNKNOWN; + + + /** + * + * + */ + public OlympusPenConnection(@NonNull final Activity context, @NonNull final ICameraStatusReceiver statusReceiver) + { + Log.v(TAG, "OlympusPenConnection()"); + this.context = context; + this.statusReceiver = statusReceiver; + connectionReceiver = new BroadcastReceiver() + { + @Override + public void onReceive(Context context, Intent intent) + { + onReceiveBroadcastOfConnection(context, intent); + } + }; + } + + /** + * + * + */ + private void onReceiveBroadcastOfConnection(Context context, Intent intent) + { + statusReceiver.onStatusNotify(context.getString(R.string.connect_check_wifi)); + Log.v(TAG,context.getString(R.string.connect_check_wifi)); + + String action = intent.getAction(); + if (action == null) + { + // + Log.v(TAG, "intent.getAction() : null"); + return; + } + + try + { + if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) + { + Log.v(TAG, "onReceiveBroadcastOfConnection() : CONNECTIVITY_ACTION"); + + WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + if (wifiManager != null) { + WifiInfo info = wifiManager.getConnectionInfo(); + if (wifiManager.isWifiEnabled() && info != null) + { + if (info.getNetworkId() != -1) + { + Log.v(TAG, "Network ID is -1, there is no currently connected network."); + } + // 自動接続が指示されていた場合は、カメラとの接続処理を行う + connectToCamera(); + } else { + if (info == null) + { + Log.v(TAG, "NETWORK INFO IS NULL."); + } else { + Log.v(TAG, "isWifiEnabled : " + wifiManager.isWifiEnabled() + " NetworkId : " + info.getNetworkId()); + } + } + } + } + } + catch (Exception e) + { + Log.w(TAG, "onReceiveBroadcastOfConnection() EXCEPTION" + e.getMessage()); + e.printStackTrace(); + } + } + + /** + * + * + */ + @Override + public void startWatchWifiStatus(Context context) + { + Log.v(TAG, "startWatchWifiStatus()"); + statusReceiver.onStatusNotify("prepare"); + + IntentFilter filter = new IntentFilter(); + filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + context.registerReceiver(connectionReceiver, filter); + } + + /** + * + * + */ + @Override + public void stopWatchWifiStatus(Context context) + { + Log.v(TAG, "stopWatchWifiStatus()"); + context.unregisterReceiver(connectionReceiver); + disconnect(false); + } + + /** + * + * + */ + @Override + public void disconnect(boolean powerOff) + { + Log.v(TAG, "disconnect()"); + disconnectFromCamera(powerOff); + connectionStatus = CameraConnectionStatus.DISCONNECTED; + statusReceiver.onCameraDisconnected(); + } + + + /** + * + * + */ + @Override + public void connect() + { + Log.v(TAG, "connect()"); + connectToCamera(); + } + + + /** + * + * + */ + @Override + public void alertConnectingFailed(String message) + { + Log.v(TAG, "alertConnectingFailed() : " + message); + final AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setTitle(context.getString(R.string.dialog_title_connect_failed_ricoh)) + .setMessage(message) + .setPositiveButton(context.getString(R.string.dialog_title_button_retry), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) + { + connect(); + } + }) + .setNeutralButton(R.string.dialog_title_button_network_settings, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) + { + try + { + // Wifi 設定画面を表示する + context.startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); + } + catch (android.content.ActivityNotFoundException ex) + { + // Activity が存在しなかった...設定画面が起動できなかった + Log.v(TAG, "android.content.ActivityNotFoundException..."); + + // この場合は、再試行と等価な動きとする + connect(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + }); + context.runOnUiThread(new Runnable() + { + @Override + public void run() + { + try + { + builder.show(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + }); + } + + @Override + public CameraConnectionStatus getConnectionStatus() + { + Log.v(TAG, "getConnectionStatus()"); + return (connectionStatus); + } + + /** + * + * + */ + @Override + public void forceUpdateConnectionStatus(CameraConnectionStatus status) + { + Log.v(TAG, "forceUpdateConnectionStatus()"); + connectionStatus = status; + } + + /** + * カメラとの切断処理 + */ + private void disconnectFromCamera(final boolean powerOff) + { + Log.v(TAG, "disconnectFromCamera()"); + try + { + cameraExecutor.execute(new OlympusPenCameraDisconnectSequence(context, powerOff)); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * カメラとの接続処理 + */ + private void connectToCamera() + { + Log.v(TAG, "connectToCamera()"); + connectionStatus = CameraConnectionStatus.CONNECTING; + try + { + cameraExecutor.execute(new OlympusPenCameraConnectSequence(context, statusReceiver, this)); + } + catch (Exception e) + { + Log.v(TAG, "connectToCamera() EXCEPTION : " + e.getMessage()); + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/hardware/OlympusPenButtonControl.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/hardware/OlympusPenButtonControl.java new file mode 100644 index 0000000..ede6f6d --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/hardware/OlympusPenButtonControl.java @@ -0,0 +1,13 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.hardware; + +import net.osdn.gokigen.pkremote.camera.interfaces.control.ICameraButtonControl; + +public class OlympusPenButtonControl implements ICameraButtonControl +{ + + @Override + public boolean pushedButton(String code, boolean isLongPress) + { + return (false); + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/hardware/OlympusPenHardwareStatus.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/hardware/OlympusPenHardwareStatus.java new file mode 100644 index 0000000..8e2ffe1 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/hardware/OlympusPenHardwareStatus.java @@ -0,0 +1,51 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.hardware; + +import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraHardwareStatus; + +import java.util.Map; + +public class OlympusPenHardwareStatus implements ICameraHardwareStatus +{ + @Override + public boolean isAvailableHardwareStatus() + { + return (false); + } + + @Override + public String getLensMountStatus() + { + return (null); + } + + @Override + public String getMediaMountStatus() + { + return (null); + } + + @Override + public float getMinimumFocalLength() + { + return (0); + } + + @Override + public float getMaximumFocalLength() + { + return (0); + } + + @Override + public float getActualFocalLength() + { + return (0); + } + + @Override + public Map inquireHardwareInformation() + { + return (null); + } + +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/playback/OlympusPenPlaybackControl.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/playback/OlympusPenPlaybackControl.java new file mode 100644 index 0000000..e6e77b5 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/olympuspen/wrapper/playback/OlympusPenPlaybackControl.java @@ -0,0 +1,464 @@ +package net.osdn.gokigen.pkremote.camera.vendor.olympuspen.wrapper.playback; +import android.graphics.Bitmap; +import android.util.Log; + +import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentListCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraFileInfo; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IContentInfoCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentListCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadThumbnailImageCallback; +import net.osdn.gokigen.pkremote.camera.interfaces.playback.IPlaybackControl; +import net.osdn.gokigen.pkremote.camera.playback.CameraContentInfo; +import net.osdn.gokigen.pkremote.camera.playback.CameraFileInfo; +import net.osdn.gokigen.pkremote.camera.playback.ProgressEvent; +import net.osdn.gokigen.pkremote.camera.utils.SimpleHttpClient; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; + +import androidx.annotation.NonNull; + +/** + * + * + */ +public class OlympusPenPlaybackControl implements IPlaybackControl +{ + private final String TAG = toString(); + private final String getPhotoUrl = "http://192.168.0.1/v1/photos/"; + private static final int DEFAULT_TIMEOUT = 3000; + private final int timeoutValue; + + public OlympusPenPlaybackControl(int timeoutMs) + { + this.timeoutValue = (timeoutMs < DEFAULT_TIMEOUT) ? DEFAULT_TIMEOUT : timeoutMs; + } + + @Override + public String getRawFileSuffix() + { + return (".ORF"); + } + + @Override + public void downloadContentList(@NonNull IDownloadContentListCallback callback) + { + List fileList = new ArrayList<>(); + String imageListurl = "http://192.168.0.1/v1/photos?";// + maxCount; + String contentList; + try + { + contentList = SimpleHttpClient.httpGet(imageListurl, timeoutValue); + if (contentList == null) + { + // ぬるぽ発行 + callback.onErrorOccurred(new NullPointerException()); + return; + } + } + catch (Exception e) + { + // 例外をそのまま転送 + callback.onErrorOccurred(e); + return; + } + try + { + JSONArray dirsArray = new JSONObject(contentList).getJSONArray("dirs"); + if (dirsArray != null) + { + int size = dirsArray.length(); + for (int index = 0; index < size; index++) + { + JSONObject object = dirsArray.getJSONObject(index); + String dirName = object.getString("name"); + JSONArray filesArray = object.getJSONArray("files"); + int nofFiles = filesArray.length(); + for (int fileIndex = 0; fileIndex < nofFiles; fileIndex++) + { + String fileName = filesArray.getString(fileIndex); + fileList.add(new CameraFileInfo(dirName, fileName)); + } + } + } + } + catch (Exception e) + { + callback.onErrorOccurred(e); + return; + } + callback.onCompleted(fileList); + } + + @Override + public void updateCameraFileInfo(ICameraFileInfo info) + { + String url = getPhotoUrl + info.getDirectoryPath() + "/" + info.getFilename() + "/info"; + Log.v(TAG, "updateCameraFileInfo() GET URL : " + url); + try + { + String response = SimpleHttpClient.httpGet(url, timeoutValue); + if ((response == null)||(response.length() < 1)) + { + return; + } + JSONObject object = new JSONObject(response); + + // データを突っ込む + boolean captured = object.getBoolean("captured"); + String av = getJSONString(object, "av"); + String tv = getJSONString(object, "tv"); + String sv = getJSONString(object,"sv"); + String xv = getJSONString(object,"xv"); + int orientation = object.getInt("orientation"); + String aspectRatio = getJSONString(object,"aspectRatio"); + String cameraModel = getJSONString(object,"cameraModel"); + String latLng = getJSONString(object,"latlng"); + String dateTime = object.getString("datetime"); + info.updateValues(dateTime, av, tv, sv, xv, orientation, aspectRatio, cameraModel, latLng, captured); + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + private String getJSONString(JSONObject object, String key) + { + String value = ""; + try + { + value = object.getString(key); + } + catch (Exception e) + { + e.printStackTrace(); + } + return (value); + } + + @Override + public void getContentInfo(@NonNull String path, @NonNull String name, @NonNull IContentInfoCallback callback) + { + String url = getPhotoUrl + path + "/" + name + "/info"; + Log.v(TAG, "getContentInfo() GET URL : " + url); + try + { + String response = SimpleHttpClient.httpGet(url, timeoutValue); + if ((response == null)||(response.length() < 1)) + { + callback.onErrorOccurred(new NullPointerException()); + } + CameraFileInfo fileInfo = new CameraFileInfo(path, name); + + JSONObject object = new JSONObject(response); + + boolean captured = object.getBoolean("captured"); + String av = getJSONString(object, "av"); + String tv = getJSONString(object, "tv"); + String sv = getJSONString(object,"sv"); + String xv = getJSONString(object,"xv"); + int orientation = object.getInt("orientation"); + String aspectRatio = getJSONString(object,"aspectRatio"); + String cameraModel = getJSONString(object,"cameraModel"); + String latLng = getJSONString(object,"latlng"); + String dateTime = object.getString("datetime"); + fileInfo.updateValues(dateTime, av, tv, sv, xv, orientation, aspectRatio, cameraModel, latLng, captured); + + callback.onCompleted(fileInfo); + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + @Override + public void downloadContentScreennail(@NonNull String path, @NonNull IDownloadThumbnailImageCallback callback) + { + //Log.v(TAG, "downloadContentScreennail() : " + path); + String suffix = "?size=view"; + String url = getPhotoUrl + path + suffix; + Log.v(TAG, "downloadContentScreennail() GET URL : " + url); + try + { + Bitmap bmp = SimpleHttpClient.httpGetBitmap(url, timeoutValue); + HashMap map = new HashMap<>(); + map.put("Orientation", 0); + callback.onCompleted(bmp, map); + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + @Override + public void downloadContentThumbnail(@NonNull String path, @NonNull IDownloadThumbnailImageCallback callback) + { + //Log.v(TAG, "downloadContentThumbnail() : " + path); + String suffix = "?size=view"; + if (path.contains(".JPG")) + { + suffix = "?size=thumb"; + } + String url = getPhotoUrl + path + suffix; + Log.v(TAG, "downloadContentThumbnail() GET URL : " + url); + try + { + Bitmap bmp = SimpleHttpClient.httpGetBitmap(url, timeoutValue); + HashMap map = new HashMap<>(); + map.put("Orientation", 0); + callback.onCompleted(bmp, map); + } + catch (Throwable e) + { + e.printStackTrace(); + callback.onErrorOccurred(new NullPointerException()); + } + } + + @Override + public void downloadContent(@NonNull String path, boolean isSmallSize, @NonNull final IDownloadContentCallback callback) + { + Log.v(TAG, "downloadContent() : " + path); + String suffix = "?size=full"; + if (isSmallSize) + { + suffix = "?size=view"; + } + String url = getPhotoUrl + path + suffix; + Log.v(TAG, "downloadContent() GET URL : " + url); + try + { + SimpleHttpClient.httpGetBytes(url, timeoutValue, new SimpleHttpClient.IReceivedMessageCallback() { + @Override + public void onCompleted() { + callback.onCompleted(); + } + + @Override + public void onErrorOccurred(Exception e) { + callback.onErrorOccurred(e); + } + + @Override + public void onReceive(int readBytes, int length, int size, byte[] data) { + float percent = (length == 0) ? 0.0f : ((float) readBytes / (float) length); + ProgressEvent event = new ProgressEvent(percent, null); + callback.onProgress(data, size, event); + } + }); + } + catch (Throwable e) + { + e.printStackTrace(); + } + } + + /** + * 撮影時刻は(個別に)取れるが、非常に遅い... + * + */ + private Date getCameraContentDate(@NonNull ICameraContent cameraContent) + { + // 各ファイルを個別に撮影時刻をとると、反応が悪すぎるので処理を抑止。 +/* + String fileInfo; + try + { + String imageInfoUrl = "http://192.168.0.1/v1/photos/" + cameraContent.getContentPath() + "/" + cameraContent.getContentName() + "/info?storage=" + cameraContent.getCardId(); + //Log.v(TAG, "getCameraContentDate() : " + imageInfoUrl); + fileInfo = SimpleHttpClient.httpGet(imageInfoUrl, DEFAULT_TIMEOUT); + if (fileInfo != null) + { + String datetime = new JSONObject(fileInfo).getString("datetime"); + SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US); // "yyyy-MM-dd'T'HH:mm:ssZ" + dateFormatter.setCalendar(new GregorianCalendar()); + return (dateFormatter.parse(datetime)); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + return (cameraContent.getCapturedDate()); +*/ + return (null); + } + + + /** + * カメラ内画像ファイルの取得処理... GRコマンドが失敗したらPENTAXコマンドを使う。 + * + */ + @Override + public void getCameraContentList(ICameraContentListCallback callback) + { + try + { +/* + if (useGrCommand) + { + getGrCameraContentListImpl(callback); + return; + } +*/ + } + catch (Exception e) + { + e.printStackTrace(); + } + getCameraContentListImpl(callback); + } + + @Override + public void showPictureStarted() + { + + } + + @Override + public void showPictureFinished() + { + + } + + /** + * RICOH GR2用のカメラ内画像ファイル一覧取得処理 + * (エラー発生時には、通常のPENTAX用のカメラ内画像ファイル一覧取得処理を使う) + * + */ + private void getGrCameraContentListImpl(ICameraContentListCallback callback) + { + List fileList = new ArrayList<>(); + String imageListurl = "http://192.168.0.1/_gr/objs"; + String contentList; + + // try ~ catch でくくらない ... だめだったら PENTAXのシーケンスに入るようにしたいので + contentList = SimpleHttpClient.httpGet(imageListurl, timeoutValue); + if (contentList == null) + { + // ぬるぽ発行 + throw (new NullPointerException()); + } + + try + { + String cameraId = ""; //statusChecker.getCameraId(); + JSONArray dirsArray = new JSONObject(contentList).getJSONArray("dirs"); + if (dirsArray != null) + { + int size = dirsArray.length(); + for (int index = 0; index < size; index++) + { + JSONObject object = dirsArray.getJSONObject(index); + String dirName = object.getString("name"); + JSONArray filesArray = object.getJSONArray("files"); + int nofFiles = filesArray.length(); + for (int fileIndex = 0; fileIndex < nofFiles; fileIndex++) + { + JSONObject fileObject = filesArray.getJSONObject(fileIndex); + String fileName = fileObject.getString("n"); + String dateString = fileObject.getString("d"); + Date capturedDate = new Date(2001, 1, 1); + if (dateString != null) + { + SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US); // "yyyy-MM-dd'T'HH:mm:ssZ" + dateFormatter.setCalendar(new GregorianCalendar()); + capturedDate = dateFormatter.parse(dateString); + } + ICameraContent cameraContent = new CameraContentInfo(cameraId, "sd1", dirName, fileName, capturedDate); + fileList.add(cameraContent); + } + } + } + } + catch (Exception e) + { + // ぬるぽ発行 + throw (new NullPointerException()); + } + callback.onCompleted(fileList); + } + + private void getCameraContentListImpl(ICameraContentListCallback callback) + { + List fileList = new ArrayList<>(); + String imageListurl = "http://192.168.0.1/v1/photos?limit=";// + maxCount; + String contentList; + try + { + contentList = SimpleHttpClient.httpGet(imageListurl, timeoutValue); + if (contentList == null) + { + // ぬるぽ発行 + callback.onErrorOccurred(new NullPointerException()); + return; + } + } + catch (Exception e) + { + // 例外をそのまま転送 + callback.onErrorOccurred(e); + return; + } + try + { + Log.v(TAG, "PHOTO LIST RECV: [" + contentList.length() + "]"); + String cameraId = "";//statusChecker.getCameraId(); + JSONArray dirsArray = new JSONObject(contentList).getJSONArray("dirs"); + if (dirsArray != null) + { + int size = dirsArray.length(); + Log.v(TAG, "DIRECTORIES : " + size); + for (int index = 0; index < size; index++) + { + JSONObject object = dirsArray.getJSONObject(index); + String dirName = object.getString("name"); + JSONArray filesArray = object.getJSONArray("files"); + int nofFiles = filesArray.length(); + Log.v(TAG, "FILES : [" + dirName + "] " + nofFiles); + for (int fileIndex = 0; fileIndex < nofFiles; fileIndex++) + { + String fileName = filesArray.getString(fileIndex); + //Log.v(TAG, "FILE : " + fileName); + ICameraContent cameraContent = new CameraContentInfo(cameraId, "sd1", dirName, fileName, null); + Date capturedDate = getCameraContentDate(cameraContent); + if (capturedDate != null) + { + cameraContent.setCapturedDate(capturedDate); + } + fileList.add(cameraContent); + } + } + } + else + { + Log.v(TAG, "NOT FOUND dirs array."); + } + } + catch (Exception e) + { + e.printStackTrace(); + try { + fileList.clear(); + } + catch (Exception ee) + { + ee.printStackTrace(); + } + } + callback.onCompleted(fileList); + } +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/PtpIpRunMode.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/PtpIpRunMode.java index 903dead..06a01d3 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/PtpIpRunMode.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/PtpIpRunMode.java @@ -11,7 +11,7 @@ public class PtpIpRunMode implements ICameraRunMode, IPtpIpRunModeHolder private boolean isChanging = false; private boolean isRecordingMode = false; - PtpIpRunMode() + public PtpIpRunMode() { // } diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpFullImageReceiver.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpFullImageReceiver.java index bfa7ca2..cc8d5e0 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpFullImageReceiver.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpFullImageReceiver.java @@ -31,13 +31,13 @@ public class PtpIpFullImageReceiver implements IPtpIpCommandCallback private int target_image_size = 0; private boolean receivedFirstData = false; - PtpIpFullImageReceiver(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher publisher) + public PtpIpFullImageReceiver(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher publisher) { this.activity = activity; this.publisher = publisher; } - void issueCommand(int objectId, int imageSize, IDownloadContentCallback callback) + public void issueCommand(int objectId, int imageSize, IDownloadContentCallback callback) { if (this.objectId != 0) { diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpImageContentInfo.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpImageContentInfo.java index ced1e30..923b16c 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpImageContentInfo.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpImageContentInfo.java @@ -17,7 +17,7 @@ public class PtpIpImageContentInfo implements ICameraContent private Date date; private final byte[] rx_body; - PtpIpImageContentInfo(int indexNumber, String contentPath, byte[] binaryData, int offset, int length) + public PtpIpImageContentInfo(int indexNumber, String contentPath, byte[] binaryData, int offset, int length) { this.indexNumber = indexNumber; this.contentPath = contentPath; @@ -111,7 +111,7 @@ public class PtpIpImageContentInfo implements ICameraContent return (indexNumber); } - int getOriginalSize() + public int getOriginalSize() { try { diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpScreennailImageReceiver.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpScreennailImageReceiver.java index fb9634c..ef5187b 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpScreennailImageReceiver.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpScreennailImageReceiver.java @@ -25,7 +25,7 @@ public class PtpIpScreennailImageReceiver implements IPtpIpCommandCallback private final IPtpIpCommandPublisher publisher; private final int objectId; - PtpIpScreennailImageReceiver(Activity activity, int objectId, IPtpIpCommandPublisher publisher, IDownloadThumbnailImageCallback callback) + public PtpIpScreennailImageReceiver(Activity activity, int objectId, IPtpIpCommandPublisher publisher, IDownloadThumbnailImageCallback callback) { this.activity = activity; this.callback = callback; diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpSmallImageReceiver.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpSmallImageReceiver.java index fd97087..dda5345 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpSmallImageReceiver.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpSmallImageReceiver.java @@ -33,14 +33,14 @@ public class PtpIpSmallImageReceiver implements IPtpIpCommandCallback private int received_total_bytes = 0; private int received_remain_bytes = 0; - PtpIpSmallImageReceiver(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher publisher) + public PtpIpSmallImageReceiver(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher publisher) { this.activity = activity; this.publisher = publisher; this.mine = this; } - void issueCommand(final int objectId, IDownloadContentCallback callback) + public void issueCommand(final int objectId, IDownloadContentCallback callback) { if (this.objectId != 0) { diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpThumbnailImageReceiver.java b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpThumbnailImageReceiver.java index 850d1ac..4b76c22 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpThumbnailImageReceiver.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/ptpip/wrapper/playback/PtpIpThumbnailImageReceiver.java @@ -23,7 +23,7 @@ public class PtpIpThumbnailImageReceiver implements IPtpIpCommandCallback private final Activity context; private final IDownloadThumbnailImageCallback callback; - PtpIpThumbnailImageReceiver(@NonNull Activity context, @NonNull IDownloadThumbnailImageCallback callback) + public PtpIpThumbnailImageReceiver(@NonNull Activity context, @NonNull IDownloadThumbnailImageCallback callback) { this.context = context; this.callback = callback; diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/preference/nikon/NikonPreferenceFragment.java b/app/src/main/java/net/osdn/gokigen/pkremote/preference/nikon/NikonPreferenceFragment.java index 88833c7..6037070 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/preference/nikon/NikonPreferenceFragment.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/preference/nikon/NikonPreferenceFragment.java @@ -167,9 +167,9 @@ public class NikonPreferenceFragment extends PreferenceFragmentCompat implement try { //super.onCreate(savedInstanceState); - addPreferencesFromResource(R.xml.preferences_fuji_x); + addPreferencesFromResource(R.xml.preferences_nikon); - ListPreference connectionMethod = (ListPreference) findPreference(IPreferencePropertyAccessor.CONNECTION_METHOD); + ListPreference connectionMethod =findPreference(IPreferencePropertyAccessor.CONNECTION_METHOD); connectionMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { @@ -246,7 +246,7 @@ public class NikonPreferenceFragment extends PreferenceFragmentCompat implement try { ListPreference pref; - pref = (ListPreference) findPreference(pref_key); + pref = findPreference(pref_key); String value = preferences.getString(key, defaultValue); if (pref != null) { @@ -271,7 +271,7 @@ public class NikonPreferenceFragment extends PreferenceFragmentCompat implement { try { - CheckBoxPreference pref = (CheckBoxPreference) findPreference(pref_key); + CheckBoxPreference pref = findPreference(pref_key); if (pref != null) { boolean value = preferences.getBoolean(key, defaultValue); pref.setChecked(value); diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/preference/olympuspen/OlympusPenPreferenceFragment.java b/app/src/main/java/net/osdn/gokigen/pkremote/preference/olympuspen/OlympusPenPreferenceFragment.java new file mode 100644 index 0000000..39450e6 --- /dev/null +++ b/app/src/main/java/net/osdn/gokigen/pkremote/preference/olympuspen/OlympusPenPreferenceFragment.java @@ -0,0 +1,313 @@ +package net.osdn.gokigen.pkremote.preference.olympuspen; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; + +import java.util.Map; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.FragmentActivity; +import androidx.preference.CheckBoxPreference; +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceManager; + +import net.osdn.gokigen.pkremote.R; +import net.osdn.gokigen.pkremote.camera.vendor.olympuspen.operation.OlympusPenCameraPowerOff; +import net.osdn.gokigen.pkremote.logcat.LogCatViewer; +import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor; +import net.osdn.gokigen.pkremote.scene.IChangeScene; + +/** + * + * + */ +public class OlympusPenPreferenceFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener +{ + private final String TAG = toString(); + private SharedPreferences preferences = null; + private OlympusPenCameraPowerOff powerOffController = null; + private LogCatViewer logCatViewer = null; + + /** + * + * + */ + public static OlympusPenPreferenceFragment newInstance(@NonNull AppCompatActivity context, @NonNull IChangeScene changeScene) + { + OlympusPenPreferenceFragment instance = new OlympusPenPreferenceFragment(); + instance.prepare(context, changeScene); + + // パラメータはBundleにまとめておく + Bundle arguments = new Bundle(); + //arguments.putString("title", title); + //arguments.putString("message", message); + instance.setArguments(arguments); + + return (instance); + } + + /** + * + * + */ + private void prepare(@NonNull AppCompatActivity context, @NonNull IChangeScene changeScene) + { + try + { + powerOffController = new OlympusPenCameraPowerOff(context, changeScene); + powerOffController.prepare(); + + logCatViewer = new LogCatViewer(changeScene); + logCatViewer.prepare(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * + * + */ + @Override + public void onAttach(Context activity) + { + super.onAttach(activity); + Log.v(TAG, "onAttach()"); + + try + { + // Preference をつかまえる + preferences = PreferenceManager.getDefaultSharedPreferences(activity); + + // Preference を初期設定する + initializePreferences(); + + preferences.registerOnSharedPreferenceChangeListener(this); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Preferenceの初期化... + * + */ + private void initializePreferences() + { + try + { + Map items = preferences.getAll(); + SharedPreferences.Editor editor = preferences.edit(); + + if (!items.containsKey(IPreferencePropertyAccessor.AUTO_CONNECT_TO_CAMERA)) { + editor.putBoolean(IPreferencePropertyAccessor.AUTO_CONNECT_TO_CAMERA, true); + } + if (!items.containsKey(IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW)) { + editor.putBoolean(IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW, true); + } + if (!items.containsKey(IPreferencePropertyAccessor.CONNECTION_METHOD)) { + editor.putString(IPreferencePropertyAccessor.CONNECTION_METHOD, IPreferencePropertyAccessor.CONNECTION_METHOD_DEFAULT_VALUE); + } + editor.apply(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * + * + */ + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) + { + Log.v(TAG, "onSharedPreferenceChanged() : " + key); + boolean value; + if (key != null) + { + switch (key) + { + case IPreferencePropertyAccessor.AUTO_CONNECT_TO_CAMERA: + value = preferences.getBoolean(key, true); + Log.v(TAG, " " + key + " , " + value); + break; + + case IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW: + value = preferences.getBoolean(key, true); + Log.v(TAG, " " + key + " , " + value); + break; + + default: + String strValue = preferences.getString(key, ""); + setListPreference(key, key, strValue); + break; + } + } + } + + /** + * + * + */ + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) + { + Log.v(TAG, "onCreatePreferences()"); + try + { + //super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.preferences_olympus); + + ListPreference connectionMethod = findPreference(IPreferencePropertyAccessor.CONNECTION_METHOD); + connectionMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + preference.setSummary(newValue + " "); + return (true); + } + }); + connectionMethod.setSummary(connectionMethod.getValue() + " "); + + findPreference("exit_application").setOnPreferenceClickListener(powerOffController); + findPreference("debug_info").setOnPreferenceClickListener(logCatViewer); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * + * + */ + @Override + public void onResume() + { + super.onResume(); + Log.v(TAG, "onResume() Start"); + + try + { + synchronizedProperty(); + } + catch (Exception e) + { + e.printStackTrace(); + } + + Log.v(TAG, "onResume() End"); + + } + + /** + * + * + */ + @Override + public void onPause() + { + super.onPause(); + Log.v(TAG, "onPause() Start"); + + try + { + // Preference変更のリスナを解除 + preferences.unregisterOnSharedPreferenceChangeListener(this); + } + catch (Exception e) + { + e.printStackTrace(); + } + + Log.v(TAG, "onPause() End"); + } + + /** + * ListPreference の表示データを設定 + * + * @param pref_key Preference(表示)のキー + * @param key Preference(データ)のキー + * @param defaultValue Preferenceのデフォルト値 + */ + private void setListPreference(String pref_key, String key, String defaultValue) + { + try + { + ListPreference pref; + pref = findPreference(pref_key); + String value = preferences.getString(key, defaultValue); + if (pref != null) + { + pref.setValue(value); + pref.setSummary(value); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * BooleanPreference の表示データを設定 + * + * @param pref_key Preference(表示)のキー + * @param key Preference(データ)のキー + * @param defaultValue Preferenceのデフォルト値 + */ + private void setBooleanPreference(String pref_key, String key, boolean defaultValue) + { + try + { + CheckBoxPreference pref = findPreference(pref_key); + if (pref != null) { + boolean value = preferences.getBoolean(key, defaultValue); + pref.setChecked(value); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * + * + */ + private void synchronizedProperty() + { + final FragmentActivity activity = getActivity(); + if (activity != null) + { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + try + { + // Preferenceの画面に反映させる + setBooleanPreference(IPreferencePropertyAccessor.AUTO_CONNECT_TO_CAMERA, IPreferencePropertyAccessor.AUTO_CONNECT_TO_CAMERA, true); + setBooleanPreference(IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW, IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW, true); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + }); + } + } + +} diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/scene/CameraSceneUpdater.java b/app/src/main/java/net/osdn/gokigen/pkremote/scene/CameraSceneUpdater.java index e1b79cc..a684bfa 100644 --- a/app/src/main/java/net/osdn/gokigen/pkremote/scene/CameraSceneUpdater.java +++ b/app/src/main/java/net/osdn/gokigen/pkremote/scene/CameraSceneUpdater.java @@ -19,6 +19,7 @@ import net.osdn.gokigen.pkremote.preference.canon.CanonPreferenceFragment; import net.osdn.gokigen.pkremote.preference.fujix.FujiXPreferenceFragment; import net.osdn.gokigen.pkremote.preference.nikon.NikonPreferenceFragment; import net.osdn.gokigen.pkremote.preference.olympus.OpcPreferenceFragment; +import net.osdn.gokigen.pkremote.preference.olympuspen.OlympusPenPreferenceFragment; import net.osdn.gokigen.pkremote.preference.panasonic.PanasonicPreferenceFragment; import net.osdn.gokigen.pkremote.preference.ricohgr2.RicohGr2PreferenceFragment; import net.osdn.gokigen.pkremote.preference.sony.SonyPreferenceFragment; @@ -330,6 +331,10 @@ public class CameraSceneUpdater implements ICameraStatusReceiver, IChangeScene, { preferenceFragment = NikonPreferenceFragment.newInstance(activity, this); } + else if (connectionMethod == ICameraConnection.CameraConnectionMethod.OLYMPUS) + { + preferenceFragment = OlympusPenPreferenceFragment.newInstance(activity, this); + } else // if (connectionMethod == ICameraConnection.CameraConnectionMethod.OPC) { preferenceFragment = OpcPreferenceFragment.newInstance(activity, interfaceProvider, this); diff --git a/app/src/main/res/values-ja/arrays.xml b/app/src/main/res/values-ja/arrays.xml index e8f1813..486eae7 100644 --- a/app/src/main/res/values-ja/arrays.xml +++ b/app/src/main/res/values-ja/arrays.xml @@ -7,6 +7,7 @@ Panasonic Sony Canon + Olympus(OM-D/PEN) @@ -19,6 +20,7 @@ PANASONIC SONY CANON + OLYMPUS diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 620e29e..3a58604 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -7,6 +7,7 @@ Panasonic Sony Canon + Olympus(OM-D/PEN) @@ -19,6 +20,7 @@ PANASONIC SONY CANON + OLYMPUS diff --git a/app/src/main/res/xml/preferences_olympus.xml b/app/src/main/res/xml/preferences_olympus.xml new file mode 100644 index 0000000..58394c3 --- /dev/null +++ b/app/src/main/res/xml/preferences_olympus.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- 2.11.0