広告IDの仕様変更:Android 13以降でGoogle GAIDを取得する方法

opoinstall
2026-08-24
5 min read

GAIDとは何か、そしてプログラムでどのように取得するのか? Google広告ID(GAID)は、広告測定のためにGoogle Play開発者サービスによって提供される、ユーザーがリセット可能なソフトウェア識別子です。必要な場合にマージ済みアプリマニフェストにAD_ID権限が含まれていることを確認した上で、AdvertisingIdClient APIを使用してメインスレッド外でプログラムから取得します。

Google広告ID(GAID、Android広告ID=AAIDとも呼ばれます)は、Androidデバイス上の広告効果測定、パーソナライズ広告の配信、およびアナリティクスを目的としてGoogle Play開発者サービスが提供する、ユーザーがリセット可能な一意の文字列です。Android 13(APIレベル33)以降をターゲットとするアプリは、Google Play開発者サービスの広告IDにアクセスする際、マージ済みマニフェストにcom.google.android.gms.permission.AD_ID権限が含まれていることを確認する必要があります。そうでない場合、APIはすべてゼロの値返します。

用語 定義
GAID 広告測定のためにGoogle Play開発者サービスが提供するGoogle広告ID。
AdvertisingIdClient 広告識別子のメタデータを照会するために使用されるGoogle Play開発者サービスのAPI。
AD_ID権限 Google Play開発者サービスの広告IDにアクセスする際、APIレベル33以降をターゲットとするアプリに求められるAndroidマニフェストの権限。
ゼロ化された識別子 広告IDが利用できない場合や拒否された場合に返される、すべてゼロのプレースホルダー値(00000000-0000-0000-0000-000000000000)。

GAIDとは何か、Google広告IDの仕組み

広告IDの技術的構造

Google広告ID(GAID)は、Google Play開発者サービスから不透明な識別子文字列として返され、一般的に128ビットの小文字16進数UUID(例:38400000-8cf0-11bd-b23e-10b96e4ef00d)の形式でフォーマットされます。アプリケーション側は、そのフォーマットからビジネスロジックを推測するのではなく、返された文字列を不透明な識別子として扱う必要があります。

ハードウェアレベルの識別子とは異なり、GAIDには明確なプライバシー制御が設計されています:

  • ユーザーによるリセットが可能:ユーザーはデバイスの設定からいつでも新しいランダムな識別子を生成できます。
  • ユーザーによる削除が可能:Android 12以降、ユーザーは広告IDを削除できるようになり、Google Play開発者サービスに対してすべてのアプリへの広告識別子の提供を停止するよう指示できます。
  • プロファイルおよびデバイスごとのスコープ:広告IDは通常、同一のデバイスユーザープロファイル内のアプリ間で利用可能ですが、同一の物理デバイス上にある異なるAndroidユーザープロファイルやゲストプロファイルには、それぞれ異なる広告識別子が割り当てられます。

識別子状態の管理におけるGoogle Play開発者サービスの役割

GAIDは、オープンソースのAndroidフレームワークのコア部分ではありません。プロプライエタリなGoogle Play開発者サービス・クライアントライブラリ(com.google.android.gms:play-services-ads-identifier)によって動的に管理・提供されるアプリケーションレベルのサービスです。

アプリケーションがGoogle Play開発者サービスを呼び出すと、クライアントはGoogle Play開発者サービスとのブロッキング通信を実行し、現在の広告識別子とユーザーの広告追跡制限(LAT)の設定を取得します。

GAIDがハードウェア識別子を置き換えた理由

初期のAndroidリリースでは、広告ネットワークや開発者はリセット不可能なハードウェア識別子を使用してコンバージョンイベントを追跡していました:

  • IMEI(国際移動体端末識別番号):デバイスのモバイル通信ハードウェアに紐づいていました。
  • MACアドレス:ネットワークインターフェースのハードウェアに紐づいていました。
  • ANDROID_ID(SSAID):近年のAndroid 8.0以降のリリースでは、この識別子はアプリの署名キー、ユーザー、およびデバイスの組み合わせごとにスコープされ、アプリ間をまたぐ汎用的な広告キーとしては機能しなくなっています。

Google Playでの広告用途においては、他の永続的なデバイス識別子で代用するのではなく、利用可能な場合に広告IDを使用する必要があります。

関連項目:GAID ──> モバイルアトリビューションアーキテクチャ

Android 13の権限要件:AD_IDマニフェストの宣言

APIレベル33の強制モデル

Android 13(APIレベル33)以降、Googleはcom.google.android.gms.permission.AD_ID権限を導入しました:

  • ターゲットSDK 33以上:Android 13以降をターゲットとするアプリケーションは、マニフェストでAD_ID権限を宣言する必要があります。権限が省略された場合、Google Play開発者サービスはゼロの文字列(00000000-0000-0000-0000-000000000000)を返します。
  • ターゲットSDK 32以下:マニフェストでのAD_ID権限の宣言は必須ではありません。ただし、広告追跡の制限や削除状態といったユーザーの広告IDプライバシー設定により、引き続き広告IDが利用できない場合やゼロ化される場合があります。
  • Playストアのポリシー宣言:APIレベル33以降をターゲットとするアップデートを提出する際、開発者はGoogle Play Consoleにおいて現在の広告IDの宣言を完了し、アプリが識別子を使用するかどうか、およびその使用方法を正確に報告する必要があります。

Android 13 GAID retrieval and zeroed identifier flow

AndroidManifest.xmlとGradle依存関係の設定

権限を宣言するには、AndroidManifest.xml内に<uses-permission>タグを追加します。アプリモジュールのbuild.gradleファイルには、公式のplay-services-ads-identifier依存関係を追加します。

以下の設定は、マニフェストの権限構文とGradleの依存関係の設定例を示しています:

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">

    <!-- ゼロ以外のGAIDにアクセスするためにAPI 33以上で必須 -->
    <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:theme="@style/Theme.MyApp">
        <!-- アプリケーションコンポーネント -->
    </application>
</manifest
// 場所:app/build.gradle
// 注意:依存関係のバージョンは例です。本番環境で使用する前に、公式リポジトリで現在の安定版を確認してください。

dependencies {
    // 公式のGoogle Play開発者サービス Ads Identifierライブラリ
    implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'

    // メインスレッド外での非同期実行用Kotlinコルーチン
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
}

マニフェストのマージの仕組み:推移的SDKインジェクション

Android APKまたはAndroid App Bundle(AAB)をビルドする際、Gradleビルドシステムは、インポートされたすべてのサードパーティライブラリのマニフェストを1つの最終的なAndroidManifest.xmlに統合(マージ)します。

インポートされた広告ネットワークSDK、アナリティクスツール、またはアトリビューションライブラリがその内部マニフェストでcom.google.android.gms.permission.AD_IDを宣言している場合、その権限は最終的なビルドに自動的にマージされます。開発者はapp/build/outputs/logs/manifest-merger-release-report.txtを検査して、どの依存関係がその権限を持ち込んだかを確認できます。

プログラムによる取得:KotlinでのAdvertisingIdClientを通じたGAIDの取得

メインスレッド外での実行が必須となるルール

AdvertisingIdClient.getAdvertisingIdInfo(context)を呼び出すと、Google Play開発者サービスへの同期的呼び出しが開始されます。Googleはこのメソッドをメイン(UI)スレッドで実行することを明確に禁止しています。

メインスレッドからgetAdvertisingIdInfo()を呼び出すと、即座にIllegalStateExceptionがスローされます:

java.lang.IllegalStateException: Calling this from your main thread can lead to deadlock

アプリケーションのANR(応答なし)エラーや実行時クラッシュを防ぐため、開発者はバックグラウンドワーカー内またはDispatchers.IOを使用したKotlinコルーチン内で抽出呼び出しをディスパッチする必要があります。

AdvertisingIdClient GAID retrieval off the main thread

Kotlinコルーチンを使用したバックグラウンドワーカータスクの実装

以下のKotlin実装は、メインスレッド外で抽出を実行し、Google Play開発者サービスの可用性例外を処理し、識別子の整合性を検証する、スレッドセーフなAdvertisingIdManagerを示しています:

package com.example.myapp.analytics

import android.content.Context
import android.util.Log
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.IOException

data class GaidResult(
    val gaid: String?,
    val isLimitAdTrackingEnabled: Boolean,
    val isZeroed: Boolean,
    val isAvailable: Boolean
)

object AdvertisingIdManager {

    private const val TAG = "AdvertisingIdManager"
    private const val ZEROED_GAID = "00000000-0000-0000-0000-000000000000"

    /**
     * メイン実行スレッド外でGoogle広告IDをプログラムにより取得します。
     * 例外、ゼロ化された状態、およびユーザーのオプトアウトを自動的に処理します。
     */
    suspend fun fetchGaid(context: Context): GaidResult = withContext(Dispatchers.IO) {
        try {
            // IOコルーチンスピードでブロックを伴うGoogle Play開発者サービスのIPCを呼び出す
            val adInfo: AdvertisingIdClient.Info = AdvertisingIdClient.getAdvertisingIdInfo(context)
            
            val rawId = adInfo.id
            val isLAT = adInfo.isLimitAdTrackingEnabled
            val isZeroed = rawId == null || rawId.equals(ZEROED_GAID, ignoreCase = true)

            if (isZeroed) {
                Log.w(TAG, "広告IDが利用できないか、ゼロ化されています。")
                GaidResult(
                    gaid = null,
                    isLimitAdTrackingEnabled = isLAT,
                    isZeroed = true,
                    isAvailable = false
                )
            } else {
                Log.d(TAG, "広告IDの取得に成功しました。LAT有効: $isLAT")
                GaidResult(
                    gaid = rawId,
                    isLimitAdTrackingEnabled = isLAT,
                    isZeroed = false,
                    isAvailable = true
                )
            }
        } catch (e: GooglePlayServicesNotAvailableException) {
            Log.e(TAG, "このデバイスにはGoogle Play開発者サービスがインストールされていないか、利用できません。", e)
            GaidResult(gaid = null, isLimitAdTrackingEnabled = true, isZeroed = false, isAvailable = false)
        } catch (e: GooglePlayServicesRepairableException) {
            Log.w(TAG, "Google Play開発者サービスの更新またはユーザーによるリカバリが必要です。", e)
            GaidResult(gaid = null, isLimitAdTrackingEnabled = true, isZeroed = false, isAvailable = false)
        } catch (e: IOException) {
            Log.e(TAG, "Google Play開発者サービスとの接続における通信エラーです。", e)
            GaidResult(gaid = null, isLimitAdTrackingEnabled = true, isZeroed = false, isAvailable = false)
        } catch (e: IllegalStateException) {
            Log.e(TAG, "広告IDの取得中に不正な状態が発生しました。", e)
            GaidResult(gaid = null, isLimitAdTrackingEnabled = true, isZeroed = false, isAvailable = false)
        } catch (e: Exception) {
            Log.e(TAG, "Google広告IDの取得中に予期せぬエラーが発生しました。", e)
            GaidResult(gaid = null, isLimitAdTrackingEnabled = true, isZeroed = false, isAvailable = false)
        }
    }
}

AdvertisingIdClient.Infoの解析と広告追跡制限(LAT)の処理

AdvertisingIdClient.getAdvertisingIdInfo()メソッドは、2つの主要なプロパティを含むAdvertisingIdClient.Infoオブジェクトを返します:

  • getId()(String):広告識別子を表す英数字の文字列。
  • isLimitAdTrackingEnabled()(Boolean):広告追跡の制限が有効な場合、Google Playのポリシーでは、広告プロファイルの作成やパーソナライズ広告のターゲット設定に広告IDデータを使用することを禁止しています。ただしポリシーは、文脈に応じた広告配信、フリークエンシーキャップ、コンバージョン追跡、レポート作成、およびセキュリティ/不正検出などのアクティビティは引き続き許可しています。しかし、現在のGoogle Play開発者サービスではこの設定が有効な場合、広告ID自体がゼロ化されるため、アプリケーションは利用可能なGAIDが残っていると想定すべきではありません。

ゼロ化された識別子とユーザーによる削除状態の処理

00000000-0000-0000-0000-000000000000文字列:表示されるタイミングとその理由

本番環境において、以下の場合にAdvertisingIdClient.Info.getId()00000000-0000-0000-0000-000000000000を返します:

  1. ユーザーが広告IDを削除した場合:ユーザーがデバイス設定から広告IDを削除したとき。
  2. 広告追跡制限が有効な場合:サポートされているOSバージョンでユーザーが広告追跡制限を有効にしたとき。
  3. マニフェスト権限が不足している場合:アプリケーションがAndroid 13+(APIレベル33+)をターゲットとしており、マージ済みマニフェストでcom.google.android.gms.permission.AD_IDの宣言に失敗した場合。

GAID zeroed identifier and privacy state handling

ユーザー設定のワークフロー:広告IDの削除

現在のAndroidリリースのユーザーは、次の手順で識別子を削除できます:

[設定] > [プライバシー] > [広告] > [広告 ID の削除](正確なラベルはデバイスのOEMによって異なる場合があります)。

削除されると、Google Play開発者サービスは基となる値を消去します。インストールされているすべてのアプリにわたる以降のAPI呼び出しは、ゼロ化された文字列を返します。

リセットおよび削除状態に関するGoogle Playのポリシー要件

広告IDに関するGoogle Playデベロッパーポリシーに従い、開発者は明確なルールに従ってユーザーのプライバシーアクションを処理する必要があります:

  • リセットの要件:ユーザーが広告IDをリセットした場合、開発者は、明示的なユーザーの同意なしに、新しい広告IDを以前の広告IDやそこから派生したデータに紐付けたり接続したりしてはなりません。
  • 削除の要件:ユーザーが広告IDを削除した場合、開発者は、そのデバイスを以前の広告IDにリンクされたデータやそこから派生したデータに接続してはなりません。

下流の取り込みパイプラインにおける識別子入力のサニタイズ

バックエンドのアトリビューションエンジンは、ゼロ化された文字列がアトリビューションデータベースを汚染するのを防ぐために、検証フィルターを実装する必要があります:

fun isGaidValid(gaid: String?): Boolean {
    if (gaid.isNullOrBlank()) return false
    val zeroedGaid = "00000000-0000-0000-0000-000000000000"
    return !gaid.equals(zeroedGaid, ignoreCase = true)
}

ゼロ化された識別子が検出された場合、下流システムはそれを有効なGAIDまたは識別子マッチングキーとして扱ってはなりません。アトリビューションやアナリティクスの処理は、個別に許可された他のシグナルのみに依存する必要があります。

Google Playのファミリーポリシーとアプリカテゴリの制限

ファミリー向けアプリにおけるデータプラクティス

Google Playは、ファミリープログラムに参加しているアプリケーションや子供を対象とするアプリケーションに対して、厳格なデータ保護ルールを課しています:

  • AAID送信の禁止:子供を対象とするアプリケーションは、広告ID(AAID)を送信してはなりません。APIレベル33以降をターゲットとするアプリの場合、コンプライアンスを容易にする仕組みとして、AD_ID権限を省略または無効化することをGoogleは推奨しています。
  • 幅広いオーディエンス向けの処理:子供と年長のオーディエンスの両方をターゲットとするアプリケーションは、子供や年齢不明のユーザーからのAAIDを送信してはなりません。デフォルトでは、年齢確認によってユーザーが子供ではないことが確認されるまで、アプリやSDKはAAIDの送信を回避すべきです。

マニフェストでのtools:node=“remove”の使用

アプリケーションが子供を対象としているにもかかわらず、インポートされたサードパーティSDKがマニフェストのマージによってAD_ID権限を自動的にインジェクトする場合、メインのAndroidManifest.xmltools:node="remove"属性を追加します:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.familyapp">

    <!-- 推移的依存関係によってインジェクトされたAD_IDを明示的に削除する -->
    <uses-permission 
        android:name="com.google.android.gms.permission.AD_ID" 
        tools:node="remove"/>

</manifest>

GAIDが利用できない場合の、ユースケースに応じた測定の代替手段

GAIDがゼロ化、削除、またはポリシーによって制限されている場合、開発チームは機能的な目的に応じてユースケース固有の代替手段を導入します:

  • キャンペーンアトリビューションGoogle Play Install Referrer APIを使用して、PlayストアのURL経由で渡されたストア仲介によるキャンペーンパラメータ(referrer=...)を取得します。GAIDの削除とは独立して動作します。
  • オンボーディングとユーザーインテント:ファーストパーティのコンテキストパラメータルーティングを使用して、ウェブランディングページから渡されたリファラトークン、プロモーションコード、およびディープリンクの宛先を復元します。
  • 開発者スコープのアナリティクスと不正防止:クロスアプリ広告追跡を行わずに、同じ開発者アカウントの下で公開されたアプリ間で共有識別子を生成するためにApp Set ID(AppSetIdClient)を使用します。
                    GAIDが利用不可またはゼロ化済み
                                 │
         ┌───────────────────────┼───────────────────────┐
         │                       │                       │
         ▼                       ▼                       ▼
   有料キャンペーン          オンボーディング &         開発者所有の
      アトリビューション        リファラインテント         アナリティクス & 不正防止
         │                       │                       │
         ▼                       ▼                       ▼
    Google Play             ファーストパーティ         App Set ID
  Install Referrer          コンテキスト              (開発者または
    (ストアURL)              ルーティング              アプリスコープ)

GAID alternatives for attribution onboarding and analytics

比較マトリクス:GAID vs Install Referrer vs App Set ID

項目 Google広告ID(GAID) Google Play Install Referrer App Set ID(AppSet
識別子のタイプ リセット可能なクロスアプリ広告UUID ストア仲介によるキャンペーンパラメータ文字列 インストール状況やPlay開発者サービスのコンテキストに応じた、開発者またはアプリスコープの識別子
マニフェスト権限 com.google.android.gms.permission.AD_ID なし なし
ユーザー削除による影響 ゼロの文字列を返す GAIDの削除とは独立している APIアクセスなしで13か月経過した場合、セット内の最後のアプリがアンインストールされた場合、またはファクトリーリセット後にリセットされる場合がある
主なユースケース クロスアプリ広告アトリビューション & リターゲティング Playストアのキャンペーンパフォーマンス追跡 不正検出 & 開発者所有のアナリティクス
ファミリーポリシーへの適合 子供から送信してはならない AAID固有の送信禁止の対象外。使用にあたっては引き続き関連するファミリーポリシーを遵守する必要がある ファミリー向けアプリのアナリティクス用途としてGoogleが推奨

よくある質問(FAQ)

AdvertisingIdClientの呼び出しでIllegalStateExceptionによるクラッシュが発生するのはなぜですか?
AdvertisingIdClient.getAdvertisingIdInfo(context)は、Google Play開発者サービスとのブロッキング通信を実行します。Googleはこのメソッドをメイン実行スレッドで呼び出すことを明確に禁止しています。開発者は、バックグラウンドスレッド内、または`Dispatchers.IO`を使用したKotlinコルーチン内で呼び出す必要があります。
アプリがAndroid 13をターゲットにしており、AD_ID権限を宣言していない場合はどうなりますか?
アプリがAPIレベル33以上をターゲットとしており、マージ済みマニフェストで`com.google.android.gms.permission.AD_ID`権限を宣言していない場合、Google Play開発者サービスAPIは実際の広告識別子の代わりに自動的に`00000000-0000-0000-0000-000000000000`を返します。
サードパーティ製SDKの依存関係によってインジェクトされたAD_ID権限を削除するにはどうすればよいですか?
サードパーティライブラリがマニフェストのマージを通じて自動的に`AD_ID`権限をインジェクトし、かつアプリがGoogle Playのファミリーポリシーに準拠する必要がある場合は、メインの`AndroidManifest.xml`ファイルに`<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/>`を追加します。

まとめと判断のフレームワーク

Google広告IDは、Androidの広告やユーザー分析のユースケースにおいて依然として重要なリセット可能な識別子ですが、Android 13以降で運用するには、マニフェストの権限ポリシーの遵守、バックグラウンド実行基準、およびゼロ化された識別子状態の適切な処理が求められます。GAIDが利用できない場合、エンジニアリングチームは特定のユースケースに基づいて測定プリミティブを選択する必要があります。たとえば、PlayストアのキャンペーンアトリビューションにはInstall Referrerを、オンボーディング状態にはファーストパーティのコンテキストパラメータを、開発者所有のアナリティクスや不正防止シナリオにはApp Set IDを選択します。

Androidのアトリビューションおよびディープリンクパイプラインの実装パターンを調べるには、OpoInstallのドキュメントをご確認ください。

関連資料

  • 概念:広告IDのライフサイクル、AD_IDマニフェスト権限、バックグラウンドスレッドでの抽出、ゼロ化された識別子の処理

  • テクノロジー:Google Play開発者サービス、AdvertisingIdClient API、Google Play Install Referrer API、OpoInstall Android SDK

  • 標準規格:Google Playデベロッパーポリシー、Android 13の動作変更、IETF RFC 4122 UUID標準

  • APIおよびクラスAdvertisingIdClientAdvertisingIdClient.InfoAppSetIdClient、OpoInstall Context API

公式ドキュメント

Share this article