サーバー間 - デバイスデータの取得ガイド

デバイスデータ取得ガイド

正確な S2S API アトリビューションとキャンペーン測定に必要な、プラットフォーム固有のデバイス識別子とパラメータを取得するための包括的なガイド。

必須のデバイス識別子: Singular では、正確なアトリビューションのために、すべての API リクエストで特定のデバイス識別子が必要です。

モバイルプラットフォーム:

  • Android(Google Play): Google Advertising ID(GAID/AIFA)と App Set ID(ASID)
  • Android(Amazon): Fire デバイス向けの Amazon Advertising ID(AMID)
  • Android(中国 OEM): Google Play 開発者サービスがないデバイス向けの Open Advertising ID(OAID)
  • Android(フォールバック): 他に利用できる識別子がない場合にのみ使用する Android ID(ANDI)
  • iOS: ベンダー用識別子(IDFV)と、利用可能な場合は広告主用識別子(IDFA)

デバイスパラメータ: モバイルプラットフォームで必須の、ロケール、デバイスメーカー、デバイスモデル、ビルドバージョン

以下のコード例は、各プラットフォームと識別子タイプの取得方法を示します。


サンプルアプリケーション

リファレンス実装

デバイスデータ取得パターンを示す、iOS と Android の完全な動作サンプル。


Singular Device ID(SDID)

アプリに Singular SDK が含まれている場合(ハイブリッドインテグレーション)、プラットフォーム固有の識別子を収集する代わりに、SDK から Singular Device ID(SDID)を取得し、 sdid パラメータとして送信します。SDK は SDID を自動的に生成し、解決します。各 SDK で SDID を取得する方法については、以下の SDK インテグレーションガイドを参照してください:

デバイスに SDK がない純粋な server-to-server インテグレーションの場合は、SDID として使用する UUIDv4 をクライアント側で生成するか、以下に記載するプラットフォーム固有の識別子を引き続き使用します。


iOS デバイス識別子

iOS デバイスでは、正確なアトリビューションのために、IDFV(常時)と IDFA(ユーザーがトラッキング許可を付与した場合)、および ATT 認可ステータスが必要です。

必須の iOS 識別子

識別子の要件:

  • IDFV: トラッキング許可の有無にかかわらず、すべての S2S リクエストで必須
  • IDFA: ユーザーが App Tracking Transparency の同意を付与した場合は提供する必要があります
  • ATT ステータス: すべてのリクエストで必須の認可ステータスコード(0〜3)

実装ガイド

iOS デバイスデータの取得方法

広告主用識別子(IDFA)

広告主用識別子(IDFA)を使用すると、広告主はユーザーのアクション(広告クリック、アプリインストール)を特定のキャンペーンに追跡・アトリビュートでき、精密なターゲティングと最適化が可能になります。

iOS 14.5 以降、アプリが IDFA にアクセスする前に、ユーザーは App Tracking Transparency(ATT)フレームワークを介してオプトインする必要があります。ユーザーの同意がない場合、IDFA はすべてゼロを返し、トラッキング機能が制限されます。


ベンダー用識別子(IDFV)

ベンダー用識別子(IDFV)は、Apple がデバイスに割り当てる一意の識別子で、ベンダー/デベロッパーごとに固有です。デバイス上の同じベンダーのすべてのアプリで一貫して同じ値になり、個人を特定することなくアプリ横断の行動トラッキングを可能にします。

実装手順:

  • IDFA へのアクセスを試みる前に、ATT プロンプトを表示して処理しておきます
  • IDFA を取得し(許可されている場合)、API リクエスト用にサーバーへ渡します
  • IDFV を取得し、API リクエスト用にサーバーへ渡します(常に必須)
  • すべてのリクエストに ATT 認可ステータスを含めます

コード例

ATT 認可のリクエストと IDFA/IDFV の取得

OBJECTIVE-C SWIFT
#import <AdSupport/AdSupport.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <UIKit/UIKit.h>

- (void)retrieveIdentifiers {
    // Request ATT authorization (iOS 14.5+)
    [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
            switch (status) {
                case ATTrackingManagerAuthorizationStatusAuthorized: {
                    // ATT authorized, retrieve IDFA
                    NSUUID *idfa = [[ASIdentifierManager sharedManager] advertisingIdentifier];
                    NSLog(@"IDFA: %@", [idfa UUIDString]);
                    NSLog(@"ATT Status: %ld", (long)status); // Status = 3
                    break;
                }
                case ATTrackingManagerAuthorizationStatusDenied:
                    NSLog(@"ATT Status: Denied (%ld)", (long)status); // Status = 2
                    break;
                case ATTrackingManagerAuthorizationStatusRestricted:
                    NSLog(@"ATT Status: Restricted (%ld)", (long)status); // Status = 1
                    break;
                case ATTrackingManagerAuthorizationStatusNotDetermined:
                    NSLog(@"ATT Status: Not Determined (%ld)", (long)status); // Status = 0
                    break;
                default:
                    NSLog(@"Unknown ATT status.");
                    break;
            }

            // Retrieve IDFV (always available)
            NSUUID *idfv = [[UIDevice currentDevice] identifierForVendor];
            if (idfv != nil) {
                NSLog(@"IDFV: %@", [idfv UUIDString]);
            } else {
                NSLog(@"Unable to retrieve IDFV.");
            }
        });
    }];
}

// Call the method to retrieve identifiers
[self retrieveIdentifiers];

識別子の利用可否:

  • IDFA: iOS 14.5 以降では ATT 認可が必要です。同意がない場合はすべてゼロを返します
  • IDFV: 常に利用可能。すべての Singular API リクエストに含めます
  • ATT ステータス値: 0=未決定、1=制限あり、2=拒否、3=許可

Android デバイス識別子(Google Play)

Google Play 開発者サービスを搭載した Android デバイスでは、すべてのリクエストで App Set ID(ASID)が必要で、利用可能な場合は Google Advertising ID(GAID/AIFA)も必要です。

必須の Google Play 識別子

識別子の要件:

  • ASID: Google Play デバイスのすべての S2S リクエストで必須
  • AIFA/GAID: 利用可能な場合(オプトアウトされていない場合)は提供する必要があります

実装ガイド

Android デバイスデータの取得方法(Google Play)

Google 広告識別子(GAID)

Google 広告識別子(GAID)は、AIFA または Android Advertising ID(AAID)とも呼ばれ、Android デバイスに割り当てられる一意の、ユーザーがリセット可能な識別子です。プライバシーを維持しながら、広告主とデベロッパーがアプリ間でユーザーのアクションを追跡・アトリビュートし、キャンペーンのターゲティングと最適化を行うことを可能にします。

JAVA KOTLIN

依存関係

お使いの build.gradle に必要な依存関係を追加します:

dependencies {
    implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
}

権限

Android 12 / API レベル 31 以降をターゲットにする場合は、お使いの AndroidManifest.xml に権限を追加します:

<uses-permission android:name="com.google.android.gms.permission.AD_ID" />

使い方

AdIdUtils.getGoogleAdId(getApplicationContext());

実装

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;

public class AdIdUtils {

    public static void getGoogleAdId(Context context) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
                    
                    String adId = adInfo.getId();
                    boolean isLimitAdTrackingEnabled = adInfo.isLimitAdTrackingEnabled();
                    
                    Log.d("GoogleAdID", "Advertising ID: " + adId);
                    Log.d("GoogleAdID", "Limit Ad Tracking: " + isLimitAdTrackingEnabled);
                } catch (Exception e) {
                    Log.e("GoogleAdID", "Error retrieving GAID", e);
                }
            }
        });
    }
}

App Set ID(ASID)

Android App Set ID は、同一デベロッパー向けにプライバシーに配慮したアプリ横断のトラッキングを提供します。分析や不正防止に役立ちますが、パーソナライズド広告には使用できません。

JAVA KOTLIN

依存関係

dependencies {
    implementation 'com.google.android.gms:play-services-appset:16.1.0'
}

使い方

AppSetIdUtils.getAppSetId(getApplicationContext());

実装

import android.content.Context;
import android.util.Log;
import com.google.android.gms.appset.AppSet;
import com.google.android.gms.appset.AppSetIdClient;
import com.google.android.gms.appset.AppSetIdInfo;
import com.google.android.gms.tasks.Task;

public class AppSetIdUtils {

    public static void getAppSetId(Context context) {
        AppSetIdClient client = AppSet.getClient(context);
        Task task = client.getAppSetIdInfo();

        task.addOnSuccessListener(info - {
            String appSetId = info.getId();
            int scope = info.getScope();

            Log.d("AppSetID", "App Set ID: " + appSetId);
            Log.d("AppSetID", "Scope: " + (scope == AppSetIdInfo.SCOPE_DEVELOPER ? "Developer" : "App"));
        }).addOnFailureListener(e - {
            Log.e("AppSetID", "Failed to retrieve App Set ID", e);
        });
    }
}

Android デバイス識別子(Google Play 以外)

Google Play 開発者サービスがない Android デバイスでは、デバイスの製造元と配信方法に応じた代替識別子が必要です。

Amazon デバイス識別子

AMID: Google Play 開発者サービスがない Amazon Fire デバイスでは、Amazon Advertising ID を提供する必要があります。

Amazon Advertising ID(AMID)の取得方法

Amazon ID(AMID)

Amazon Advertising Identifier は、Google Play 開発者サービスがない Amazon Fire デバイス上でユーザーがリセット可能な広告トラッキングを可能にし、ユーザーのプライバシーを維持しながらアトリビューションを実現します。

要件:

  • Fire OS 5.1 以降が動作する Amazon Fire デバイスで機能します
  • ユーザーの Limit Ad Tracking 設定を尊重します
  • Fire OS 以外のデバイスでは利用できない場合があります
JAVA KOTLIN

使い方

AdvertisingIdHelper.getAmazonAdvertisingId(getContentResolver());

実装

import android.content.ContentResolver;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;

public class AdvertisingIdHelper {

    public static void getAmazonAdvertisingId(ContentResolver contentResolver) {
        String advertisingID = "";
        boolean limitAdTracking = false;

        try {
            limitAdTracking = Settings.Secure.getInt(contentResolver, "limit_ad_tracking") != 0;
            advertisingID = Settings.Secure.getString(contentResolver, "advertising_id");

            Log.d("AdvertisingID", "Amazon Advertising ID: " + advertisingID);
            Log.d("LimitAdTracking", "Limit Ad Tracking: " + limitAdTracking);

        } catch (SettingNotFoundException e) {
            Log.e("AdvertisingID", "Advertising ID not supported on this device", e);
        }
    }
}

中国 OEM 識別子

OAID: Google Play 開発者サービスがない中国製デバイスでは、Open Advertising Identifier を提供する必要があります。

Open Advertising ID(OAID)の取得方法

Open Advertising ID(OAID)

Open Advertising Identifier(OAID)は、中国で製造された Android デバイスにおける広告用の一意かつ匿名の識別子です。Google Play 開発者サービスが利用できないデバイス向けの GAID の代替として、Mobile Security Alliance(MSA)によって導入されました。

対応デバイス: Huawei、Xiaomi、OPPO、Vivo、およびその他の中国製 Android デバイス

アクセスは MSA SDK または Huawei Mobile Services(HMS)経由で行います。

JAVA KOTLIN

依存関係

dependencies {
    implementation 'com.bun.msa.sdk:msa:1.0.26'
}

実装

import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import com.bun.msa.sdk.DeviceId;
import com.bun.msa.sdk.DeviceIdSupplier;
import com.bun.msa.sdk.IIdentifierListener;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "OAIDExample";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getOAID();
    }

    private void getOAID() {
        try {
            DeviceId deviceId = new DeviceId(this);
            deviceId.getDeviceIds(new IIdentifierListener() {
                @Override
                public void onSupport(boolean isSupport, DeviceIdSupplier supplier) {
                    if (isSupport && supplier != null) {
                        String oaid = supplier.getOAID();
                        Log.d(TAG, "OAID: " + oaid);
                    } else {
                        Log.e(TAG, "OAID not supported on this device");
                    }
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "Error retrieving OAID", e);
        }
    }
}

Android ID フォールバック

ANDI の制限: Android ID は、他に利用できる識別子がなく、かつアプリが Google Play ストア経由で配信されていない場合にのみ提供できます。Google Play のアプリでは禁止されています。

Android ID(ANDI)の取得方法

Android ID(ANDI)

Android ID は、デバイスの初回セットアップ時に生成される一意の 64 ビット識別子です。Android 8.0(Oreo)以降、アプリごと・ユーザーごとにスコープが分けられ、同じ署名鍵を共有しない限り、異なるアプリは異なる Android ID を受け取ります。

永続性: デバイスを初期化するか、OTA 更新後にアプリをアンインストール/再インストールしない限り、値は一定のままです。

JAVA KOTLIN
import android.provider.Settings;
import android.content.Context;

String androidId = Settings.Secure.getString(
    context.getContentResolver(), 
    Settings.Secure.ANDROID_ID
);

Web およびクロスプラットフォーム識別子

Web アプリケーションおよびクロスプラットフォーム実装では、正確なアトリビューション追跡のために Singular Device ID(SDID)が必要です。

必須の Web 識別子

SDID: Web、PC、コンソール、CTV プラットフォームのすべての S2S リクエストで Singular Device ID が必要です。

Singular Device ID(SDID)の取得方法

Singular Web SDK デバイス ID

Singular Device ID(SDID)は、Web アプリケーションおよび非モバイルプラットフォームにおいて、一貫したセッション横断のトラッキングを提供します。

前提条件: SDID を取得する前に、Singular Web SDK を実装して初期化しておく必要があります。

使い方

// Retrieve SDID after Singular SDK initialization
const sdid = window.singularSdk.getSingularDeviceId();
console.log("Singular Device ID:", sdid);

実装に関する注意: getSingularDeviceId() は、Singular SDK が正常に初期化された後にのみ呼び出してください。初期化前に取得しようとすると null が返されます。


モバイルデバイスパラメータ

必須のデバイスパラメータは、モバイルプラットフォームでのアトリビューションと分析に不可欠なコンテキストを提供します。

必須パラメータ

モバイルプラットフォーム: iOS と Android のすべての S2S リクエストで、ロケール、デバイスメーカー、デバイスモデル、ビルドが必要です。

デバイスパラメータの取得方法

パラメータの取得

完全なデバイスプロファイリングのために、ロケール、製造元、モデル、ビルド情報を収集します。

OBJECTIVE-C SWIFT JAVA KOTLIN
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <sys/sysctl.h>

// Retrieve Locale
NSString *retrieveLocale() {
    NSString *locale = [[NSLocale currentLocale] localeIdentifier];
    NSLog(@"Locale: %@", locale);
    return locale;
}

// Retrieve Manufacturer (always Apple for iOS)
NSString *retrieveManufacturer() {
    return @"Apple";
}

// Retrieve Device Model
NSString *deviceModel() {
    size_t bufferSize = 64;
    char model[bufferSize];
    int status = sysctlbyname("hw.machine", model, &bufferSize, NULL, 0);
    
    if (status == 0) {
        NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
        NSLog(@"Device Model: %@", deviceModel);
        return deviceModel;
    } else {
        NSLog(@"Unable to retrieve device model.");
        return nil;
    }
}

// Retrieve Build Version
NSString *buildVersion() {
    size_t bufferSize = 64;
    char build[bufferSize];
    int status = sysctlbyname("kern.osversion", build, &bufferSize, NULL, 0);
    
    if (status == 0) {
        NSString *buildVersion = [NSString stringWithCString:build encoding:NSUTF8StringEncoding];
        NSLog(@"Build Version: %@", buildVersion);
        return buildVersion;
    } else {
        NSLog(@"Unable to retrieve build version.");
        return nil;
    }
}

パラメータのマッピング:

  • ロケール(lc): 言語と地域のコード(例: en_US、zh_CN)
  • メーカー(ma): デバイスの製造元(Apple、Samsung、Xiaomi)
  • モデル(mo): 具体的なデバイスモデル(iPhone14,2、SM-G991B)
  • ビルド(bd): 「Build/」を接頭辞とする OS ビルドバージョン

タイムスタンプパラメータ

オプションのタイムスタンプパラメータは、デバイスのインストールおよび更新の状態を示します。これらは OS が報告する値で、デバイス上で収集され、SESSION リクエストで送信されます。

install_time の取得方法

install_time の取得

install_time は、アプリがデバイスに実際にインストールされた時刻を OS が報告する Unix タイムスタンプ(秒)です。Android では PackageInfo.firstInstallTime (ミリ秒)を読み取り、1000 で割ります。iOS にはインストール時刻の API がないため、標準的な近似として、アプリの Documents ディレクトリの作成日を使用します。

OBJECTIVE-C SWIFT JAVA KOTLIN
#import <Foundation/Foundation.h>

// install_time: creation date of the Documents directory (proxy)
NSFileManager *fm = [NSFileManager defaultManager];
NSURL *docs = [[fm URLsForDirectory:NSDocumentDirectory
                          inDomains:NSUserDomainMask] firstObject];
NSDictionary *attrs = [fm attributesOfItemAtPath:docs.path error:nil];
NSDate *created = attrs[NSFileCreationDate];
long installTime = (long)[created timeIntervalSince1970];
NSLog(@"install_time: %ld", installTime);

これはデバイスのインストール時刻であり、Singular のアトリビューションインストール時刻ではありません。アトリビューションでは、セッションタイムスタンプ( utime )が使用されます。これは初回セッション( install=true )のものです。

update_time の取得方法

update_time の取得

update_time は、アプリがデバイス上で最後に更新された時刻を OS が報告する Unix タイムスタンプ(秒)です。Android では PackageInfo.lastUpdateTime (ミリ秒)を読み取り、1000 で割ります。iOS には更新時刻の API がないため、標準的な近似として、更新のたびに書き換えられるアプリバンドルの実行ファイルの作成日を使用します。

OBJECTIVE-C SWIFT JAVA KOTLIN
#import <Foundation/Foundation.h>

// update_time: creation date of the app bundle executable (proxy)
NSString *execPath = [[NSBundle mainBundle] executablePath];
NSDictionary *attrs = [[NSFileManager defaultManager]
    attributesOfItemAtPath:execPath error:nil];
NSDate *updated = attrs[NSFileCreationDate];
long updateTime = (long)[updated timeIntervalSince1970];
NSLog(@"update_time: %ld", updateTime);

アプリが一度も更新されていないデバイスでは、これは install_time と等しくなります。これはアトリビューションのアクティビティではなく、アプリの更新を反映します。