OSDN Git Service

自動転送のために仕組みを仕込んでみた。(その2)
authorMRSa <mrsa@myad.jp>
Fri, 29 Mar 2019 16:17:00 +0000 (01:17 +0900)
committerMRSa <mrsa@myad.jp>
Fri, 29 Mar 2019 16:17:00 +0000 (01:17 +0900)
app/src/main/java/net/osdn/gokigen/pkremote/transfer/AutoTransferFragment.java
app/src/main/java/net/osdn/gokigen/pkremote/transfer/FileAutoTransferMain.java [new file with mode: 0644]
app/src/main/java/net/osdn/gokigen/pkremote/transfer/ITransferMessage.java [new file with mode: 0644]
app/src/main/res/layout/fragment_auto_transfer.xml
app/src/main/res/values-ja/strings.xml
app/src/main/res/values/strings.xml

index 6fbbed6..05b9a13 100644 (file)
@@ -1,6 +1,7 @@
 package net.osdn.gokigen.pkremote.transfer;
 
 import android.content.Context;
+import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.os.Vibrator;
 import android.util.Log;
@@ -10,7 +11,9 @@ import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.ImageButton;
+import android.widget.ImageView;
 import android.widget.ProgressBar;
+import android.widget.TextView;
 
 import net.osdn.gokigen.pkremote.R;
 import net.osdn.gokigen.pkremote.camera.interfaces.IInterfaceProvider;
@@ -22,14 +25,20 @@ import androidx.fragment.app.Fragment;
 
 import static android.content.Context.VIBRATOR_SERVICE;
 
-public class AutoTransferFragment extends Fragment implements View.OnClickListener
+/**
+ *   自動転送クラス
+ *
+ */
+public class AutoTransferFragment extends Fragment implements View.OnClickListener, ITransferMessage
 {
     private final String TAG = this.toString();
 
-    private IInterfaceProvider interfaceProvider = null;
-    private IChangeScene changeScene = null;
+    private static final int SLEEP_MS = 3000;   // 待機時間
+
     private AppCompatActivity activity = null;
+    private FileAutoTransferMain transferMain = null;
     private View myView = null;
+    private boolean transferThreadIsRunning = false;
 
     public static AutoTransferFragment newInstance(@NonNull AppCompatActivity context, IChangeScene sceneSelector, @NonNull IInterfaceProvider provider)
     {
@@ -45,17 +54,14 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
         return (instance);
     }
 
-
     /**
      *
      */
     private void prepare(@NonNull AppCompatActivity activity, IChangeScene sceneSelector, IInterfaceProvider interfaceProvider)
     {
         Log.v(TAG, "prepare()");
-
         this.activity = activity;
-        this.changeScene = sceneSelector;
-        this.interfaceProvider = interfaceProvider;
+        transferMain = new FileAutoTransferMain(activity, sceneSelector, interfaceProvider, this);
     }
 
     /**
@@ -120,8 +126,11 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
     {
         super.onPause();
 
-        // 画面を抜ける時には、自動転送を停止させる
-        finishTransfer();
+        // 画面を抜ける時に転送モードであった場合は、自動転送を停止させる
+        if (transferThreadIsRunning)
+        {
+            finishTransfer();
+        }
     }
 
     private void prepare(@NonNull View view)
@@ -146,19 +155,76 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
         }
     }
 
+    /**
+     *   転送開始
+     *
+     */
     private void startTransfer()
     {
+        if (activity == null)
+        {
+            //  activityがない場合は動かない。
+            Log.v(TAG, "ACTIVITY IS NULL...");
+            return;
+        }
         try
         {
-            // STARTボタンを無効化
+            // STARTボタンを無効化してぶるぶるする...
             controlButton(false);
-
-            // ぶるぶるする
             Vibrator vibrator = (activity != null) ? (Vibrator) activity.getSystemService(VIBRATOR_SERVICE) : null;
             if (vibrator != null)
             {
                 vibrator.vibrate(50);
             }
+
+            // 画面上にある自動転送の設定を取得
+            CheckBox raw = activity.findViewById(R.id.check_auto_download_raw);
+            CheckBox original = activity.findViewById(R.id.check_auto_download_original);
+            final boolean isRaw = raw.isChecked();
+            final boolean isSmallSize = !original.isChecked();  // 画面上のチェックとは逆にする...
+
+            Thread thread = new Thread(new Runnable()
+            {
+                @Override
+                public void run()
+                {
+                    int count = 0;
+                    if (transferMain != null)
+                    {
+                        // 前処理...
+                        transferMain.start(isRaw, isSmallSize);
+                    }
+                    while (transferThreadIsRunning)
+                    {
+                        try
+                        {
+                            if (transferMain != null)
+                            {
+                                // チェックして追加ファイルがあったらダウンロード
+                                transferMain.downloadFiles();
+                            }
+                            count++;
+                            Log.v(TAG, "TRANSFER LOOP : " + count);
+
+                            // ちょっと待機...
+                            Thread.sleep(SLEEP_MS);
+                        }
+                        catch (Exception e)
+                        {
+                            e.printStackTrace();
+                        }
+                    }
+                    if (transferMain != null)
+                    {
+                        // 後処理...
+                        transferMain.finish();
+                    }
+                }
+            });
+
+            // 転送の開始
+            transferThreadIsRunning = true;
+            thread.start();
         }
         catch (Exception e)
         {
@@ -167,10 +233,17 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
     }
 
 
+    /**
+     *   転送終了
+     *
+     */
     private void finishTransfer()
     {
         try
         {
+            // 転送モードを止める
+            transferThreadIsRunning = false;
+
             // STARTボタンを有効化
             controlButton(true);
 
@@ -187,6 +260,10 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
         }
     }
 
+    /**
+     *   画面上のボタンを制御する
+     *
+     */
     private void controlButton(boolean isStartButtonEnable)
     {
         try
@@ -198,6 +275,7 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
                 start.setEnabled(isStartButtonEnable);
                 stop.setEnabled(!isStartButtonEnable);
                 CheckBox check = activity.findViewById(R.id.check_auto_download_raw);
+                CheckBox original = activity.findViewById(R.id.check_auto_download_original);
                 ProgressBar bar = activity.findViewById(R.id.auto_transfer_progress_bar);
                 ImageButton reload = activity.findViewById(R.id.button_reload);
                 ImageButton connect = activity.findViewById(R.id.button_wifi_connect);
@@ -211,6 +289,10 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
                     {
                         check.setEnabled(true);
                     }
+                    if (original != null)
+                    {
+                        original.setEnabled(true);
+                    }
                     if (reload != null)
                     {
                         reload.setVisibility(View.VISIBLE);
@@ -232,6 +314,10 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
                     {
                         check.setEnabled(false);
                     }
+                    if (original != null)
+                    {
+                        original.setEnabled(false);
+                    }
                     if (reload != null)
                     {
                         reload.setEnabled(false);
@@ -251,6 +337,10 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
         }
     }
 
+    /**
+     *
+     *
+     */
     @Override
     public void onClick(View v)
     {
@@ -267,4 +357,65 @@ public class AutoTransferFragment extends Fragment implements View.OnClickListen
             finishTransfer();
         }
     }
+
+    /**
+     *
+     *
+     */
+    @Override
+    public void storedImage(@NonNull final String filename, final Bitmap picture)
+    {
+        if (activity != null)
+        {
+            activity.runOnUiThread(new Runnable() {
+                @Override
+                public void run()
+                {
+                    TextView textView = activity.findViewById(R.id.image_view_information);
+                    if (textView != null)
+                    {
+                        textView.setText(filename);
+                    }
+                    try
+                    {
+                        if (picture != null)
+                        {
+                            ImageView imageView = activity.findViewById(R.id.image_view_area);
+                            if (imageView != null)
+                            {
+                                imageView.setImageBitmap(picture);
+                            }
+                        }
+                    }
+                    catch (Throwable t)
+                    {
+                        t.printStackTrace();
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     *
+     *
+     */
+    @Override
+    public void showInformation(@NonNull final String message)
+    {
+        if (activity != null)
+        {
+            activity.runOnUiThread(new Runnable() {
+                @Override
+                public void run()
+                {
+                    TextView textView = activity.findViewById(R.id.auto_download_information_text);
+                    if (textView != null)
+                    {
+                        textView.setText(message);
+                    }
+                }
+            });
+        }
+    }
 }
diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/transfer/FileAutoTransferMain.java b/app/src/main/java/net/osdn/gokigen/pkremote/transfer/FileAutoTransferMain.java
new file mode 100644 (file)
index 0000000..3eb79d0
--- /dev/null
@@ -0,0 +1,183 @@
+package net.osdn.gokigen.pkremote.transfer;
+
+import android.util.Log;
+
+import net.osdn.gokigen.pkremote.R;
+import net.osdn.gokigen.pkremote.camera.interfaces.IInterfaceProvider;
+import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent;
+import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentListCallback;
+import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentsRecognizer;
+import net.osdn.gokigen.pkremote.playback.detail.MyContentDownloader;
+import net.osdn.gokigen.pkremote.scene.IChangeScene;
+
+import java.util.List;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+
+/**
+ *   画像の自動転送を実現するクラス
+ *   (UIスレッドでは動いていないので注意)
+ */
+class FileAutoTransferMain implements ICameraContentListCallback
+{
+    private final String TAG = this.toString();
+
+    private final IInterfaceProvider interfaceProvider;
+    private final IChangeScene changeScene;
+    private final AppCompatActivity activity;
+    private final ITransferMessage messageInterface;
+    private final MyContentDownloader downloader;
+    private boolean firstContent = false;
+    private List<ICameraContent> baseContentList = null;
+    private List<ICameraContent> currentContentList = null;
+    private int dummyCount = 0;
+
+    FileAutoTransferMain(@NonNull AppCompatActivity context, IChangeScene sceneSelector, @NonNull IInterfaceProvider provider, @NonNull ITransferMessage messageInterface)
+    {
+        this.activity = context;
+        this.changeScene = sceneSelector;
+        this.interfaceProvider = provider;
+        this.messageInterface = messageInterface;
+        this.downloader = new MyContentDownloader(context, provider.getPlaybackControl());
+    }
+
+    /**
+     *   画像の自動転送 前処理
+     *
+     */
+    void start(boolean getRaw, boolean smallSize)
+    {
+        String message = "TRANSFER START [raw:" + getRaw + "] [small:" + smallSize + "]";
+        Log.v(TAG, message);
+
+        try
+        {
+            // 内部データの初期化
+            dummyCount = 0;
+            baseContentList = null;
+            currentContentList = null;
+            firstContent = true;
+
+            // 現在のカメラ画像一覧をとってくる
+            interfaceProvider.getPlaybackControl().getCameraContentList(this);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *   画像の自動転送  本処理
+     *
+     */
+    void downloadFiles()
+    {
+        try
+        {
+            Log.v(TAG, "CHECK FILE");
+            interfaceProvider.getPlaybackControl().getCameraContentList(this);
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *   画像の自動転送 後処理
+     *
+     */
+    void finish()
+    {
+        try
+        {
+            Log.v(TAG, "FINISH");
+            messageInterface.showInformation("");
+            baseContentList = null;
+            currentContentList = null;
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        System.gc();
+    }
+
+    private boolean downloadImages()
+    {
+        try
+        {
+            Log.v(TAG, "downloadImages()");
+
+            // baseContentList と currentContentList の差分を確認する
+
+            // 見つけた画像を(連続して)ダウンロードする
+
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        return (false);
+    }
+
+
+    // ICameraContentListCallback
+    @Override
+    public void onCompleted(List<ICameraContent> contentList)
+    {
+        Log.v(TAG, "RECEIVE CONTENT LIST");
+        try
+        {
+            if (firstContent)
+            {
+                baseContentList = contentList;
+                if ((baseContentList != null)&&(baseContentList.size() > 0))
+                {
+                    firstContent = false;
+                }
+            }
+            else
+            {
+                currentContentList = contentList;
+            }
+            if ((baseContentList != null)&&(currentContentList != null)&&(currentContentList.size() > 0))
+            {
+                // コンテンツ数の差異を確認する。
+                int baseSize = baseContentList.size();
+                int currentSize = currentContentList.size();
+                dummyCount++;
+                if (baseSize != currentSize)
+                {
+                    // 画像ファイル数が変わった!
+                    messageInterface.showInformation(activity.getString(R.string.image_checking) + " " + currentSize);
+                    if (downloadImages())
+                    {
+                        // ベースのコンテンツリストを更新する
+                        baseContentList = currentContentList;
+                        currentContentList = null;
+                    }
+                }
+                else
+                {
+                    // 画像ファイルサイズが変わっていない場合は表示を消す
+                    messageInterface.showInformation("[" + dummyCount + "]");
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+    // ICameraContentListCallback
+    @Override
+    public void onErrorOccurred(Exception e)
+    {
+        Log.v(TAG, "RECEIVE FAILURE...");
+        e.printStackTrace();
+    }
+}
diff --git a/app/src/main/java/net/osdn/gokigen/pkremote/transfer/ITransferMessage.java b/app/src/main/java/net/osdn/gokigen/pkremote/transfer/ITransferMessage.java
new file mode 100644 (file)
index 0000000..06c8232
--- /dev/null
@@ -0,0 +1,11 @@
+package net.osdn.gokigen.pkremote.transfer;
+
+import android.graphics.Bitmap;
+
+import androidx.annotation.NonNull;
+
+public interface ITransferMessage
+{
+    void storedImage(@NonNull String filename, Bitmap picture);
+    void showInformation(@NonNull String message);
+}
index 0e782e6..0ec2049 100644 (file)
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/scroll_view_transfer"
+    android:layout_height="match_parent"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <ImageView
-        android:id="@+id/image_view_area"
-        android:layout_width="match_parent"
-        android:layout_height="160dp"
-        android:src="@null"
-        android:scaleType="centerCrop"
-        tools:ignore="ContentDescription" />
-    <View
-        android:layout_width="fill_parent"
-        android:layout_height="1dp"
-        android:background="@android:color/darker_gray"/>
-
-    <LinearLayout
+    android:layout_alignParentTop="true"
+    android:layout_alignParentLeft="true"
+    android:layout_alignParentStart="true"
+    >
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:tools="http://schemas.android.com/tools"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        style="?android:attr/buttonBarStyle"
-        android:orientation="horizontal">
+        android:orientation="vertical">
 
-        <Button
-            android:id="@+id/transfer_start_button"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+        <ImageView
+            android:id="@+id/image_view_area"
+            android:layout_width="match_parent"
+            android:layout_height="160dp"
+            android:src="@null"
+            android:scaleType="fitCenter"
+            tools:ignore="ContentDescription" />
+
+        <TextView
+            android:id="@+id/image_view_information"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
             android:layout_weight="1"
-            android:visibility="visible"
-            android:enabled="true"
-            style="?android:attr/buttonBarButtonStyle"
-            android:text="@string/button_transfer_start" />
+            android:gravity="start"
+            android:clickable="true"
+            android:focusable="true"
+            android:text="@string/blank"
+            android:textColor="@color/background_dark"
+            android:textSize="9pt" />
 
-        <Button
-            android:id="@+id/transfer_stop_button"
-            android:layout_width="wrap_content"
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dp"
+            android:background="@android:color/darker_gray"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:visibility="visible"
-            android:enabled="false"
-            style="?android:attr/buttonBarButtonStyle"
-            android:text="@string/button_transfer_stop" />
+            style="?android:attr/buttonBarStyle"
+            android:orientation="horizontal">
 
-    </LinearLayout>
-    <View
-        android:layout_width="fill_parent"
-        android:layout_height="1dp"
-        android:background="@android:color/darker_gray"/>
+            <Button
+                android:id="@+id/transfer_start_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:visibility="visible"
+                android:enabled="true"
+                style="?android:attr/buttonBarButtonStyle"
+                android:text="@string/button_transfer_start" />
 
-    <CheckBox android:id="@+id/check_auto_download_raw"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/action_download_with_raw"
-        android:checked="false"
-        android:textSize="8pt"
-        />
+            <Button
+                android:id="@+id/transfer_stop_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:visibility="visible"
+                android:enabled="false"
+                style="?android:attr/buttonBarButtonStyle"
+                android:text="@string/button_transfer_stop" />
 
-    <View
-        android:layout_width="fill_parent"
-        android:layout_height="1dp"
-        android:background="@android:color/darker_gray"/>
+        </LinearLayout>
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dp"
+            android:background="@android:color/darker_gray"/>
 
-    <TextView
-        android:id="@+id/auto_download_information_text"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"
-        android:gravity="start"
-        android:clickable="true"
-        android:focusable="true"
-        android:text="@string/blank"
-        android:textColor="@color/background_dark"
-        android:textSize="9pt" />
+        <CheckBox android:id="@+id/check_auto_download_raw"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/action_download_with_raw"
+            android:checked="false"
+            android:textSize="8pt"
+            />
+        <CheckBox android:id="@+id/check_auto_download_original"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/action_auto_download_original_size"
+            android:checked="false"
+            android:textSize="8pt"
+            />
 
-    <ProgressBar
-        android:id="@+id/auto_transfer_progress_bar"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:visibility="gone"
-        />
-</LinearLayout>
+        <View
+            android:layout_width="fill_parent"
+            android:layout_height="1dp"
+            android:background="@android:color/darker_gray"/>
+
+        <TextView
+            android:id="@+id/auto_download_information_text"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:gravity="start"
+            android:clickable="true"
+            android:focusable="true"
+            android:text="@string/blank"
+            android:textColor="@color/background_dark"
+            android:textSize="9pt" />
+
+        <ProgressBar
+            android:id="@+id/auto_transfer_progress_bar"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:visibility="gone"
+            />
+    </LinearLayout>
+</ScrollView>
index e61fdc8..5e15bca 100644 (file)
     <string name="select_radio_date">日付</string>
     <string name="select_radio_path">パス</string>
 
-    <string name="action_download_with_raw">RAWも取得</string>
+    <string name="action_auto_download_original_size">オリジナルサイズを取得</string>
+    <string name="action_download_with_raw">RAWや動画も取得</string>
+
     <string name="dialog_title_batch_download">一括取得(サイズの選択)</string>
     <string name="dialog_positive_download">ダウンロード</string>
     <string name="dialog_label_batch_download">選択 : </string>
 
     <string name="button_transfer_start">転送開始</string>
     <string name="button_transfer_stop">転送終了</string>
+    <string name="image_checking">撮影画像確認中&#8230;</string>
 
 </resources>
index 8696571..b3cba33 100644 (file)
     <string name="select_radio_date">Date</string>
     <string name="select_radio_path">Path</string>
 
-    <string name="action_download_with_raw">Download with RAW</string>
+    <string name="action_auto_download_original_size">Download Original Size</string>
+    <string name="action_download_with_raw">Download with RAW/MOV</string>
+
     <string name="dialog_title_batch_download">Batch Download(select size)</string>
     <string name="dialog_positive_download">Download</string>
     <string name="dialog_label_batch_download">Selected : </string>
 
     <string name="button_transfer_start">TRANSFER START</string>
     <string name="button_transfer_stop">TRANSFER STOP</string>
+    <string name="image_checking">Image checking&#8230;</string>
 
 </resources>