Google Playの連絡先権限ポリシー対応ガイド — Android 17のContact PickerとREAD_CONTACTS申告、Flutterでの移行手順

はじめに

Google Play が連絡先の読み取り権限 READ_CONTACTS の扱いを厳しくします。Android 17(API 37)以上を target にしたアプリは、2027 年 1 月 27 日から「なぜ権限が必要か」の申告と審査が必須になります。r/FlutterDev でも注意喚起の投稿が出ていました。

写真・動画の権限で Photo Picker への移行が求められたのと同じ流れで、今回は Android 17 で入った新しい Contact Picker が「代わりの手段」として用意されています。ただし Contact Picker は古い Android にはありません。この記事では、ポリシーの中身、Contact Picker の仕組み、Android 16 以前をどう扱うか、Flutter アプリで何を確認すればよいかを順に整理します。

ポリシーの中身 — 対象・期限・申告

Play Console ヘルプの「READ_CONTACTS policy」によると、要点は次のとおりです。

  • 対象: target が Android 17(API 37)以上で、READ_CONTACTS を要求するアプリ
  • 原則: Contact Picker でアプリの中心機能が満たせない場合に限り、権限を要求できる
  • 時系列: 2026 年 4 月 15 日に発表 → 2026 年 9 月から Play Console で「申告するか、権限を外して Picker を使うか」を促す表示 → 2027 年 1 月 27 日から順守が必須(Console で 30 日の自動延長が可能)
  • 例外: 社内向けのアプリと、企業のデバイス管理アプリ

申告フォームでは、権限が必要な機能を選び(連絡先管理、電話・SMS、通話履歴、CRM、着信の選別、アクセシビリティ、パーソナルアシスタント、友だち検索、バックアップ、キーボードの予測変換など)、なぜ Picker では足りないのかを説明します。

注目すべきは「原則認められない」側の例です。ファイルの共有、共同作業、招待・紹介、送金相手の選択だけを理由にした権限は通りません。「自前で連絡先選択画面を作りたいから」も理由になりません。多くのアプリで連絡先を使う場面は「友だちを招待する」「送り先を 1 人選ぶ」なので、ここに当たるアプリは権限を外す前提で考えた方がよいでしょう。

なお、Web 検索の要約などで「2026 年 10 月 28 日が期限」とする情報も見かけますが、公式ヘルプの記載は 2027 年 1 月 27 日です。10 月 28 日は、ポリシーをまとめているサイトでは位置情報の権限ポリシーの日付として載っており、連絡先の期限ではありません。期限は必ず公式ページで確認してください。また、Google が 4 月に告知した Play Console の公開前チェック(pre-review checks)が 10 月 27 日から始まり、連絡先や位置情報の権限の問題を事前に指摘するようになります。こちらは期限ではありませんが、次のリリースで指摘が出る可能性があるので、早めに整理しておくと慌てずに済みます。

Contact Picker の仕組みと、Android 16 以前の扱い

Android 17 の Contact Picker

Contact Picker は、ユーザーが選んだ連絡先の、アプリが求めた項目だけを渡すシステムの画面です。アプリは ContactsPickerSessionContract.ACTION_PICK_CONTACTS で起動し、エクストラで欲しい項目(電話番号・メール・住所などの MIME タイプ)や複数選択、選択数の上限を指定します。

結果として返るのは 1 つの セッション URI です。ContentResolver で ContactsContract.Data と同じ形の列を読めますが、次の制約があります。

  • 読めるのは選ばれた連絡先の、要求した項目だけ。アカウント関連のメタデータは除かれる
  • 権限は一時的。後で使うなら、受け取った時点でアプリ側に保存する
  • selection / selectionArgs を指定すると例外になる

既存の ACTION_PICK も、target が 17 以上なら自動で新しい画面に置き換わります。複数項目の要求や仕事用プロファイルとの切り替えを使いたい場合は、新しいアクションに書き換えます。

Android 16 以前ではどうなるか

ここが実務上の落とし穴です。Contact Picker はバックポートされていません。Android 16 以前の端末では従来の ACTION_PICK が動きます。

従来の方式にも、権限なしで済む使い方はあります。「連絡先」ではなく「電話番号」や「メールアドレス」の行を直接選ばせる方法です(例: Phone.CONTENT_TYPE を指定した ACTION_PICK)。この場合は選ばれた 1 件の値を権限なしで読めます。一方、「連絡先」を選ばせてから、その人の電話番号やメールをアドレス帳に問い合わせると READ_CONTACTS が必要です。Capawesome の解説が指摘するとおり、連絡先の URI だけでは表示名などの情報しか取れません。

つまり古い OS では、1 件・1 項目なら権限なしで取れるが、複数人の選択や複数項目の取得はできない、という線引きになります。

Flutter アプリで確認すること

Flutter では、連絡先まわりをプラグインに任せていることが多いはずです。権限を外す前に、次を確認します。

1. マージ後のマニフェストに READ_CONTACTS が残っていないか

プラグインのマニフェストから権限が入り込むことがあります。build/app/outputs/ 以下のマージ済みマニフェストを確認し、不要なら tools:node="remove" で明示的に消します。

2. 使っているプラグインの「権限なし」の条件

  • flutter_contacts: README では READ_CONTACTS / WRITE_CONTACTS を自分でマニフェストに書く手順です。システムの選択画面を開く FlutterContacts.native.showPicker() は権限なしで動くとされていますが、Android で項目を指定する showPicker(properties: …) は READ_CONTACTS が必要で、無いと例外になります。
  • system_contact_picker: 権限を一切宣言・要求しない設計です。Android 17 以上と iOS では複数選択・複数項目に対応し、Android 9〜16 では従来の ACTION_PICK で「名前+1 項目・1 人だけ」に制限されます(条件を超えるとエラー)。getCapabilities() で端末ごとの可否を確認してから UI を出し分けられます。まだ 0.0.x 系の若いパッケージなので、採用するなら実機での確認が前提です。

3. 機能ごとの仕分け

連絡先に触れる箇所を洗い出し、「ユーザーが選ぶだけ(招待・送り先選び)」と「アドレス帳全体が必要(同期・友だち検索)」に分けます。前者は Picker に移して権限を外し、後者だけを申告の対象にします。招待機能のためだけに権限を持っているなら、申告しても通らない可能性が高いので、先に外すのが安全です。

4. targetSdk を上げるタイミング

ポリシーの対象は target が 37 以上のアプリです。とはいえ Play には target API の引き上げ要件が毎年あるため、いずれ対象になります。targetSdk を上げる作業と同時にやると原因の切り分けが難しくなるので、権限の整理を先に終えてから target を上げる順番をおすすめします。

まとめ

  • target が Android 17(API 37)以上のアプリは、2027 年 1 月 27 日から READ_CONTACTS に申告と審査が必須
  • 招待・共有・送り先の選択だけが理由の権限は原則認められない
  • 代わりは Android 17 の Contact Picker。ただし古い OS にはなく、従来方式では「1 人・1 項目」までなら権限なしで取れる
  • Flutter ではマージ後のマニフェストと、プラグインごとの「権限なしで動く条件」を確認する

写真・動画に続き、連絡先も「アプリが全部読む」から「ユーザーが選んだ分だけ渡す」に移りました。今後もほかの個人データで同じ流れが続くと考えて、データへのアクセスは必要最小限の範囲で設計しておくと手戻りが減ります。

ソース