OSDN Git Service

VisionKids 画像取得も作りこんだ。これで。
authorMRSa <mrsa@myad.jp>
Tue, 25 Jul 2023 14:11:15 +0000 (23:11 +0900)
committerMRSa <mrsa@myad.jp>
Tue, 25 Jul 2023 14:11:15 +0000 (23:11 +0900)
app/build.gradle
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/VisionKidsInterfaceProvider.kt
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/connection/IVisionKidsConnection.kt [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/connection/VisionKidsCameraDisconnectSequence.java
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/connection/VisionKidsConnection.java
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/playback/VisionKidsCameraContentProvider.kt
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/playback/VisionKidsCameraInfo.kt [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/playback/VisionKidsPlaybackControl.kt

index b8784ce..0e73118 100644 (file)
@@ -7,8 +7,8 @@ android {
         applicationId "net.osdn.gokigen.pkremote"
         minSdkVersion 14
         targetSdkVersion 34
-        versionCode 10804
-        versionName "1.8.4"
+        versionCode 10805
+        versionName "1.8.5"
         multiDexEnabled true
     }
     buildTypes {
index 601198d..c4ee164 100644 (file)
@@ -24,7 +24,7 @@ import net.osdn.gokigen.pkremote.camera.vendor.visionkids.wrapper.playback.Visio
 class VisionKidsInterfaceProvider(activity: AppCompatActivity, provider: ICameraStatusReceiver, informationReceiver: IInformationReceiver) : IVisionKidsInterfaceProvider, ICameraRunMode
 {
     private val playbackControl = VisionKidsPlaybackControl(activity, provider, informationReceiver)
-    private val cameraConnection = VisionKidsConnection(activity, provider)
+    private val cameraConnection = VisionKidsConnection(activity, provider, playbackControl)
     private val hardwareStatus = VisionKidsHardwareStatus()
 
     // IVisionKidsInterfaceProvider
diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/connection/IVisionKidsConnection.kt b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/connection/IVisionKidsConnection.kt
new file mode 100644 (file)
index 0000000..8879d92
--- /dev/null
@@ -0,0 +1,6 @@
+package net.osdn.gokigen.pkremote.camera.vendor.visionkids.wrapper.connection
+
+interface IVisionKidsConnection
+{
+    fun forceDisconnect()
+}
\ No newline at end of file
index eb289a6..e496a0a 100644 (file)
@@ -2,13 +2,16 @@ package net.osdn.gokigen.pkremote.camera.vendor.visionkids.wrapper.connection;
 
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+
 public class VisionKidsCameraDisconnectSequence implements Runnable
 {
     private final String TAG = this.toString();
+    private final IVisionKidsConnection connection;
 
-    VisionKidsCameraDisconnectSequence()
+    VisionKidsCameraDisconnectSequence(@NonNull final IVisionKidsConnection connection)
     {
-        // なにもしない
+        this.connection = connection;
     }
 
     @Override
@@ -16,5 +19,6 @@ public class VisionKidsCameraDisconnectSequence implements Runnable
     {
         // なにもしない(というかできない)
         Log.v(TAG, " Power off (VisionKids)");
+        connection.forceDisconnect();
     }
 }
index d27a09a..df512e8 100644 (file)
@@ -27,6 +27,7 @@ public class VisionKidsConnection implements ICameraConnection
     private final AppCompatActivity context;
     private final ICameraStatusReceiver statusReceiver;
     private final BroadcastReceiver connectionReceiver;
+    private final IVisionKidsConnection myConnection;
     private final Executor cameraExecutor = Executors.newFixedThreadPool(1);
     private CameraConnectionStatus connectionStatus = CameraConnectionStatus.UNKNOWN;
 
@@ -34,7 +35,7 @@ public class VisionKidsConnection implements ICameraConnection
      *
      *
      */
-    public VisionKidsConnection(@NonNull final AppCompatActivity context, @NonNull final ICameraStatusReceiver statusReceiver)
+    public VisionKidsConnection(@NonNull final AppCompatActivity context, @NonNull final ICameraStatusReceiver statusReceiver, @NonNull final IVisionKidsConnection myConnection)
     {
         Log.v(TAG, "VisionKidsConnection()");
         this.context = context;
@@ -47,6 +48,7 @@ public class VisionKidsConnection implements ICameraConnection
                 onReceiveBroadcastOfConnection(context, intent);
             }
         };
+        this.myConnection = myConnection;
     }
 
     /**
@@ -221,7 +223,7 @@ public class VisionKidsConnection implements ICameraConnection
         Log.v(TAG, "disconnectFromCamera()");
         try
         {
-            cameraExecutor.execute(new VisionKidsCameraDisconnectSequence());
+            cameraExecutor.execute(new VisionKidsCameraDisconnectSequence(myConnection));
         }
         catch (Exception e)
         {
index 03e8f31..374c25a 100644 (file)
@@ -14,6 +14,46 @@ class VisionKidsCameraContentProvider(context: AppCompatActivity) : IFtpServiceC
     private val cameraContentList = ArrayList<ICameraContent>()
     private lateinit var callback : ICameraContentListCallback
 
+    fun getCameraContent(name: String) : ICameraContent?
+    {
+        try
+        {
+            for (cameraContent in cameraContentList)
+            {
+                if (cameraContent.contentName == name)
+                {
+                    return (cameraContent)
+                }
+            }
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+        return (null)
+    }
+
+    fun forceDisconnect()
+    {
+        try
+        {
+            ftpClient.enqueueCommand(FtpCommand("quit", "QUIT\r\n"))
+            try
+            {
+                Thread.sleep(750)
+            }
+            catch (ee: Exception)
+            {
+                ee.printStackTrace()
+            }
+            ftpClient.disconnect()
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+    }
+
 
     fun getContentList(callback: ICameraContentListCallback)
     {
@@ -230,5 +270,4 @@ class VisionKidsCameraContentProvider(context: AppCompatActivity) : IFtpServiceC
     {
         private val TAG = VisionKidsCameraContentProvider::class.java.simpleName
     }
-
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/playback/VisionKidsCameraInfo.kt b/app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/visionkids/wrapper/playback/VisionKidsCameraInfo.kt
new file mode 100644 (file)
index 0000000..087584d
--- /dev/null
@@ -0,0 +1,32 @@
+package net.osdn.gokigen.pkremote.camera.vendor.visionkids.wrapper.playback
+
+import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraFileInfo
+import java.util.Date
+
+class VisionKidsCameraInfo(private val fileName: String, private val date: Date) : ICameraFileInfo
+{
+    override fun getDatetime(): Date { return (date) }
+    override fun getDirectoryPath(): String { return ("/") }
+    override fun getFilename(): String { return (fileName) }
+    override fun getAperature(): String { return ("") }
+    override fun getShutterSpeed(): String  { return ("") }
+    override fun getIsoSensitivity(): String { return ("") }
+    override fun getExpRev(): String { return ("") }
+    override fun getOrientation(): Int { return (0) }
+    override fun getAspectRatio(): String {return ("") }
+    override fun getModel(): String { return ("") }
+    override fun getLatLng(): String { return ("") }
+    override fun getCaptured(): Boolean { return (true) }
+    override fun updateValues(
+        dateTime: String?,
+        av: String?,
+        tv: String?,
+        sv: String?,
+        xv: String?,
+        orientation: Int,
+        aspectRatio: String?,
+        model: String?,
+        LatLng: String?,
+        captured: Boolean
+    ) { }
+}
index c5635eb..1c5dc70 100644 (file)
@@ -2,6 +2,7 @@ package net.osdn.gokigen.pkremote.camera.vendor.visionkids.wrapper.playback
 
 import android.util.Log
 import androidx.appcompat.app.AppCompatActivity
+import androidx.preference.PreferenceManager
 import net.osdn.gokigen.pkremote.IInformationReceiver
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentListCallback
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraFileInfo
@@ -11,10 +12,18 @@ import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentList
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadThumbnailImageCallback
 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IPlaybackControl
 import net.osdn.gokigen.pkremote.camera.interfaces.status.ICameraStatusReceiver
+import net.osdn.gokigen.pkremote.camera.playback.ProgressEvent
+import net.osdn.gokigen.pkremote.camera.utils.SimpleHttpClient
+import net.osdn.gokigen.pkremote.camera.utils.SimpleHttpClient.IReceivedMessageCallback
+import net.osdn.gokigen.pkremote.camera.vendor.visionkids.wrapper.connection.IVisionKidsConnection
+import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor
+import java.util.Date
 
-class VisionKidsPlaybackControl(activity: AppCompatActivity, private val provider: ICameraStatusReceiver, private val informationReceiver: IInformationReceiver): IPlaybackControl
+class VisionKidsPlaybackControl(activity: AppCompatActivity, private val provider: ICameraStatusReceiver, private val informationReceiver: IInformationReceiver, timeoutMs: Int = DEFAULT_TIMEOUT): IPlaybackControl, IVisionKidsConnection
 {
     private val contentProvider = VisionKidsCameraContentProvider(activity)
+    private val preferences = PreferenceManager.getDefaultSharedPreferences(activity)
+    private val timeoutValue = Math.max(DEFAULT_TIMEOUT, timeoutMs)
 
     override fun getRawFileSuffix(): String
     {
@@ -29,6 +38,28 @@ class VisionKidsPlaybackControl(activity: AppCompatActivity, private val provide
     override fun getContentInfo(path: String?, name: String?, callback: IContentInfoCallback?)
     {
         Log.v(TAG, "getContentInfo($path, $name)")
+        try
+        {
+            if (name == null)
+            {
+                callback?.onErrorOccurred(Exception())
+                return
+            }
+            val contentInfo = contentProvider.getCameraContent(name)
+            if (contentInfo != null)
+            {
+                callback?.onCompleted(VisionKidsCameraInfo(name, contentInfo.capturedDate))
+            }
+            else
+            {
+                callback?.onCompleted(VisionKidsCameraInfo(name, Date()))
+            }
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
+        return
     }
 
     override fun updateCameraFileInfo(info: ICameraFileInfo?)
@@ -36,26 +67,70 @@ class VisionKidsPlaybackControl(activity: AppCompatActivity, private val provide
         // 利用箇所なし
     }
 
-    override fun downloadContentScreennail(
-        path: String?,
-        callback: IDownloadThumbnailImageCallback?
-    ) {
-        Log.v(TAG, "downloadContentScreennail($path)")
+    override fun downloadContentScreennail(path: String?, callback: IDownloadThumbnailImageCallback?)
+    {
+        // サムネイルしか取得できないので統合する
+        downloadContentThumbnail(path, callback)
     }
 
-    override fun downloadContentThumbnail(
-        path: String?,
-        callback: IDownloadThumbnailImageCallback?
-    ) {
-        Log.v(TAG, "downloadContentThumbnail($path)")
+    override fun downloadContentThumbnail(path: String?, callback: IDownloadThumbnailImageCallback?)
+    {
+        try
+        {
+            val address = preferences.getString(IPreferencePropertyAccessor.VISIONKIDS_HOST_IP, IPreferencePropertyAccessor.VISIONKIDS_HOST_IP_DEFAULT_VALUE)?: IPreferencePropertyAccessor.VISIONKIDS_HOST_IP_DEFAULT_VALUE
+            val urlToGet = "http://$address/DCIM/T/$path".replace("//","/")
+            Log.v(TAG, "downloadContentThumbnail($path) : $urlToGet")
+
+            val bmp = SimpleHttpClient.httpGetBitmap(urlToGet, HashMap(), timeoutValue)
+            val map = HashMap<String, Any>()
+            map["Orientation"] = 0
+            callback?.onCompleted(bmp, map)
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+            callback?.onErrorOccurred(e)
+        }
     }
 
-    override fun downloadContent(
-        path: String?,
-        isSmallSize: Boolean,
-        callback: IDownloadContentCallback?
-    ) {
-        Log.v(TAG, "downloadContent($path, $isSmallSize)")
+    override fun downloadContent(path: String?, isSmallSize: Boolean, callback: IDownloadContentCallback?)
+    {
+        try
+        {
+            // 取得先URLを特定する
+            val dataType = if (isSmallSize) { "T" } else { "O" }
+            val address = preferences.getString(IPreferencePropertyAccessor.VISIONKIDS_HOST_IP, IPreferencePropertyAccessor.VISIONKIDS_HOST_IP_DEFAULT_VALUE)?: IPreferencePropertyAccessor.VISIONKIDS_HOST_IP_DEFAULT_VALUE
+            val urlToGet = "http://$address/DCIM/$dataType/$path".replace("//","/")
+            Log.v(TAG, "downloadContent($path, $isSmallSize) : $urlToGet")
+
+            // 画像データを取得する
+            try
+            {
+                SimpleHttpClient.httpGetBytes(urlToGet, HashMap(), timeoutValue,
+                    object : IReceivedMessageCallback {
+                        override fun onCompleted() {
+                            callback?.onCompleted()
+                        }
+                        override fun onErrorOccurred(e: java.lang.Exception) {
+                            callback?.onErrorOccurred(e)
+                        }
+                        override fun onReceive(readBytes: Int, length: Int, size: Int, data: ByteArray) {
+                            val percent = if (length == 0) 0.0f else readBytes.toFloat() / length.toFloat()
+                            val event = ProgressEvent(percent, null)
+                            callback?.onProgress(data, size, event)
+                        }
+                    })
+            }
+            catch (t: Throwable)
+            {
+                t.printStackTrace()
+                callback?.onErrorOccurred(NullPointerException())
+            }
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
     }
 
     override fun getCameraContentList(callback: ICameraContentListCallback)
@@ -80,8 +155,14 @@ class VisionKidsPlaybackControl(activity: AppCompatActivity, private val provide
     {
         Log.v(TAG, "showPictureFinished()")
     }
+
+    override fun forceDisconnect()
+    {
+        contentProvider.forceDisconnect()
+    }
     companion object
     {
         private val TAG = VisionKidsPlaybackControl::class.java.simpleName
+        private const val DEFAULT_TIMEOUT = 3000
     }
 }