コンテンツの自動更新

最終更新: 2013/7

このチュートリアルではコンテンツの自動更新方法について学びます。
thumbnail.cgicommand.cgi を使用します

作成した Android Tutorial 4: サムネイルの表示 に自動更新機能を追加します。
FlashAirの内容が更新されると、コンテンツリストも更新します。

メモ: このチュートリアルの学習効果を高めるため、FlashAirをお手持ちのデジタルカメラに挿入することをお勧めします。
新しい写真を撮影したり、撮影済みの写真を削除すると、このアプリケーションにFlashAirの変更内容が反映されます。

コンテンツのファイル名とサムネイルのペアを含むリストは次のようになります:

This image shows the content list

FlashAirを挿入したデジタルカメラで写真を撮ると、コンテンツリストが(指定した時間後)にリフレッシュされ、撮った写真が反映されます:

This image shows an updated content list

新しく追加されたイメージファイルの名前をクリック(タップ)すれば、撮影したばかりの写真を表示することもできます:

This image shows the new image in an image view

表示されているとおり、Android 端末に画像ファイルがダウンロードされます。

アプリケーションを作成するために、次のファイルを作成します:

  • MainActivity.java
  • activity_main.xml
  • ImageViewActivity.java
  • activity_image_view.xml

重要: Android application は、デフォルトの状態ではインターネットにアクセスすることができません。
そのため、設定ファイル AndroidManifest.xml を変更し、権限を与える必要があります。
パス: [Project_Folder]/AndroidManifest.xml
AndroidManifest.xml に以下のコードを追加してください:

<uses-permission android:name="android.permission.INTERNET" />

リストのレイアウト作成

ではまず、 activity_main.xml を記述して、レイアウトを決定します。
このファイルは、layout フォルダに配置されています。
パス: [Project_Folder]/res/layout/activity_main.xml

activity_main.xmlAndroid Tutorial 3: コンテンツのダウンロードと同じになります。
実装の説明についてはそちらを参照してください。

イメージビューのレイアウト作成

次に、 activity_image_view.xml を記述して、レイアウトを決定します。
このファイルは、layout フォルダに配置されています。
パス: [Project_Folder]/res/layout/activity_image_view.xml

activity_image_view.xmlAndroid Tutorial 3: コンテンツのダウンロードと同じになります。
実装の説明についてはそちらを参照してください。

コンテンツリストの作成

さて、 MainActivity.java を修正します。
まずは FlashAir の任意のフォルダにあるファイル名の一覧を取得します(詳細は Android Tutorial 3: コンテンツのダウンロード を確認してください)。

次に、リスト中のファイル名とそのファイルのサムネイル画像をペアとして ListView に表示し、、動作を設定します(詳細は Android Tutorial 4: サムネイルの表示 を確認してください)。

初期化

Android Tutorial 4: サムネイルの表示MainActivity.java をコピーし、それを新しい MainActivity.java としてご使用ください。

class MainActivity 宣言, メンバ変数、と onCreate(Bundle savedInstanceState) 関数を下記のように置き換えます:

MainActivity.java (1)

public class MainActivity extends Activity implements AdapterView.OnItemClickListener {

    ListView listView;
    ImageView imageView;
    TextView currentDirText;
    TextView numFilesText;
    Button backButton;
    String rootDir = "DCIM";
    String directoryName = rootDir; // Initialize to rootDirectory
    SimpleAdapter listAdapter;
    int checkInterval = 5000;
    Handler updateHandler;
    boolean viewingList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewingList = true; // Start out viewing the list
        try {
            // Set buttons
            getWindow().setTitleColor(Color.rgb(65, 183, 216));
            backButton = (Button)findViewById(R.id.button1);
            backButton.getBackground().setColorFilter(Color.rgb(65, 183, 216), PorterDuff.Mode.SRC_IN);
            backButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(directoryName.equals(rootDir)) {
                        listRootDirectory();
                    }
                    else {
                        int index = directoryName.lastIndexOf("/");
                        directoryName = directoryName.substring(0, index);
                        listDirectory(directoryName);
                    }
                }
            });
            backButton.setEnabled(false); // Disable in root directory
            listRootDirectory();
        } catch(Exception e) {
            Log.e("ERROR", "ERROR: " + e.toString());
            e.printStackTrace();
        }
        updateHandler = new Handler();
        startUpdate();
    }

前回までに作成した MainActivity クラスにメンバ変数を追加しました。

  • 11行目
    FlashAirの状態をチェックする時間間隔を設定しています。
  • 12行目
    後述の関数で実装する Runnable を管理する Handler updateHandlerを宣言しています。
  • 13行目
    現在コンテンツリストや画像を表示ししているかを追跡する boolean viewingList を宣言しています 。

ルートのフォルダを"DCIM"としていますが(8行目)、他のフォルダをルートにしても構いません。
販売されている多くのデジタルカメラが撮影した画像を "DCIM" フォルダへ格納しているので、ここでは "DCIM" を設定しました。

残りの MainActivity.java はそのまま使用します(コンテンツリストの設定を含める必要があります)。

ビューの状態による制御

MainActivity.java に、更新の状態をチェックする処理を追加します。
この処理は、 以前作成した class MainActivity に含めます。

ユーザーがコンテンツリストを表示していない場合には、FlashAirの状態を監視する必要はありません。 コンテンツリストを表示する際に、最新の情報を取得するためです。
ユーザーがコンテンツリストを表示中の場合にだけ、FlashAirの状態を監視し、変更内容を反映するようにしましょう。

コンテンツリストのビューが表示されているかを判断するために、上記で宣言したフラグ viewingList (13行目)を更新するリスナー関数をオーバーライドします。

MainActivity.java (2)

    @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            super.onWindowFocusChanged(hasFocus);
            if(hasFocus) {
                viewingList = true;
            }
            else {
                viewingList = false;
            }
        }


    public boolean checkIfListView() {
        // Check if user is viewing a content list
        if(viewingList) {
            return true;
        }
        return false;
    }

hasFocus 変数は、コンテンツリストを表示している場合に True です。 ユーザーが View を切り替えると通知されます。 これは、以下の Runnable の実装を容易にしています。

更新ハンドラの設定と コンテンツの更新

FlashAirの更新状態を取得するためには、以下のコマンドを使用します。

  • command.cgiop=102 を指定します。
    • コマンド: http://flashair/command.cgi?op=102
    • コマンドが返す情報:
      • 1 アップデートされている
      • 0 アップデートされていない

コマンドCGIは 1 を1度だけ返します。 その後別の変更が行われるまでは 0 を返します。

コマンドの実行には前項 Android Tutorial 3: コンテンツのダウンロードまでに作成した、 FlashAirRequest.java を使用します。

次の関数では、コンテンツリストを自動更新する動作と、その間隔を決定します。

MainActivity.java (3)

    public Runnable statusChecker = new Runnable() {
        @Override
        public void run() {
            if (checkIfListView() == true) {
                new AsyncTask<String, Void, String>(){
                    @Override
                    protected String doInBackground(String... params) {
                        return FlashAirRequest.getString(params[0]);
                    }
                    @Override
                    protected void onPostExecute(String status) {
                        if(status.equals("1")) {
                            // Fetch current contents of FlashAir and display list
                            listDirectory(directoryName);
                        }
                    }
                }.execute("http://flashair/command.cgi?op=102");
            }
            updateHandler.postDelayed(statusChecker, checkInterval);
        }
    };


    public void startUpdate() {
        statusChecker.run();
    }


    public void stopUpdate() {
        updateHandler.removeCallbacks(statusChecker);
    }
  • 3-20行目 Runnable class のメイン処理 run() 関数を設定しています。
  • 19行目 updateHandlerに対し、 statusCheckerrun()関数が、 checkIntervalミリ秒後に実行されるよう設定しています。 このコードが自身の関数内の run() 関数で実行されていることに注意してください。 これは長い時間 updateHandler が停止せず、 checkInterval にミリ秒単位で設定した時間ごとに、再度実行されることを意味します。

画像表示画面の作成

class ImageViewActivityAndroid Tutorial 3: コンテンツのダウンロードと同じです。
実装の詳細についてはこのチュートリアルを参照してください。

サンプルコード

android_tutorial_05.zip (533KB)

このサイトのサンプルコードは 二条項BSDライセンスで提供されています。