2013年3月2日土曜日

Web Activities と Android の Intent の対応

Web Activities は Android の Intent みたいな機能で、Firefox OS でサポートされています。

Web Activities を使うにはアプリのマニフェストファイルに宣言します。
AndroidManifest は XML でしたが、こちらは JSON です。 { "name": "My App", "description": "my first web app", "launch_path": "./index.html", "activities": { "share": { "filters": { "type": ["image/png", "image/gif"] }, "href": "./index.html", "disposition": "window" } } } "activities" 部分が Web Activities の宣言です。
Android でいうと Activity の <intent-filter> 部分です。
この中に、このアプリが処理できる activity を記述していきます。

"share" 部分が Android でいう ACTION にあたる部分です。ここに指定できる activity 名はまだ完全には決まっていないようです。
典型的なものとして

・view 表示する
・share 共有する
・dial 電話をかける
・pick 画像や動画を選択する
・new メールなどを作成する

があります。
他の activity は上記のサイトで紹介していますが、個人的にはこれ以外はあんまり使わないと思います。

Android と比較すると

Web Activities⇔Android
view⇔ACTION_VIEW
share⇔ACTION_SEND
dial⇔ACTION_DIAL
pick⇔ACTION_PICK
new⇔ACTION_SENDTO

に対応します。

"filters" は対応するデータを指定するプロパティです。Android だと <intent-filter>タグ内の <data>タグにあたります。

"filter" の中の "type" はデータのタイプを指定するプロパティです。MIME Type というわけではないようで、"url" を指定することができます(でも将来的に url は text/html になるかもしれないらしい)。普通に "image/png" とかも指定できます。多分 "text/*" とか指定できると思うけど情報がないのでわかりません。Android だと <data> タグの mimeType 属性にあたります。
"url" というプロパティもあるらしいですが情報が少なすぎてよくわからないです。

"href" にはこの activity を処理するときに開くページを指定します。Android だと <intent-filter> タグを含む<activity> タグにあたります。

"disposition" はページを開くときの方法として "window" もしくは "inline" を指定します。
"window" の場合が画面全体が遷移先のアプリになり、"inline" ではダイアログで遷移先のアプリが開きます。



Android で registerReceiver() メソッドで BroadcastReceiver を動的に登録できたように、Web Activities でも Activity Handler を動的に登録することができます。
* どうもまだ実装されていないみたい? bug 775181 var register = navigator.mozRegisterActivityHandler({ name: "pick", disposition: "inline", filters: { type: "image/png" }
 }); register.onerror = function () { console.log("can not register activity");
 } mozUnregisterActivityHandlerで登録を解除することができます。(* どうもまだ実装されていないみたい? bug 775181) navigator.mozUnregisterActivityHandler(activityHandlerDescription);
mozIsActivityHandlerRegistered で登録されているか確かめることができます。(* どうもまだ実装されていないみたい? bug 775181) var bool = navigator.mozIsActivityHandlerRegistered(activityHandlerDescription);


マニフェストで宣言した場合でも、動的に Activity Handler を登録した場合でも、activity を受けとったときの処理は次のように行います。 navigator.mozSetMessageHandler("activity", function (req) {
 req.source; // ActivityOptions read-only // 処理 // ユーザーが操作をキャンセルした(= 前の画面に戻ることを意図している)ときは req.postError("user canceled"); // のように postError() を呼びます。 // そうしないと前の画面に戻れません。 // "pick" など値を返す場合は req.postResult(any result); // を呼びます。 }); 呼び出し元から渡されたデータは source パラメータで参照することができます。これは ActivityOptions オブジェクトで、次の様に定義されています。 interface ActivityOptions { attribute DOMString name; attribute Object? data; // a dictionary };



acitivty を呼び出すほうは、MozActivity のオブジェクトを作成します。

例)pick
*実際に動かしてみてOKだった var pick = new MozActivity({ name: "pick", data: { type: "image/png" } }); pick.onsuccess = function() { // データが返される場合、this.result の中にいろいろ入ってるらしい // 情報が少なくてよくわからない // 画像が返ってくる場合は this.result.blob; // にデータが入っている }; pick.onerror = function() { // エラー }


例)view
*実際に動かしてみてOKだった var pick = new MozActivity({ name: "view", data: { type: "url", url: "http://y-anz-m.blogspot.jp" } }); pick.onsuccess = function() { // view のときは普通値は返ってこないと思う }; pick.onerror = function() { // エラー } type: "url" はいずれ type: "text/html" になるかもしれないらしい。


例)dial
*実際に動かしてみてOKだった var pick = new MozActivity({ name: "dial", data: { number: "+46777888999" } }); pick.onsuccess = function() { // view のときは普通値は返ってこないと思う }; pick.onerror = function() { // エラー } + っているのかな?よくわからない。。。


例)share : URL を送る
*実際に動かしてみてOKだった var pick = new MozActivity({ name: "share", data: { type: "url", url: "http://y-anz-m.blogspot.jp" } }); pick.onsuccess = function() { // share のときは普通値は返ってこないと思う }; pick.onerror = function() { // エラー }


例)share : プレインテキストを送る

type をどうしたらいいのかまったくリファレンスがないのでわかりません。 うぁーん。
そもそも Brower の share 機能がないってどういうこと???


例)share : 画像を送る var image = getImage(); // blob かな? var pick = new MozActivity({ name: "share", data: { type: "image/png", number: "1", // なくてもいいかもしれない blobs: blob, filenames: "hogefile", // なくてもいいかもしれない filepaths: "hogepath" // なくてもいいかもしれない } }); pick.onsuccess = function() { // share のときは普通値は返ってこないと思う }; pick.onerror = function() { // エラー }



ぜんぜんドキュメントがまとまってなくて、ぐぬぬ、ぐぬぬ、ですよー。


実際に試してみた

1. ギャラリーアプリからの画像の共有を処理する

"share": { "filters": { "type": ["image/png", "image/gif", "image/jpg", "image/jpeg"] }, "href": "./index.html", "disposition": "window" } だと、ギャラリーからの共有にアプリが現れませんでしたが、 "share": { "filters": { "type": "image/*" }, "href": "./index.html", "disposition": "window" } だと、共有にアプリが現れました。
呼び出し元で指定してる type が "image/*" なので(以下を参照)、image/* にしとかないと受けとれないっぽいです。
呼び出し元が image/* ってのもどうかと思うけど。。。

こういう javascript にしておくと function init() { navigator.mozSetMessageHandler("activity", function (req) {
 var ao = req.source; // ActivityOptions var s = ao.name + ", data : "; for (var p in ao.data) { s += p + ", "; } alert(s); }); } window.addEventListener("load", init); data に含まれているプロパティが取得できます。これによると type, number, blobs, filenames, filepaths というプロパティがあることがわかりました。

そこで次の様にしてみると function init() { navigator.mozSetMessageHandler("activity", function (req) {
 var ao = req.source; // ActivityOptions var s = "name = " + ao.name + "\ndata : "; for (var p in ao.data) { s += p + ", "; } s += "\n"; s += "data.type = " + ao.data.type + "\n"; s += "data.number = " + ao.data.number + "\n"; s += "data.blobs = " + ao.data.blobs + "\n"; s += "data.filenames = " + ao.data.filenames + "\n"; s += "data.filepaths = " + ao.data.filepaths + "\n"; alert(s); }); } window.addEventListener("load", init); こうなりました。


2. Twitter アプリから Email で送るを処理する

"share": { "filters": { "type": ["image/*", "url"] }, "href": "./index.html", "disposition": "window" } のようにしてみたけど、起動候補にでませんでした。そこで "new": { "href": "./index.html", "disposition": "window" } にしたらでました。
type に "mail"、URI というプロパティに mailto:subject=... のような URI が入ってました。


3. pick を呼び出してみる

function init() { var pick = new MozActivity({ name: "pick", data: { type: "image/png" } }); pick.onsuccess = function() { // データが返される場合、this.result の中にいろいろ入ってるらしい // 情報が少なくてよくわからない // 画像が返ってくる場合は alert(this.result.blob); // にデータが入っている }; pick.onerror = function() { // エラー } } window.addEventListener("load", init);

画像を選択したあと


4. url を view で表示してみる

function init() { var pick = new MozActivity({ name: "view", data: { type: "url", url: "http://y-anz-m.blogspot.jp" } }); } window.addEventListener("load", init);


まとめ

受け渡されるデータ構造は上のリンク先の記事は全くあてにならなかったので注意してください。実際に動かした結果は次の様になりました。

ギャラリーから画像 share
ActivityOptions ao = req.source
ao.name : "share"
ao.data.type : "image/*"
ao.data.number
ao.data.blobs
ao.data.filenames
ao.filepaths

Twitter アプリからEmailで送る new
ActivityOptions ao = req.source
ao.name : "new"
ao.data.type : "mail"
ao.data.URI


同じ activity を複数登録できません。なので、 "activities": { "share": { "filters": { "type": "image/*" }, "href": "./index_for_image.html", "disposition": "window" }, "share": { "filters": { "type": "url" }, "href": "./index_for_url.html", "disposition": "window" } } のように type によって処理するページを変えたりとかできません。えーなんでー。。。


なんといってもプリインの Browser に share 機能がなくてすごく残念です。。。




0 件のコメント:

コメントを投稿