2013年10月14日月曜日

自転車のかごにゴミを捨てられていた…


比較的新しくてキレイな俺の自転車のかごにタバコの空き箱と栄養ドリンクの瓶が捨てられていた。しかも瓶は逆さまで液体が少しかごに付いていた。

目つきが鋭くなる程度の怒りが込み上げてあたりを見渡すも犯人らしき人物は見つからない。財布とケータイだけを持って出かけていたから拭くものもなくさらに怒りが増す。

Twitterで迷惑行為をさらして炎上し、退学させられたり損害賠償を請求されたりするのをみていたときはちょっとやりすぎではと思っていたけど、自分が被害者になるとそれくらいはまあ妥当かなとも感じてしまった。

おふざけやポイ捨てなどで他人に迷惑かけることに罪悪感を感じない自分勝手なガキどもには大学を卒業してほしくないし損害賠償をしてきっちりと反省して欲しいと強く思った。

さらに怒りが収まらないのでネットで同志たちの意見を聞こうと検索してみた。やはり同じ被害に遭っている人は多く目撃情報などもあった。若い男をイメージしていたけど中年のおっさんが多いようだ。捨てる理由は、「特に何も考えていない」という意見が多い。

相手の気持ちとか何も考えずに、むしろ道端に捨てるよりも捨てやすい的な…。法的にも不法投棄で注意程度しかお咎めはないようだ。

こういう人って逆に自分がされたときってどうなんだろ? イラっとしながら隣の自転車とかに入れてさらに自分もやらなきゃ損っ、的な考えだろうか…。なんだか悲しいな…。少し時間が経って落ち着いてきた。ここでネット上で見つけたいい話を載せておく。
夜遅くまで予備校で勉強していた私と友人A君。
地元の駅に着いたら、A君の自転車かごにはビニール袋に入ったごみが入れられていました。
袋には、カンやらコンビニ弁当などがゴチャゴチャと。
それを見て私はA君に「うわぁー、最悪やね。駅のゴミ箱にでも捨てとけやぁ?」
 と言うとA君は 「いや。カンも入ってるから、家で分別して捨てとくは」と一言。
その時はなんか自分が情けなく感じるほど、A君がまぶしく見えました。
A君かっこよすぎw。 こんなにかっこいい対処方法は他にないので、僕も次からこんな感じでいきたいと思います。たとえ独りのときでも本番に備えてこれでいきます。最後に面白いまとめがあったので載せておきます!

みんな自転車のカゴにおかしなもの捨てられすぎwww

さてと、汚れたかごを拭くついでに自転車全体をキレイにしてくるかな。

2013年8月25日日曜日

タイムラインのつぶやきを効率よく読めるアプリ

Twitterでフォローしている人が増えてくるとタイムラインに流れるツイートをすべて読むことはできなくなってくる。

自分の興味あることをつぶやくユーザーはフォローしておきたいけど、その人のツイートを全部を読みたいかというとそうでもない。特に読む必要がないツイートも多く、人気のあるツイートだけ読める方が便利だ。

リアルで仲の良い友達のつぶやきは全部読みたいけど、その他のフォローユーザーのつぶやきは人気のものだけ表示できれば効率よく情報が収集できる。そんなことを考えてつくったアンドロイドアプリがタイムラインピックアップ (Twitter)だ。

ツイッターのタイムラインからお気に入りやリツイート数が一定以上あるツイートだけがタイムラインに表示される。また、ホームだけでなくリストにも対応していて、「表示する・しない」の境界値は自由に設定できるので、例えばリアルな友達リストは条件を緩くしたり(全表示も可)、知り合いや特定のリストからは比較的人気のあるつぶやきだけを表示したりするようにできる。


単純にお気に入りやリツイート数だけで抽出すると、そのユーザーのフォロワー数に大きく依存してしまう。つまり、フォロワー10000人の人気ユーザーと、フォロワー100人程度の知り合いユーザーだと前者の方がつぶやきが見られる可能性が高く、その分ふぁぼやRTを獲得しやすい。

そこで、ピックアップの条件として一定数以上の他に、「お気に入り数/フォロワー数」や「リツイート数/フォロワー数」の項目も用意した。



そのユーザーのフォロワーの何%にあたる数のふぁぼやRTがあったがで表示・非表示を決める。10000フォロワー以上のアルファツイッタラーのつぶやきで10ふぁぼしかされていないものは人気がないと言えるけれど、100フォロワー程度のユーザーのツイートで10ふぁぼされているものは面白いつぶやきであることが多い。

アプリはマルチアカウントにも対応していて、リストの切り替えも左右にスワイプするだけでスムーズに行える。フォントの大きさやツイートをタップしたときに連携するクライアントアプリもアカウントごとに設定できるので、かなり使い勝手は良いはず。


自分用に作ったアプリで僕にとってはかなり重宝しているので、ぜひお試し下さい。最初にツイッターと連携するための認証が必要です。認証によってTimelinePickupが行えるようになる行為はタイムラインとフォローユーザーの観覧で、書き込みや変更等は許可されませんので、安心してご利用ください。


アプリの評価や感想などいただけると大変嬉しいです。要望にもなるべく対応していきたいと思っていますので、どうぞ宜しくお願いします!


2013年8月20日火曜日

なんか胸がほんの少しだけ苦しい。

LINEに登録されている友達が徐々に増えてきて、たぶんアプリが連絡帳を見て自動で登録しているんだろうけど、PCで見るとニックネームだけで誰かわからない人も多い そんな中、フルネームで知らない人の名前があったり・・。 アイコンと下の名前から、あー、たぶん結婚して苗字が変わったんだなと気づく。

スマホでLINEを確認すると、やはり同じアイコンで昔の本名(携帯の登録名)がでている。10年前の当時にFacebookとかあったら、お互いの投稿とかを時々みて結婚とかもっと伝わってきたのかな・・。

京都にいて毎週会っていたときは仲良くても、距離が離れるとメールとか電話はしなくなる。Facebookで検索すればいるんだろうけど、なんかそうするのも違う気がする。 FacebookとかTwitterとか、距離が離れても繋がっていられるのが一番の魅力だと僕は思っているけど、いま感じているこの切ないような思いは決して悪い気持ちではない。

僕と彼女の携帯には今もお互いの電話番号が入っているのだろうけど、たぶんこの先、連絡をとることはない。

だけど、それでも僅かにつながっていて、もし何かの偶然で再び会えることがあるのかもしれない、そんな風に思わせるこの感覚は、携帯があってSNSがなかったほんの短い時代特有のもの。

彼女の携帯にも僕の番号がまだ残っているんだなーと思えただけで、なんだか嬉しくてもっと頑張りたいなーと思うわけ。

別に恋していたわけじゃないし、どちらかというと友達に近かった。でも、手は繋いだかな笑

当時は別に好きな娘がいたんだけど(いま考えると顔で惚れていたと思います。すみません。)異性で性格も見た目もよけりゃー、100%友達ってわけにはならないよね。お互いの環境を考慮して無意識に理性は強く働いてる。恋していたわけじゃないけど、異性としてはもちろん見ていた。男とは手繋がない。

だから、接点のない今はもう連絡できない。

それに比べると、男友達とか3年くらい連絡なくて結婚までしても、平気で「京都帰ってきてるけ?」とかちょー短いメール送ってくる。

彼女の幸せを願いつつ、いつかまた会えるかもしれないという思いを感じつつ、電話することのない番号をスマホに残しつつ、いつ会っても恥ずかしくない自分でいられるように頑張っていきたい。

まあ、僕はSNSとか今もたいしてやってないんだけどさ

2013年6月3日月曜日

林原めぐみのTokyo Boogie Night


中高校生の頃よく聞いていたラジオがまだやっている。当時はこの時間には布団に入っていて、たまに眠って聞き逃したときは後悔するくらいに好きだった。

大学に入って聞かなくなったけど、あれから15年以上経っても変わらず放送されていて、まるでそこだけ時間が止まっていたかのように感じる。ほんとに15年も経ったのかな・・。当時の林原さんの年齢と同じくらいになったけど、彼女は歳とっていないようw

やっぱラジオいいなー・・。いまも変わらずに続けていたことに勝手に感謝。

2013年3月3日日曜日

AQUA DROPs ツイストリング・ノート(A5方眼)

最も使いやすいノートの形態を考えたとき、ページの差し替えがきく「バインダー」と「ルーズリーフ」の組み合わせか、もしくは折り返して省スペースで使える「リングノート」かの二択だろう。

不要になったページはどんどん捨てたいけど、デスク上などではコンパクトに使いたい。バインダーは何度も使えてエコだけど、片手で持ったままメモれるリングノートは何かと便利。

どっち買えばいいんやー、もうどっちも買わない! と、思っていたらLIHIT LAB.(リヒトラブ)の「ツイストリング・ノート」を見つけました。

見た感じはリングノートのような細いリングだが、ツイストリングは簡単に取り外しができるのだ。ノートの表面はエンボス加工で文字とドッドがデザインされている。

もっとシンプルに見せたい場合は、リングを外して表紙と背表紙を反対にすればデザイン面が内側になりスッキリする。ウラ面はこのとおり何もなく超シンプルな大人ブラック。

これが商品名にもなっているツイストリング。通常のバインダーに比べ細いが、上下斜めにずらすだけでぱっと開くことができる!

今回はツイストリングノート以外にも、カードホルダー(品番A-5000P)を一緒に買った。名刺入れの代わりに何枚か名刺を入れておくときに便利。

表紙と背表紙を反対にしてカードフォルダーを挟むといい感じに。カードフォルダはカードが落ちにくいよう配慮され横から入れるようにできている。

ルーズリーフの抜き差しができ、さらにリングノートのように折りたたんで使えるこの便利さ!

リングの半径は最小限で厚みがなく、おしゃれで使いやすい。最大収納枚数は40枚。

ルーズリーフはリング穴がA5/24穴の専用のものを使う必要があるので注意。このツイストリングはシリーズが多く、B5やメモサイズ等あるので好きなものを選べる。 http://www.lihit-lab.com/products/catalog/search/note.html

今回のレビューに使ったのはAQUA DROPs ツイストリング・ノート(A5方眼)品番 N-1659。色々迷ったがこのサイズが使いやすく、ブラックのシンプルさが気に入った。


2013年2月25日月曜日

アプリの実機検証ができるサービスAppKitBox試してみた

禁煙アプリで表示不具合の報告があり、端末を教えてもらうとHTC Jとのこと。
HTC Jの解像度を調べるとQHD(540×960ピクセル)で、手持ちの端末やエミュレータで再現できなかったので、auショップと家電店を回ってみたがHTC J butterflyしかおいていなかった。

どうしようかなーと悩みながら、実機が置いてあって検証ができるようなスペースはないか調べてみると、検証サービスは結構あるが値段が高く、今回は不具合の確認だけなのでむしろ自分でやりたい。端末のレンタルもあるが高いし手間がかかる。

端末の検証カフェでもあればそこそこ流行りそうだな・・などと思いつつ諦めかけていたら、クラウド上でリモート操作&デバックができるAppKitBoxなるサービスを見つけた。



以前にそういうサービスがあるのを何かで知ったが、正直リモートとか使いづらそうだし表示も遅いんじゃなかなという偏見があって食いつきはしなかった。でも今回ちらっとだけ覗いてみた。

まず会社はどこだと。リモートできちんと操作できる環境とかシステム体系を整えられるところなのかと。運営会社は「NTTレゾナント株式会社」。少し期待度が高まる。

「2.5時間まで無料」。これなら今回分は無料でいけるな。そして1時間945円。安くはないが他のサービスに比べるとお得感があるし30分単位なので、うまくいけば毎回1コインで片付けられる。

サービスを使用するとエミュレータのような画面が現れて操作できるよう。本当にデバックはできるのか? 「Eclipse(ADT)・DDMS・adbと連携可能」 これ結構いけるかもしれんと利用を決める。

最初にRemote TestKit for Androidをダウンロードしインストール・起動すると、まずログイン画面。ユーザー名、メールアドレス、パスワードを入力してログインすると端末一覧の画面へ。

持っているチケットは15枚で2.5時間分ある。空き端末だけでもかなり揃ってるし、KDDIの端末もある。素晴らしい。



HTC Jも運良く空き端末リストにあったので、さっそく起動する! 突如、画面にHTC Jのエミュレータが。というか実機が雲の向こうで動いているのか?! 操作方法はエミュレータとほとんど同じなので迷うことはない。

 

時間制限もあるので、ひとまずGoogle Playからアプリをいれて表示を確かめてみた。専用のアカウントが入っているとマニュアルにあったが、なんか入ってなかったような・・。アプリを起動すると特におかしな表示になっていなかったので一安心。不具合はユーザーの環境に依存しているのか? ホームアプリとか入れてるのかな。



今後のこともあるし、リモートでデバックがうまくいくかどうかも確認しておきたい。上部メニューの有効機能からADT・DDMS・adbの項目を選択。



下記のダイアログがでる。リモートゆえにタイムアウトの設定を長く取らないとダメなのか。桁が増えてるから結構時間かかるのかな?



指示通りにEclipseのPreferencesで各項目を変更する。



次はファイルのパスを通せと。参照ボタンからadbの場所を探す。



Android SDKのplatform-toolsファルダ内にadb.exeを発見。

 

マニュアルを見ながら設定していたらここで時間切れに。チケットをもう3枚使おうかと思った矢先。まさかのGALAXY SⅢが無料?! これを起動して先ほどの続きを。

 

adbへのパスを通してEclipseのDDMSを見ると、LogCat見れた!! すごいっ! 何もしてないのに?!



Eclipseからのインストール先にもちゃんとGALAXY SⅢある!エミュレータと同じ使い勝手で離れた実機を使えてるw
 

いくらかリモートゆえの制約があって、カメラ、音声入力、電話、センサー、GPSなどは使えない。設定変更もできないよう。3G回線も使えないがwi-fiは使える。速度はそんなに速くないよう。



まとめると、マジで助かりました。すごい有難いサービス。エミュレータよりもサクサク動くし、こんなに便利にリモートで実機が使えるのは想像していなかった。本当は実機を模したスーパーエミュレータなんじゃないか?

これで不具合あったときに端末がなくて四苦八苦せずに済む。幾らか制限はあるので注意。詳細はサイトで確認あれ。 http://appkitbox.com/

2013年1月28日月曜日

多言語対応 Supporting Different Languages

参照元(翻訳): Supporting Different Languages | Android Developers

アプリケーションのコードからUIに使っている文字列を抜き出し、それらを別ファイルへ保存しておくことは良い慣習である。Androidは各プロジェクト毎にリソースディレクトリを持つことで、これを容易に行える。

プロジェクトの作成にAndroid SDK Toolsを使えば、プロジェクトのトップレベルに res/ ディレクトリが生成されている。様々なリソースタイプに対するサブディレクトリがこのres/ディレクトリにある。いくつかのデフォルトのファイル、例えば res/values/strings.xml があり、これはstringの値を保持している。


Create Locale Directories and String Files

より多くの言語をサポートするためにres/の中に values ディレクトリを追加作成し、valueはハイフンとISO国コードをディレクトリ名の後ろに付加する。例えば、values-es/ は言語コード"es"の地域に対するリソースを含むディレクトリである。Androidは実行時に端末のロケール設定に従って適したリソースをロードする。

サポートする言語を決めたら、サブディレクトリとstringファイルを次のように作成する。

MyProject/
    res/
       values/
           strings.xml
       values-es/
           strings.xml
       values-fr/
           strings.xml

各ロケールに対するstringの値を適切なファイルへ加える。

実行時に、ユーザーの端末にセットされているロケールに応じて、適切なstringリソースのセットがAndroid systemによって使用される。

例えば、次の例は異なる言語に対する違うstringリソースである。

English(default locale), /values/strings.xml:


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="title">My Application</string>
    <string name="hello_world">Hello World!</string>
</resources>

Spanish, /values-es/strings.xml:


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="title">Mi Aplicación</string>
    <string name="hello_world">Hola Mundo!</string>
</resources>

French, /values-fr/strings.xml:


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="title">Mon Application</string>
    <string name="hello_world">Bonjour le monde !</string>
</resources>

note: どのようなリソースタイプにもロケール修飾子(またはコンフィギュレーション修飾子)は使用できる。例えばbitmap drawableのローカライズされたバージョンを提供したいときなど。詳しくはLocalizationを参照のこと。

Use the String Resources

<string>のname属性によって定義されたリソース名を用いることでコードやそのほかのXMLファイルの中でstringリソースを参照することが可能である。

ソースコートの中で次のシンタックスでstringリソースを参照できる。R.strng.<string_name>.このような文字リソースを受け取るメソッドはいくつもある。例えば次のよう。

// Get a string resource from your app's Resources
String hello = getResources().getString(R.string.hello_world);

// Or supply a string resource to a method that requires a string
TextView textView = new TextView(this);
textView.setText(R.string.hello_world);

XMLファイルでは、string値を代入できるXMLの属性であればどこでも次のシンタックスでstringリソースを参照できる。

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

2013年1月26日土曜日

アプリ内課金商品の購入 Purchase In-app Billing Products

参照元(翻訳): Purchasing In-app Billing Products | Android Developers

アプリがGoogle Playと接続すると、アプリ内商品の購入リクエストが行える。Google Playによってユーザーが支払い方法を入力するためのチェックアウトのインターフェイスが提供されるので、アプリケーション側で直接支払いの処理を扱う必要はない。

アイテムが購入されると、Google Playはユーザーが所有していることを認識し、アイテムが消費されるまでは同じユーザーが同じ商品IDのアイテムを購入できないようにする。あなたはアプリ内でのアイテムの消費をコントロールでき、再び購入可能にするようGoogle Playに通知することができる。

また、あなたはGoogle Playに問い合せて、すぐにユーザーの購入したリストを検索することができる。これは例えば、アプリ起動時にユーザーの購入状態を復元したいときに役立つ。


Purchase an Item

購入リクエストはIabHelperインスタンスのlaunchPurchaseFlow(Activity, String, int, OnIabPurchaseFinishedListener, String)を呼ぶことで開始する。この呼び出しはアクティビティのメインスレッドから行う必要がある。launchPurchaseFlowメソッドのパラメータは次のとおり。
  • 最初の引数は呼び出すアクティビティ。
  • 2つめ引数は購入するアイテムのID(SKU)。商品名ではなくIDを与える。デベロッパーコンソールで前もってそのアイテムを定義し有効にしておかないと認識に失敗する。
  • 3つめの引数はリクエストコード。これは正のintegerが可能で、Google Playはこの値をアクティビティのonActivityResult呼び出しに購入レスポンスと共に返す。
  • 4つめは引数はリスナーで、購入処理が完了しGoogle Playからの購入レスポンスを扱うときに通知される。
  • 5つめの引数は'developer payload'の文字列で、オーダーに対する追加情報(空の文字列でもよい)を送るために使用できる。これは典型的には、購入リクエストをユニークに識別する文字列トークンを渡すのに使われる。string値を指定すると、Google Playはこの値を購入レスポンスと共に返す。続いてあなたがこの購入の問合せを行うとき、Google Playはこの値と購入詳細を返す。
    Security Recommendation: 実践的にはあなたのアプリケーションで購入を行ったユーザーを識別するのに役立つ文字列を渡すと良い。そうすることで、あなたは後からユーザーのこの購入が正当なものであることを確かめられる。消耗するアイテムに対してはランダムな文字列を使うが、永続的なアイテムに対してはユーザーをユニークに識別する文字列を使うべきだろう。
次の例は商品ID SKU_GASに対して、任意のリクエストコード値(10001)、エンコードしたpayload文字列を使って購入リクエストを行う方法を示している。

mHelper.launchPurchaseFlow(this, SKU_GAS, 10001,   
   mPurchaseFinishedListener, "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");

購入のオーダーがうまくいくと、Google Playからのレスポンスデータが保存されたPurchaseオブジェクトがリスナーに渡される。

次の例はリスナーで購入レスポンスをどのように扱えるかを示している。このレスポンスは購入オーダーが成功したかどうか、ユーザーが購入したのがgasなのかpremium upgradeなのかによって異なる。この例ではgasは複数回購入可能な商品なので、あなたはユーザーが再び購入可能になるように購入を消費すべきである。詳しくはのちのセクションで。premium upgradeは一度のみの購入商品なので、それを消費する必要はない。ユーザーが新たにアイテムを購入したことが分かるように、UIをすぐに更新するのが良い。

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener 
   = new IabHelper.OnIabPurchaseFinishedListener() {
   public void onIabPurchaseFinished(IabResult result, Purchase purchase) 
   {
      if (result.isFailure()) {
         Log.d(TAG, "Error purchasing: " + result);
         return;
      }      
      else if (purchase.getSku().equals(SKU_GAS)) {
         // consume the gas and update the UI
      }
      else if (purchase.getSku().equals(SKU_PREMIUM)) {
         // give user access to premium content and update the UI
      }
   }
};

Security Recommendation: Google Playから購入レスポンスを受け取ったとき、返ってきたデーターのsignature、orderId、Purchaseオブジェクトの中のdeveloperPaylaodの文字列が期待している値かどうか確かめる。oderIdは以前に処理していないユニークな値か、developerPayloadはこの購入リクエストに対して送ったトークンと適合しているかを確かめる。さらに用心するなら、この確認は自社サーバーで行うべきである。


Query Purchased Items


購入が成功すると、このユーザーの購入データはGoogle Playのアプリ内課金サービスによってローカルにキャッシュされる。アプリの開始時や再開時など頻繁にアプリ内課金サービスにユーザーの購入商品を問い合わせることは良い実践で、これによりユーザーの現在の商品所有状態が常にアプリ内で反映される。

ユーザーの購入を復元するために、IabHelperインスタンスでqueryInventoryAsync(QueryInventoryFinishedListener)を呼び出す。QueryInventoryFinishedListenerの引数は問い合わせが完了し、そのレスポンスを処理するときに通知されるリスナーである。メインスレッドから安全に呼ぶことができる。

mHelper.queryInventoryAsync(mGotInventoryListener);

問い合わせが完了すると、問い合わせ結果がInventoryオブジェクトに保存されリスナーに渡される。アプリ内課金のサービスは、端末に現在ログインしているユーザーアカウントが行った購入のみを返す。

IabHelper.QueryInventoryFinishedListener mGotInventoryListener 
   = new IabHelper.QueryInventoryFinishedListener() {
   public void onQueryInventoryFinished(IabResult result,
      Inventory inventory) {

      if (result.isFailure()) {
        // handle error here
      }
      else {
        // does the user have the premium upgrade?
        mIsPremium = inventory.hasPurchase(SKU_PREMIUM);        
        // update UI accordingly
      }
   }
};


Consume a Purchase

Google Playでの購入アイテムの所有情報を追跡するためにIn-app Billing Version 3が使える。一度アイテムが購入されると、アイテムは"owned"と見なされその状態では再びGoogle Playから購入することはできない。再びアイテムを購入可能にするには、そのアイテムに対する消費リクエストを送らなければならない。管理しているアプリ内商品はすべて消費可能であるが、アプリ内での消費メカニズムはあなた次第である。例えば、ゲーム内通貨やreplensihable game tokensなどユーザーが何度も購入したいような一時的に役立つ物に対しては消費を実装する。プレミアムアップグレードのような一度購入すると永続的な効果がある物に対しては消費を実装しないだろう。

アプリ内商品のユーザーへの提供をどの様に管理し、追跡するかはあなたの責務である。例えば、ユーザーがゲーム内通貨を購入すれば、あなたプレイヤの資金に購入した分を追加すべきだろう。

Security Recommendation: アプリ内商品(消費あり)の効果をユーザーに提供する前に、あなたは消費リクエストを送らなければならない。アイテムを提供する前に消費レスポンスの成功を受け取るようにする。

購入消費を記録する為にIabHelperインスタンスからconsumeAsync(Purchase, OnConsumeFinishedListener)を呼ぶ。このメソッドの最初の引数はPurchaseオブジェクトで消費アイテムを指す。2番目の引数はリスナーで消費処理が完了しGoogle Playからの消費レスポンスを扱うときに通知される。この呼び出しはメインスレッドから行って良い。

この例では、ユーザーがアプリ内で購入したガスのアイテムを消費する。

mHelper.consumeAsync(inventory.getPurchase(SKU_GAS), 
   mConsumeFinishedListener);

次の例はOnConsumeFinishedListenerの実装方法を示している。

IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
   new IabHelper.OnConsumeFinishedListener() {
   public void onConsumeFinished(Purchase purchase, IabResult result) {
      if (result.isSuccess()) {
         // provision the in-app purchase to the user
         // (for example, credit 50 gold coins to player's character)
      }
      else {
         // handle error
      }
   }
};

Check for Consumable Items on Startup
ユーザーがアプリケーション起動したとき、消費アイテムをチェックすることは重要である。一般的に、最初にあなたはアプリ内課金サービスにユーザーの消費したアイテムを問い合わせる(queryInventoryAsync)。それから、消費しうるPurchaseオブジェクトをInventoryから取得する。もしユーザーによって所有されている消費アイテムを発見したら、すぐにGoogle Playに消費リクエストを送り、ユーザーにアイテムを提供する。起動時のこのチェックの実装の仕方はTrivialDriveサンプルを参照のこと。

2013年1月22日火曜日

販売のためのアプリ内商品の確立 Establishing In-app Billing Products for Sale

参照元(翻訳): Establishing In-app Billing Products for Sale | Android Developers

課金アプリを公開する前に、Google Play Developer Consoleで販売可能なデジタル商品のプロダクトリストを定義する。

Specify In-app Products in Google Play

デベロッパーコンソールでアプリ内商品の情報を定義し、商品リストをアプリに関連付ける。
  1. 署名されたAPKファイルをビルドする。
  2. デベロッパーコンソールで作成したアプリのエントリーを開く。
  3. APKタブからUpload new APKをクリックし署名済みAPKをアップロードする。まだ公開はしない!
  4. アップロードしたアプリのin-app Productsタブをクリックする。
  5. 新しい商品を追加するためのoptionをクリックし、商品情報のフォームを埋める。商品情報は、アイテムのユニークID(SKU)、説明、価格、利用できる国。IDは後ほどアプリで商品詳細の問い合わせに必要なのでメモる。
    important: Version 3は管理されたアプリ内商品のサポートのみを提供する。ゆえに新しいアイテムをデベロッパーコンソールの商品リストに追加するときは、購入タイプが"Managed"であることを確認する。
  6. フォームの入力が終わればすぐに商品はアクティブになりアプリで購入することができる。
    Warning: APKのアップデートから反映まで2-3時間かかる場合がある。もし反映前にテストを行うと、アプリケーションは次のエラーメッセージと共に'purchase cancelled'レスポンスを受け取るだろう。"This version of the application is not enabled for In-app Billing."

Query Items Available for Purchase

Google Playに問合せを行い、アプリに関連づいた商品情報(価格、タイトル、説明、タイプ)をプログラムで検索することができる。これは例えば、ユーザーが利用可能だが所有していないアイテムのリストを表示したいときに便利だ。

Note: 問い合わせを行うときは、商品のIDを明示する必要があるだろう。各商品IDはデベロッパーコンソールの"In-app Products"タブのName/ID欄に並んでいる。

商品情報の検索には、IabHelperインスタンスのqueryInventoryAsync(boolean, List, QueryInventoryFinishedListener)を呼ぶ。

  • 最初の引数は商品情報を検索するかどうかを指定する(trueをセットすべき)。
  • Listはあなたの検索したい商品のID(SKUとも呼ぶ)をひとつ以上含む。
  • 最後のQueryInventoryFinishedListenerは問い合わせが完了しレスポンスを扱うときに呼ばれるリスナーを指定する。
サンプルにある便利なクラスを使用すれば、このクラスは課金リクエストを管理するバックグランドスレッドを操作するので、メインスレッドから安全に問合せを行うことができる。
次のコードはあらかじめデベロッパーコンソールで定義したSKU_APPLEとSKU_BANANAのIDを持ったふたつの商品の詳細を検索する方法を示している。

List additionalSkuList = new List();
additionalSkuList.add(SKU_APPLE);
additionalSkuList.add(SKU_BANANA);
mHelper.queryInventoryAsync(true, additionalSkuList,
   mQueryFinishedListener);

問い合わせが成功すると、クエリーの結果がInventoryオブジェクトに保存され、このオブジェクトはリスナーに返される。

次のコードは検索結果からアイテムの価格を調べる方法を示している。

IabHelper.QueryInventoryFinishedListener 
   mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
   public void onQueryInventoryFinished(IabResult result, Inventory inventory)   
   {
      if (result.isFailure()) {
         // handle error
         return;
       }

       String applePrice =
          inventory.getSkuDetails(SKU_APPLE).getPrice();
       String bananaPrice =
          inventory.getSkuDetails(SKU_BANANA).getPrice();

       // update the UI 
   }
}

アプリ内課金の準備 Preparing Your In-app Billing Application

参照元(翻訳): Preparing Your In-app Billing Application | Android Developers

まずはIn-app Billing Version 3 APIを含むライブラリーをプロジェクトに追加する必要がある。Google Playと通信するためのパーミッションをアプリに設定することに加え、使用するAPI versionがGoogle Playでサポートされているか確認しなければならない。


Download the Sample Application

ここでは、アプリ内課金のサンプルアプリ「TrivialDrive」を実装の参考に使用する。このサンプルは課金サービスとmarshal and unmarshal data typesをすばやくセットアップしたり、アプリのメインスレッドからの課金リクエストを処理したりする便利なクラスを含む。

サンプルアプリのダウンロード:
  1. Android SKD Managerを開く。
  2. SDK Managerの中のExtrasセクションを開く。
  3. Google Play Billing Libraryを選択する。In-app BillingのVersion 3以上が選択されていることを確認する。
  4. ダウンロードを完了するためにinstallをクリックする。
/your/sdk/location/extras/google/play_billing/in-app-billing-v03 にサンプルファイルがインストールされる。


Add Your Application to the Developer Console

Google Play Developer Consoleで課金アプリの公開やアプリ内で購入可能な様々なデジタル商品の管理を行う。デベロッパーコンソールで新しいアプリのエントリーを作成したとき、自動的にアプリのpublic license keyが作られる。このキーはアプリからGoogle Playへのセキュリティ接続を確立するために必要である。アプリに対して一度だけこのキーの生成が必要で、apkファイルをアップデートするときはこれらのステップを繰り返す必要はない。

デベロッパーコンソールにアプリを追加:
  1. Google Play Developer Consoleにログイン。アプリ内アイテムを売るためにはGoogle Checkout Merchantアカウントが必要。
  2. もしまだ新しいバージョンのデベロッパーコンソールにログインしていない場合は、Try the new designをクリックする。
  3. All ApplicationsタブにあるAdd new applicationをクリックし、アプリ名を入力、Prepare Store Listingをクリックする。
  4. Service & APIs タブからアプリのために生成されたpublic license keyをメモる。これはBase64 の文字列で後にアプリのコードに組み込む必要がある。

Add the In-app Billing Library

Version 3を使うために、Android projectにIInAppBillingService.aidlファイルを追加しなければならない。Android Interface Definition Language (AIDL)ファイルはGoogle Play serviceとのインターフェイスを定義したものだ。

IInAppBillingService.aidlファイルはサンプルアプリのなかにある。新しいアプリの作成 or 既存のアプリの変更のどちらかによって、次の指示に従う。

New Project
  1. TrivialDraiveのサンプルファイルをAndroid projectにコピーする。
  2. これらのサンプルファイルのパッケージ名をあなたのプロジェクトで使用するパッケージ名に修正する。Eclipseではパッケージ名を右クリック、Refactor > Renameのショートカットが使える。
  3. AndroidManifest.xmlファイルを開きパッケージ属性の値を使用するパッケージ名に更新する。
  4. コンパイルがうまくいくようにimport statementを要求のある通り修正する。Eclipseではエラーを出しているファイル上でCtrl+Shift+Oのショートカットが使える。
  5. サンプルをあなたのアプリケーションを作成するために修正する。デベロッパーコンソールのBase64 public license keyをあたなのMainActivity.java上でコピーすることを忘れないように。
Existing Project
  1. IInAppBillingService.aidlファイルをAndroid projectに追加。
    • Eclipseを使っていれば、/src ディレクトリーにaidlファイルをインポートする。
    • そうでない場合は、次のディレクトリを作ってaidlファイルをコピーする。 /src/com/android/vending/billing
  2. アプリをBuildして、IInAppBillingService.javaファイルが /gen ディレクトリに生成されていることを確認する。
  3. TrivialDriveサンプルの /util ディレクトリのhelperクラスをプロジェクトに追加する。あなたのプロジェクトのコンパイルがうまくいくようにパッケージ名宣言を忘れずに変更する。
これであなたのプロジェクトはIn-app Billing Version 3ライブラリーを含んでいる。


Set the Billing Permission

Google Playの課金サービスとやりとりするための権限が必要になる。マニフェストファイルに次の1行を加える。

<uses-permission android:name="com.android.vending.BILLING /">


Initiate a Connection with Google Play

アプリから課金リクエストを送るためにActivityとGoogle Playの課金サービスをバインドしなくてはならない。サンプルで与えられたクラスが課金サービスのバインドを処理するので、あなたはネットワークの接続を直接管理しなくてよい。

Google Playとの同期通信をセットアップするために、activityのonCreateメソッドのなかでIabHeplerインスタンスを作成する。コンストラクタにactivityのコンテキストとライセンスキーを渡す。

Security Recommendation:Google Playから与えたれたライセンスキーそのままをコードに組み込まないことを強く勧める。代わりに、実行時に部分文字列を組み合わせて構成したり、暗号化したものを復号してコンストラクタに渡す。これにより悪意あるサードパーティがAPKファイルからライセンスキーの文字列を変更することを難しくする。

IabHelper mHelper;

@Override
public void onCreate(Bundle savedInstanceState) {
   // ...
   String base64EncodedPublicKey;
   
   // compute your public key and store it in base64EncodedPublicKey
   mHelper = new IabHelper(this, base64EncodedPublicKey);
}

次にIabHelperインスタンスのstartSetupメソッドを呼びサービスのバインディグを実行する。メソッドにはOnIabSetupFinishedListenerのインスタンスを渡す。これはIabHelperが非同期セットアップを完了すると呼ばれる。セットアップの一環としてIabHelperはIn-app Billing Version 3 APIがGoogle Playでサポートされているかどうかチェックする。もしこのバージョンがサポートされていなかったりバインディング中にエラーが発生した場合はこのリスナーに通知がいき、エラーメッセージを含んだIabResultオブジェクトが渡される。

mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
   public void onIabSetupFinished(IabResult result) {
      if (!result.isSuccess()) {
         // Oh noes, there was a problem.
         Log.d(TAG, "Problem setting up In-app Billing: " + result);
      }            
         // Hooray, IAB is fully set up!  
   }
});

セットアップが正常に完了すると、mHeplerをGoogle Play serviceとの通信に使用できる。アプリを起動したとき、ユーザーがどのアプリ内アイテムを所有しているかを調べることは良い実践である。これについては後のセクションで触れる。

important: アクティビティを終了させるときはアンバインドするのを忘れてはならない。アンバインドしないとデバイスのパフォーマンスを下げる場合がある。アンバインドしリソースを開放するには、アクティビティが終了するときにIabHelperのdisposeメソッドを呼ぶ。

@Override
public void onDestroy() {
   if (mHelper != null) mHelper.dispose();
   mHelper = null;
}

2013年1月20日日曜日

アプリ内商品の販売 Selling In-app Products

参照元(翻訳): Selling In-app Products | Android Developers

ここでは、アンドロイドのアプリ内課金についての一般的な実装方法がわかる。

Google Playのアプリ内課金を使えば、デジタルコンテンツやアプリのアップブレードに対する請求を行うことができる。in app Billing APIを使うことで簡単にアプリに課金を組み込める。Google Playに商品の詳細をリクエストしたり、アプリ内商品のオーダーを発行したり、ユーザーの購入履歴に基づいて所有情報を復帰させたりできる。また、ローカルでの価格や有効性などを問い合わせることもできる。Google Playがユーザーへの課金処理をシームレスにし、より直感的な体験をユーザーへ提供する。

ここではVersion 3 APIでの導入方法を説明する。


Lessons

アプリ内課金の準備 Preparing Your In-app Billing Application
  • サンプルアプリのダウンロード
  • デベロッパーコンソールにアプリを追加
  • アプリ内課金ライブラリーの追加
  • パーミッションの設定
  • Google Playと接続開始
販売のためのアプリ内商品の確立 Establishing In-app Billing Products for Sale
  • アプリ内商品の特定
  • アプリ内商品の詳細問い合わせ
アプリ内課金商品の購入 Purchase In-app Billing Products
  • アイテムの購入
  • 購入したアイテムの問い合わせ
  • 購入品の消費
課金アプリのテスト Testing Your In-app Billing Application
  • 静的な返答でのテスト
  • 独自商品IDでのテスト