フルスクリーン タイプのオートコンプリート ウィジェット

Android では、オートコンプリート ウィジェットはフラグメント(英語)として追加することができます。イベント リスナーを追加し、オートコンプリートされたプレイスのリファレンスをアプリケーションにて受け取ります。あるいは、オートコンプリート ウィジェットをインテント(英語)で起動することもできます。
アクティビティのXML レイアウト ファイルにフラグメントを追加する方法:
<fragment
  android:id="@+id/place_autocomplete_fragment"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"
  />

アクティビティの onCreate() メソッドにイベント リスナーを追加する方法:
// 
PlaceAutocompleteFragment fragment = (PlaceAutocompleteFragment)
    getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);

fragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
   @Override
   public void onPlaceSelected(Place place) { // 選択したプレイスを処理
   }
   @Override
   public void onError(Status status) { // エラーを処理
   }


オートコンプリート ウィジェットを起動するインテントを作成する方法:
try {
   Intent intent =
            new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
           .build(this);
   startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
   GooglePlayServicesUtil
           .getErrorDialog(e.getConnectionStatusCode(), getActivity(), 0);
} catch (GooglePlayServicesNotAvailableException e) {
   // 例外を処理
}


iOS(Objective-C)では、オートコンプリートのデリゲートを実装してプレイス選択に対応します。
@interface MyViewController () 
@end

@implementation ViewController
.
.
.
- (IBAction)onLaunchClicked:(id)sender {
  // ボタン押下時にオートコンプリート ビュー コントローラーを表示
  GMSAutocompleteViewController *acController = [[GMSAutocompleteViewController alloc] init];
  acController.delegate = self;
  [self presentViewController:acController animated:YES completion:nil];
}

- (void)viewController:(GMSAutocompleteViewController *)viewController
    didAutocompleteWithPlace:(GMSPlace *)place {
  // ユーザーがプレイスを選択
  [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)viewController:(GMSAutocompleteViewController *)viewController
    didAutocompleteWithError:(NSError *)error {
  [self dismissViewControllerAnimated:YES completion:nil];
}

// ユーザーがキャンセル ボタンを押下
- (void)wasCancelled:(GMSAutocompleteViewController *)viewController {
  [self dismissViewControllerAnimated:YES completion:nil];
}

@end

Swift の場合:
import UIKit
import GoogleMaps

class MyViewController: UIViewController {
    
    @IBAction func onLaunchClicked(sender: AnyObject) {
        let acController = GMSAutocompleteViewController()
        acController.delegate = self
        self.presentViewController(acController, animated: true, completion: nil)
    }
}

extension MyViewController: GMSAutocompleteViewControllerDelegate {
    
    func viewController(viewController: GMSAutocompleteViewController!, didAutocompleteWithPlace place: GMSPlace!) {
        // ユーザーがプレイスを選択
        self.dismissViewControllerAnimated(true, completion: nil)
    }
    
    func viewController(viewController: GMSAutocompleteViewController!, didAutocompleteWithError error: NSError!) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
    
    func wasCancelled(viewController: GMSAutocompleteViewController!) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}

Place Picker にもオートコンプリートを


今回、場所名や住所、地図上の位置など、自分の現在地を知らせるのに便利な UI ウィジェット Place Picker にもオートコンプリート機能を追加しました。ユーザーは場所名や住所の一部を入力するだけで、目的の場所をさらに素早く選択できるようになります。

なお、すでにアプリで Place Picker を利用している場合は、自動的にオートコンプリート機能が実行されますので、開発者側では何もする必要はありません。
まずはドキュメントとコード サンプルをご覧ください。ご質問やご意見、ご提案などがありましたら、Stack Overflow(英語)または Google Maps API のバグ報告用掲示板(英語)にてお知らせください。

Posted by 丸山 智康 (Tomoyasu Maruyama) - Google Maps Solution Architect, Google Maps API for Work

それ以降のユーザー操作もシンプルになりました。以前はこの場面で、デバイスに登録されたメールアドレスから、Google アカウントを選択する画面が表示され、続いて [Create Google+ Profile] ダイアログとパーミッションに同意するダイアログが表示されていました。
それが、ユーザーにアカウントを選択して同意してもらうだけという単一のステップに変更されました。ユーザーが Google+ プロファイルを所有していない場合、作成するステップは省略されています。その後の同意ダイアログは別途表示することになります。アプリがなぜユーザーのカレンダーや連絡先にアクセスするかについて、ユーザーが理解しやすいよう、データが実際に必要になったときのみ、コンテキスト内で認可を求めるのがベストプラクティスです。
これらに変更によって、Google アカウントを使ったサインイン率が向上すると期待しています。

InstacartNPR OneBring! など、この新しい API を使用したアプリは既に公開されています。
次回の投稿では、API を変更して Google Sign-In を使用するアプリのコーディングをもっと簡単にする方法について説明します。


Posted by Eiji Kitamura - Developer Relations Team

Eric Froemling は独立系のデベロッパーで、ゲーム「Bombsquad」は当初趣味として製作していました。しかし今、Eric はこのゲームで生計を立てています。昨年 Eric は、このゲームのビジネスモデルを有償から無償に切り替えました。Player Analytics を活用して、プレイヤーの定着率とマネタイズ(収益化)の方法を改善した結果、アクティブ ユーザー 1 人 1 日あたりの平均収益(ARPDAU)が 140 % 増となりました。

プレイヤーのゲーマー体験を改善して、定着率と現金収入を増やすために、Eric が Player Analytics とデベロッパー コンソールをどのように使用したかについては、こちらの動画をご覧ください。

Auxbrain が明かす、Google Play ゲーム サービスで成功するためのヒント


ゲーム開発会社 Auxbrain の創設者であり CEO である Kevin Pazirandeh は、「Zombie Highway」 のクリエイターでもあります。Kevin は Google Play ゲーム サービスの活用方法の知見を次のようにコメントしています。

「多少の例外はありますが、エンゲージメント(ユーザーのゲーム利用時間)の測定については、これほど良いツールは他に見当たりません。さらに、ユーザーの定着率が表形式で示されているだけでなく、エンゲージメントの変化もわかることも大事です。このツールを使ったことのない人たちのために説明すると、ユーザーの定着率のテーブルは毎日更新されるもので、最初にプレイした日から数日後に再度プレイしたプレーヤーのパーセンテージがわかります。自分のゲームの定着率をよく似た他のゲームのものと比較すれば、開発した機能が正しかったかそうでないか、デベロッパーにはすぐにわかります」

Google Play ゲーム サービスのアナリティクス ツールを最大限に活用するための方法について、Kevin がとっておきのコツを教えてくれました。
  1. Player Analytics は無償で使える - あなたのゲームに Google Play ゲーム サービスを既に組み込んでいる場合は、デベロッパー コンソール上で [Game services] > [Player Analytics] を選択すると、そのゲームに関するアナリティクス データを取得することができます。
  2. 変更は必ずしも改善とはならない - デベロッパーがよかれと思ってゲームに手を加えても、プレーヤーはその変更を改善とは捉えない場合があります。ゲームに変更を加えるときには、その効果を測る方法も、戦略として用意しておきましょう。Player Analytics で変更の影響が確認できない領域については変更を実施せず、効果が予測できる変更を優先させましょう。
  3. 成績やイベントを設定するとプレーヤーの進捗が追跡できる - プレーヤーの成績やイベントを記録する機能を実装すると、プレイヤーの進捗レポートや Event viewer を使用して、各プレイヤーのゲームの到達度を追跡することができます。こうすると、プレーヤーが苦戦したり行き詰ったりする場面がすぐにわかるので、プレーヤーが先に進めるように救済する方法を探すこともできます。
  4. サインイン情報を使用してより多くのデータを入手 - 収集したプレーヤーの進捗データが増えるのに比例して、Player Analytics のレポートの精度も上がります。データを収集するには、ゲームに加わるプレーヤーを増やすのが一番です。プレイヤーのログインは自動的に実行し、ゲームに再訪したプレイヤーに対しては、最初の画面で(チュートリアルを示してから)、前回の続きからゲームを開始できるようにします。
  5. 定着率テーブルでプレーヤーのエンゲージメントを追跡 - 定着率テーブル レポートで、どのタイミングでプレーヤーが離脱するかを長期間にわたって観察することができます。ゲームに変更を加える前後で定着率が変化したかどうかを見ることもできますし、ゲームの設計を変更するとプレーヤーの離脱するタイミングが早くなったり遅くなったりするかどうかを、他の類似ゲームと比較して判断することもできます。
Google Play Games Services の詳細はこちらをご覧ください。また、当社の製品とベストプラクティスの情報は、あなたのビジネスを世界規模に拡大することにつながる可能性があります。


Posted by Eiji Kitamura - Developer Relations Team



Google My Business API の詳細およびアクセスの申請方法については、こちらのデベロッパー向けのページ(英語)をご覧ください。

ご質問やご意見などがありましたら、Google My Business API フォーラムにて API チームにご連絡ください。

Posted by 丸山 智康 (Tomoyasu Maruyama) - Google Maps Solution Architect, Google Maps API for Work

以前なら、ユーザーは「サインイン」ボタンにタッチしてから、複数のステップ(アカウントの選択、プロファイル情報へアクセスするためのパーミッション付与、場合によっては Google+ アカウントの作成など)を実行しなければなりませんでした。ところが Google Play サービス 8.3 では、ワンタップするだけで基本プロファイルにアクセスできます。

新しい API に関するドキュメントはこちらでご確認いただけます。

また、複数のデバイスで同時にサインインしやすくするため、Google Sign-In を使っている場合でも、従来のパスワードベースの認証を使っている場合でも、Smart Lock API は重要な更新を受信します。また、新しい API メソッドを追加しました。このメソッドは、ユーザーがサインイン用に使用しているメールアドレスをサインイン用のフォームにあらかじめ入力しておく、またはフォームが表示された際にユーザーの入力を支援するような設定を行うためのダイアログを表示するためのものです。getHintPickerサンプル コード)をご確認ください。このメソッドでは、どのデバイスからもパーミッションを受け取る必要はなく、メソッドがデバイス上のアカウント情報をサインイン情報として受信していた、ピッカーに代わる役割を果たします。したがって Marshmallow では、デバイスからのアクセスにはランタイム パーミッションが必要となります。

ヒント情報を使用すれば、サインイン用のフォームに必要な情報、すなわち名前、メールアドレス、プロフィール画像などを、サインイン時にワンタップで一気に入力することができます。あるいはメールアドレスを使って、ユーザーをサインインやサインアップの操作にスマートに誘導することもできます。ユーザーが選択したエントリがデバイス上のアカウントと一致する場合、検証済みのメールアドレスを Google からヒント情報として送信して、メールアドレスの検証とユーザー認証を省略できる仕組みをシステムに実装するのが一番望ましい方法です。ID Token ã¯、Google Sign-In でも採用しています。

Google Play サービスには、ユーザーの所在地を特定するために、GPS、WiFi、携帯電話の無線通信用信号など、内蔵している位置情報のセンサーから情報を抽出し、使いやすい API に統合して格納する、位置情報統合(FLP)機能があります。バッチ化については、FLP を改善しました。バージョン 8.3 より古いバージョンでは、位置情報のバッチ API を使用して FLP でネットワーク トラフィックを統合し、使用電力を節約していました。ただし、アプリが位置情報リクエストのバッチを削除した場合、バッチはクリアされていました。これを防ぐために、バッチ化した位置情報を直ちに返す API を追加しました。詳細は、FusedLocationProviderApi の flushLocations と removeLocationUpdates メソッドの呼び出しをご確認ください。

App Invites は、ユーザーが知人とアプリを共有できるようにするテクノロジーです。Google Play サービス 8.3 には、App Invites を組み込んでアプリをビルドすると、コーディングをかなりシンプルにできるよう更新されました。AppInvite.AppInviteApi.getInvitation() メソッドが使えるようになりました。このメソッドは、ディープリンク アクティビティの起動に使用する ResultCallback をセットアップするので、コードがシンプルになります。

Play Game サービスの Player Stats API もアップデートされています。最新版には、ゲームを辞めてしまいそうなプレーヤーを表す、新しいシグナルが追加されました。このシグナルを利用して、辞めそうなプレーヤーに通常価格よりお得なパワーアップ アイテムを販売するなど、ユーザーの定着率を上げる特別プロモーションを提供できます。

最後に、ウェアラブル端末対応のアプリを開発している場合、優れたユーザー エクスペリエンスを提供するには、バッテリーの寿命と電力利用の最適化が極めて重要になることはご存じでしょう。Google Play サービス 8.3 では、緊急時にもデータ アイテムを同期できる DataApi を更新しました。データ アイテムに優先度が追加されたので、同期を実行するタイミングを指定できるようになりました。遠隔操作アプリのように、すぐに同期しなければならないアプリを制作されている場合、setUrgent() を呼び出すと、同期を直ちに実行することができます。連絡先を更新するアプリであれば、多少の同期遅れを許可することができます。緊急ではない DataItems は 30 分まで遅延できますが、2~3分以内に届くことがほとんどです。デフォルトでは優先度は「低」に設定されています。したがって、以前と同様に即時の同期を実行したい場合は、setUrgent() を呼び出す必要があります。

Android Wear API のリスナーに、フィルターが追加されたため、リスナーは変更のサブセットのみを携帯端末とウォッチの両方で受け取れるようになりました。Android の Manifest ファイルに登録済みのリスナーはフィルターで抽出され、プロセスの開始が必要なイベントのみを受信します。それ以外のイベントは、addListener() などのメソッドで追加された、接続中のリスナーに送信されます。リスナーが関心を持っていないイベントを除去する手間が省けるので、アプリやシステムの効率が上がります。

今回の Google Play サービスのリリースについての説明は、以上です。詳細は、Google デベロッパーサイトをご覧ください。

Posted by Eiji Kitamura - Developer Relations Team

接続端末の開発では、他の端末との通信方法を選択し、ユーザーと接続端末の通信を許可する必要があります。そこで Weave が必要となります。Weave では、双方向から操作できる通信機能を端末に直接組み込むことができます。また携帯電話や端末がクラウドから、ローカルやリモートで相互に通信できるメッセージング サービスも提供しており、Weave クラウド サーバーを使用することで、リモート通信でウェブ接続端末にどこからでも安全にアクセスできます。Weave で端末の設定やアクセス制限を安全に行うこともできます。さらに Brillo 内に直接組み込まれているため Brillo に対してシームレスに動作しますが、Weave ライブラリを既存の Linux ベース OS で使用することも可能です。

Weave の優れた機能については、次のビデオをご覧ください。
Weave には iOS 用と Android 用のモバイル SDK が搭載されており、モバイル ユーザーの接続状態を管理し、さらに機能を強化できるアプリを構築できます。アプリを実際の端末まで適用したいと考えるアプリ開発者は、Weave のモバイル およびウェブ API を使用して、機種や台数に関係なく Weave 端末を 1 つのアプリで制御できます。

Brillo と Weave は、デフォルト設定でもオープン、拡張可能、しかも安全なため、さまざまな端末や使用事例をサポートでき、提供されるプラットフォーム、ツール、サービスで端末やアプリがさらに使いやすくなります。

プラットフォーム以外にも、認定 Weave ブランドの端末を提供する Weave 互換性プログラムのほか、シリコン ベンダーが Brillo 準拠のハードウェア開発と販売を行うための、ハードウェア プログラムを順次公開していきます。

Posted by Eiji Kitamura - Developer Relations Team
Share on Twitter Share on Facebook

先日お知らせした Android Wear のコースに続き、新しいオンライン コース「Google Cast and Android TV Development」(Google Cast と Android TV の開発)を Udacity に開設したことをお知らせします。このコースでは、既存の Android アプリを拡張して、テレビと連携させる方法を説明しています。実用的なアドバイス、コード スニペット、サンプルコードの詳細な説明など、盛りだくさんの内容です。

Google Cast と Android TV の両方に対応するためにアプリを書き直す必要はありません。Android TV は、Android に新しいフォームファクタが加わっただけのものです。Leanback library により、大きなスクリーンにアプリを表示するのが簡単になります。また、アプリに映画のような UI を追加することもできます。Google Cast には、誰もがすぐにこのデバイスを使えるように、サンプルやガイドが用意されています。また Google は Cast Companion Library を提供していますが、これは Android アプリの Google Cast への追加を迅速かつ簡単に実行するためのものです。

オンライン コースでは、Android Wear や Android Auto など、他の Google プラットフォームも含めた、ユビキタス コンピューティング シリーズの一環として実施します。それぞれが独立した短期コースのため、単独でも一括でも受講可能です。

学習は今すぐ、無料で開始できます。ユーザーのみなさんが、あなたのアプリをテレビで見られる日を待っていますよ。


Posted by Takuo Suzuki - Developer Relations Team
Share on Twitter Share on Facebook


Posted by Yoshifumi Yamaguchi - Developer Relations Team
Share on Twitter Share on Facebook

図のこれらの曲線は何を意味しているのでしょうか?この場合、ゲームの収益化が期待できないことを示しています。稼いだ通貨量より使った通貨量が少なければ、ユーザーは黒字になります。ユーザーはお金が足りないと感じていません。これはプレイヤーが通貨の使い方または通貨を使うことの価値を理解していないということです。仮想通貨を利用可能なコンテンツがどのくらいあるか、またそのようなコンテンツをすぐに見つけやすくなっているかを再検証する必要があります。またインフレは好ましくないため、ゲームで稼ぐことができる通貨の量を減らすことを検討しても良いでしょう。最終的に、図 2 のような曲線を描くことが望ましいといえます。
図 2 バランスのとれた経済 図 2 バランスのとれた経済
図 1 よりかなり改善されました。ユーザーは、稼ぐ量よりも多くの通貨を使っています。でも少し待ってください。なぜこのようになったのでしょうか?これには 2 つの理由があります。1 つめは、プレイヤーが変更の前に貯めていた通貨のストックを使っているからです。そして 2 つ目は、ユーザーがアプリで購入した通貨は、上の図に含めるべきではないということです。これは覚えておくべき重要なポイントです。もう数日待てば、2 つの曲線が少し近づくでしょう。その差分が、ユーザーが IAP を通じて購入した仮想通貨ということになります。

図 3 安定した経済 図 3 安定した経済
Play Games Services では、コード 2 行でこのように経済を視覚化できます。iOS や Android でも利用でき、ユーザーがサインインする必要もありません。Android や iOS のアプリでは以下のようになります。
実装方法についての詳細はこちらをご覧ください。

実装が完了すれば、Play Store デベロッパー コンソール にてグラフを表示することができます。[Game Service] セクションで、[Player analytics] から [overview] をクリックしてください。


Posted by Eiji Kitamura - Developer Relations Team
Share on Twitter Share on Facebook

このコースは、Android Wear、Android Auto、Android TV、Google Cast といった、Google プラットフォーム上のユビキタス コンピューティング シリーズの一部として提供されます。それぞれが独立した短期コースのため、単独でも一括でも受講可能です。Android Wear プラットフォームは、お持ちのアプリに機能性をプラスし、他アプリとの差別化を実現する絶好の機会です。この Udacity コースでは、時間をかけず簡単に Android Wear プラットフォームについて学ぶことができます。

今すぐ無料のコースを始めましょう!


Posted by Eiji Kitamura - Developer Relations Team
Share on Twitter Share on Facebook

Google では 12 月 16 日(æ°´)、Google のテクノロジーの最新情報を紹介する開発者向けイベント Google Developers Meetup #2 を開催します。本イベントでは、Google の Developer Relations チームや Google Developer Experts が、Google の開発プラットフォーム、API, SDK、ツールなどの活用方法をご紹介します。


■イベント概要

【イベント名】 Google Developers Meetup #2
【日程】 2015 å¹´ 12 月 16 日(æ°´) 19:00 - 21:00 (開場: 18:30)※ 終了後、懇親会(軽食付き)を行う予定です。
【場所】 イベント&コミュニティスペース dots. in 渋谷
【定員】 200 名
【会費】 無料
【主催】 グーグル株式会社


■セッション
※アジェンダは予告なく変更させていただく可能性があります。予めご了承ください。


■申し込み方法
こちらのフォームよりお申し込みください

多くの皆様のご参加をお待ちしております。



Posted by Takuo Suzuki - Developer Relations Team

Share on Twitter Share on Facebook

Google Play の機能を利用した RogerVoice アプリ開発の詳細について:


Posted by Eiji Kitamura - Developer Relations Team
Share on Twitter Share on Facebook

新

API バージョン 3.23 (2015 å¹´ 11 月以降の試験運用バージョン) では、一時的に旧コントロール スタイルに切り替えることができます。バージョン 3.22 と 3.23 で旧コントロール スタイルを使用するには、地図を初期化する前に単独のパラメータ google.maps.controlStyle = 'azteca' を設定します。このパラメータは 2016 å¹´ 8 月まで使用可能であり、アプリケーションに必要なアップデートを実施するには十分な時間がとれると思います。バージョン 3.24 (2016 å¹´ 2 月以降の試験運用バージョン) では、このパラメータは削除されます。地図に重複するカスタム コントロールまたは UI を使用している場合、2016 å¹´ 8 月までに時間的余裕をもって新コントロール スタイルでアプリケーションをテストし、アップデートすることを推奨します。新しいロゴは API のバージョンすべてに影響を及ぼす唯一の変更であり、削除することはできません。

各コントロールによる影響についての詳しい説明と、旧コントロールに戻すための切り替え方法についてはデベロッパー ドキュメントをご参照ください。また、Maps API の バージョンごとの動作方法、使用している API のバージョンを確認する方法、およびデベロッパー向けのベストプラクティスについての詳細は、Maps API の バージョン ガイド をご覧ください。


Posted by Eiji Kitamura - Developer Relations Team
Share on Twitter Share on Facebook



またGoogle Play デベロッパー コンソールの機能を最大限に活用してアプリを公開し、ユーザー数の拡大やユーザー エンゲージメントの向上を実現する方法についてもご紹介しています。

Posted by Takuo Suzuki - Developer Relations Team
Share on Twitter Share on Facebook

変更の理由:
  1. HTTP ページのアイコンを使用することで、セキュリティの状態がさらに分かりやすくなります。
  2. 知っておくべきセキュリティ状態の種類が少なくなります。

混在コンテンツ(Mixed Content)に関する警告の非表示

HTTP 画像など特定の混在コンテンツを含む HTTPS ページが主に変更の対象となります。

サイト運営者が直面する課題: HTTP サイトから HTTPS に移行することで混在コンテンツが発生します。これは長期的に見ると望ましくないものの、移行のデバッグには不可欠です。移行中のサイトの安全性は完全とは言えませんが、以前に比べて低下することはまずありません。

黄色い「三角形の警告」バッジを非表示にすると、このような移行期間中は混在コンテンツのあるページに関する警告が表示されなくなります。サイト運営者には、一刻も早い HTTPS への切り替えをおすすめします。

セキュリティ状態の種類を減少

Chrome におけるセキュリティ状態の種類が、4 つから 3 つになります。

ウェブページのセキュリティ状態を正確に表示することと、多数のセキュリティの状態や詳細情報をユーザーを混乱させないこと。この 2 つを適切に両立させる必要があります。HTTP ページアイコンと、この黄色の「三角形の警告」バッジが判別しにくいということが分かったため、この 2 つの状態のセキュリティ上の違いについて、強調しないほうがよいと判断しました。デベロッパーや関心をお持ちのユーザーは、URL が「https://」で始まっているかどうかで違いを区別できます。

将来的にはほとんどのウェブサイトが安全となることを願っており、アイコンの種類を安全かそうでないかの 2 つに集約できるよう計画を進めています。今回の発表はその計画の成功に向けての小さな 1 歩です。


Posted by Eiji Kitamura - Developer Relations Team
Share on Twitter Share on Facebook

1. 設定: 非対称鍵のペアの作成

まず、次のように非対称鍵のペアを作成します。
KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
keyPairGenerator.initialize(
        new KeyGenParameterSpec.Builder(KEY_NAME,
                KeyProperties.PURPOSE_SIGN)
                .setDigests(KeyProperties.DIGEST_SHA256)
                .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                .setUserAuthenticationRequired(true)
                .build());
keyPairGenerator.generateKeyPair();
.setUserAuthenticationRequired(true) ã«æ³¨ç›®ã—てください。このメソッドを呼ぶことにより、秘密鍵を使用する前に、登録した指紋の認証を強制できるようになります。

次に作成した秘密鍵と公開鍵を以下のように取得します。
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
PublicKey publicKey =
        keyStore.getCertificate(MainActivity.KEY_NAME).getPublicKey();
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
PrivateKey key = (PrivateKey) keyStore.getKey(KEY_NAME, null);

2. 登録: サーバーへの公開鍵の登録

次に、公開鍵をバックエンドに送信し、その後のユーザの購入がユーザーによって承認されていること(この公開鍵に対応する秘密鍵によって署名されていること)をバックエンドが確認する必要があります。このサンプルでは、公開鍵の送信を模擬的に再現するためにバックエンド実装を端末上で動作する模擬コードを使用していますが、実際には公開鍵をネットワーク経由で送信する必要があります。
boolean enroll(String userId, String password, PublicKey publicKey);

3. 認証: 指紋による署名処理

商品購入などでユーザーが処理を認証できるように、指紋センサーへのタッチを促すプロンプトを表示します。
続いて、次のように指紋の読み込みを開始します。

Signature.getInstance("SHA256withECDSA");
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
PrivateKey key = (PrivateKey) keyStore.getKey(KEY_NAME, null);
signature.initSign(key);
CryptoObject cryptObject = new FingerprintManager.CryptoObject(signature);
CancellationSignal cancellationSignal = new CancellationSignal();
FingerprintManager fingerprintManager =
        context.getSystemService(FingerprintManager.class);
fingerprintManager.authenticate(cryptoObject, cancellationSignal, 0, this, null);

4. 最終処理: バックエンドへのデータ送信と照合

認証が成功したら、次のように署名済みのデータ(このサンプルでは、購入処理の内容)をバックエンドに送信します。
Signature signature = cryptoObject.getSignature();
// Include a client nonce in the transaction so that the nonce is also signed 
// by the private key and the backend can verify that the same nonce can't be used 
// to prevent replay attacks.
Transaction transaction = new Transaction("user", 1, new SecureRandom().nextLong());
try {
    signature.update(transaction.toByteArray());
    byte[] sigBytes = signature.sign();
    // Send the transaction and signedTransaction to the dummy backend
    if (mStoreBackend.verify(transaction, sigBytes)) {
        mActivity.onPurchased(sigBytes);
        dismiss();
    } else {
        mActivity.onPurchaseFailed();
        dismiss();
    }
} catch (SignatureException e) {
    throw new RuntimeException(e);
}

最後に、ステップ 2 で登録した公開鍵を使用し、バックエンドにある署名済みデータと照合します。
@Override
public boolean verify(Transaction transaction, byte[] transactionSignature) {
    try {
        if (mReceivedTransactions.contains(transaction)) {
            // It verifies the equality of the transaction including the client nonce
            // So attackers can't do replay attacks.
            return false;
        }
        mReceivedTransactions.add(transaction);
        PublicKey publicKey = mPublicKeys.get(transaction.getUserId());
        Signature verificationFunction = Signature.getInstance("SHA256withECDSA");
        verificationFunction.initVerify(publicKey);
        verificationFunction.update(transaction.toByteArray());
        if (verificationFunction.verify(transactionSignature)) {
            // Transaction is verified with the public key associated with the user
            // Do some post purchase processing in the server
            return true;
        }
    } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
        // In a real world, better to send some error message to the user
    }
    return false;
}

ステップ 1 で述べたとおり、秘密鍵を使用する前にユーザー認証が毎回必要であるため、この時点でユーザー自身の指紋が正しく認証されているとみなすことができます。バックエンドで購入後の処理を実行し、ユーザーに処理が成功したことを通知しましょう。

その他の更新されたサンプル

その他に、 Android for Work API に関連する Marshmallow で更新された機能についてサンプルを更新しました。




  • AppRestrictionEnforcer と AppRestrictionSchema のサンプルは、Android 5.0 Lollipop の Android for Work API の一部として アプリ制限機能導入時にリリースされました。AppRestrictionEnforcer は、プロファイル オーナーとして他のアプリに制限を設定する方法について説明しています。AppRestrictionSchema は、AppRestrictionEnforcer で制御できるいくつかの制限を定義しています。この更新は、Android 6.0 で追加導入された 2 つの制限タイプの使用方法について説明しています。

  • 更新されたサンプルがデベロッパーの皆様のお役に立てればと思います。サンプルについてのご質問は、GitHub ページ ã§ Issue を登録するか、Pull Request ã‚’送っていただくようお願い致します。


    Posted by Takeshi Hagikura - Developer Relations Team
    Share on Twitter Share on Facebook