Register now for Android Dev Summit 2019!

Wear OS 上でパーミッションをリクエストする

Android 6.0(API レベル 23)で新しいパーミッション モデルが導入され、Wear OS by Google に固有の変更や、すべての Android ベースのデバイスに適用される変更が加えられています。

コンパニオン スマートフォン アプリがある場合でも、ユーザーは Wear アプリにパーミッションを付与する必要があります。Android 6.0(API レベル 23)以降の Wear アプリは、スマートフォン アプリに付与されたパーミッションを受け取ることはできません。たとえば、ユーザーがスマートフォン アプリに位置情報を使用するパーミッションを付与していたとしても、Wear アプリに対してもう一度同じパーミッションを付与する必要があります。

注: このページでは、時計アプリのコンパニオンとなるスマートフォン アプリを作成するケースも想定しています。ただし、スマートフォン アプリの作成は必須ではなく、時計アプリはスタンドアロン アプリでも構いません。

Android 6.0(API レベル 23)のパーミッション モデルでは、Wear アプリとスマートフォン アプリの両方で、「アプリが必要とする可能性のあるすべてのパーミッションを、事前にユーザーから付与されていなければならない」という要件が削除され、アプリのインストールやアップグレードを効率的に行えるようになりました。今後、パーミッションは、実際にアプリが必要とするときに初めてリクエストされます。

注: アプリが新しいパーミッション モデルを使用するには、uses-sdk-elementcompileSdkVersion の両方に値 23 を指定する必要があります。

以下では、Wear OS アプリを開発する際の Android 6.0(API レベル 23)パーミッション モデルの使用方法について説明します。

パーミッション シナリオ

Wear OS の場合、大きく分けて以下の 4 つのシナリオで dangerous パーミッションをリクエストすることが考えられます。

  • Wear アプリが、ウェアラブル デバイス上で稼働するアプリ用のパーミッションをリクエストする場合。
  • Wear アプリが、ハンドセット上で稼働するアプリ用のパーミッションをリクエストする場合。
  • スマートフォン アプリが、ウェアラブル デバイス上で稼働するアプリ用のパーミッションをリクエストする場合。
  • ウェアラブル アプリが、コンパニオンのスマートフォン アプリとは異なるパーミッション モデルを使用する場合。

それぞれのシナリオについて以下で説明します。パーミッション リクエストの詳細については、パーミッション リクエストのパターンをご覧ください。

Wear アプリが、ウェアラブル デバイスで稼働するアプリ用のパーミッションをリクエストする場合

Wear アプリが、ウェアラブル デバイス上で稼働するアプリ用のパーミッションをリクエストすると、そのパーミッションを付与するよう求めるダイアログがユーザーに対して表示されます。アプリやサービスができるのは、アクティビティから requestPermissions() メソッドを呼び出すことだけです。ウォッチフェイスなど、サービス経由でユーザーがアプリとインタラクションしている場合、サービスはパーミッションをリクエストする前にアクティビティを開く必要があります。

アプリは、特定の機能を実行するうえでパーミッションが必要だと明白にわかるタイミングで、コンテキスト内でパーミッションをリクエストします。アプリが特定のパーミッションを必要とすることが明白である場合は、アプリの起動時にリクエストすることもできます。そこまで明白でない場合は、パーミッションをリクエストする前に追加の説明を表示するようにしてください。

アプリやウォッチフェイスが一度に複数のパーミッションを必要とする場合は、パーミッションのリクエストが連続して表示されます。

複数のパーミッション画面が連続して表示されます。

図 1: パーミッション画面が連続して表示されます。

注: Android 6.0(API レベル 23)以降、Wear OS は、カレンダー、連絡先、位置情報のデータを自動的に Wear デバイスに同期します。そのため、Wear がこのようなデータをリクエストすると、このシナリオが適用されます。

Wear アプリが、スマートフォンのパーミッションをリクエストする場合

Wear アプリからスマートフォンのパーミッションをリクエストする場合、Wear アプリは、ユーザーをスマートフォンに送り、パーミッションを許可してもらう必要があります。その際、スマートフォン アプリのアクティビティを使用して、ユーザーに追加の説明を表示することができます。このアクティビティには、パーミッションを許可するボタンと拒否するボタンの 2 つを含める必要があります。

Wear アプリがユーザーをスマートフォンに送り、パーミッションを付与してもらいます。

図 2: ユーザーをスマートフォンに送り、パーミッションを付与してもらいます。

スマートフォン アプリが、ウェアラブルのパーミッションをリクエストする場合

ユーザーがスマートフォン アプリを操作しており、そのアプリがウェアラブルのパーミッションを必要とする場合、スマートフォン アプリは、ユーザーをウェアラブルに送り、パーミッションを許可してもらう必要があります。スマートフォン アプリは、ウェアラブル上で requestPermissions() メソッドを使用して、システム パーミッション ダイアログをトリガーします。

スマートフォン アプリがユーザーをウェアラブルに送り、パーミッションを付与してもらいます。

図 3: ユーザーをウェアラブルに送り、パーミッションを付与してもらいます。

ウェアラブルとスマートフォン アプリ間でパーミッション モデルが一致しない場合

スマートフォン アプリの方では Android 6.0(API レベル 23)モデルを使用し始めたが、ウェアラブル アプリの方ではまだ使用を開始していない場合、Wear アプリはダウンロードされますが、インストールはされません。ユーザーが初めてアプリを起動すると、保留中のパーミッションをすべて許可するようリクエストされます。パーミッションが付与されると、アプリがインストールされます。ウォッチフェイスなど、ランチャーを持たないアプリの場合、アプリに必要なパーミッションを付与するよう求めるストリーム通知が表示されます。

パーミッション リクエストのパターン

ユーザーにパーミッションをリクエストする際のパターンには、いくつかの種類があります。優先度の高い順に以下に示します。

  • コンテキスト内でリクエスト: 特定の機能を実行するうえで明白にパーミッションが必要だが、アプリの実行そのものには必須ではない場合。
  • コンテキスト内で説明: パーミッションをリクエストする理由が明白ではなく、アプリの実行には必須でない場合。
  • 事前にリクエスト: パーミッションの必要性が明白で、アプリの実行に必須である場合。
  • 事前に説明: パーミッションの必要性は明白ではないが、アプリの実行に必須である場合。

コンテキスト内でリクエスト

アプリは、特定の機能を実行するうえでパーミッションが必要だと明白にわかるタイミングで、パーミッションをリクエストします。パーミッションと使用する機能との関連性をユーザーが理解すれば、パーミッションを付与する可能性が高くなります。

たとえば、アプリが周辺の有名スポットを表示する場合、ユーザーの位置情報が必要になります。周辺のスポットの検索と位置情報のパーミッションの必要性との間には明白な関連性があるため、ユーザーがタップして周辺のスポットを検索しようとしたとき、アプリは、すぐに位置情報のパーミッションをリクエストできます。関連性が明白なので、アプリが追加の説明画面を表示する必要はありません。

パーミッションの必要性が明白な場合、アプリはパーミッションをリクエストします。

図 4: コンテキスト内でリクエストします。

コンテキスト内で説明

必要に応じて、パーミッションをリクエストする前に追加の説明を表示することもできます。アプリが特定の機能を実行するうえで、リクエストしたパーミッションにアクセスしなければならない理由が明白でない場合は、そのアクションのコンテキスト内で追加説明を行う必要があります。

コンテキスト内で説明する例を図 5 に示します。アプリはパーミッションがなくてもタイマーを開始できますが、インラインのキューで、アクティビティの一部(位置情報の検出)がロックされていることを説明します。ユーザーがキューをタップすると、パーミッション リクエスト画面が表示され、位置情報検出機能のロックを解除できるようになります。

shouldShowRequestPermissionRationale() メソッドを使用すると、アプリが詳細情報を表示するかどうかを指定することができます。詳細については、実行時にパーミッションをリクエストするをご覧ください。

パーミッションの必要性が生じた場合に、パーミッションが必要となる理由を説明します。

図 5: コンテキスト内で説明します。

事前にリクエスト

アプリ自体が動作するために明白にパーミッションが必要である場合、ユーザーがアプリを起動したときにパーミッションをリクエストすることができます。たとえば、地図アプリの場合、想定されているアクティビティを実行するために、デバイスの位置情報にアクセスする必要があることは明白です。このパーミッションのために説明を行う必要はありません。

アプリを実行するうえでパーミッションの必要性が明白な場合、起動時にパーミッションをリクエストすることができます。

図 6: 事前にリクエストする

事前に説明

場合によっては、アプリの基本機能にパーミッションが必要であるにもかかわらず、パーミッションの必要性が明白でないこともあります。このような場合、ユーザーが初めてアプリを起動したときや、初めてウォッチフェイスを設定したときに、アプリやウォッチフェイス上でユーザーに説明を表示し、パーミッションをリクエストすることもできます。

起動時にパーミッションをリクエストする場合、アプリがパーミッションを必要とする理由を説明することができます。

図 7: 事前に説明します。

拒否された場合

リクエストされたパーミッションをユーザーが拒否した場合、目的のアクティビティにとってそのパーミッションが重要でないのであれば、アクティビティの継続を妨げることはできません。パーミッションが拒否されたことでアクティビティの一部が無効になった場合は、目で見てわかる実用的なフィードバックを提供します。図 8 では、ユーザーがパーミッションを付与しなかったために機能がロックされていることを、ロックアイコンで示しています。

ユーザーがパーミッションを拒否した場合、対象の機能にロックアイコンが表示されます。

図 8: パーミッションが拒否されたために機能がロックされていることを、ロックアイコンで示しています。

以前に拒否されたウェアラブルのパーミッション ダイアログを再度表示する場合は、[Deny, don't show again] オプションを追加します。ユーザーがこのオプションを選択すると、以降、そのパーミッションは、ウェアラブルの Settings アプリからでなければ許可できなくなります。

パーミッションのリクエストを停止するオプションが表示されます。

図 9: パーミッション リクエスト画面を今後表示しないオプションが表示されます。

サービスのパーミッション

上記で説明したように、requestPermissions() メソッドを呼び出せるのは、アクティビティに限られます。そのため、ウォッチフェイスなど、サービス経由でユーザーがアプリとインタラクションしている場合、サービスはパーミッションをリクエストする前にバックグラウンド アクティビティを開く必要があります。このアクティビティは、追加の説明を表示するものでも、システム ダイアログを表示するだけの非表示アクティビティでも構いません。

ウェアラブル アプリがウォッチフェイス以外のサービスを実行していて、パーミッションのリクエストを必要とするアプリが起動されていない場合は、ウェアラブル上に説明の通知を配置することができます。この通知内にアクティビティを開くアクションを設置しておくと、そこからシステム パーミッション ダイアログをトリガーすることができます。

注: パーミッション リクエストでストリーム通知を利用できるのは、この方法だけに限られます。

ユーザーがサービス経由で間接的にアプリとインタラクションしているときに、パーミッションの付与が必要となる場合があります。

図 10: サービスがパーミッションをリクエストします。

Settings

スマートフォンの場合と同じように、ユーザーはいつでも Settings から Wear アプリのパーミッションを変更することができます。そのため、パーミッションを必要とする操作をユーザーが試みた場合、アプリはまず checkSelfPermission() メソッドを呼び出して、現在アプリにその操作を行うためのパーミッションが付与されているかどうかを確認する必要があります。このチェックは、ユーザーが以前にパーミッションを付与していることがわかっていても行う必要があります。ユーザーがその後でパーミッションを取り消している可能性があるためです。

ユーザーは、Settings アプリからパーミッションを変更できます。

図 11: Settings アプリを使用して設定を変更します。