もっと使おうPhoneGap/Cordova 2.0.0

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

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

今回はFileReaderオブジェクトを使って,これまでに作成した画像ファイルとテキストファイルを読み込む手順を紹介していきます。

FileReaderオブジェクトを使ったファイルロード

PERSISTENTファイルシステムのファイル一覧を表示し,ファイル名をクリックして,ファイル内のデータを表示するアプリケーションを作成してみましょう。

新たに登場するオブジェクトとメソッドは次のとおりです。

  • FileReaderオブジェクト
  • readAsDataURLメソッド
  • readAsTextメソッド

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

PERSISTENTファイルシステムのファイル一覧を表示。ファイル名をクリックして,ファイル内のデータを表示(iOS/Android)

PERSISTENTファイルシステムのファイル一覧を表示し,ファイル名をクリックすることでファイルの中身が表示されるサンプルを作成します。これまでのサンプルでは,PERSISTENTファイルシステムに画像ファイルまたはテキストファイルが書き込まれます。画像の場合はその画像を表示,テキストファイルの場合は,テキストファイルの中身を表示します。

テスト用のソースコードは次のとおりです。

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

  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 (5)</title>
  7    </head>
  8    <body>
  9      <div class="app">
 10        <h1>File API Test</h1>
 11        <ul id="fileList"></ul>
 12        <div id="viewer" style="display: none">
 13          <table>
 14            <tr>
 15              <th>ファイル名</th>
 16              <td id="fileName"></td>
 17            </tr>
 18            <tr>
 19              <th>ファイルサイズ</th>
 20              <td id="fileSize"></td>
 21            </tr>
 22          </table>
 23          <div id="fileContents"></div>
 24          <input id="back" type="button" value="Back">
 25        </div>
 26      </div>
 27      <script type="text/javascript" src="cordova-2.0.0.js"></script>
 28      <script type="text/javascript">
 29      var directoryEntry;
 30  
 31      document.addEventListener('deviceready', init, false);
 32      function init() {
 33        // PERSISTENTファイルシステムを取得
 34        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, getFilesFromDirectory, fail);
 35        document.getElementById('back').addEventListener('click', back, false);
 36      }
 37  
 38      function getFilesFromDirectory(fileSystem) {
 39        // FileSystemオブジェクトのrootプロパティには,DirectoryEntryオブジェクトが格納されている
 40        directoryEntry = fileSystem.root;
 41  
 42        // DirecotryEntryオブジェクトのcreateReaderメソッドを使い,
 43        // ディレクトリ内のファイルを読み込むためのDirectoryReaderオブジェクトを生成
 44        var directoryReader = directoryEntry.createReader();
 45  
 46        // DirectoryReaderオブジェクトのreadEntriesメソッドを使い,
 47        // ディレクトリ内のエントリを読み込み,コールバック関数に配列として渡す
 48        directoryReader.readEntries(putFileName, fail);
 49      }
 50  
 51      function putFileName(entries) {
 52        // ディレクトリ内のエントリがFileEntryオブジェクトまたは
 53        // DirectoryEntryオブジェクトとして配列で渡される
 54        for ( index = 0; index < entries.length; index++ ) {
 55          // ファイルのみを表示する (ディレクトリは表示しない)
 56          if ( entries[index].isFile ) {
 57            // ファイル名を格納する DOM を生成
 58            var listItem = document.createElement('li');
 59            listItem.textContent = entries[index].name;
 60            listItem.title = entries[index].fullPath;
 61            listItem.addEventListener('click', viewFileEntry, false);
 62  
 63            // 作成した DOM を <ul id="fileList"></ul> に挿入
 64            document.getElementById('fileList').appendChild(listItem);
 65          }
 66        }
 67      }
 68  
 69      function viewFileEntry(event) {
 70        // FileEntryオブジェクトを取得
 71        directoryEntry.getFile(event.target.textContent, null, getFile, fail);
 72      }
 73  
 74      function getFile(fileEntry) {
 75        // Fileオブジェクトを取得
 76        fileEntry.file(readFile, fail);
 77      }
 78  
 79      function readFile(file) {
 80        var reader = new FileReader();
 81        document.getElementById('fileName').textContent = file.name;
 82        document.getElementById('fileSize').textContent = file.size;
 83   
 84        // ファイルタイプの判定
 85        // Androidの場合は,Fileオブジェクトのtypeプロパティから判定
 86        // iOSの場合は,Fileオブジェクトのnameプロパティから,拡張子で判定
 87        if
 88        (
 89          ( 'Android' === device.platform && 'jpg' === file.type ) ||
 90          ( file.name.match(/\.jpg$/i) )  
 91        ) {
 92          // 画像ファイルを readAsDataURL で読み込み
 93          reader.readAsDataURL(file);
 94          reader.onloadend = function(event) {
 95            document.getElementById('fileList').style.display = 'none';
 96            document.getElementById('viewer').style.display = 'block';
 97            var img = new Image();
 98            img.src = event.target.result;
 99            img.onload = function() {
100              document.getElementById('fileContents').appendChild(img);
101            }
102          }
103        } 
104        else if
105        (
106          ( 'Android' === device.platform && 'txt' === file.type ) ||
107          ( file.name.match(/\.txt$/i) )  
108        ) {
109          // テキストファイルを readAsText で読み込み
110          reader.readAsText(file);
111          reader.onloadend = function(event) {
112            document.getElementById('fileContents').textContent = event.target.result;
113            document.getElementById('fileList').style.display = 'none';
114            document.getElementById('viewer').style.display = 'block';
115            document.getElementById('fileContents').style.whiteSpace = 'pre';
116          }
117        }
118      }
119  
120      function back() {
121        document.getElementById('fileName').textContent = '';
122        document.getElementById('fileSize').textContent = '';
123        document.getElementById('fileContents').textContent = '';
124        document.getElementById('fileList').style.display = 'block';
125        document.getElementById('viewer').style.display = 'none';
126        document.getElementById('fileContents').style.whiteSpace = 'normal';
127      }
128  
129      function fail(error) {
130        // エラーについては http://docs.phonegap.com/en/2.0.0/cordova_file_file.md.html#FileError を参照
131        alert('エラーが発生しました。エラーコード: ' + error.code);
132      }
133      </script>
134    </body>
135  </html>

まずはiOSで実行してみましょう。アプリケーションを起動すると,PERSISTENTファイルシステムに格納されているファイルの一覧が<ul><li>要素で表示されます。DirectoryEntry/FileEntryに用意されているisFileプロパティを参照し,ファイルのみを対象としています。

PERSISTENTファイルシステムに格納されているファイルの一覧が列挙される

PERSISTENTファイルシステムに格納されているファイルの一覧が列挙される

ファイル名をクリックすると,ファイルの詳細が表示されます。画像ファイルの場合は画像が,テキストファイルの場合はテキストデータを画面に表示します。

画像ファイルをクリックすると,画像が表示される

画像ファイルをクリックすると,画像が表示される

テキストファイルをクリックすると,中身が表示される

テキストファイルをクリックすると,中身が表示される

iOSシミュレータでファイルを取り扱うアプリケーションを作成する場合,XcodeのデバッグログにBase64エンコードされたファイルデータを書き出す影響で,動作が遅くなります。スキーマの編集画面を開き,Build ConfigurationをDebugからReleaseにすることで,動作速度を向上させることができます。

著者プロフィール

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

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

コメント

コメントの記入