OSDN Git Service

FUJI X対応の準備。
authorMRSa <mrsa@myad.jp>
Sun, 19 Apr 2020 11:47:07 +0000 (20:47 +0900)
committerMRSa <mrsa@myad.jp>
Sun, 19 Apr 2020 11:47:07 +0000 (20:47 +0900)
26 files changed:
app/build.gradle
app/src/main/java/net/osdn/gokigen/gr2control/Gr2ControlMain.java
app/src/main/java/net/osdn/gokigen/gr2control/camera/ICameraConnection.java
app/src/main/java/net/osdn/gokigen/gr2control/camera/fuji_x/IFujiXInterfaceProvider.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/gr2control/camera/fuji_x/operation/CameraPowerOffFujiX.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/gr2control/camera/ricohgr2/wrapper/RicohGr2PlaybackControl.java
app/src/main/java/net/osdn/gokigen/gr2control/camera/utils/SimpleHttpClient.java
app/src/main/java/net/osdn/gokigen/gr2control/camera/utils/SimpleHttpSendCommandDialog.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/gr2control/camera/utils/SimpleLogDumper.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/gr2control/playback/ScalableImagePager.java
app/src/main/java/net/osdn/gokigen/gr2control/preference/IPreferencePropertyAccessor.java
app/src/main/java/net/osdn/gokigen/gr2control/preference/fuji_x/FujiXPreferenceFragment.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/gr2control/preference/olympus/PreferenceFragment.java
app/src/main/java/net/osdn/gokigen/gr2control/preference/ricohgr2/RicohGr2PreferenceFragment.java
app/src/main/java/net/osdn/gokigen/gr2control/scene/CameraSceneUpdater.java
app/src/main/res/drawable/ic_linked_camera_black_24dp.xml [new file with mode: 0644]
app/src/main/res/layout-land/http_request_layout.xml [new file with mode: 0644]
app/src/main/res/layout/http_request_layout.xml [new file with mode: 0644]
app/src/main/res/values-ja/arrays.xml
app/src/main/res/values-ja/strings.xml
app/src/main/res/values/arrays.xml
app/src/main/res/values/strings.xml
app/src/main/res/xml/preferences_fuji_x.xml [new file with mode: 0644]
app/src/main/res/xml/preferences_opc.xml
app/src/main/res/xml/preferences_ricoh_gr2.xml
build.gradle

index 2711d27..1f5a31d 100644 (file)
@@ -6,8 +6,8 @@ android {
         applicationId "net.osdn.gokigen.gr2control"
         minSdkVersion 14
         targetSdkVersion 29
-        versionCode 1002006
-        versionName "1.2.6"
+        versionCode 1002007
+        versionName "1.2.7"
     }
     buildTypes {
         release {
@@ -19,11 +19,11 @@ android {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    implementation 'androidx.appcompat:appcompat:1.0.2'
-    implementation 'androidx.preference:preference:1.0.0'
-    implementation 'androidx.exifinterface:exifinterface:1.0.0'
+    implementation 'androidx.appcompat:appcompat:1.1.0'
+    implementation 'androidx.preference:preference:1.1.1'
+    implementation 'androidx.exifinterface:exifinterface:1.2.0'
     implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
-    implementation 'com.google.android.material:material:1.0.0'
+    implementation 'com.google.android.material:material:1.1.0'
 
     api files('libs/olycamerakit.jar')
 }
index 33f7cad..fe9227d 100644 (file)
@@ -84,7 +84,7 @@ public class Gr2ControlMain extends AppCompatActivity
      *
      */
     @Override
-    public void onRequestPermissionsResult(int requestCode, @NonNull String  permissions[], @NonNull int[] grantResults)
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[]  permissions, @NonNull int[] grantResults)
     {
         super.onRequestPermissionsResult(requestCode, permissions, grantResults);
         onReadyClass();
index af49b49..33915ec 100644 (file)
@@ -14,6 +14,7 @@ public interface ICameraConnection
         OPC,
         SONY,
         RICOH_GR2,
+        FUJI_X,
     }
 
     enum CameraConnectionStatus
diff --git a/app/src/main/java/net/osdn/gokigen/gr2control/camera/fuji_x/IFujiXInterfaceProvider.java b/app/src/main/java/net/osdn/gokigen/gr2control/camera/fuji_x/IFujiXInterfaceProvider.java
new file mode 100644 (file)
index 0000000..3e5f679
--- /dev/null
@@ -0,0 +1,39 @@
+package net.osdn.gokigen.gr2control.camera.fuji_x;
+
+import net.osdn.gokigen.gr2control.camera.ICameraButtonControl;
+import net.osdn.gokigen.gr2control.camera.ICameraConnection;
+import net.osdn.gokigen.gr2control.camera.ICameraHardwareStatus;
+import net.osdn.gokigen.gr2control.camera.ICameraInformation;
+import net.osdn.gokigen.gr2control.camera.ICameraStatus;
+import net.osdn.gokigen.gr2control.camera.ICameraStatusWatcher;
+import net.osdn.gokigen.gr2control.camera.ICaptureControl;
+import net.osdn.gokigen.gr2control.camera.IDisplayInjector;
+import net.osdn.gokigen.gr2control.camera.IFocusingControl;
+import net.osdn.gokigen.gr2control.camera.ILiveViewControl;
+import net.osdn.gokigen.gr2control.camera.ICameraRunMode;
+import net.osdn.gokigen.gr2control.camera.playback.IPlaybackControl;
+import net.osdn.gokigen.gr2control.camera.IZoomLensControl;
+import net.osdn.gokigen.gr2control.liveview.liveviewlistener.ILiveViewListener;
+
+/**
+ *
+ *
+ */
+public interface IFujiXInterfaceProvider
+{
+    ICameraConnection getRicohGr2CameraConnection();
+    ILiveViewControl getLiveViewControl();
+    ILiveViewListener getLiveViewListener();
+    IFocusingControl getFocusingControl();
+    ICameraInformation getCameraInformation();
+    IZoomLensControl getZoomLensControl();
+    ICaptureControl getCaptureControl();
+    IDisplayInjector getDisplayInjector();
+    ICameraStatus getCameraStatusListHolder();
+    ICameraButtonControl getButtonControl();
+    ICameraStatusWatcher getCameraStatusWatcher();
+    IPlaybackControl getPlaybackControl();
+
+    ICameraHardwareStatus getHardwareStatus();
+    ICameraRunMode getCameraRunMode();
+}
diff --git a/app/src/main/java/net/osdn/gokigen/gr2control/camera/fuji_x/operation/CameraPowerOffFujiX.java b/app/src/main/java/net/osdn/gokigen/gr2control/camera/fuji_x/operation/CameraPowerOffFujiX.java
new file mode 100644 (file)
index 0000000..c2f185a
--- /dev/null
@@ -0,0 +1,77 @@
+package net.osdn.gokigen.gr2control.camera.fuji_x.operation;
+
+import android.content.Context;
+
+import net.osdn.gokigen.gr2control.R;
+import net.osdn.gokigen.gr2control.preference.IPreferencePropertyAccessor;
+import net.osdn.gokigen.gr2control.scene.ConfirmationDialog;
+import net.osdn.gokigen.gr2control.scene.IChangeScene;
+
+import androidx.preference.Preference;
+
+public class CameraPowerOffFujiX implements Preference.OnPreferenceClickListener, ConfirmationDialog.Callback
+{
+
+    private final Context context;
+    private final IChangeScene changeScene;
+    private String preferenceKey = null;
+
+    /**
+     *   コンストラクタ
+     *
+     */
+    public CameraPowerOffFujiX(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_exit, this);
+            return (true);
+        }
+        return (false);
+    }
+
+    /**
+     *
+     *
+     */
+    @Override
+    public void confirm()
+    {
+        if (preferenceKey.contains(IPreferencePropertyAccessor.EXIT_APPLICATION))
+        {
+            // アプリケーションを終了する。
+            changeScene.exitApplication();
+        }
+    }
+}
index d87843f..073a14e 100644 (file)
@@ -48,7 +48,7 @@ public class RicohGr2PlaybackControl implements IPlaybackControl
 
     RicohGr2PlaybackControl(int timeoutMSec)
     {
-        this.timeoutValue  = (timeoutMSec < DEFAULT_TIMEOUT) ? DEFAULT_TIMEOUT : timeoutMSec;
+        this.timeoutValue  = Math.max(DEFAULT_TIMEOUT, timeoutMSec); // (timeoutMSec < DEFAULT_TIMEOUT) ? DEFAULT_TIMEOUT : timeoutMSec;
     }
 
     @Override
@@ -182,7 +182,7 @@ public class RicohGr2PlaybackControl implements IPlaybackControl
         Log.v(TAG, "downloadContentScreennail() GET URL : " + url);
         try
         {
-            Bitmap bmp = SimpleHttpClient.httpGetBitmap(url, timeoutValue);
+            Bitmap bmp = SimpleHttpClient.httpGetBitmap(url, null, timeoutValue);
             HashMap<String, Object> map = new HashMap<>();
             map.put("Orientation", 0);
             callback.onCompleted(bmp, map);
@@ -206,7 +206,7 @@ public class RicohGr2PlaybackControl implements IPlaybackControl
         Log.v(TAG, "downloadContentThumbnail() GET URL : " + url);
         try
         {
-            Bitmap bmp = SimpleHttpClient.httpGetBitmap(url, timeoutValue);
+            Bitmap bmp = SimpleHttpClient.httpGetBitmap(url, null, timeoutValue);
             HashMap<String, Object> map = new HashMap<>();
             map.put("Orientation", 0);
             callback.onCompleted(bmp, map);
@@ -231,7 +231,7 @@ public class RicohGr2PlaybackControl implements IPlaybackControl
         Log.v(TAG, "downloadContent() GET URL : " + url);
         try
         {
-            SimpleHttpClient.httpGetBytes(url, timeoutValue, new SimpleHttpClient.IReceivedMessageCallback() {
+            SimpleHttpClient.httpGetBytes(url, null, timeoutValue, new SimpleHttpClient.IReceivedMessageCallback() {
                 @Override
                 public void onCompleted() {
                     callback.onCompleted();
index 9341e8f..1a491ca 100644 (file)
@@ -12,8 +12,11 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.util.List;
+import java.util.Map;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 /**
  *
@@ -128,9 +131,26 @@ public class SimpleHttpClient
      *
      *
      */
-    public static void httpGetBytes(String url, int timeoutMs, @NonNull IReceivedMessageCallback callback)
+    public static void httpGetBytes(String url, Map<String, String> setProperty, int timeoutMs, @NonNull IReceivedMessageCallback callback)
+    {
+        httpCommandBytes(url, "GET", null, setProperty, null, timeoutMs, callback);
+    }
+
+    /**
+     *
+     *
+     *
+     */
+    public static void httpPostBytes(String url, String postData, Map<String, String> setProperty, int timeoutMs, @NonNull IReceivedMessageCallback callback)
+    {
+        httpCommandBytes(url, "POST", postData, setProperty, null, timeoutMs, callback);
+    }
+
+    private static void httpCommandBytes(@NonNull String url, @NonNull String requestMethod, @Nullable String postData, @Nullable Map<String, String> setProperty, @Nullable String contentType, int timeoutMs, @NonNull IReceivedMessageCallback callback)
     {
         HttpURLConnection httpConn = null;
+        OutputStream outputStream = null;
+        OutputStreamWriter writer = null;
         InputStream inputStream = null;
         int timeout = timeoutMs;
         if (timeoutMs < 0)
@@ -138,15 +158,43 @@ public class SimpleHttpClient
             timeout = DEFAULT_TIMEOUT;
         }
 
-        //  HTTP GETメソッドで要求を投げる
+        //  HTTP メソッドで要求を送出
         try
         {
             final URL urlObj = new URL(url);
             httpConn = (HttpURLConnection) urlObj.openConnection();
-            httpConn.setRequestMethod("GET");
+            httpConn.setRequestMethod(requestMethod);
+            if (setProperty != null)
+            {
+                for (String key : setProperty.keySet())
+                {
+                    String value = setProperty.get(key);
+                    httpConn.setRequestProperty(key, value);
+                }
+            }
+            if (contentType != null)
+            {
+                httpConn.setRequestProperty("Content-Type", contentType);
+            }
             httpConn.setConnectTimeout(timeout);
             httpConn.setReadTimeout(timeout);
-            httpConn.connect();
+            if (postData == null)
+            {
+                httpConn.connect();
+            }
+            else
+            {
+                httpConn.setDoInput(true);
+                httpConn.setDoOutput(true);
+                outputStream = httpConn.getOutputStream();
+                writer = new OutputStreamWriter(outputStream, "UTF-8");
+                writer.write(postData);
+                writer.flush();
+                writer.close();
+                writer = null;
+                outputStream.close();
+                outputStream = null;
+            }
 
             int responseCode = httpConn.getResponseCode();
             if (responseCode == HttpURLConnection.HTTP_OK)
@@ -155,7 +203,7 @@ public class SimpleHttpClient
             }
             if (inputStream == null)
             {
-                Log.w(TAG, "httpGet: Response Code Error: " + responseCode + ": " + url);
+                Log.w(TAG, " http " + requestMethod + " Response Code Error: " + responseCode + ": " + url);
                 callback.onErrorOccurred(new NullPointerException());
                 callback.onCompleted();
                 return;
@@ -163,7 +211,7 @@ public class SimpleHttpClient
         }
         catch (Exception e)
         {
-            Log.w(TAG, "httpGet: " + url + "  " + e.getMessage());
+            Log.w(TAG, "http " + requestMethod + " " + url + "  " + e.getMessage());
             e.printStackTrace();
             if (httpConn != null)
             {
@@ -173,11 +221,72 @@ public class SimpleHttpClient
             callback.onCompleted();
             return;
         }
+        finally
+        {
+            try
+            {
+                if (writer != null)
+                {
+                    writer.close();
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+            try
+            {
+                if (outputStream != null)
+                {
+                    outputStream.close();
+                }
+            }
+            catch (IOException e)
+            {
+                e.printStackTrace();
+            }
+        }
 
         // 応答を確認する
         try
         {
             int contentLength = httpConn.getContentLength();
+            if (contentLength < 0)
+            {
+                // コンテンツ長が取れない場合の処理...
+                try
+                {
+                    Map<String, List<String>> headers = httpConn.getHeaderFields();
+
+                    /*
+                    // 応答ヘッダをすべてダンプするロジック...
+                    for (String key : headers.keySet())
+                    {
+                        final List<String> valueList = headers.get(key);
+                        Log.v(TAG, " " + key + " : " + getValue(valueList));
+                    }
+                    */
+
+                    // コンテンツ長さが取れない場合は、HTTP応答ヘッダから取得する
+                    List<String> valueList = headers.get("X-FILE_SIZE");
+                    try
+                    {
+                        if (valueList != null)
+                        {
+                            contentLength = Integer.parseInt(getValue(valueList));
+                        }
+                    }
+                    catch (Exception ee)
+                    {
+                        ee.printStackTrace();
+                    }
+                }
+                catch (Exception e)
+                {
+                    e.printStackTrace();
+                }
+            }
+
             byte[] buffer = new byte[BUFFER_SIZE];
             int readBytes = 0;
             int readSize = inputStream.read(buffer, 0, BUFFER_SIZE);
@@ -210,15 +319,53 @@ public class SimpleHttpClient
         callback.onCompleted();
     }
 
+
+    public static String getValue(List<String> valueList)
+    {
+        // 応答ヘッダの値切り出し用...
+        boolean isFirst = true;
+        final StringBuilder values = new StringBuilder();
+        for (String value : valueList)
+        {
+            values.append(value);
+            if (isFirst)
+            {
+                isFirst = false;
+            }
+            else
+            {
+                values.append(" ");
+            }
+        }
+        return (values.toString());
+    }
+
+    public static Bitmap httpGetBitmap(String url, Map<String, String> setProperty, int timeoutMs)
+    {
+        return (httpCommandBitmap(url, "GET", null, setProperty, null, timeoutMs));
+    }
+
+    /**
+     *
+     *
+     *
+     */
+    public static Bitmap httpPostBitmap(String url, String postData, int timeoutMs)
+    {
+        return (httpCommandBitmap(url, "POST", postData, null, null, timeoutMs));
+    }
+
     /**
      *
      *
      *
      */
-    public static Bitmap httpGetBitmap(String url, int timeoutMs)
+    private static Bitmap httpCommandBitmap(@NonNull String url, @NonNull String requestMethod, @Nullable String postData, @Nullable Map<String, String> setProperty, @Nullable String contentType, int timeoutMs)
     {
         HttpURLConnection httpConn = null;
         InputStream inputStream = null;
+        OutputStream outputStream = null;
+        OutputStreamWriter writer = null;
         Bitmap bmp = null;
 
         int timeout = timeoutMs;
@@ -227,15 +374,44 @@ public class SimpleHttpClient
             timeout = DEFAULT_TIMEOUT;
         }
 
-        //  HTTP GETメソッドで要求を投げる
+        //  HTTP メソッドで要求を送出
         try
         {
             final URL urlObj = new URL(url);
             httpConn = (HttpURLConnection) urlObj.openConnection();
-            httpConn.setRequestMethod("GET");
+            httpConn.setRequestMethod(requestMethod);
+            if (setProperty != null)
+            {
+                for (String key : setProperty.keySet())
+                {
+                    String value = setProperty.get(key);
+                    httpConn.setRequestProperty(key, value);
+                }
+            }
+            if (contentType != null)
+            {
+                httpConn.setRequestProperty("Content-Type", contentType);
+            }
             httpConn.setConnectTimeout(timeout);
             httpConn.setReadTimeout(timeout);
-            httpConn.connect();
+
+            if (postData == null)
+            {
+                httpConn.connect();
+            }
+            else
+            {
+                httpConn.setDoInput(true);
+                httpConn.setDoOutput(true);
+                outputStream = httpConn.getOutputStream();
+                writer = new OutputStreamWriter(outputStream, "UTF-8");
+                writer.write(postData);
+                writer.flush();
+                writer.close();
+                writer = null;
+                outputStream.close();
+                outputStream = null;
+            }
 
             int responseCode = httpConn.getResponseCode();
             if (responseCode == HttpURLConnection.HTTP_OK)
@@ -248,14 +424,14 @@ public class SimpleHttpClient
             }
             if (inputStream == null)
             {
-                Log.w(TAG, "httpGet: Response Code Error: " + responseCode + ": " + url);
+                Log.w(TAG, "http: (" + requestMethod + ") Response Code Error: " + responseCode + ": " + url);
                 return (null);
             }
             inputStream.close();
         }
         catch (Exception e)
         {
-            Log.w(TAG, "httpGet: " + url + "  " + e.getMessage());
+            Log.w(TAG, "http: (" + requestMethod + ") " + url + "  " + e.getMessage());
             e.printStackTrace();
             if (httpConn != null)
             {
@@ -263,6 +439,31 @@ public class SimpleHttpClient
             }
             return (null);
         }
+        finally
+        {
+            try
+            {
+                if (writer != null)
+                {
+                    writer.close();
+                }
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+            try
+            {
+                if (outputStream != null)
+                {
+                    outputStream.close();
+                }
+            }
+            catch (IOException e)
+            {
+                e.printStackTrace();
+            }
+        }
         return (bmp);
     }
 
@@ -273,7 +474,37 @@ public class SimpleHttpClient
      */
     public static String httpPost(String url, String postData, int timeoutMs)
     {
-        return (httpCommand(url, "POST", postData, timeoutMs));
+        return (httpCommand(url, "POST", postData, null, null, timeoutMs));
+    }
+
+    /**
+     *
+     *
+     *
+     */
+    public static String httpGetWithHeader(String url, Map<String, String> headerMap, String contentType, int timeoutMs)
+    {
+        return (httpCommand(url, "GET", null, headerMap, contentType, timeoutMs));
+    }
+
+    /**
+     *
+     *
+     *
+     */
+    public static String httpPostWithHeader(String url, String postData, Map<String, String> headerMap, String contentType, int timeoutMs)
+    {
+        return (httpCommand(url, "POST", postData, headerMap, contentType, timeoutMs));
+    }
+
+    /**
+     *
+     *
+     *
+     */
+    public static String httpPutWithHeader(String url, String putData, Map<String, String> headerMap, String contentType, int timeoutMs)
+    {
+        return (httpCommand(url, "PUT", putData, headerMap, contentType, timeoutMs));
     }
 
     /**
@@ -283,7 +514,17 @@ public class SimpleHttpClient
      */
     public static String httpPut(String url, String postData, int timeoutMs)
     {
-        return (httpCommand(url, "PUT", postData, timeoutMs));
+        return (httpCommand(url, "PUT", postData, null, null, timeoutMs));
+    }
+
+    /**
+     *
+     *
+     *
+     */
+    public static String httpOptions(String url, String optionsData, int timeoutMs)
+    {
+        return (httpCommand(url, "OPTIONS", optionsData, null, null, timeoutMs));
     }
 
     /**
@@ -291,7 +532,7 @@ public class SimpleHttpClient
      *
      *
      */
-    private static String httpCommand(String url, String requestMethod, String postData, int timeoutMs)
+    private static String httpCommand(String url, String requestMethod, String postData, Map<String, String> setProperty, String contentType, int timeoutMs)
     {
         HttpURLConnection httpConn = null;
         OutputStream outputStream = null;
@@ -310,20 +551,38 @@ public class SimpleHttpClient
             final URL urlObj = new URL(url);
             httpConn = (HttpURLConnection) urlObj.openConnection();
             httpConn.setRequestMethod(requestMethod);
+            if (setProperty != null)
+            {
+                for (String key : setProperty.keySet())
+                {
+                    String value = setProperty.get(key);
+                    httpConn.setRequestProperty(key, value);
+                }
+            }
+            if (contentType != null)
+            {
+                httpConn.setRequestProperty("Content-Type", contentType);
+            }
             httpConn.setConnectTimeout(timeout);
             httpConn.setReadTimeout(timeout);
-            httpConn.setDoInput(true);
-            httpConn.setDoOutput(true);
-
-            outputStream = httpConn.getOutputStream();
-            writer = new OutputStreamWriter(outputStream, "UTF-8");
-            writer.write(postData);
-            writer.flush();
-            writer.close();
-            writer = null;
-            outputStream.close();
-            outputStream = null;
 
+            if (postData == null)
+            {
+                httpConn.connect();
+            }
+            else
+            {
+                httpConn.setDoInput(true);
+                httpConn.setDoOutput(true);
+                outputStream = httpConn.getOutputStream();
+                writer = new OutputStreamWriter(outputStream, "UTF-8");
+                writer.write(postData);
+                writer.flush();
+                writer.close();
+                writer = null;
+                outputStream.close();
+                outputStream = null;
+            }
             int responseCode = httpConn.getResponseCode();
             if (responseCode == HttpURLConnection.HTTP_OK)
             {
@@ -332,6 +591,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 ("");
             }
         }
@@ -372,8 +639,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();
@@ -407,6 +718,7 @@ public class SimpleHttpClient
         return (replyString);
     }
 
+
     public interface IReceivedMessageCallback
     {
         void onCompleted();
diff --git a/app/src/main/java/net/osdn/gokigen/gr2control/camera/utils/SimpleHttpSendCommandDialog.java b/app/src/main/java/net/osdn/gokigen/gr2control/camera/utils/SimpleHttpSendCommandDialog.java
new file mode 100644 (file)
index 0000000..a086ac5
--- /dev/null
@@ -0,0 +1,334 @@
+package net.osdn.gokigen.gr2control.camera.utils;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+
+
+import net.osdn.gokigen.gr2control.R;
+import net.osdn.gokigen.gr2control.camera.ILiveViewControl;
+
+import java.util.Map;
+
+public class SimpleHttpSendCommandDialog extends DialogFragment implements View.OnClickListener
+{
+    private final String TAG = toString();
+    private ILiveViewControl liveViewControl = null;
+    private Dialog myDialog = null;
+    private EditText http_header = null;
+    private EditText method = null;
+    private EditText service = null;
+    private EditText parameter = null;
+    private EditText command = null;
+    private TextView responseArea = null;
+    private String urlToSend = null;
+    private Map<String, String> headerMap;
+
+    private static final int TIMEOUT_MS = 6000;
+    private static final String COMMUNICATE_URL_DEFAULT = "http://192.168.0.10/";
+
+    /**
+     *
+     *
+     */
+    public static SimpleHttpSendCommandDialog newInstance(@Nullable String urlToSend, @Nullable ILiveViewControl liveViewControl,  @Nullable Map<String, String> headerMap)
+    {
+        SimpleHttpSendCommandDialog instance = new SimpleHttpSendCommandDialog();
+        instance.prepare(urlToSend, liveViewControl, headerMap);
+
+        // パラメータはBundleにまとめておく
+        Bundle arguments = new Bundle();
+        //arguments.putString("method", method);
+        //arguments.putString("message", message);
+        instance.setArguments(arguments);
+
+        return (instance);
+    }
+
+    /**
+     *
+     *
+     */
+    private void prepare(@Nullable String urlToSend, @Nullable ILiveViewControl liveViewControl, @Nullable Map<String, String> headerMap)
+    {
+        if ((urlToSend == null)||(!urlToSend.contains("http://")))
+        {
+            this.urlToSend = COMMUNICATE_URL_DEFAULT;
+        }
+        else
+        {
+            this.urlToSend = urlToSend;
+        }
+
+        //
+        this.liveViewControl = liveViewControl;
+
+        this.headerMap = headerMap;
+        //headerMap = new HashMap<>();
+        //headerMap.put("User-Agent", "OlympusCameraKit"); // "OI.Share"
+        //headerMap.put("X-Protocol", "OlympusCameraKit"); // "OI.Share"
+    }
+
+    @Override
+    public void onPause()
+    {
+        super.onPause();
+        Log.v(TAG, "AlertDialog::onPause()");
+        try
+        {
+            if (myDialog != null)
+            {
+                myDialog.cancel();
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     *
+     */
+    @Override
+    public @NonNull Dialog onCreateDialog(Bundle savedInstanceState)
+    {
+        final Activity activity = getActivity();
+
+        // コマンド送信ダイアログの生成
+        final AlertDialog.Builder alertDialog = new AlertDialog.Builder(activity);
+
+        // Get the layout inflater
+        LayoutInflater inflater = activity.getLayoutInflater();
+        final View alertView = inflater.inflate(R.layout.http_request_layout, null, false);
+        alertDialog.setView(alertView);
+
+        alertDialog.setIcon(R.drawable.ic_linked_camera_black_24dp);
+        alertDialog.setTitle(activity.getString(R.string.dialog_http_command_title_command));
+        http_header = alertView.findViewById(R.id.edit_http_header);
+        method = alertView.findViewById(R.id.edit_method);
+        service = alertView.findViewById(R.id.edit_service);
+        parameter = alertView.findViewById(R.id.edit_parameter);
+        command = alertView.findViewById(R.id.edit_command);
+        responseArea = alertView.findViewById(R.id.olympuspen_command_response_value);
+        final Button sendButton = alertView.findViewById(R.id.send_message_button);
+        final Button toRunningButton = alertView.findViewById(R.id.change_to_liveview);
+        final Button toPlaybackButton = alertView.findViewById(R.id.change_to_playback);
+
+        if (liveViewControl != null)
+        {
+            toRunningButton.setOnClickListener(this);
+            toPlaybackButton.setOnClickListener(this);
+        }
+        else
+        {
+            // ライブビューのオン・オフ切り替えボタンを非表示にする
+            toRunningButton.setVisibility(View.GONE);
+            toPlaybackButton.setVisibility(View.GONE);
+        }
+        sendButton.setOnClickListener(this);
+        alertDialog.setCancelable(true);
+        try
+        {
+            if (method != null)
+            {
+                method.setText(activity.getText(R.string.http_method_string));
+            }
+            if (http_header != null)
+            {
+                http_header.setText(urlToSend);
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+
+        // ボタンを設定する(実行ボタン)
+        alertDialog.setPositiveButton(activity.getString(R.string.dialog_positive_execute),
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which)
+                    {
+                        dialog.dismiss();
+                    }
+                });
+
+        // ボタンを設定する (キャンセルボタン)
+        alertDialog.setNegativeButton(activity.getString(R.string.dialog_negative_cancel),
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        dialog.cancel();
+                    }
+                });
+
+        // 確認ダイアログを応答する
+        myDialog = alertDialog.create();
+        return (myDialog);
+    }
+
+    private void changeRunMode(boolean isStartLiveView)
+    {
+        // ライブビューの停止と開始
+        Log.v(TAG, "changeRunMode() : " + isStartLiveView);
+        if (liveViewControl == null)
+        {
+            Log.v(TAG, "liveViewControl is NULL...");
+            return;
+        }
+        try
+        {
+            if (isStartLiveView)
+            {
+                liveViewControl.startLiveView(false);
+            }
+            else
+            {
+                liveViewControl.stopLiveView();
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void onClick(View view)
+    {
+        if (view.getId() == R.id.change_to_liveview)
+        {
+            changeRunMode(true);
+            return;
+        }
+        if (view.getId() == R.id.change_to_playback)
+        {
+            changeRunMode(false);
+            return;
+        }
+
+
+        try
+        {
+            String methodStr = "";
+            String serviceStr = "";
+            String commandStr = "";
+            String parameterStr = "";
+            final Activity activity = getActivity();
+            if (activity != null)
+            {
+                if (http_header != null)
+                {
+                    String httpStr = http_header.getText().toString().toLowerCase();
+                    if (!httpStr.contains("http://"))
+                    {
+                        this.urlToSend = COMMUNICATE_URL_DEFAULT;
+                        http_header.setText(COMMUNICATE_URL_DEFAULT);
+                    }
+                    else
+                    {
+                        this.urlToSend = httpStr;
+                    }
+                }
+                
+                if (method != null)
+                {
+                    methodStr = method.getText().toString().toLowerCase();
+                }
+                final boolean isPost = (methodStr.contains("post"));
+                final boolean isPut = (methodStr.contains("put"));
+
+                if (service != null)
+                {
+                    serviceStr = service.getText().toString();
+                }
+                if (command != null)
+                {
+                    commandStr = command.getText().toString();
+                }
+                if (parameter != null)
+                {
+                    // GET メソッドのときは、 commandStr と parameterStrを結合する。
+                    parameterStr = parameter.getText().toString();
+                    if ((!isPost)&&(parameterStr.length() > 0))
+                    {
+                        commandStr = commandStr + "&" + parameterStr;
+                    }
+                }
+
+                //  > GET  : http://xxx.xxx.xxx.xxx/(serviceStr) + "?" (commandStr) + "&" (parameterStr)
+                //  > POST : http://xxx.xxx.xxx.xxx/(serviceStr) + "?" (commandStr) , parameterStr ← BODY
+                if (commandStr.length() > 0)
+                {
+                    serviceStr = urlToSend + serviceStr + "?" + commandStr;
+                }
+                else
+                {
+                    // commandStrにデータが記入されていない場合はServiceStrのみ
+                    serviceStr = urlToSend + serviceStr;
+                }
+
+                final String url = serviceStr;
+                final String param = parameterStr;
+
+                Thread thread = new Thread(new Runnable() {
+                    @Override
+                    public void run()
+                    {
+                        try
+                        {
+                            String reply;
+                            if (isPost)
+                            {
+                                reply =  SimpleHttpClient.httpPostWithHeader(url, param, headerMap, null, TIMEOUT_MS);
+                            }
+                            else if (isPut)
+                            {
+                                reply =  SimpleHttpClient.httpPutWithHeader(url, param, headerMap, null, TIMEOUT_MS);
+                            }
+                            else
+                            {
+                                reply = SimpleHttpClient.httpGetWithHeader(url, headerMap, null, TIMEOUT_MS);
+                            }
+                            Log.v(TAG, "URL : " + url + " "+ param + " RESP : " + reply);
+                            final String response = reply;
+                            activity.runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    if (responseArea != null)
+                                    {
+                                        responseArea.setText(response);
+                                    }
+                                }
+                            });
+                        }
+                        catch (Exception e)
+                        {
+                            e.printStackTrace();
+                        }
+                    }
+                });
+                thread.start();
+            }
+            else
+            {
+                Log.v(TAG, "getActivity() Fail...");
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/app/src/main/java/net/osdn/gokigen/gr2control/camera/utils/SimpleLogDumper.java b/app/src/main/java/net/osdn/gokigen/gr2control/camera/utils/SimpleLogDumper.java
new file mode 100644 (file)
index 0000000..1035c80
--- /dev/null
@@ -0,0 +1,78 @@
+package net.osdn.gokigen.gr2control.camera.utils;
+
+import android.app.Activity;
+import android.os.Environment;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import net.osdn.gokigen.gr2control.R;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Locale;
+
+public class SimpleLogDumper
+{
+    private static final String TAG = SimpleLogDumper.class.getSimpleName();
+
+    /**
+     *   デバッグ用:ログにバイト列を出力する
+     *
+     */
+    public static void dump_bytes(String header, byte[] data)
+    {
+        if (data == null)
+        {
+            Log.v(TAG, "DATA IS NULL");
+            return;
+        }
+        if (data.length > 8192)
+        {
+            Log.v(TAG, " --- DUMP DATA IS TOO LONG... " + data.length + " bytes.");
+            return;
+        }
+
+        int index = 0;
+        StringBuffer message;
+        message = new StringBuffer();
+        for (byte item : data)
+        {
+            index++;
+            message.append(String.format("%02x ", item));
+            if (index >= 16)
+            {
+                Log.v(TAG, header + " " + message);
+                index = 0;
+                message = new StringBuffer();
+            }
+        }
+        if (index != 0)
+        {
+            Log.v(TAG, header + " " + message);
+        }
+        System.gc();
+    }
+
+    public static void binaryOutputToFile(@NonNull Activity activity, String fileNamePrefix, byte[] rx_body)
+    {
+        try
+        {
+            Calendar calendar = Calendar.getInstance();
+            String extendName = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault()).format(calendar.getTime());
+            final String directoryPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath() + "/" + activity.getString(R.string.app_name2) + "/";
+            String outputFileName = fileNamePrefix + "_" + extendName + ".bin";
+            String filepath = new File(directoryPath.toLowerCase(), outputFileName.toLowerCase()).getPath();
+            FileOutputStream outputStream = new FileOutputStream(filepath);
+            outputStream.write(rx_body, 0, rx_body.length);
+            outputStream.flush();
+            outputStream.close();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+}
index 75e2ab7..0b88d91 100644 (file)
@@ -38,7 +38,7 @@ public class ScalableImagePager extends ViewPager
         for (int position = 0; position < getChildCount(); position++)
         {
             View view = getChildAt(position);
-            float viewportCenterX = getScrollX() + getWidth() / 2;
+            float viewportCenterX = getScrollX() + getWidth() / 2.0f;
             float contentLeftX = view.getX();
             float contentRightX =  view.getX() + view.getWidth();
             if (contentLeftX < viewportCenterX && contentRightX > viewportCenterX)
index 6d4b731..6ddf8ee 100644 (file)
@@ -52,6 +52,15 @@ public interface IPreferencePropertyAccessor
     String RICOH_GET_PICS_LIST_TIMEOUT = "ricoh_get_pics_list_timeout";
     String RICOH_GET_PICS_LIST_TIMEOUT_DEFAULT_VALUE = "5";
 
+    String FUJI_X_DISPLAY_CAMERA_VIEW = "fujix_display_camera_view";
+
+    String FUJI_X_FOCUS_XY = "fujix_focus_xy";
+    String FUJI_X_FOCUS_XY_DEFAULT_VALUE = "7,7";
+
+    String FUJI_X_LIVEVIEW_WAIT = "fujix_liveview_wait";
+    String FUJI_X_LIVEVIEW_WAIT_DEFAULT_VALUE = "80";
+
+
 /*
     //String GR2_DISPLAY_MODE = "gr2_display_mode";
     //String GR2_DISPLAY_MODE_DEFAULT_VALUE = "0";
diff --git a/app/src/main/java/net/osdn/gokigen/gr2control/preference/fuji_x/FujiXPreferenceFragment.java b/app/src/main/java/net/osdn/gokigen/gr2control/preference/fuji_x/FujiXPreferenceFragment.java
new file mode 100644 (file)
index 0000000..4da6d9a
--- /dev/null
@@ -0,0 +1,382 @@
+package net.osdn.gokigen.gr2control.preference.fuji_x;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+
+import net.osdn.gokigen.gr2control.R;
+import net.osdn.gokigen.gr2control.camera.fuji_x.operation.CameraPowerOffFujiX;
+import net.osdn.gokigen.gr2control.logcat.LogCatViewer;
+import net.osdn.gokigen.gr2control.preference.IPreferencePropertyAccessor;
+import net.osdn.gokigen.gr2control.scene.IChangeScene;
+
+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;
+
+public class FujiXPreferenceFragment  extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener, Preference.OnPreferenceClickListener
+{
+    private final String TAG = toString();
+    private AppCompatActivity context = null;
+    private SharedPreferences preferences = null;
+    private CameraPowerOffFujiX powerOffController = null;
+    private LogCatViewer logCatViewer = null;
+
+    /**
+     *
+     *
+     */
+    public static FujiXPreferenceFragment newInstance(@NonNull AppCompatActivity context, @NonNull IChangeScene changeScene)
+    {
+        FujiXPreferenceFragment instance = new FujiXPreferenceFragment();
+        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 CameraPowerOffFujiX(context, changeScene);
+            powerOffController.prepare();
+
+            logCatViewer = new LogCatViewer(changeScene);
+            logCatViewer.prepare();
+
+            this.context = context;
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     *
+     */
+    @Override
+    public void onAttach(@NonNull 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<String, ?> 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.USE_PLAYBACK_MENU)) {
+                editor.putBoolean(IPreferencePropertyAccessor.USE_PLAYBACK_MENU, false);
+            }
+            if (!items.containsKey(IPreferencePropertyAccessor.CONNECTION_METHOD)) {
+                editor.putString(IPreferencePropertyAccessor.CONNECTION_METHOD, IPreferencePropertyAccessor.CONNECTION_METHOD_DEFAULT_VALUE);
+            }
+            if (!items.containsKey(IPreferencePropertyAccessor.FUJI_X_DISPLAY_CAMERA_VIEW)) {
+                editor.putBoolean(IPreferencePropertyAccessor.FUJI_X_DISPLAY_CAMERA_VIEW, false);
+            }
+            if (!items.containsKey(IPreferencePropertyAccessor.SHARE_AFTER_SAVE)) {
+                editor.putBoolean(IPreferencePropertyAccessor.SHARE_AFTER_SAVE, false);
+            }
+            if (!items.containsKey(IPreferencePropertyAccessor.FUJI_X_FOCUS_XY)) {
+                editor.putString(IPreferencePropertyAccessor.FUJI_X_FOCUS_XY, IPreferencePropertyAccessor.FUJI_X_FOCUS_XY_DEFAULT_VALUE);
+            }
+            if (!items.containsKey(IPreferencePropertyAccessor.FUJI_X_LIVEVIEW_WAIT)) {
+                editor.putString(IPreferencePropertyAccessor.FUJI_X_LIVEVIEW_WAIT, IPreferencePropertyAccessor.FUJI_X_LIVEVIEW_WAIT_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, " CAPTURE BOTH CAMERA AND LIVE VIEW : " + key + " , " + value);
+                    break;
+
+                case IPreferencePropertyAccessor.USE_PLAYBACK_MENU:
+                    value = preferences.getBoolean(key, false);
+                    Log.v(TAG, " " + key + " , " + value);
+                    break;
+
+                case IPreferencePropertyAccessor.FUJI_X_DISPLAY_CAMERA_VIEW:
+                    value = preferences.getBoolean(key, false);
+                    Log.v(TAG, " DISPLAY CAMERA VIEW : " + key + " , " + value);
+                    break;
+
+                case IPreferencePropertyAccessor.SHARE_AFTER_SAVE:
+                    value = preferences.getBoolean(key, false);
+                    Log.v(TAG, " SHARE AFTER SAVE : " + 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_fuji_x);
+
+            ListPreference connectionMethod = findPreference(IPreferencePropertyAccessor.CONNECTION_METHOD);
+            if (connectionMethod != null)
+            {
+                connectionMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+                    @Override
+                    public boolean onPreferenceChange(Preference preference, Object newValue) {
+                        preference.setSummary(newValue + " ");
+                        return (true);
+                    }
+                });
+                connectionMethod.setSummary(connectionMethod.getValue() + " ");
+            }
+            Preference exitPreference = findPreference("exit_application");
+            if (exitPreference != null)
+            {
+                exitPreference.setOnPreferenceClickListener(powerOffController);
+            }
+            Preference debugPreference = findPreference("debug_info");
+            if (debugPreference != null)
+            {
+                debugPreference.setOnPreferenceClickListener(logCatViewer);
+            }
+            Preference wifiPreference = findPreference("wifi_settings");
+            if (wifiPreference != null)
+            {
+                wifiPreference.setOnPreferenceClickListener(this);
+            }
+        }
+        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();
+        final boolean defaultValue = true;
+        if (activity != null)
+        {
+            activity.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    try
+                    {
+                        // Preferenceの画面に反映させる
+                        setBooleanPreference(IPreferencePropertyAccessor.AUTO_CONNECT_TO_CAMERA, IPreferencePropertyAccessor.AUTO_CONNECT_TO_CAMERA, defaultValue);
+                        setBooleanPreference(IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW, IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW, defaultValue);
+                        setBooleanPreference(IPreferencePropertyAccessor.USE_PLAYBACK_MENU, IPreferencePropertyAccessor.USE_PLAYBACK_MENU, defaultValue);
+                        setBooleanPreference(IPreferencePropertyAccessor.FUJI_X_DISPLAY_CAMERA_VIEW, IPreferencePropertyAccessor.FUJI_X_DISPLAY_CAMERA_VIEW, false);
+                        setBooleanPreference(IPreferencePropertyAccessor.SHARE_AFTER_SAVE, IPreferencePropertyAccessor.SHARE_AFTER_SAVE, defaultValue);
+                    }
+                    catch (Exception e)
+                    {
+                        e.printStackTrace();
+                    }
+                }
+            });
+        }
+    }
+
+    @Override
+    public boolean onPreferenceClick(Preference preference)
+    {
+        try
+        {
+            String preferenceKey = preference.getKey();
+            if (preferenceKey.contains("wifi_settings"))
+            {
+                // Wifi 設定画面を表示する
+                Log.v(TAG, " onPreferenceClick : " + preferenceKey);
+                if (context != null)
+                {
+                    context.startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+                }
+            }
+            return (true);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return (false);
+    }
+}
index 9adbee1..f75e05d 100644 (file)
@@ -2,8 +2,10 @@ package net.osdn.gokigen.gr2control.preference.olympus;
 
 import android.app.ProgressDialog;
 import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.util.Log;
 
 import net.osdn.gokigen.gr2control.R;
@@ -36,9 +38,10 @@ import jp.co.olympus.camerakit.OLYCamera;
  *   SettingFragment
  *
  */
-public class PreferenceFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener, PreferenceSynchronizer.IPropertySynchronizeCallback
+public class PreferenceFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener, PreferenceSynchronizer.IPropertySynchronizeCallback, Preference.OnPreferenceClickListener
 {
     private final String TAG = toString();
+    private AppCompatActivity context = null;
     private IOlyCameraPropertyProvider propertyInterface = null;
     private ICameraHardwareStatus hardwareStatusInterface = null;
     private ICameraRunMode changeRunModeExecutor = null;
@@ -70,13 +73,22 @@ public class PreferenceFragment extends PreferenceFragmentCompat implements Shar
     private void setInterface(@NonNull AppCompatActivity context, @NonNull IInterfaceProvider factory, @NonNull IChangeScene changeScene)
     {
         Log.v(TAG, "setInterface()");
-        this.propertyInterface = factory.getOlympusInterfaceProvider().getCameraPropertyProvider();
-        this.changeRunModeExecutor = factory.getCameraRunMode();
-        hardwareStatusInterface = factory.getHardwareStatus();
-        powerOffController = new CameraPowerOff(context, changeScene);
-        powerOffController.prepare();
-        logCatViewer = new LogCatViewer(changeScene);
-        logCatViewer.prepare();
+        try
+        {
+            this.propertyInterface = factory.getOlympusInterfaceProvider().getCameraPropertyProvider();
+            this.changeRunModeExecutor = factory.getCameraRunMode();
+            hardwareStatusInterface = factory.getHardwareStatus();
+            powerOffController = new CameraPowerOff(context, changeScene);
+            powerOffController.prepare();
+            logCatViewer = new LogCatViewer(changeScene);
+            logCatViewer.prepare();
+
+            this.context = context;
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
     }
 
     /**
@@ -84,22 +96,28 @@ public class PreferenceFragment extends PreferenceFragmentCompat implements Shar
      *
      */
     @Override
-    public void onAttach(Context activity)
+    public void onAttach(@NonNull Context activity)
     {
         super.onAttach(activity);
         Log.v(TAG, "onAttach()");
-
-        // Preference をつかまえる
-        preferences = PreferenceManager.getDefaultSharedPreferences(activity);
-        if (preferenceSynchronizer == null)
+        try
         {
-            preferenceSynchronizer = new PreferenceSynchronizer(this.propertyInterface, preferences, this);
-        }
+            // Preference をつかまえる
+            preferences = PreferenceManager.getDefaultSharedPreferences(activity);
+            if (preferenceSynchronizer == null)
+            {
+                preferenceSynchronizer = new PreferenceSynchronizer(this.propertyInterface, preferences, this);
+            }
 
-        // Preference を初期設定する
-        initializePreferences();
+            // Preference を初期設定する
+            initializePreferences();
 
-        preferences.registerOnSharedPreferenceChangeListener(this);
+            preferences.registerOnSharedPreferenceChangeListener(this);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
     }
 
     /**
@@ -167,6 +185,7 @@ public class PreferenceFragment extends PreferenceFragmentCompat implements Shar
         //super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.preferences_opc);
 
+        try
         {
             final HashMap<String, String> sizeTable = new HashMap<>();
             sizeTable.put("QVGA", "(320x240)");
@@ -195,9 +214,15 @@ public class PreferenceFragment extends PreferenceFragmentCompat implements Shar
                 }
             });
             connectionMethod.setSummary(connectionMethod.getValue() + " ");
+
+            findPreference("exit_application").setOnPreferenceClickListener(powerOffController);
+            findPreference("debug_info").setOnPreferenceClickListener(logCatViewer);
+            findPreference("wifi_settings").setOnPreferenceClickListener(this);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
         }
-        findPreference("exit_application").setOnPreferenceClickListener(powerOffController);
-        findPreference("debug_info").setOnPreferenceClickListener(logCatViewer);
     }
 
     /**
@@ -205,26 +230,33 @@ public class PreferenceFragment extends PreferenceFragmentCompat implements Shar
      */
     private void setHardwareSummary()
     {
-        // レンズ状態
-        findPreference("lens_status").setSummary(hardwareStatusInterface.getLensMountStatus());
-
-        // メディア状態
-        findPreference("media_status").setSummary(hardwareStatusInterface.getMediaMountStatus());
-
-        // 焦点距離
-        String focalLength;
-        float minLength = hardwareStatusInterface.getMinimumFocalLength();
-        float maxLength = hardwareStatusInterface.getMaximumFocalLength();
-        float actualLength = hardwareStatusInterface.getActualFocalLength();
-        if (minLength == maxLength)
+        try
         {
-            focalLength = String.format(Locale.ENGLISH, "%3.0fmm", actualLength);
+            // レンズ状態
+            findPreference("lens_status").setSummary(hardwareStatusInterface.getLensMountStatus());
+
+            // メディア状態
+            findPreference("media_status").setSummary(hardwareStatusInterface.getMediaMountStatus());
+
+            // 焦点距離
+            String focalLength;
+            float minLength = hardwareStatusInterface.getMinimumFocalLength();
+            float maxLength = hardwareStatusInterface.getMaximumFocalLength();
+            float actualLength = hardwareStatusInterface.getActualFocalLength();
+            if (minLength == maxLength)
+            {
+                focalLength = String.format(Locale.ENGLISH, "%3.0fmm", actualLength);
+            }
+            else
+            {
+                focalLength = String.format(Locale.ENGLISH, "%3.0fmm - %3.0fmm (%3.0fmm)", minLength, maxLength, actualLength);
+            }
+            findPreference("focal_length").setSummary(focalLength);
         }
-        else
+        catch (Exception e)
         {
-            focalLength = String.format(Locale.ENGLISH, "%3.0fmm - %3.0fmm (%3.0fmm)", minLength, maxLength, actualLength);
+            e.printStackTrace();
         }
-        findPreference("focal_length").setSummary(focalLength);
 
         // カメラのバージョン
         try
@@ -275,16 +307,21 @@ public class PreferenceFragment extends PreferenceFragmentCompat implements Shar
     {
         super.onResume();
         Log.v(TAG, "onResume() Start");
-
-        // 撮影モードかどうかを確認して、撮影モードではなかったら撮影モードに切り替える
-        if ((changeRunModeExecutor != null) && (!changeRunModeExecutor.isRecordingMode()))
+        try
+        {
+            // 撮影モードかどうかを確認して、撮影モードではなかったら撮影モードに切り替える
+            if ((changeRunModeExecutor != null) && (!changeRunModeExecutor.isRecordingMode()))
+            {
+                // Runモードを切り替える。(でも切り替えると、設定がクリアされてしまう...。
+                changeRunModeExecutor.changeRunMode(true);
+            }
+            synchronizeCameraProperties(true);
+        }
+        catch (Exception e)
         {
-            // Runモードを切り替える。(でも切り替えると、設定がクリアされてしまう...。
-            changeRunModeExecutor.changeRunMode(true);
+            e.printStackTrace();
         }
-        synchronizeCameraProperties(true);
         Log.v(TAG, "onResume() End");
-
     }
 
     /**
@@ -488,4 +525,29 @@ public class PreferenceFragment extends PreferenceFragmentCompat implements Shar
             }
         });
     }
+
+
+    @Override
+    public boolean onPreferenceClick(Preference preference)
+    {
+        try
+        {
+            String preferenceKey = preference.getKey();
+            if (preferenceKey.contains("wifi_settings"))
+            {
+                // Wifi 設定画面を表示する
+                Log.v(TAG, " onPreferenceClick : " + preferenceKey);
+                if (context != null)
+                {
+                    context.startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+                }
+            }
+            return (true);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return (false);
+    }
 }
index 46269fe..ced0bb6 100644 (file)
@@ -1,8 +1,10 @@
 package net.osdn.gokigen.gr2control.preference.ricohgr2;
 
 import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.util.Log;
 
 import net.osdn.gokigen.gr2control.R;
@@ -22,9 +24,10 @@ import androidx.preference.Preference;
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceManager;
 
-public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener
+public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener, Preference.OnPreferenceClickListener
 {
     private final String TAG = toString();
+    private AppCompatActivity context = null;
     private SharedPreferences preferences = null;
     private CameraPowerOffRicohGr2 powerOffController = null;
     private LogCatViewer logCatViewer = null;
@@ -60,6 +63,8 @@ public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implem
 
             logCatViewer = new LogCatViewer(changeScene);
             logCatViewer.prepare();
+
+            this.context = context;
         }
         catch (Exception e)
         {
@@ -72,7 +77,7 @@ public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implem
      *
      */
     @Override
-    public void onAttach(Context activity)
+    public void onAttach(@NonNull Context activity)
     {
         super.onAttach(activity);
         Log.v(TAG, "onAttach()");
@@ -161,7 +166,7 @@ public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implem
 
                 case IPreferencePropertyAccessor.CAPTURE_BOTH_CAMERA_AND_LIVE_VIEW:
                     value = preferences.getBoolean(key, true);
-                    Log.v(TAG, " " + key + " , " + value);
+                    Log.v(TAG, " BOTH LV : " + key + " , " + value);
                     break;
 
                 case IPreferencePropertyAccessor.USE_PLAYBACK_MENU:
@@ -171,27 +176,27 @@ public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implem
 
                 case IPreferencePropertyAccessor.GR2_DISPLAY_CAMERA_VIEW:
                     value = preferences.getBoolean(key, true);
-                    Log.v(TAG, " " + key + " , " + value);
+                    Log.v(TAG, " GR2 DISPLAY : " + key + " , " + value);
                     break;
 
                 case IPreferencePropertyAccessor.GR2_LCD_SLEEP:
                     value = preferences.getBoolean(key, false);
-                    Log.v(TAG, " " + key + " , " + value);
+                    Log.v(TAG, " GR2 LCD : " + key + " , " + value);
                     break;
 
                 case IPreferencePropertyAccessor.SHARE_AFTER_SAVE:
                     value = preferences.getBoolean(key, false);
-                    Log.v(TAG, " " + key + " , " + value);
+                    Log.v(TAG, " SHARE : " + key + " , " + value);
                     break;
 
                 case IPreferencePropertyAccessor.USE_GR2_SPECIAL_COMMAND:
                     value = preferences.getBoolean(key, true);
-                    Log.v(TAG, " " + key + " , " + value);
+                    Log.v(TAG, " GR2 SPECIAL : " + key + " , " + value);
                     break;
 
                 case IPreferencePropertyAccessor.PENTAX_CAPTURE_AFTER_AF:
                     value = preferences.getBoolean(key, false);
-                    Log.v(TAG, " " + key + " , " + value);
+                    Log.v(TAG, " PENTAX AFTER AF : " + key + " , " + value);
                     break;
 
                 default:
@@ -215,18 +220,36 @@ public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implem
             //super.onCreate(savedInstanceState);
             addPreferencesFromResource(R.xml.preferences_ricoh_gr2);
 
-            ListPreference connectionMethod = (ListPreference) 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() + " ");
+            ListPreference connectionMethod = findPreference(IPreferencePropertyAccessor.CONNECTION_METHOD);
+            if (connectionMethod != null)
+            {
+                connectionMethod.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+                    @Override
+                    public boolean onPreferenceChange(Preference preference, Object newValue) {
+                        preference.setSummary(newValue + " ");
+                        return (true);
+                    }
+                });
+                connectionMethod.setSummary(connectionMethod.getValue() + " ");
+            }
+
+            Preference exitApplication = findPreference("exit_application");
+            if (exitApplication != null)
+            {
+                exitApplication.setOnPreferenceClickListener(powerOffController);
+            }
+
+            Preference debug = findPreference("debug_info");
+            if (debug != null)
+            {
+                debug.setOnPreferenceClickListener(logCatViewer);
+            }
 
-            findPreference("exit_application").setOnPreferenceClickListener(powerOffController);
-            findPreference("debug_info").setOnPreferenceClickListener(logCatViewer);
+            Preference wifi = findPreference("wifi_settings");
+            if (wifi != null)
+            {
+                wifi.setOnPreferenceClickListener(this);
+            }
         }
         catch (Exception e)
         {
@@ -289,7 +312,7 @@ public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implem
         try
         {
             ListPreference pref;
-            pref = (ListPreference) findPreference(pref_key);
+            pref = findPreference(pref_key);
             String value = preferences.getString(key, defaultValue);
             if (pref != null)
             {
@@ -314,8 +337,9 @@ public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implem
     {
         try
         {
-            CheckBoxPreference pref = (CheckBoxPreference) findPreference(pref_key);
-            if (pref != null) {
+            CheckBoxPreference pref = findPreference(pref_key);
+            if (pref != null)
+            {
                 boolean value = preferences.getBoolean(key, defaultValue);
                 pref.setChecked(value);
             }
@@ -359,4 +383,29 @@ public class RicohGr2PreferenceFragment  extends PreferenceFragmentCompat implem
             });
         }
     }
+
+
+    @Override
+    public boolean onPreferenceClick(Preference preference)
+    {
+        try
+        {
+            String preferenceKey = preference.getKey();
+            if (preferenceKey.contains("wifi_settings"))
+            {
+                // Wifi 設定画面を表示する
+                Log.v(TAG, " onPreferenceClick : " + preferenceKey);
+                if (context != null)
+                {
+                    context.startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+                }
+            }
+            return (true);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return (false);
+    }
 }
index a0e218a..3076e21 100644 (file)
@@ -9,6 +9,7 @@ import net.osdn.gokigen.gr2control.camera.IInterfaceProvider;
 import net.osdn.gokigen.gr2control.liveview.IStatusViewDrawer;
 import net.osdn.gokigen.gr2control.logcat.LogCatFragment;
 import net.osdn.gokigen.gr2control.playback.ImageGridViewFragment;
+import net.osdn.gokigen.gr2control.preference.fuji_x.FujiXPreferenceFragment;
 import net.osdn.gokigen.gr2control.preference.olympus.PreferenceFragment;
 import net.osdn.gokigen.gr2control.preference.ricohgr2.RicohGr2PreferenceFragment;
 
@@ -206,7 +207,12 @@ public class CameraSceneUpdater implements ICameraStatusReceiver, IChangeScene
                         preferenceFragment = RicohGr2PreferenceFragment.newInstance(activity, this);
                     //} else if (connectionMethod == ICameraConnection.CameraConnectionMethod.SONY) {
                     //    preferenceFragment = SonyPreferenceFragment.newInstance(this, this);
-                    } else //  if (connectionMethod == ICameraConnection.CameraConnectionMethod.OPC)
+                    }
+                    else if (connectionMethod == ICameraConnection.CameraConnectionMethod.FUJI_X)
+                    {
+                        preferenceFragment = FujiXPreferenceFragment.newInstance(activity, this);
+                    }
+                    else //  if (connectionMethod == ICameraConnection.CameraConnectionMethod.OPC)
                     {
                         preferenceFragment = PreferenceFragment.newInstance(activity, interfaceProvider, this);
                     }
diff --git a/app/src/main/res/drawable/ic_linked_camera_black_24dp.xml b/app/src/main/res/drawable/ic_linked_camera_black_24dp.xml
new file mode 100644 (file)
index 0000000..201c572
--- /dev/null
@@ -0,0 +1,15 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M12,14m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M16,3.33c2.58,0 4.67,2.09 4.67,4.67H22c0,-3.31 -2.69,-6 -6,-6v1.33M16,6c1.11,0 2,0.89 2,2h1.33c0,-1.84 -1.49,-3.33 -3.33,-3.33V6"/>
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M17,9c0,-1.11 -0.89,-2 -2,-2L15,4L9,4L7.17,6L4,6c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,9h-5zM12,19c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
+</vector>
diff --git a/app/src/main/res/layout-land/http_request_layout.xml b/app/src/main/res/layout-land/http_request_layout.xml
new file mode 100644 (file)
index 0000000..4cbeb36
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <LinearLayout
+            android:id="@+id/info_edit_data"
+            android:orientation="vertical"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:padding="6dp"
+            >
+            <LinearLayout
+                android:id="@+id/mode_change_button_area"
+                android:orientation="horizontal"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:padding="6dp"
+                >
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:tag="button"
+                    android:id="@+id/change_to_liveview"
+                    android:text="@string/dialog_button_liveview"
+                    android:layout_gravity="center"
+                    android:visibility="visible"
+                    android:textSize="6pt" />
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:tag="button"
+                    android:id="@+id/change_to_playback"
+                    android:text="@string/dialog_button_playback"
+                    android:layout_gravity="center"
+                    android:visibility="visible"
+                    android:textSize="6pt" />
+            </LinearLayout>
+
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/method_name"
+                android:tag="title"
+                android:maxWidth="130dp"
+                android:minWidth="130dp"
+                android:layout_gravity="start">
+            </TextView>
+
+            <EditText android:id="@+id/edit_http_header"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="text"
+                android:hint="@string/http_dialog_http_url_hint"
+                />
+
+            <EditText android:id="@+id/edit_method"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="text"
+                android:hint="@string/http_dialog_method_hint"
+                />
+
+            <EditText android:id="@+id/edit_service"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="text"
+                android:hint="@string/http_dialog_service_hint"
+                />
+
+            <EditText android:id="@+id/edit_command"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="text"
+                android:hint="@string/http_dialog_command_hint"
+                />
+
+            <EditText android:id="@+id/edit_parameter"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="textMultiLine"
+                android:hint="@string/http_dialog_parameter_hint"
+                />
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:tag="button"
+                android:id="@+id/send_message_button"
+                android:text="@string/dialog_send_message"
+                android:layout_gravity="center"
+                android:textSize="6pt" />
+
+            <View
+                android:layout_width="fill_parent"
+                android:layout_height="2dp"
+                android:background="@android:color/darker_gray"/>
+
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/olympuspen_command_response_value"
+                android:text="@string/blank"
+                />
+
+            <View
+                android:layout_width="fill_parent"
+                android:layout_height="2dp"
+                android:background="@android:color/darker_gray"/>
+
+        </LinearLayout>
+    </ScrollView>
+</LinearLayout>
diff --git a/app/src/main/res/layout/http_request_layout.xml b/app/src/main/res/layout/http_request_layout.xml
new file mode 100644 (file)
index 0000000..4cbeb36
--- /dev/null
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <LinearLayout
+            android:id="@+id/info_edit_data"
+            android:orientation="vertical"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:padding="6dp"
+            >
+            <LinearLayout
+                android:id="@+id/mode_change_button_area"
+                android:orientation="horizontal"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:padding="6dp"
+                >
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:tag="button"
+                    android:id="@+id/change_to_liveview"
+                    android:text="@string/dialog_button_liveview"
+                    android:layout_gravity="center"
+                    android:visibility="visible"
+                    android:textSize="6pt" />
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:tag="button"
+                    android:id="@+id/change_to_playback"
+                    android:text="@string/dialog_button_playback"
+                    android:layout_gravity="center"
+                    android:visibility="visible"
+                    android:textSize="6pt" />
+            </LinearLayout>
+
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/method_name"
+                android:tag="title"
+                android:maxWidth="130dp"
+                android:minWidth="130dp"
+                android:layout_gravity="start">
+            </TextView>
+
+            <EditText android:id="@+id/edit_http_header"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="text"
+                android:hint="@string/http_dialog_http_url_hint"
+                />
+
+            <EditText android:id="@+id/edit_method"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="text"
+                android:hint="@string/http_dialog_method_hint"
+                />
+
+            <EditText android:id="@+id/edit_service"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="text"
+                android:hint="@string/http_dialog_service_hint"
+                />
+
+            <EditText android:id="@+id/edit_command"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="text"
+                android:hint="@string/http_dialog_command_hint"
+                />
+
+            <EditText android:id="@+id/edit_parameter"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:autoLink="all"
+                android:linksClickable="true"
+                android:inputType="textMultiLine"
+                android:hint="@string/http_dialog_parameter_hint"
+                />
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:tag="button"
+                android:id="@+id/send_message_button"
+                android:text="@string/dialog_send_message"
+                android:layout_gravity="center"
+                android:textSize="6pt" />
+
+            <View
+                android:layout_width="fill_parent"
+                android:layout_height="2dp"
+                android:background="@android:color/darker_gray"/>
+
+            <TextView
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/olympuspen_command_response_value"
+                android:text="@string/blank"
+                />
+
+            <View
+                android:layout_width="fill_parent"
+                android:layout_height="2dp"
+                android:background="@android:color/darker_gray"/>
+
+        </LinearLayout>
+    </ScrollView>
+</LinearLayout>
index eb85ea9..9cab506 100644 (file)
@@ -3,11 +3,13 @@
     <string-array name="connection_method">
         <item>Ricoh GR II / PENTAX DSLR</item>
         <item>OPC(Olympus Air)</item>
+        <item>Fujifilm X</item>
     </string-array>
 
     <string-array name="connection_method_value">
-        <item >RICOH_GR2</item>
+        <item>RICOH_GR2</item>
         <item>OPC</item>
+        <item>FUJI_X</item>
     </string-array>
 
     <string-array name="gr2_display_mode">
index 611a605..2dea045 100644 (file)
@@ -9,6 +9,7 @@
     <string name="dialog_positive_execute">OK</string>
     <string name="dialog_negative_cancel">Cancel</string>
     <string name="dialog_message_power_off">カメラの電源を切り、アプリケーションを終了します。</string>
+    <string name="dialog_message_exit">アプリケーションを終了します。</string>
     <string name="dialog_title_button_retry">再試行</string>
     <string name="dialog_title_connect_failed">接続失敗</string>
     <string name="dialog_title_button_network_settings">WiFi設定</string>
 
     <string name="pref_ricoh_get_pics_list_timeout">撮影画像一覧取得時のタイムアウト(単位:秒)</string>
     <string name="pref_summary_ricoh_get_pics_list_timeout">カメラ内の画像が多い場合は数を増やしてください。</string>
+
+    <string name="pref_exit_only">アプリ終了</string>
+    <string name="pref_fujix_display_camera_view">LVをカメラでも表示</string>
+    <string name="pref_fujix_display_camera_view_summary">お試し:ライブビューをカメラ画面で同時表示します</string>
+    <string name="pref_fujix_focus_xy">フォーカス点数 (default: 7,7)</string>
+    <string name="pref_summary_fujix_focus_xy">フォーカス点数を指定します</string>
+    <string name="pref_fujix_liveview_wait">LV画像受信待ち間隔(default: 80)</string>
+    <string name="pref_summary_fujix_liveview_wait">ライブビュー画像受信間隔を指定します</string>
+    <string name="pref_special_thanks">Special Thanks to</string>
+
+    <string name="dialog_http_command_title_command">HTTPmessage送信</string>
+    <string name="http_dialog_service_hint">(service)</string>
+    <string name="http_dialog_method_hint">GET/POST/PUT</string>
+    <string name="http_method_string">GET</string>
+    <string name="http_service_string">get_camprop.cgi</string>
+    <string name="http_dialog_command_hint">(command)</string>
+    <string name="http_dialog_parameter_hint">(paramenter)</string>
+    <string name="http_dialog_http_url_hint">http://192.168.1.1/</string>
+    <string name="dialog_send_message">送信</string>
+    <string name="dialog_button_liveview">ライブビュー</string>
+    <string name="dialog_button_playback">画像参照</string>
+
+    <string name="pref_wifi_settings">WiFi設定</string>
+    <string name="pref_summary_wifi_settings"> </string>
+
 </resources>
index eb85ea9..9cab506 100644 (file)
@@ -3,11 +3,13 @@
     <string-array name="connection_method">
         <item>Ricoh GR II / PENTAX DSLR</item>
         <item>OPC(Olympus Air)</item>
+        <item>Fujifilm X</item>
     </string-array>
 
     <string-array name="connection_method_value">
-        <item >RICOH_GR2</item>
+        <item>RICOH_GR2</item>
         <item>OPC</item>
+        <item>FUJI_X</item>
     </string-array>
 
     <string-array name="gr2_display_mode">
index 4e85442..05fe8dd 100644 (file)
@@ -13,6 +13,8 @@
     <string name="dialog_negative_cancel">Cancel</string>
 
     <string name="dialog_message_power_off">Power Off</string>
+    <string name="dialog_message_exit">Exit Application</string>
+
 
     <string name="dialog_title_connect_failed">Connect failed</string>
     <string name="dialog_title_button_retry">Retry</string>
 
     <string name="pref_cat_application_control">App. Control</string>
     <string name="pref_exit_power_off">Exit Application(and Camera OFF)</string>
+    <string name="pref_exit_only">Exit Application</string>
+
+    <string name="pref_fujix_display_camera_view">Use Camera Display</string>
+    <string name="pref_fujix_display_camera_view_summary">EXPERIMENTAL: Shows liveview screen both camera and smartphone.</string>
+
+    <string name="pref_fujix_focus_xy">Number of Focus Point X,Y (default: 7,7)</string>
+    <string name="pref_summary_fujix_focus_xy"> </string>
+
+    <string name="pref_fujix_liveview_wait">Liveview receive wait (default: 80)</string>
+    <string name="pref_summary_fujix_liveview_wait"> </string>
+
+    <string name="pref_special_thanks">Special Thanks to</string>
 
     <string name="pref_capture_both_camera_and_live_view">Capture both camera and Live View</string>
 
 
     <string name="pref_ricoh_get_pics_list_timeout">Get Pics List Timeout(unit: sec.)</string>
     <string name="pref_summary_ricoh_get_pics_list_timeout">If the camera has many number of Pics, increase number.</string>
+
+    <string name="dialog_http_command_title_command">HTTP Send</string>
+    <string name="http_dialog_service_hint">(service)</string>
+    <string name="http_dialog_method_hint">GET/POST/PUT</string>
+    <string name="http_method_string">GET</string>
+    <string name="http_service_string">get_camprop.cgi</string>
+    <string name="http_dialog_command_hint">(command)</string>
+    <string name="http_dialog_parameter_hint">(paramenter)</string>
+    <string name="http_dialog_http_url_hint">http://192.168.1.1/</string>
+    <string name="dialog_send_message">Send</string>
+    <string name="dialog_button_liveview">to LiveView</string>
+    <string name="dialog_button_playback">to Playback</string>
+
+    <string name="pref_wifi_settings">WIFI Settings</string>
+    <string name="pref_summary_wifi_settings"> </string>
+
 </resources>
diff --git a/app/src/main/res/xml/preferences_fuji_x.xml b/app/src/main/res/xml/preferences_fuji_x.xml
new file mode 100644 (file)
index 0000000..116a68f
--- /dev/null
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+    <PreferenceCategory
+        android:title="@string/pref_cat_application_control">
+
+        <PreferenceScreen
+            android:key="exit_application"
+            android:icon="@drawable/ic_power_settings_new_black_24dp"
+            android:title="@string/pref_exit_only" />
+
+        <ListPreference
+            android:title="@string/pref_connection_method"
+            android:entryValues="@array/connection_method_value"
+            android:entries="@array/connection_method"
+            android:key="connection_method"
+            android:defaultValue="FUJI_X"/>
+
+        <PreferenceScreen
+            android:key="wifi_settings"
+            android:title="@string/pref_wifi_settings"
+            android:summary="@string/pref_summary_wifi_settings" />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:title="@string/pref_cat_camera">
+
+        <CheckBoxPreference
+            android:key="capture_both_camera_and_live_view"
+            android:title="@string/pref_capture_both_camera_and_live_view" />
+
+        <CheckBoxPreference
+            android:key="fujix_display_camera_view"
+            android:title="@string/pref_fujix_display_camera_view"
+            android:summary="@string/pref_fujix_display_camera_view_summary"/>
+
+        <EditTextPreference
+            android:key="fujix_focus_xy"
+            android:title="@string/pref_fujix_focus_xy"
+            android:defaultValue="7,7"
+            android:summary="@string/pref_summary_fujix_focus_xy" />
+
+        <EditTextPreference
+            android:key="fujix_liveview_wait"
+            android:title="@string/pref_fujix_liveview_wait"
+            android:defaultValue="80"
+            android:summary="@string/pref_summary_fujix_liveview_wait" />
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:title="@string/pref_cat_initialize">
+
+        <CheckBoxPreference
+            android:key="auto_connect_to_camera"
+            android:title="@string/pref_auto_connect_camera"
+            android:summary="@string/pref_summary_auto_connect_camera" />
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:title="@string/pref_cat_others">
+
+        <CheckBoxPreference
+            android:key="share_after_save"
+            android:title="@string/pref_call_share_after_save" />
+
+        <CheckBoxPreference
+            android:key="use_playback_menu"
+            android:title="@string/pref_use_playback_menu"
+            android:summary="@string/summary_use_playback_menu" />
+
+        <Preference
+            android:key="special_thanks"
+            android:title="@string/pref_special_thanks"
+            android:summary="https://github.com/hkr/fuji-cam-wifi-tool"
+            android:selectable="true">
+            <intent android:action="android.intent.action.VIEW"
+                android:data="https://github.com/hkr/fuji-cam-wifi-tool" />
+        </Preference>
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
+        android:title="@string/pref_cat_gokigen">
+
+        <Preference
+            android:key="instruction_link"
+            android:title="@string/pref_instruction_manual"
+            android:summary="https://osdn.net/projects/gokigen/wiki/GR2Control"
+            android:selectable="true">
+            <intent android:action="android.intent.action.VIEW"
+                android:data="https://osdn.net/projects/gokigen/wiki/GR2Control" />
+        </Preference>
+
+        <Preference
+            android:key="privacy_policy"
+            android:title="@string/pref_privacy_policy"
+            android:summary="https://osdn.net/projects/gokigen/wiki/PrivacyPolicy"
+            android:selectable="true">
+            <intent android:action="android.intent.action.VIEW"
+                android:data="https://osdn.net/projects/gokigen/wiki/PrivacyPolicy" />
+        </Preference>
+
+        <PreferenceScreen
+            android:key="debug_info"
+            android:title="@string/pref_degug_info"
+            android:summary="@string/pref_summary_debug_info" />
+
+    </PreferenceCategory>
+</PreferenceScreen>
index 0c5194a..afe9783 100644 (file)
             android:key="connection_method"
             android:defaultValue="OPC"/>
 
+        <PreferenceScreen
+            android:key="wifi_settings"
+            android:title="@string/pref_wifi_settings"
+            android:summary="@string/pref_summary_wifi_settings" />
+
     </PreferenceCategory>
 
     <PreferenceCategory
index 1140257..9ea0916 100644 (file)
             android:key="connection_method"
             android:defaultValue="RICOH_GR2"/>
 
+        <PreferenceScreen
+            android:key="wifi_settings"
+            android:title="@string/pref_wifi_settings"
+            android:summary="@string/pref_summary_wifi_settings" />
+
     </PreferenceCategory>
 
     <PreferenceCategory
index f53f49f..7a8b51e 100644 (file)
@@ -7,9 +7,7 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.5.0'
-        
-
+        classpath 'com.android.tools.build:gradle:3.6.3'
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
     }