2013年4月26日金曜日

Androidアプリの画面をdpでデザインする: Design layout of Android App with dp

Androidでは、1ピクセルの大きさが、機種によって大きく異なる。
そのため、一辺の長さを100ピクセルに指定してサムネイルの画像を表示すると、機種によっては大きさが半分ぐらいになってしまう。

では、機種に依存せずに、同じ見た目の大きさにするにはどうしたらよいのだろうか?
そのためには、ピクセルの単位で大きさを指定するのではなく、dip、pxと文字数を合わせてdpと呼ばれる事が多い、の単位で大きさを指定すればよい。
dipは、device independent pixcel(端末非依存ピクセル)の略で、1辺の大きさが1/160インチの仮想的なピクセルである。

前述のサムネイルの大きさがまちまちになる問題を避けるには、100ピクセルと言ったサイズを指定するのではなく、50dpと言うようにサイズを指定すればよい。そうすれば、見た目の大きさはすべての端末で同じ大きさになり、問題は解決する。

しかし、である。Androidは、端末の画面サイズも機種によりまちまちである。
例えば、50dpのサムネイルは横に幾つまではみ出さずに表示できるのだろうか?と言う疑問に突き当たる。
そこで、各種端末の画面の大きさをdp単位で求めてみたのが下表である。

表: 端末毎のdp単位で求めた画面サイズ
機種: Modelディスプレイサイズ: Display Size
(inch)
幅: Width (px)高さ: Height (px)dpi幅: Width (dp)高さ: Height (dp)
HTC Desire3.7480800252305508
Xperia4.0480854245314558
Galaxy S4.0480800233329549
Galaxy Nexus4.77201280312369655
Xperia Z5.010801920441392697
Galaxy Note5.38001280285449719
Galaxy Note II5.57201280267431767
Galaxy Mega 6.36.37201280233494879
Galaxy Tab7.06001024170566966
Nexus 77.08001280216594950
Optimus Pad8.976812801687331,221
Nexus 1010.0160025603028481,357

上記の表を見ると、縦画面の場合、HTC DesireからGalaxy Sまでは6つ、Galaxy NexusからXperia Zまでは7つ、Galaxy Noteは8つということが分かる。

このように、大きさをdp単位で指定し、各端末の画面サイズはdp単位の大きさを持つと考えるて、画面のレイアウトを考えればよい。

結構面倒な気もするが、画面の大きさがまちまちなのは、PCのブラウザの画面も同じなので、レイアウトの考え方は、ブラウザと同じように考えればよい。

ブラウザで横幅のレイアウトを考えるとき、%指定で幅をしていすれば上手く行く事が多い。Androidの場合、大きさを0dpと指定し、weightで幅の割合を指定すると、同様の事ができる。このように、HTMLやCSSでのレイアウトのテクニックをAndroidのレイアウトのXMLファイルで応用できないかを考えるとよい。実際、XMLファイルで指定できる属性は、HTMLでも名前が違うだけで同様の属性がある事が多い。

2013年2月8日金曜日

課金APIの概略 - Androidのアプリ内課金(In-App Billing)のまとめ (その2)

課金API概略


開発者のアプリは、端末にインストールされているGoogle Playアプリによって公開されているAPIを使って、課金サービスにアクセスする。
Google Playアプリは、課金リクエストとその応答を、Google Playサーバーと開発者のアプリの間で運ぶ。開発者のアプリは直接Google Playのサーバーと通信する事はなく、課金要求は、プロセス間通信(IPC)を介して、Google Playアプリへ送られる。

アプリ課金は、Google Playを介して配布されたアプリの中でのみ実装できる。また、課金要求を完了するには、Google Playアプリがネットワークを通じてGoogle Playサーバーにアクセスする必要がある。

APIの仕様は、Version 2とVersion 3とで大きく異なる。大きな相違点は以下の通り。

  • Version 2は非同期で処理されるが、Version 3では同期で処理される点である。
  • Version 2は、Android 1.6以降でサポートされるが、Version 3は、Android 2.2以降でサポートされる。

Version 3 APIの概略


購入フロー


購入の典型的な流れは以下の通り。
  1. IInAppBillingService#isBillingSupportedのリクエストをGoogle Playに送って、端末がアプリ課金APIをサポートしているかどうかを決定する。
  2. 次に、アプリ開始時もしくはユーザーがログインしたタイミングで、IInAppBillingService#getPurchasesのリクエストを送って、ユーザーが製品を購入済みかどうかをチェックする。Google Playは、購入済みの製品のIDを含むBundleを返す。
  3. 大抵の場合、購入可能なアイテムの情報をユーザーに示す必要がある。Google PlayのDevelopper Consoleで定義した製品の詳細情報を問い合わせるには、IInAppBillingService#getSkuDetailsを送ればよい。Google Playは、価格、タイトル、説明、製品タイプを含むBundleを返す。
  4. 製品がユーザーによって購入されていなければ、即座に購入を開始できる。購入するには、まず、product ID等を含むIInAppBillingService#getBuyIntentを送って購入のためのIntentをGoogle Playから取得する。product IDを指定するため、開発者はDevelopper Consoleで新しい製品を定義したときに、product IDをメモしておく必要がある。その後の流れは以下の通り。
    1. Google Playは購入を開始するためのPendingIntentを含むBundleを返す。
    2. アプリは、PendingIntentをActivity#startIntentSenderForResultを呼び出して、開始させる。
    3. 購入のフローが完了したら、Google Playは、Activity#onActivityResultに応答のIntentを送ってくる。

購入製品の消費


    ユーザーが購入した製品を消費した事にした場合の流れは以下の通り。
    1. IInAppBillingService#getPurchasesのリクエストを送って、ユーザーが製品を購入済みかどうかをチェックする。
    2. 購入していれば、IInAppBillingService#consumePurchaseを呼び出して、消費した事にする。


    2013年2月1日金曜日

    アプリ内課金の製品タイプ - Androidのアプリ内課金(In-App Billing)のまとめ (その1)

    Androidのアプリ内課金の日本語の情報が、古い情報しか見当たらないので、現状(2013年2月)をまとめておく。

    APIのバージョン

    現状で、最初に考えるべき事は、課金のAPIのバージョンを決めることである。
    現在の段階では、APIのバージョンは以下の通り。
    • Version 3(推奨)
    • Version 2
    バージョンの違いによって、販売できる製品(product)、課金APIの処理方式に違いがある。
    結論を先に書くと、定期的に自動課金をする場合(購読タイプの製品)は、Version 2を選択するしかない。(数週間後には、改善されるかもしれない)
    そうでなければ、コーディングが楽な処理方式のVersion 3を選択するべきである。

    販売できる製品タイプ

    Version 3の場合


    管理タイプ製品(managed)


    現在のところ、これしかない。これは、Googleによって購入履歴が管理されている。管理の単位はGoogle Playのユーザーアカウント毎である。

    Googleによって管理される事により、アプリは、どのような場合でも、ユーザーが製品を購入したかどうかをAPIを通じて知る事ができる。例え、アプリが再インストールされた場合や別端末で購入した場合であってもである。

    Version 3の場合はVersion 2と異なり、管理タイプ製品には消費(consume)機能がある。
    通常、管理タイプは、一度購入すると二度と購入することができない。この機能は、一度だけ課金したい場合、例えば、広告を外すとか上位機能を有効にするとかに有用な機能である。
    しかし、何度も購入できる製品の場合、例えばゲームで使う薬草やコイン等の場合は、二度と購入できないのでは困る。そのような場合は、課金タイプに対して、消費APIを呼び出す事により再度購入できるようになる。

    Version 2の場合


    販売できる製品タイプは以下の通り。
    • 管理タイプ製品(managed)
    • 非管理タイプ製品(unmanaged)
    • 購読タイプ製品(subuscription)

    管理タイプ製品


    Google Playのユーザーアカウント毎にに一度だけ購入できるタイプの製品である。広告を外すとか、上位機能を有効にするとかの場合に使う製品である。
    ユーザーが管理タイプの製品を購入すると、Google Playでは、ユーザー毎に各アイテムの購入情報が永続的に管理される。
    もし、ユーザーが一度購入した製品を購入しようとしても、Google Play側で「既に購入済み」のエラーを表示して再購入を予防する。
    このタイプは、ユーザーがアプリを再インストールしたり、データを消去したり、別の新しい端末にインストールした時でも、購入情報をリストアできるため、便利である。

    非管理タイプ製品


    Google Playには、購入情報が保存されないタイプの製品である。つまり、後でGoogle Playに購入情報を問い合わせる事ができない。非管理タイプは、開発者側で購入情報を管理する必要がある。
    また、Google Playは、ユーザーが何度も同じ製品を購入することを阻止しない。
    非管理タイプは、消費されてしまうアイテム、つまりゲームの薬草や燃料などを売るのに向いていいる。このようなアイテムは、アプリの中で消費され、何度も購入するものだからである。

    購読タイプ製品


    これは、開発者が指定した間隔で課金される製品である。ユーザーが購読タイプを購入すると、Google Playとその課金システムは、指定された間隔と金額でユーザーに請求する。一度、ユーザーが購入すると、Google Playは、ユーザーの同意や行動がなくても、永続的に課金を続ける。
    ユーザーは、いつでも購入をキャンセルする事ができる。
    購読は、管理タイプ製品のみ適用できる。一度ユーザーが購入すると、払い戻しの機会はない。払い戻しを求めるユーザーは、開発者に直接連絡しなければならない。