もっと使おうPhoneGap/Cordova 2.0.0

第6回 File APIを使ったiOS/Androidアプリケーション作成[その3]

この記事を読むのに必要な時間:およそ 11.5 分

前回は,実際にFile APIを使ってファイルの操作を行う準備について説明しました。今回は前回に続いて以下の操作について紹介します。

  • TEMPORARYファイルシステムのファイル一覧を取得し,画面に表示
  • Camera APIで作成したファイルをPERSISTENTファイルシステムに移動
  • PERSISTENTファイルシステムに,画像ファイルの詳細データを格納したテキストファイルを作成

今回も前回と同様,iOSとAndroid,両OSでの手順を紹介していきます。実機を使用せず,Mac OS上のiOSシミュレータ,Windows上のAndroidエミュレータとPCに接続されているカメラデバイスを用いた手順を紹介します。

TEMPORARYファイルシステムのファイル一覧を取得(iOS/Android)

前回紹介したFile APIのオブジェクト,メソッドを用いて,TEMPORARYファイルシステム上のファイル一覧を取得してみましょう。ソースコードは次のとおりです。

リスト1 ソースコード: File API Test (2)

 1 <!DOCTYPE html>
 2 <html>
 3    <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 5     <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" />
 6     <title>File API Test (2)</title>
 7   </head>
 8   <body>
 9     <div class="app">
10       <h1>File API Test</h1>
11       <ul id="tempfs_fileList"></ul>
12     </div>
13     <script type="text/javascript" src="cordova-2.0.0.js"></script>
14     <script type="text/javascript">
15     document.addEventListener('deviceready', init, false);
16     function init() {
17       // TEMPORARYファイルシステムを取得
18       window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, getFilesFromDirectory, fail);
19     }
20 
21     function getFilesFromDirectory(fileSystem) {
22       // FileSystemオブジェクトのrootプロパティには,DirectoryEntryオブジェクトが格納されている
23       var directoryEntry = fileSystem.root;
24 
25       // DirecotryEntryオブジェクトのcreateReaderメソッドを使い,
26       // ディレクトリ内のファイルを読み込むためのDirectoryReaderオブジェクトを作成
27       var directoryReader = directoryEntry.createReader();
28 
29       // DirectoryReaderオブジェクトのreadEntriesメソッドを使い,
30       // ディレクトリ内のエントリを読み込み,コールバック関数に配列として渡す
31       directoryReader.readEntries(putFileName, fail);
32     }
33 
34     function putFileName(entries) {
35       // ディレクトリ内のエントリがFileEntryオブジェクトまたは
36       // DirectoryEntryオブジェクトとして配列で渡される
37       for ( index = 0; index < entries.length; index++ ) {
38         // ファイル名を格納する DOM を作成
39         var listItem = document.createElement('li');
40         listItem.textContent = entries[index].name;
41         
42         // 作成した DOM を <ul id="tempfs_fileList"></ul> に挿入
43         document.getElementById('tempfs_fileList').appendChild(listItem);
44       }
45     }
46 
47     function fail(error) {
48       // エラーについては http://docs.phonegap.com/en/2.0.0/cordova_file_file.md.html#FileError を参照
49       alert('エラーが発生しました。エラーコード: ' + error.code);
50     }
51     </script>
52   </body>
53 </html>

このサンプルコードでは,TEMPORARYファイルシステムのファイル一覧を取得し,列挙します。iOSシミュレータ,Androidエミュレータで実行した場合の動作結果は次のとおりです。

iOSシミュレータで実行

iOSシミュレータで実行

Androidエミュレータで実行

Androidエミュレータで実行

リスト1サンプルコードで行っている処理の流れは次のとおりです。

  1. requestFileSystemでTEMPORARYファイルシステムを取得
  2. FileSystemオブジェクトのrootプロパティから,TEMPORARYファイルシステムのルートディレクトリの情報(DirectoryEntryオブジェクト)を取得
  3. DirectoryEntryオブジェクトのcreateReaderメソッドを用いて,DirectoryReaderオブジェクトを作成
  4. DirectoryReaderオブジェクトのreadEntriesメソッドを用いて,ディレクトリ内のファイル/ディレクトリエントリを読み込む
  5. readEntriesメソッドから渡されたFileEntry/DirectoryEntryの配列を受け取り,ファイル名を<li>要素で列挙

第4回の記事を参照し,各オブジェクトの関係性や処理の流れを把握しておくと理解しやすいでしょう。

18行目のrequestFileSystemメソッドは,PERSISTENTまたはTEMPORARYのどちらかのFileSystemオブジェクトを取得します。第3引数で指定したgetFilesFromDirectory関数に,取得したFileSystemオブジェクトが渡されます。

18  window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, getFilesFromDirectory, fail);

FileSystemオブジェクトのrootプロパティには,DirectoryEntryオブジェクトが格納されています。DirectoryEntryオブジェクトのcreateReaderメソッドを用いて,TEMPORARYファイルシステム,ルートディレクトリ内のディレクトリ・ファイルを読み込むためのオブジェクト--DirectoryReaderオブジェクトを作成し,directoryReader変数に格納します。

22  // FileSystemオブジェクトのrootプロパティには,DirectoryEntryオブジェクトが格納されている
23  var directoryEntry = fileSystem.root;
24  
25  // DirecotryEntryオブジェクトのcreateReaderメソッドを使い,
26  // ディレクトリ内のファイルを読み込むためのDirectoryReaderオブジェクトを作成
27  var directoryReader = directoryEntry.createReader();

DirectoryReaderオブジェクトには1つだけメソッドが用意されています。ディレクトリ内のエントリを読み込むメソッド--readEntriesメソッドを用いて,ディレクトリ内のディレクトリ・ファイル情報を第1引数で指定したputFileName関数に渡します。

29  // DirectoryReaderオブジェクトのreadEntriesメソッドを使い,
30  // ディレクトリ内のエントリを読み込み,コールバック関数に配列として渡す
31  directoryReader.readEntries(putFileName, fail);

あるディレクトリ内にディレクトリが1つ,ファイルが3つある場合には,次のような配列がコールバック関数に渡されます。

[<DirectoryEntry>, <FileEntry>, <FileEntry>, <FileEntry>]

putFileName関数はDirectoryEntry/FileEntryが格納された配列を受け取り,for文で配列の要素の数だけDOMを作成して,ディレクトリ名/ファイル名を列挙します。

34  function putFileName(entries) {
35    // ディレクトリ内のエントリがFileEntryオブジェクトまたは
36    // DirectoryEntryオブジェクトとして配列で渡される
37    for ( index = 0; index < entries.length; index++ ) {
38      // ファイル名を格納する DOM を作成
39      var listItem = document.createElement('li');
40      listItem.textContent = entries[index].name;
41      
42      // 作成した DOM を <ul id="tempfs_fileList"></ul> に挿入
43      document.getElementById('tempfs_fileList').appendChild(listItem);
44    }
45  }

fail関数はFile APIでファイルを操作している場合にエラーが起こった際に呼び出される関数です。FileErrorオブジェクトを受け取り,エラーコードを表示します。数値とエラーコードの対応は次のとおりです。

// cordova-2.0.0.js 2180-2195
// File error codes
// Found in DOMException
FileError.NOT_FOUND_ERR = 1; 
FileError.SECURITY_ERR = 2; 
FileError.ABORT_ERR = 3; 

// Added by File API specification
FileError.NOT_READABLE_ERR = 4; 
FileError.ENCODING_ERR = 5; 
FileError.NO_MODIFICATION_ALLOWED_ERR = 6; 
FileError.INVALID_STATE_ERR = 7; 
FileError.SYNTAX_ERR = 8; 
FileError.INVALID_MODIFICATION_ERR = 9; 
FileError.QUOTA_EXCEEDED_ERR = 10;
FileError.TYPE_MISMATCH_ERR = 11;
FileError.PATH_EXISTS_ERR = 12;

著者プロフィール

富田宏昭(とみだひろあき)

株式会社キクミミでFileMaker/SQLiteを使ったWebアプリ開発に従事しながら,オープンソースソフトウェアのハウツー記事執筆を行う。趣味は横乗り系スポーツ,美術館めぐり,高速ジャンクション鑑賞。

コメント

コメントの記入