コンテンツのダウンロード
第3回では、FlashAirのコンテンツをダウンロードするアプリを作成します。 ダウンロード処理では、CordovaのFileプラグイン及びFileTransferプラグインを使用します。
事前準備
1. プロジェクトを作成する
まずは作成するアプリのプロジェクトを作成します。 前回までと同じく、プロジェクトを作成したいディレクトリへ移動し、以下のコマンドを実行します。
> cordova create cordovatutorial3 com.fixstars.flashair.tutorial CordovaTutorial3
また、プロジェクト作成後、browserプラットフォーム及び第2回で使用したStatusbarプラグイン(config.xml
へのコード追加作業含む)の追加を行ってください。
2. 第2回で使用したファイルを追加する
第2回で使用したファイルを以下のようにコピーして追加します。
cordovatutorial3 ├─ hooks ├─ platforms ├─ plugins ├─ www │ ├─ css │ │ └─ load.css(上書きコピー) │ ├─ img │ │ └─ logo.png │ ├─ js │ │ ├─ jquery-3.1.1.min.js(上書きコピー) │ │ ├─ load.js(上書きコピー) │ │ └─ tutorial2.js(上書きコピー) │ ├─ index.html(上書きコピー) │ └─ tutorial2.html(上書きコピー) └─ config.xml
アプリのトップ画面作成
1. index.htmlを編集する
アプリのトップ画面であるindex.html
を編集します。
第2回の36~39行目を、以下のように変更してください。
/www/index.html
<p class="pos-center"><button type="button" onclick="location.href='tutorial2.html'">2.コンテンツリストの取得</button></p>
<p class="pos-center"><button type="button" onclick="location.href='tutorial3.html'">3.コンテンツのダウンロード</button></p>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/load.js"></script>
</body>
- 37行目
タップされたらtutorial3.html
の画面へ遷移するボタンを追加しています。コンテンツのダウンロードはtutorial3.html
の画面で行います。
2. 実行結果
上記の編集が完了したら、ビルドを行い、出来上がったアプリのインストールを行ってください。第2回と比べて、「3.コンテンツのダウンロード」ボタンを追加しています。
Androidデバイスの場合
iOSデバイスの場合
コンテンツのダウンロード画面の作成
1. tutorial3.htmlを作成する
続いて、コンテンツのダウンロード画面を作成します。tutorial2.htmlとの共通部分が多いので、コピーしたファイルをtutorial3.html
として保存して、9~24行目を以下のように変更してください。
/www/tutorial3.html
<title>Tutorial3</title>
<link rel="stylesheet" type="text/css" href="css/load.css">
</head>
<body onload="onLoad()">
<div id="header" class="pos-center">
<div id="head-left"><<br>Back</div>
<h1 id="head-center">Download</h1>
<div id="head-right"></div>
</div>
<div id="list"></div>
<hr>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="js/tutorial3.js"></script>
</body>
</html>
- 9行目
画面のタイトルをTutorial3
に変更しています。 - 15行目
ヘッダーのタイトルをDownload
に変更しています。 - 18-19行目
tutorial3.js
で取得するコンテンツリストをここに表示させます。 - 22行目
ロードするJavaScriptの内、tutorial2.js
をtutorial3.js
へ変更しています。tutorial3.js
については後述します。
2. tutorial3.jsで使用するプラグインを追加する
次はtutorial3.js
の作成に移りますが、その前にそちらで使用するプラグインを追加していきます。 まず、ダウンロード処理で使用するFileTransferプラグインを追加します。 また、ダウンロード時に端末内のファイルへアクセス(書き込み)を行うのに必要なFileプラグインも追加します。 また、ファイルのダウンロード後、コンテンツの表示にウェブブラウザビューを使用するので、Inappbrowserプラグインも追加します。 それぞれの追加コマンドは以下の通りです。
> cordova plugin add cordova-plugin-file -save
cordova plugin add cordova-plugin-file-transfer -save
cordova plugin add cordova-plugin-inappbrowser -save
3. tutorial3.jsを作成する
コンテンツのダウンロード画面でロードするtutorial3.js
を作成していきます。 ダウンロード処理はFileTransferプラグインのdownloadを利用して行います。 また、tutorial2.jsと異なり、コンテンツリストは階層表示ができるようにします。
/www/js/tutorial3.js
var currentPath = "/";
var wlansd = new Array();
var doesFileExist = false;
function onLoad(){
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady(){
getFileList("");
$(document).on("click", "a.dir", function(){
getFileList(this.text);
});
$(document).on("click", "a.file", function(){
downloadFile(this.text, currentPath);
});
document.addEventListener("backbutton", onBackKeyDown, false);
$("#head-left").click(function(){
onBackKeyDown();
});
}
function onBackKeyDown(){
if(doesFileExist == false){
location.href = "index.html";
} else if(currentPath == "/"){
location.href = "index.html";
} else {
getFileList("..");
}
}
// Get the content list.
function getFileList(dir){
doesFileExist = false;
var nextPath = makePath(dir);
var url = "http://flashair/command.cgi?op=100&DIR=" + nextPath;
$.get(url, function(data){
//Save the current path.
currentPath = nextPath;
// Split lines by new line characters.
wlansd = data.split(/\n/g);
// Ignore the first line (title) and last line (blank).
wlansd.shift();
wlansd.pop();
splitFileList(currentPath);
wlansd.sort(cmptime);
showFileList(currentPath);
// Success to get content list.
doesFileExist = true;
});
}
// Make a Path to show next.
function makePath(dir){
var arrPath = currentPath.split("/");
if(currentPath == "/"){
arrPath.pop();
}
if(dir == ".."){
// Go to parent directory. Remove last fragment.
arrPath.pop();
} else if(dir != "" && dir != "."){
// Go to child directory. Append dir to the current path.
arrPath.push(dir);
}
if (arrPath.length == 1){
arrPath.push("");
}
return arrPath.join("/");
}
// Split the content list data.
function splitFileList(){
for(var i=0; i<wlansd.length; i++){
var elements = wlansd[i].split(",");
wlansd[i] = new Array();
wlansd[i]["r_uri"] = elements[0];
wlansd[i]["fname"] = elements[1];
wlansd[i]["fsize"] = Number(elements[2]);
wlansd[i]["attr"] = Number(elements[3]);
wlansd[i]["fdate"] = Number(elements[4]);
wlansd[i]["ftime"] = Number(elements[5]);
}
}
// Sort contents by date and time.
function cmptime(a,b){
if(a["fdate"] == b["fdate"]){
return a["ftime"] - b["ftime"];
} else {
return a["fdate"] - b["fdate"];
}
}
// Show the content list.
function showFileList(){
$("#list").html("");
$.each(wlansd, function(){
var file = this;
var filelink = $("<a href='javascript:void(0)'></a>");
var caption = file["fname"];
var faDir = file["r_uri"];
var fileobj = $("<div></div>");
// Skip hidden file.
if(file["attr"] & 0x02){
return;
}
// Make a link to directories and files.
if(file["attr"] & 0x10){
filelink.addClass("dir");
} else {
filelink.addClass("file");
}
$("#list").append(
fileobj.append(
filelink.append(
caption
)
)
);
});
}
// Download the content.
function downloadFile(fname, dir){
var fileTransfer = new FileTransfer();
var dlPath = dir !="/" ? dir + "/" + fname : dir + fname;
var dlUrl = encodeURI("http://flashair" + dlPath);
var destUrl = encodeURI("cdvfile://localhost/persistent/download/" + fname);
fileTransfer.download(dlUrl, destUrl, function(entry) {
window.open = cordova.InAppBrowser.open(entry.toURL(), "_blank", "location=no");
}, function(error) {
switch (error.code){
case 1:
alert("Failed to download the file. Error code is 'FILE_NOT_FOUND_ERR'");
break;
case 2:
alert("Failed to download the file. Error code is 'INVALID_URL_ERR'");
break;
case 3:
alert("Failed to download the file. Error code is 'CONNECTION_ERR'");
break;
case 4:
alert("Failed to download the file. Error code is 'ABORT_ERR'");
break;
case 5:
alert("Failed to download the file. Error code is 'NOT_MODIFIED_ERR'");
break;
}
});
}
- 1行目
コンテンツリストの取得や表示で使用する(FlashAir上の)カレントディレクトリの変数を宣言しています。初期値は"/"
(root)です。 - 9-21行目
deviceready
イベントが発火した後、最初にgetFileList('')
でrootのコンテンツリストを取得・表示させています。 そして、class="dir"
を持つリンクがタップされた場合はそのディレクトリのコンテンツリストを新たに表示させます。 また、class="file"
を持つリンクがタップされた場合はそのファイルコンテンツをダウンロードするdownloadFile
関数を呼び出します。 - 23-31行目
getFileList
関数でコンテンツリストのデータを取得できなかった場合、もしくはカレントディレクトリがrootの場合は、トップ画面へ戻るようにしています。また、カレントディレクトリがrootでない場合は、一つ前(親)のディレクトリのコンテンツリストを表示するようにしています。 - 33-52行目
コンテンツリストのデータを取得する関数です。 36行目でcommand.cgi?op=100のコマンドを発行しています。FlashAirから返ってきたデータに対する処理は、2番目の引数であるコールバック関数(function(data) {...}
)の内部に記述します。 これは、CGIコマンドの実行が非同期的に行われるためです。取得したデータは48行目のshowFileList
関数で表示させています。 - 54-71行目
FlashAir上での絶対パスを作成するヘルパー関数です。 - 73-84行目
取得したコンテンツリストのデータを細分化して格納する関数です。 細分化したデータは、r_uri
がコンテンツのあるディレクトリ、fname
がコンテンツ名、fsize
がコンテンツのサイズ、attr
がコンテンツの属性、fdate
がコンテンツの作成日、ftime
がコンテンツの作成時間になります。 - 86-92行目
取得したコンテンツリストのデータを更新日時順に並べ替える関数です。 - 94-120行目
取得したコンテンツリストをHTML中に用意したlist
の位置に表示させる関数です。 - 123行目
FileTransferのインスタンス変数を宣言しています。 - 124-125行目
ファイルのダウンロード元となるサーバのURLを設定します。 - 126行目
ダウンロードしたファイルの保存先を設定します。 これは端末上のファイルのフルパスで指定する必要があります。ただし、FileTransferプラグインのdownloadではcdvfile
形式のパスを使用でき、これを使用すれば、プラットフォームに依存せず指定された場所(アプリ内)に保存されるようになります。cdvfile
の詳細については公式のFileプラグインのcdvfile protocol及びFileTransferプラグインのBackwards ompatibility Notesをご覧ください。 - 128-148行目
FileTransferプラグインのdownloadを利用して、ファイルのダウンロードを行っています。第1引数はダウンロード元URL、第2引数はダウンロード先のURL、第3引数はダウンロードのサクセスコールバック関数、第4引数はダウンロードのエラーコールバック関数です。サクセスコールバック関数(function(entry) {...}
)では、Inappbrowserプラグインの機能を利用して、ダウンロードしたファイルコンテンツをウェブブラウザビューで表示します。また、エラーコールバック関数(function(error) {...}
)では、デバッグ用として受け取ったエラーコードのアラートを出力します。 (※本サンプルコードではFileTransferプラグインのエラーコードを表示していますが、実際のアプリでは適切なメッセージを表示するのがよいでしょう。)
4. 実行結果
プロジェクト内の全てのファイルの配置が完了したら、ビルドを行い、アプリへインストールします。 ここで一つ注意点があります。 Androidデバイスでは以下の画面の通り、インストール時にストレージへのアクセス権限の許可が必要になります。 これはFileプラグイン及びFileTransferプラグイン利用でandroid.permission.WRITE_EXTERNAL_STORAGEパーミッションの利用を設定するためです。 (※iOSデバイスでは許可が必要になる権限はありません。)
アプリインストール後、FlashAirへ無線LAN接続していれば、トップ画面の「3.コンテンツのダウンロード」ボタンをタップすることで、コンテンツリストが表示されます。 またリストの内、ファイルコンテンツをタップすれば、アプリ内へのダウンロードを行い、ウェブブラウザビューで表示されます。 (以下の右側の画面は「テスト.txt」ファイルをタップして、ダウンロード完了後に表示される画面です。)
Androidデバイスの場合
iOSデバイスの場合
サンプルコード
- このサンプルコードはApache License, Version 2.0で提供されています。
- 「cordova_tutorial_03」ディレクトリは、zipファイルで圧縮してPhoneGap Buildへアップロードすることでビルドできます。 ビルド方法はHelloWorldアプリをビルドするをご確認ください。
- Cordovaプロジェクトで確認する場合は、「cordova_tutorial_03」ディレクトリ内のデータをプロジェクト内へ上書きコピーしてください。