2013年1月24日木曜日

uses-featureに大苦戦

X メールなんですけど。

どうしても Nexus 7 に対応させたかったんですよ。

対応出来ていない理由が、permission絡みで、カメラ関係とLandscape関係だったってのは大体想像ついたんですけど、結局対応させるのに2ヶ月以上かかりました。。。

なぜか

まずは X メール が元々Android 1.6 Xperia をターゲットに入れて作成され始めたために、対象のAPI レベルが 4 で、コンパイルのターゲットも API 4 にしていたんです。

この状態のmanifesto.xmlはuses-featureは使えるんですが、android:requiredが使えないので、特定のハードウェア要件によるフィルタリング阻止が出来なかったんですね。


この中で色々検討してたんです。プロジェクトをもう一つ高レベルのAPI用に作ってリリースするとか、なんとか抜け道はないかとか。


試行錯誤の結果、コンパイルターゲットをAndroid 2.1(APIいくつか忘れた!)に上げてみたところ、なんとmanifestoのターゲットは API 4 のまま、android:requeredが使えるようになったんです!

これで晴れて uses-feature でのフィルタリングを回避して X メール を Nexus 7 にインストール出来るようになりました!


この後問題が出ないとは限りませんけどね。

そのときはきっとプロジェクトを分けて対応するしかないかも知れないです。。


2013年1月21日月曜日

X mail 2.4.6 リリース

な、なんと。

前回の2.4.5はリリースに失敗しておりました。。情けない。。

というわけで前回の修正点を含めた以下が更新されています。


・メールを全員に返信時、自分を受信者に含めない状態だと送信者以外のアドレスがコピーされなくなっていた不具合を修正。
・送信後のメッセージをクリックが必要なオーケーダイアログから不要なトーストメッセージに変更。
・送信先のサジェストリストで、「.」を入力した時やリストを最後までスクロールさせたさいに発生していたエラーを修正。
・機種ごとに動作が不安定だった、カメラ起動時のフラッシュライト機能を削除した。


2013年1月17日木曜日

Chrome extension 入門一歩先

本格的にChrome extensionを作ってみました。

で、色々忘れないように備忘録的に書いておこうかと。

ちなみにHello Worldは他に譲ります。概念的な部分をもしかしたら厳密には違うかもしれませんが、書き記しておきます。

まずはmanifest.json。バージョン2について


忘れちゃいけないことを列挙します。
  • "manifest_version":2がバージョン2であることの宣言
  • permissionで、tabsなどは不要
  • インラインで書かれたjsやcssは動かないので、使う時はmanifestの中で、それぞれのスコープ宣言部でインクルードする
  • 通信permissionやmatchesは"http://*/*"のような書き方が出来る

ここからが大事。Chrome extensionの世界観


extensionはブラウザを改造するものです。ブラウザはURLからHTML等を取得し、ドキュメントを描画するものです。extensionはブラウザの動作に働きかけるために以下の3つのスコープを持っています。
  • アイコン表示とクリック時に表示されるポップアップなどのUIプロセス
  • extensionが有効化されている間、常駐しているバックグラウンドプロセス
  • コンテンツとともに動作するコンテントスクリプトプロセス

extensionはユーザーに有効化されると、ブラウザとは別のプロセスとして動作します。この基本がバックグラウンドプロセスであり、全ての中心であると考えるとデザインしやすいと思います。

このプロセスはユーザーとのやり取りもコンテンツとのやり取りも行いませんが、extensionが有効である限り常にロードされており、変数などが保持されます。ページ毎のコンテントスクリプトプロセスやイベントドリブンなUIプロセスはバックグラウンドプロセスとchrome.extension.getBackgroundPage();で直接スコープを読みだしたり、メッセージを使ってより対話的な情報交換を行うことで、ブラウジングとUIを結びつける高度なアプリケーションを作成できるようになります。

スコープの読み出し例

/* manifest.json */
{
    ...
    "background": {
        "scripts": ["background.js"]
    },
    ...
    "browser_action": {
        ...
        "default_popup": "popup.html"
    }
}
/* background.jsにvar resultがグローバル変数として宣言されている場合、popup.html内のスクリプトタグでインクルードされている(ここではそう記述されているとする)popup.js内ではこのresultの内容を以下のように参照可能 */
var bg = chrome.extension.getBackgroundPage();
var bg_result = bg.result;

メッセージ利用例

/* manifest.json */
{
    ...
    "background": {
        "scripts": ["background.js"]
    },
    ...
    "content_scripts": [{
        "matches": ["http://*/*", "https://*/*"],
        "js": "contentscript.js",
        "run_at": "document_end"
    }],...
    ...
}
/* background.jsにvar resultがグローバル変数として宣言されている場合、contentscript.js内ではこのresultの内容を以下のように参照可能 */
/* contentscript.js */
...
//以下でメッセージをやり取りする接続(パイプ)を作成する
var port = chrome.extension.connect({"name": "message_pipe"});
//以下でメッセージを送信して
port.postMessage({"dataA": "A", "dataB": "B", "dataC": "C"});
//以下でbackground.jsからの返信を受け取る
port.onMessage.addListener(function(msg){
    //msgにはbackground.jsからの返信オブジェクトが入っており、resultA~resultCが参照できる
    var reA = msg.resultA;
    var reB = msg.resultB;
    var reC = msg.resultC;
});
/* background.js */
...
//接続された時に以下が動くので
chrome.extension.onConnect.addListener(function(port){
    //メッセージのリスナを登録しておく
    port.onMessage.addListener(function(msg){
        //msgにはcontentscript.jsからの送信オブジェクトが入っており、dataA~dataCが参照できる
        var reA = msg.dataA + " result";
        var reB = msg.dataB + " result";
        var reC = msg.dataC + " result";
        //contentscript.jsに返信
        port.postMessage({"resultA": reA, "resultB": reB, "resultC": reC});
    });
});

バックグラウンドプロセスは省略可能で、例えばアイコンクリックでどこからか、何らかの情報を取得し、ポップアップに何かを表示するだけのextensionであればバックグラウンドプロセスを宣言する必要はないかもしれません。

2つめは今出ましたアイコンとポップアップなどのインタラクティブUI部分です。具体的には以下の3種類があります。
  • アイコンとポップアップのブラウザアクション
  • アドレスバー内に表示するページアクション
  • 別タブで専用のページを表示するオプションページ

これらはそれぞれmanifesut.json内に"browser_action", "page_action", "options_page"という名前で宣言し、関連するファイルを結びつけます。

UI系のプロセスはスコープがmanifest内で宣言したファイルまでで、それを越えることができません。タブに表示されている通常のコンテンツの情報を取得するには上で紹介した方法を用いてバックグラウンドプロセスを介して情報を取得する必要があります。直接コンテントスクリプトとやり取りすることは恐らく難しいか出来ないと思われます。動作するタイミングの関係でバックグラウンドプロセス(もしくはローカルストレージ)を介するほうが無難だと思います。

最後はコンテントスクリプトプロセスです。ブラウズするドキュメントに対し、manifest.json内run_atのタイミングで関連付けされたjsファイルを読み込みます。このスコープはダウンロードされたコンテンツですので、documentオブジェクトは実際ダウンロードされたコンテンツを参照します。

このプロセスの中でコンテンツ内の必要な情報をバックグラウンドプロセス(もしくはローカルストレージ)に渡すというのがコンテンツ解析系のextensionでは基本的な動きになるのではないでしょうか?


以上。

2013年1月10日木曜日

X mailer 2.4.5 リリース

今回の修正は以下です。

・送信後のメッセージをクリックが必要なオーケーダイアログから不要なトーストメッセージに変更。
・送信先のサジェストリストで、「.」を入力した時やリストを最後までスクロールさせたさいに発生していたエラーを修正。
・機種ごとに動作が不安定だった、カメラ起動時のフラッシュライト機能を削除した。


うー、なんだかんだ次のアプリの設計に入れてないなぁ。
頑張ります。

このアプリも頑張りますよ!

なんせ、自分が使ってますからね(笑)

2013年1月6日日曜日

Nexus 7 がどうなったかと今後

バージョンアップ中にお亡くなりになりましたNexus 7 ですが、結局google playにお問い合わせして交換ということになりました。

最初、ASUSのカスタマセンターに電話したんですが、Google Playから購入したものはここに電話しろ!と言われた番号にかけて、何も悪いことはしていないという確認の後(boot loaderから初期化を試したか?とかは聞かれたけど、自作アプリをPCら放り込んだことは特に言及されなかった)、交換の手続き説明。

手順としては、


  • 送られたメールにあるリンクからGoogle PlayでNexus 7の発注を新たに行う(ここで使うクレジットカードが保証になっているとのこと
  • Nexus 7が梱包材と一緒に届くので、その梱包材で壊れた端末を印刷した証書と一緒に、これまた同梱されている着払い配達伝票で送る
  • 最初に送られてきたメールにある送りましたよ登録をする
のような手順だったと思います。ぶっちゃけ年末のガン飲み週間の前だったので記憶が。。。


というわけで、めでたくNexus 7 2台持ちになりました~。パチパチパチ~


そして、次に作るアプリも決定しましたよ!


「戦略じゃんけんゲーム」


ああ~アイディアパクられる!(ないです)

今回はUI設計からちゃんと考えようと思います。
対象はAndroid 2.2以上かな。


また進展ありましたらブログします