OSDN Git Service

Ricoh Theta対応の V2.1対応。OSC V2対応?
authorMRSa <mrsa@myad.jp>
Sat, 18 Jan 2020 12:07:09 +0000 (21:07 +0900)
committerMRSa <mrsa@myad.jp>
Sat, 18 Jan 2020 12:07:09 +0000 (21:07 +0900)
app/src/main/java/net/osdn/gokigen/pkremote/camera/utils/SimpleHttpClient.java
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/theta/wrapper/connection/ThetaCameraConnectSequence.java
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/theta/wrapper/playback/ThetaCameraContent.java
app/src/main/java/net/osdn/gokigen/pkremote/camera/vendor/theta/wrapper/playback/ThetaPlaybackControl.java

index 7b1c078..d73ce3e 100644 (file)
@@ -581,6 +581,14 @@ public class SimpleHttpClient
             if (inputStream == null)
             {
                 Log.w(TAG, "http " + requestMethod + " : Response Code Error: " + responseCode + ": " + url);
+/*
+                inputStream = httpConn.getInputStream();
+                if (inputStream != null)
+                {
+                    // DUMP RESPONSE DETAIL
+                    Log.w(TAG, " RESP : " + readFromInputStream(inputStream));
+                }
+*/
                 return ("");
             }
         }
@@ -621,8 +629,52 @@ public class SimpleHttpClient
         }
 
         // 応答の読み出し
+        return (readFromInputStream(inputStream));
+/*
+        BufferedReader reader = null;
+        String replyString = "";
+        try
+        {
+            StringBuilder responseBuf = new StringBuilder();
+            reader = new BufferedReader(new InputStreamReader(inputStream));
+
+            int c;
+            while ((c = reader.read()) != -1)
+            {
+                responseBuf.append((char) c);
+            }
+            replyString = responseBuf.toString();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        finally
+        {
+            try
+            {
+                if (reader != null)
+                {
+                    reader.close();
+                }
+            }
+            catch (IOException e)
+            {
+                e.printStackTrace();
+            }
+        }
+        return (replyString);
+*/
+    }
+
+    private static String readFromInputStream(InputStream inputStream)
+    {
         BufferedReader reader = null;
         String replyString = "";
+        if (inputStream == null)
+        {
+            return ("");
+        }
         try
         {
             StringBuilder responseBuf = new StringBuilder();
@@ -656,6 +708,7 @@ public class SimpleHttpClient
         return (replyString);
     }
 
+
     public interface IReceivedMessageCallback
     {
         void onCompleted();
index dc404d2..cdd7a53 100644 (file)
@@ -1,14 +1,20 @@
 package net.osdn.gokigen.pkremote.camera.vendor.theta.wrapper.connection;
 
 import android.app.Activity;
+import android.content.SharedPreferences;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
 
 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 org.json.JSONArray;
+import org.json.JSONObject;
 
 /**
  *   Thetaとの接続シーケンス
@@ -32,25 +38,111 @@ public class ThetaCameraConnectSequence implements Runnable
     @Override
     public void run()
     {
-        final String oscInfoUrl = "http://192.168.1.1/osc/info";
+        try
+        {
+            final String oscInfoUrl = "http://192.168.1.1/osc/info";
+            final int TIMEOUT_MS = 5000;
+
+            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+            boolean useThetaV21 = preferences.getBoolean(IPreferencePropertyAccessor.USE_OSC_THETA_V21, false);
+
+            String response = SimpleHttpClient.httpGet(oscInfoUrl, TIMEOUT_MS);
+            Log.v(TAG, " " + oscInfoUrl + " " + response);
+            if (response.length() > 0)
+            {
+                try
+                {
+                    JSONArray apiLevelArray = new JSONObject(response).getJSONArray("apiLevel");
+                    int size = apiLevelArray.length();
+                    for (int index = 0; index < size; index++)
+                    {
+                        int api = apiLevelArray.getInt(index);
+                        if ((api == 2)&&(useThetaV21))
+                        {
+                            // API Level V2.1を使用して通信する
+                            connectApiV21();
+                            return;
+                        }
+                    }
+                }
+                catch (Exception e)
+                {
+                    e.printStackTrace();
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            // onConnectError(e.getLocalizedMessage());
+        }
+
+        // API Level V2 を使用して通信する
+        connectApiV2();
+    }
+
+    /**
+     *
+     */
+    private void connectApiV2()
+    {
         final String commandsExecuteUrl = "http://192.168.1.1/osc/commands/execute";
         final String startSessionData = "{\"name\":\"camera.startSession\",\"parameters\":{\"timeout\":0}}";
         final String getStateUrl = "http://192.168.1.1/osc/state";
+        final int TIMEOUT_MS = 2000;
 
+        try
+        {
+            String response = SimpleHttpClient.httpPost(commandsExecuteUrl, startSessionData, TIMEOUT_MS);
+            Log.v(TAG, " " + commandsExecuteUrl + " " + startSessionData + " " + response);
+
+            String response2 = SimpleHttpClient.httpPost(getStateUrl, "", TIMEOUT_MS);
+            Log.v(TAG, " " + getStateUrl + " " + response2);
+
+            onConnectNotify();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            onConnectError(e.getLocalizedMessage());
+        }
+    }
+
+    private void connectApiV21()
+    {
+        final String commandsExecuteUrl = "http://192.168.1.1/osc/commands/execute";
+        final String startSessionData = "{\"name\":\"camera.startSession\",\"parameters\":{\"timeout\":0}}";
+        final String getStateUrl = "http://192.168.1.1/osc/state";
         final int TIMEOUT_MS = 5000;
+
         try
         {
-            String response = SimpleHttpClient.httpGet(oscInfoUrl, TIMEOUT_MS);
-            Log.v(TAG, " " + oscInfoUrl + " " + response);
+            String responseS = SimpleHttpClient.httpPost(commandsExecuteUrl, startSessionData, TIMEOUT_MS);
+            Log.v(TAG, " " + commandsExecuteUrl + " " + startSessionData + " " + responseS);
+
+            String response = SimpleHttpClient.httpPost(getStateUrl, "", TIMEOUT_MS);
+            Log.v(TAG, " " + getStateUrl + " " + response);
             if (response.length() > 0)
             {
+                int apiLevel = 1;
+               JSONObject object = new JSONObject(response);
+               try
+               {
+                   apiLevel = object.getJSONObject("state").getInt("_apiVersion");
+               }
+               catch (Exception e)
+               {
+                   e.printStackTrace();
+               }
+               if (apiLevel != 2)
+               {
+                   JSONObject jsonObject = object.getJSONObject("state");
+                   String sessionId = jsonObject.getString("sessionId");
+                   String setApiLevelData = "{\"name\":\"camera.setOptions\",\"parameters\":{" + "\"sessionId\" : \"" + sessionId + "\", \"options\":{ \"clientVersion\":2}}}";
 
-                String response2 = SimpleHttpClient.httpPost(commandsExecuteUrl, startSessionData, TIMEOUT_MS);
-                Log.v(TAG, " " + commandsExecuteUrl + " " + startSessionData + " " + response2);
-
-                String response3 = SimpleHttpClient.httpPost(getStateUrl, "", TIMEOUT_MS);
-                Log.v(TAG, " " + getStateUrl + " " + response3);
-
+                   String response3 = SimpleHttpClient.httpPost(commandsExecuteUrl, setApiLevelData, TIMEOUT_MS);
+                   Log.v(TAG, " " + commandsExecuteUrl + " " + setApiLevelData + " " + response3);
+               }
                 onConnectNotify();
             }
             else
index 8f95ce9..688b347 100644 (file)
@@ -25,7 +25,7 @@ public class ThetaCameraContent implements ICameraContent
         this.url = url;
         this.size = size;
         this.date = date;
-        // Log.v(TAG, " [" + " " + "] " + name + " " + path + " (" + size + ") " + date + " " + url);
+        Log.v(TAG, " [" + " " + "] " + name + " " + path + " (" + size + ") " + date + " " + url);
     }
 
     @Override
@@ -68,10 +68,12 @@ public class ThetaCameraContent implements ICameraContent
     private String getContentPathFromUrl()
     {
         // データ内容 : "http://192.168.1.1/files/abcde/100RICOH/R0010032.JPG"
+        //Log.v(TAG, " URL : " + url);
         try
         {
-            int index = url.indexOf("/");
-            return (url.substring(0, index));
+            // http:// を削る
+            int index =  url.lastIndexOf("/");
+            return (url.substring(7, index));
         }
         catch (Exception e)
         {
index 1ab312a..c28479a 100644 (file)
@@ -3,6 +3,8 @@ package net.osdn.gokigen.pkremote.camera.vendor.theta.wrapper.playback;
 import android.app.Activity;
 import android.content.SharedPreferences;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Base64;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -114,16 +116,58 @@ public class ThetaPlaybackControl implements IPlaybackControl
 
     private void downloadContentThumbnailV21(String path, IDownloadThumbnailImageCallback callback)
     {
-        //  POST /osc/commands/execute
-        //  {"name":"camera.getImage","parameters":{"_type":"thumb","fileUri":"100RICOH/R0010093.JPG"}}
-        Log.v(TAG, "downloadContentThumbnail() : " + path);
+        //  fileContent の URLをそのまま使用する
+        Log.v(TAG, "downloadContentThumbnailV21() : " + path);
+        String paramData = null;
         try
         {
-            String url = "http://192.168.1.1/osc/commands/execute";
-            String postData = "{\"name\":\"camera.getImage\",\"parameters\":{\"_type\":\"thumb\",\"fileUri\":\"" + path + "\"}}";
-            Log.v(TAG, " postData : " + postData);
-
-            Bitmap bmp = SimpleHttpClient.httpPostBitmap(url, postData, timeoutValue);
+            String url = "http://" + path;
+            int index = 0;
+            for (ICameraContent content : cameraContentList)
+            {
+                String targetPath = content.getContentPath() + "/" + content.getContentName();
+                if (targetPath.equals(path))
+                {
+                    //Log.v(TAG, " MATCHED : (" + index + ") " + path);
+                    paramData = "{\"name\":\"camera.listFiles\",\"parameters\":{\"fileType\":\"all\",\"startPosition\": " + index + ",\"entryCount\":" + 1 + ",\"maxThumbSize\":640,\"_detail\":true, \"_sort\":\"newest\"}}";
+                    break;
+                }
+                index++;
+            }
+            //Log.v(TAG, " downloadContentThumbnailV21 : " + paramData);
+            Bitmap bmp = null; // SimpleHttpClient.httpGetBitmap(url, null, timeoutValue);
+            if (paramData != null)
+            {
+                try
+                {
+                    Log.v(TAG, " exec getFileList");
+                    String imageListurl = "http://192.168.1.1/osc/commands/execute";
+                    String contentList = SimpleHttpClient.httpPost(imageListurl, paramData, timeoutValue);
+                    if (contentList != null)
+                    {
+                        JSONObject resultsObject = new JSONObject(contentList).getJSONObject("results");
+                        JSONArray entriesArray = resultsObject.getJSONArray("entries");
+                        int size = entriesArray.length();
+                        if (size > 0)
+                        {
+                            JSONObject object = entriesArray.getJSONObject(0);
+                            String fileName = object.getString("name");
+                            //String fileUri = object.getString("fileUrl");
+                            //String fileSize = object.getString("size");
+                            //String fileDateTime = object.getString("dateTime");    // detail : false
+                            //String thumbnail = object.getString("thumbnail");       // detail : true (Base64)
+                            String fileDateTime = object.getString("dateTimeZone"); // detail : true
+                            byte[] thumb = Base64.decode( object.getString("thumbnail"), Base64.DEFAULT);     // detail : true (Base64)
+                            bmp = BitmapFactory.decodeByteArray(thumb, 0, thumb.length);
+                            Log.v(TAG, " ----- camera.listFiles : " + fileName + " " + fileDateTime + " [" + thumb.length + "] (" + size + ")");
+                        }
+                    }
+                }
+                catch (Exception e)
+                {
+                    e.printStackTrace();
+                }
+            }
             HashMap<String, Object> map = new HashMap<>();
             map.put("Orientation", 0);
             callback.onCompleted(bmp, map);
@@ -154,7 +198,34 @@ public class ThetaPlaybackControl implements IPlaybackControl
 
     private void downloadContentImplV21(String path, boolean isSmallSize, final IDownloadContentCallback callback)
     {
-        downloadContentImpl(path, isSmallSize, callback);
+        Log.v(TAG, "downloadContentV21() : " + path + " (small :" + isSmallSize + ")");
+        final String urlToGet = "http://" + path;
+        try
+        {
+            SimpleHttpClient.httpGetBytes(urlToGet, null, 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);
+                    //Log.v(TAG, " onReceive : " + readBytes + " " + length + " " + size);
+                    ProgressEvent event = new ProgressEvent(percent, null);
+                    callback.onProgress(data, size, event);
+                }
+            });
+        }
+        catch (Throwable e)
+        {
+            e.printStackTrace();
+        }
     }
 
     private void downloadContentImpl(String path, boolean isSmallSize, final IDownloadContentCallback callback)
@@ -190,7 +261,6 @@ public class ThetaPlaybackControl implements IPlaybackControl
         }
     }
 
-
     @Override
     public void getCameraContentList(ICameraContentListCallback callback)
     {
@@ -277,7 +347,9 @@ public class ThetaPlaybackControl implements IPlaybackControl
         String contentList;
         try
         {
-            String paramStr = "{\"name\":\"camera.listFiles\",\"parameters\":{\"fileType\":\"all\",\"entryCount:\"" +  maxCount + ",\"maxThumbSize\":0,\"_detail\":false}}";
+            String paramStr = "{\"name\":\"camera.listFiles\",\"parameters\":{\"fileType\":\"all\",\"entryCount\":" +  maxCount + ",\"maxThumbSize\":640,\"_detail\":false, \"_sort\":\"newest\"}}";
+            //String paramStr = "{\"name\":\"camera.listFiles\",\"parameters\":{\"fileType\":\"all\",\"entryCount\":" +  maxCount + ",\"maxThumbSize\":640,\"_detail\":true, \"_sort\":\"newest\"}}";
+            Log.v(TAG, " paramStr : " + paramStr);
             contentList = SimpleHttpClient.httpPost(imageListurl, paramStr, timeoutValue);
             if (contentList == null)
             {
@@ -296,7 +368,7 @@ public class ThetaPlaybackControl implements IPlaybackControl
         }
         try
         {
-            // Log.v(TAG, "PHOTO LIST RECV: [" + contentList.length() + "] " + contentList);
+            Log.v(TAG, "PHOTO LIST RECV: [" + contentList.length() + "] ");
             JSONObject resultsObject = new JSONObject(contentList).getJSONObject("results");
             JSONArray entriesArray = resultsObject.getJSONArray("entries");
             int size = entriesArray.length();
@@ -307,10 +379,12 @@ public class ThetaPlaybackControl implements IPlaybackControl
                 String fileName = object.getString("name");
                 String fileUri = object.getString("fileUrl");
                 String fileSize = object.getString("size");
-                String fileDateTime = object.getString("dateTime");
+                String fileDateTime = object.getString("dateTime");    // detail : false
+                //String fileDateTime = object.getString("dateTimeZone"); // detail : true
+                //String thumbnail = object.getString("thumbnail");       // detail : true (Base64)
 
                 cameraContentList.add(new ThetaCameraContent(fileName, null, fileUri, fileSize, fileDateTime));
-                // Log.v(TAG, " [" + (index + 1) + "] " + fileName + " " + fileUri + " " + fileSize + " " + fileDateTime + " ");
+                Log.v(TAG, " [" + (index + 1) + "] " + fileName + " " + fileUri + " " + fileSize + " " + fileDateTime);
             }
         }
         catch (Exception e)