SysTecevo

AndroidのPackage Visibilityとは?queriesの設定・アプリが見つからない原因と対処

初回掲載日:
最終更新日:

Android Package Visibilityで見えるアプリと絞り込まれるアプリを示す図解

Android 11(APIレベル30)以降をtargetにしたアプリでは、端末にインストールされた他アプリの情報が初期状態からすべて見えるとは限りません。これがPackage Visibility(パッケージ可視性)です。

先に結論を言うと、特定のアプリを見つけたいなら、まず本当に検索が必要かを確認し、必要な範囲だけをManifestの<queries>で宣言します。すべてのインストール済みアプリを列挙するためのQUERY_ALL_PACKAGESは例外的な手段で、Google Playでは用途の申告と審査が関係します。

この記事の要点
  • Android 11以降はPackageManagerの検索結果が絞られることがある
  • 特定アプリ・Intent・Providerを必要な範囲だけ<queries>に書く
  • 起動できるかだけを知りたい処理は、先に列挙せず起動してActivityNotFoundExceptionを処理できる
  • Play公開アプリでQUERY_ALL_PACKAGESを安易に使わない

Package Visibilityとは

Package Visibilityは、アプリから見える他アプリの範囲をAndroidが制御する仕組みです。Android 11(APIレベル30)以上をtargetにしたアプリでは、他アプリの一覧や情報を取得するAPIの結果が既定でフィルタリングされます。対象になる代表例はqueryIntentActivities()、getPackageInfo()、getInstalledApplications()などです。

これは単なるエラー対策ではなく、インストール済みアプリの一覧が不要な機能にまで渡らないようにするプライバシー保護です。Android 10(APIレベル29)以下をtargetにしたアプリでは、同じ形の既定フィルタリングは適用されませんが、targetSdkを上げた時点で影響を再確認してください。

「起動できない」と「見つけられない」は分けて考える

Package Visibilityで混乱しやすいのは、アプリを起動する処理と、起動前に候補アプリを検索する処理が同じではない点です。Android公式の一般的な案内では、URLなどを開くだけならIntentを実行し、利用可能なアプリがない場合のActivityNotFoundExceptionを処理する方法があります。startActivity()で別アプリのActivityを起動するだけなら、必ずしも<queries>は必要ありません。

一方で「共有ボタンを表示する前に対応アプリの有無を調べたい」「設定画面にインストール済みの連携アプリを一覧表示したい」という場合は、検索結果を得るための可視性宣言が必要になります。

queriesのpackage intent providerを必要な範囲で選ぶ比較図
<queries>は、特定パッケージ・Intent・Providerのどれを照会するかに合わせて絞ります。

Deep LinkやApp Linksとの違い

Deep LinkやApp Linksは「どのURLをどのActivityで開くか」を決める仕組みです。Package Visibilityは「他アプリの存在や対応コンポーネントを、事前の検索結果として見せるか」を決めます。

たとえばブラウザーでURLを開く処理と、ブラウザー候補を事前に一覧表示する処理では必要な宣言が変わります。URL連携の設定は、必要に応じてAndroid App Linksの記事も参照してください。

Manifestの<queries>はどこに書く?

<queries>は、アプリのManifestのルート<manifest>直下に置きます。<application>の中に入れると意図した宣言になりません。代表的な3パターンを、サンプル値で示します。

1. 特定パッケージを指定する

<manifest ...>
    <queries>
        <package android:name="com.example.partner" />
    </queries>
    <application ... />
</manifest>

連携先のpackage nameが決まっている場合に向いています。ライブラリがホストアプリと通信する場合も、AAR側のManifestに必要な宣言を持たせる設計があります。

2. Intentの条件で指定する

<queries>
    <intent>
        <action android:name="android.intent.action.SEND" />
        <data android:mimeType="image/jpeg" />
    </intent>
</queries>

package nameを知らず、特定のIntent filterに対応するアプリを探したい場合の形です。公式ドキュメントでは、1つの<intent>に含める<action>は1つなどの制限が説明されています。必要以上に広いワイルドカードを使わないようにします。

3. Provider authorityで指定する

<queries>
    <provider android:authorities="com.example.files" />
</queries>

Content Providerを照会する場合はauthorityを指定します。複数の連携先がある場合も、実際に必要なauthorityだけを記載します。

PackageManager APIごとの注意

やりたいこと代表API確認ポイント
対応Activityを検索queryIntentActivities()Intentの条件に合うアプリだけが対象。事前に候補を表示するなら<queries>を検討
特定packageの情報を取得getPackageInfo()対象packageを<package>で可視化。存在しない場合と不可視の場合をログで分ける
インストール済み一覧を取得getInstalledApplications() / getInstalledPackages()API 30以上ではフィルタリングを前提にする。全件取得を目的にしない
URLやIntentを起動startActivity()まず起動して例外処理できるケースがある。候補一覧が必要なら別途宣言

Javaでの最小実装例

次の例は、候補Activityを表示する前に照会する場合の最小形です。package名やIntentはサンプルなので、実際の連携仕様に置き換えてください。

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/jpeg");

List<ResolveInfo> targets = getPackageManager()
        .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

if (targets.isEmpty()) {
    // 対応アプリがない場合の表示
} else {
    // targetsを使って選択UIを表示
}

照会結果が空だった場合でも、原因は「未インストール」「Intent filter不一致」「Package Visibilityで不可視」のいずれかかもしれません。空の結果だけでアプリ未インストールと断定しないことが重要です。

設定手順:必要性の判断から確認まで

  1. 検索が本当に必要か決める。単にURLやIntentを開くだけなら、起動して例外を処理する設計で足りる場合があります。
  2. 対象を絞る。package、Intent、Provider authorityのどれで表現できるかを決めます。
  3. Manifestのルート直下へ追加する。必要な宣言だけを<queries>に書きます。
  4. 検索APIを確認する。debugビルドだけでなく、実際のtargetSdkとrelease構成を確認します。
  5. 未インストール・不一致・不可視を分ける。ログと端末状態を組み合わせて判断します。
  6. Playポリシーを確認する。全アプリ照会が必要な理由を、機能の中心目的と結びつけて説明できるか確認します。

QUERY_ALL_PACKAGESは最後の手段

QUERY_ALL_PACKAGESは端末上の全アプリを広く見えるようにするための権限です。Android公式も「まれなケース」と位置づけ、まず自動的に見えるアプリや限定的な<queries>で実現できないかを確認するよう案内しています。

Google Playでは、インストール済みアプリの情報は個人情報・センシティブ情報として扱われ、API 30以上をtargetにしたアプリの広範な可視性は、アプリの中核機能に直接必要な場合に制限されます。対象アプリでもPlay Consoleで申告が必要になることがあるため、「一覧を取れるから追加する」という順番にしないでください。広告や分析目的のアプリ一覧収集も避けます。

アプリが見つからないときの診断フロー

Androidアプリが見つからないときにtarget SDK、queries、API、AppsFilterログを順に確認する診断フロー
空の検索結果を見たら、Manifestだけでなくtarget SDK・API・Intent条件・ログを順に確認します。
症状主な原因候補確認・対処
Android 10では見つかるが11以降で空targetSdk 30以上で既定フィルタリング必要な照会を<queries>へ限定追加
特定アプリだけ見つからないpackage名の誤り、対象未インストール、宣言漏れ実機のpackage名とManifest配置を確認
Intent検索だけ空action、category、MIME、schemeの不一致実際のintent-filterと照合し、宣言を広げすぎない
起動時に例外対応Activityなし、Intent不備、端末状態ActivityNotFoundExceptionを処理し、ユーザー向け代替導線を用意
宣言後も挙動が変わらないManifestの階層ミス、古いAPK、別variant、キャッシュrelease相当のManifestを確認して再インストール

AppsFilterのログで不可視を確認する

Android公式のテスト手順では、必要に応じてパッケージフィルタリングのログを有効化できます。テスト用端末で次のコマンドを使い、LogcatのAppsFilterとBLOCKEDを確認します。これは記事執筆環境で実行した結果ではなく、公式手順の紹介です。

adb shell pm log-visibility --enable com.example.myapp

ログ有効化中は性能に影響するため、確認が終わったら無効化します。package名は実際のアプリのものに置き換えてください。

adb shell pm log-visibility --disable com.example.myapp

LogcatにAppsFilterのBLOCKEDが出た場合は、visibilityの対象外になっている候補です。ただし、ログだけで解決策が決まるわけではありません。どのAPIを呼び、何を照会したいかへ戻って<queries>を最小限に調整します。

リリース前チェックリスト

  • 他アプリの検索が本当に必要か確認した
  • targetSdk 30以上での挙動を確認した
  • <queries>を<manifest>直下へ置いた
  • package、Intent、Provider authorityの条件を実際の連携先と照合した
  • 検索結果が空の場合と、起動失敗時の代替処理を用意した
  • QUERY_ALL_PACKAGESを使う理由が中核機能に直接結びついている
  • Play公開時に権限申告が必要か確認した
  • 未インストール、不可視、Intent不一致を別々にテストした
  • release相当のAPKでManifestと実機ログを確認した

FAQ

Q. Android 11未満でも<queries>は必要ですか?

Package Visibilityの主なフィルタリングは、Android 11以降をtargetにしたアプリで問題になります。アプリのtargetSdkと実際の端末を組み合わせて確認してください。

Q. QUERY_ALL_PACKAGESを追加すれば解決しますか?

技術的に広い可視性を得られる場合はありますが、Play公開では用途が制限されます。特定連携なら、まず限定的な<queries>を使う方針です。

Q. startActivity()の前に必ずqueryIntentActivities()を呼ぶべきですか?

必須ではありません。起動を試してActivityNotFoundExceptionを処理できるケースがあります。候補一覧や事前表示が必要な場合だけ、検索と可視性を設計します。

Q. Manifestへ書いたのにアプリが見つかりません。

ルート直下か、対象variantへ反映されているか、package名・Intent filter・MIME等が一致しているかを確認します。古いAPKを起動していないかも見直してください。

まとめ

Package Visibilityは、Android 11以降のアプリ間連携で「検索結果が空になる」問題を理解するための基本概念です。まず検索せずに起動できる処理かを分け、検索が必要なら<queries>で特定package・Intent・Providerだけを宣言します。QUERY_ALL_PACKAGESはプライバシーとGoogle Playポリシーの影響が大きいため、最後に検討してください。

設定後は、target SDK、Manifestの配置、API条件、未インストール状態、AppsFilterログを順に確認すると、闇雲に権限を広げず原因を絞れます。外部アプリとのURL連携を実装する場合は、App Linksの設定と検証も合わせて確認すると役割を整理しやすくなります。

参考にした公式情報