Google Playの連絡先権限ポリシーにより、2027年1月27日からAndroid 17(API レベル37)以降をターゲットとするアプリは、次の場合にリクエストできます: READ_CONTACTS Android Contact Pickerがコア機能をサポートできない場合に限られ、Play Consoleでの申告で正当化する必要があります。連絡先を読み取って友達の招待、ファイルの共有、電話番号の入力を行うほとんどのCapacitorアプリでは、Contact Pickerに切り替えて権限を削除するのが解決策です。本ガイドでは、ポリシーを説明し、その方法を紹介します。 @capgo/capacitor-contacts、そして本当に全アドレス帳が必要な場合にどうすればよいかを解説します。
ポリシーの内容
Googleは2026年4月15日、プライバシー更新の一環としてこのポリシーを発表しました。Play Consoleのヘルプページからの主なポイントは以下の通りです:
- 対象: Android 17 (API 37) 以上をターゲットにし、
READ_CONTACTS. - ルール: アプリのコア機能においてAndroidの連絡先ピッカーが不十分な場合のみ、
READ_CONTACTSをリクエストできます。 - 宣言: この権限を保持するアプリは、Play Console に宣言フォームを提出し、どの機能がその権限を必要とするか、そしてなぜピッカーでは不十分かを説明する必要があります。
- タイムライン: Play Console は 2026 年 9 月から、
READ_CONTACTSを宣言するアプリにプロンプトを表示し始めます。2027 年 1 月 27 日にコンプライアンスが必須となります。Google は Play Console で 30 日間のセルフサービス延長に言及しています。 - 例外: プライベートアプリとエンタープライズデバイス管理アプリは対象外です。
- データ: 連絡先データは User Data ポリシーにより個人かつ機密情報とみなされ、対象者からの許可なく非公開の連絡先データを公開することはできません。
READ_CONTACTS を保持できるユースケース
Google は、連絡先管理アプリ、ダイヤラーや SMS アプリ、通話履歴と通話スクリーニング、CRM、アクセシビリティ機能、パーソナルアシスタント、フレンドマッチング、バックアップとリストア、キーボードやオートコンプリートなどのコア機能を挙げています。
ピッカーに切り替えるべきユースケース
誰かを招待または紹介する、ファイルを共有する、コラボレーションする、または送金先として連絡先を選択する場合。アプリが連絡先を読む理由がこれらであれば、宣言は承認されません。ピッカーを使用してください。
Android 17での変更点
Android 17には新しいシステム連絡先ピッカーが搭載されました。アプリは、ユーザーが選択した連絡先とフィールドのみを公開する、一時的な読み取り専用セッションURIを取得できます。パーミッションは不要です。Android 17をターゲットとするアプリでは、従来の Intent.ACTION_PICK contacts intentがこの新しいピッカーに自動的にアップグレードされます。また、新しいintent actionを通じて、特定のデータフィールド(電話番号、メール、郵便住所)や複数選択をリクエストすることも可能です。
旧バージョンのAndroidでは、連絡先ピッカーを通じて特定のデータ行(例:電話番号)を選択すると、アプリが READ_CONTACTSなしで読み取れるURIが返されていました。これが、すべてのAndroidバージョンでパーミッション不要のフローを可能にしています。
「連絡先を選択」にREAD_CONTACTSが必要だった理由
多くのCapacitorプラグインは、「連絡先を選択」を実装するために、まず連絡先全体を選択するピッカーを開き、その後その連絡先の電話番号やメールをアドレス帳からクエリします。この2番目のクエリには READ_CONTACTSが必要です。そのため、電話番号1つだけ欲しかっただけのアプリでもパーミッションを宣言する必要があり、これがまさにポリシーが対象としている問題です。
修正方法は、ピッカーに必要な特定のフィールドを要求し、結果URIにデータが含まれるようにすることです。
READ_CONTACTSなしで電話番号、メール、住所を選択
@capgo/capacitor-contacts に追加されました property バージョン8.1.0でオプションが追加されました。設定すると、Androidは電話番号、メール、または郵便住所テーブルに対してピッカーを開き、許可されたURIから選択された行を読み取ります。 READ_CONTACTS はすべてのAndroidバージョンで必要です。iOSでは、システムピッカーは連絡先へのアクセス権限を必要としません。
bun add @capgo/capacitor-contacts
bunx cap sync
import { CapacitorContacts, ContactProperty } from '@capgo/capacitor-contacts';
export async function pickPhoneNumber(): Promise<string | undefined> {
const { contacts } = await CapacitorContacts.pickContacts({
property: ContactProperty.PhoneNumber,
});
const picked = contacts[0];
return picked?.phoneNumbers?.[0]?.value;
}
export async function pickEmail(): Promise<string | undefined> {
const { contacts } = await CapacitorContacts.pickContacts({
property: ContactProperty.EmailAddress,
});
return contacts[0]?.emailAddresses?.[0]?.value;
}
を使用すると、 property、結果には連絡先が含まれます id, displayName 選択されたプロパティのみが対象です。複数選択は無視され、プロパティ取得は常に単一の値を返します。ユーザーがキャンセルした場合は、空の配列を確認してください。
このプラグインは独自の manifest で READ_CONTACTS または WRITE_CONTACTS 宣言しないため、プロパティ取得のみを使う場合、マージ後の manifest はクリーンなままです。
READ_CONTACTS がまだ必要な場合
以下のプラグインメソッドはアドレス帳を読み取るため、引き続きこの権限を要求します:
pickContacts()またはpickContact()なしでproperty連絡先の全レコードを取得したい場合getContacts(),getContactById(),countContacts()getGroups(),getGroupById(),getAccounts()
アプリが CRM、バックアップツール、友達マッチング機能なら、それは正当なコア用途です。権限は自分で追加し、宣言を提出してください:
<!-- android/app/src/main/AndroidManifest.xml -->
<uses-permission android:name="android.permission.READ_CONTACTS" />
import { CapacitorContacts } from '@capgo/capacitor-contacts';
const perm = await CapacitorContacts.requestPermissions({ permissions: ['readContacts'] });
if (perm.readContacts === 'granted' || perm.readContacts === 'limited') {
const { contacts } = await CapacitorContacts.getContacts({
fields: ['displayName', 'phoneNumbers'],
limit: 200,
offset: 0,
});
console.log(contacts.length);
}
このポリシーの対象は READ_CONTACTS。連絡先への書き込みには WRITE_CONTACTS ( createContact, updateContactById, deleteContactById)は本ポリシーの対象ではありません。ただし、それらのメソッドを使用する場合にのみ追加してください。
Capacitor アプリの移行プラン
-
マージされたマニフェストを確認する。 リリースをビルドして、
android/app/build/intermediates/merged_manifest/(または Android Studio の Merged Manifest タブを使用)。一部のプラグインは、READ_CONTACTS気づかないうちに追加されることがあります。プラグインが追加した権限が不要な場合は、次の方法で削除してください:tools:node="remove":<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.READ_CONTACTS" tools:node="remove" /> </manifest> -
連絡先にアクセスする箇所をすべて洗い出す。 それぞれについて、プロパティ付きのピッカーか、アドレス帳全体かを決める。
-
招待と共有のフローを置き換える を使用して
pickContacts({ property }). -
権限はコア機能にのみ残す、宣言テキストを用意します。対象機能、ピッカーが不十分な理由、機能が見つかりにくい場合は動画を含めてください。
-
ネイティブビルドをリリースします。 マニフェストやプラグインの変更には新しいPlayリリースが必要です。CIでビルドしている場合、 Capgo のビルド は署名済みのAndroidビルドを生成でき、 Android keystore ジェネレーター は初めて署名を設定する場合に役立ちます。
-
UI変更をOTAで配信します。 新しいネイティブプラグインが公開されたら、ピッカー周辺の文言やフローの調整は Capgo Live Updates.
他の連絡先プラグインからの移行
以下を使用する場合は、 @capacitor-community/contacts (執筆時点では8.0.0)、そのAndroid版は pickContact ピッカーを開く前にcontacts権限グループをリクエストし、その後アドレス帳から連絡先全体を読み取ります。プロパティモードはありません。メソッド名も異なります(getContact vs getContactById、projectionオブジェクト vs fields 配列)。当社の コミュニティ版 contacts プラグインと Capgo プラグインの比較では、 各呼び出しをマッピングしています。
もしCapacitor内でまだCordovaのcontactsプラグインを使用しているなら、今が置き換えの好機です。詳細は CordovaからCapacitorへの移行.
トラブルシューティング
ピッカーは電話番号のない連絡先を返します。 呼び出しました pickContacts() なしで property かつアプリに READ_CONTACTS。 id と displayName (および Android 17 以降のピッカーで許可されたフィールド)のみが返されます。 property.
Play Console は依然としてアプリが READ_CONTACTS を宣言していると表示されます。 ライブラリが追加しています。マージされた manifest を確認し、 tools:node="remove"で削除してください。また、他のトラックの古いリリースも確認してください。アクティブなアーティファクトはすべてカウントされます。
宣言が拒否されました。 招待、紹介、共有はピッカーのユースケースとして挙げられています。機能を再設計するか、全リストがコアである理由を明確に示してください(例:アドレス帳全体を対象に実行するフレンドマッチング)。
iOSが連絡先へのアクセス許可を求めます。 アドレス帳を読み取るメソッドを呼び出しています。ピッカーでの選択には不要です。削除してください。 NSContactsUsageDescription 選ぶだけなら。
重要な日程
| 日付 | 何が起きるか |
|---|---|
| 2026年4月15日 | ポリシー発表 |
| 2026年9月 | Play Consoleが宣言対象のアプリに対し READ_CONTACTS 宣言の提出を促す |
| 2027年1月27日 | Android 17 (API 37) 以降をターゲットとするアプリは準拠が必須 |
提出前にPlay Consoleのヘルプページでポリシーを確認してください。Googleが期限や文言を更新する場合があります。