AndroidでのAdvertigingIDの取得方法を紹介します。

AdMaxSDKを作る上で、必須な処理です。

これを取得しないと、価値のある広告が表示できないのです。

ということでまずはAdvertisingIDの説明です。

AdvertisingIDとは

Androidデベロッパーのヘルプページより引用します。

広告 ID
広告 ID (“advertising ID”) とは、ユーザーがリセットできる匿名かつ固有の広告 ID で、Google Play 開発者サービスで提供されます。この広告 ID によってユーザーの管理性は向上し、デベロッパーはシンプルな標準システムで引き続きアプリを収益化できます。また、ユーザーは自分の ID をリセットしたり、Google Play アプリ内のインタレスト ベース広告をオプトアウトしたりできます。

匿名かつ固有の広告IDというのがキモなのではないでしょうか。

Androidさんが提供してくれているというのが助かります。

Q&Aの所に気になる質問と解答があったので紹介します。

Q: 広告の目的以外で永続 ID を使用できますか?

A: はい。ただしプライバシーポリシーを掲示し、デベロッパーの条項と、アプリ提供地域の該当するすべてのプライバシー法に従ってデータを管理している場合に限ります。

ここでいう永続IDというのはかの有名なAndroidIDなどを指します。

つまりAdvertisingIDは広告以外で使う事は許されていないということになります。

とっても便利なのにもったいな…。

では改めましてAdvertisingIDの取得方法を紹介します。

使うライブラリ

GooglePlayServicesを使います。

build.gradleに以下のdependenciesを追加してください。

build.gradle
1
2
3
dependencies {
compile "com.google.android.gms:play-services:+"
}

Libraryのバージョンについて

compile "com.google.android.gms:play-services:+"+の部分がバージョンになります。

+にすると最新バージョンを使うということになります。

例えばv5.0以上のものを使いたい場合は5.+と記入すれば良いわけです。

僕が作ったサービスではここは固定のバージョンにしています。

なぜ固定にするかというと、com.google.android.gms:play-servicesのライブラリを使用する上での問題ですが、AndroidManifest.xmlに使うライブラリのバージョンを書かなければなりません。

AndroidManifest.xml
1
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

これが間違っているとアプリが落ちるんですよ。

デバッグして、気持ちが緊張しているときにいきなりアプリが落ちるとか、精神的に大ダメージなんで固定にしました。

バージョンアップの度にライブラリのバージョンを最新バージョンに指定するようにしています。

AdvertisingIDの取得

こんなコードで取得できます。

1
2
3
4
5
6
7
8
import android.content.Context;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
Context context;
AdvertisingIdClient.Info info = AdvertisingIdClient.getAdvertisingIdInfo(context);
// AdvertisingID
String advertiginID = info.getId();
// OptOutされているか
boolean limitAdTrackingEnabled = info.isLimitAdTrackingEnabled();

こんな感じです。

LimitAdTrackingEnabled

これは広告IDを使用して良いかどうかの値になります。

これはユーザーさんが決める値となっています。

Android端末を持っている人はインストールされているアプリの中にGoogle設定というアプリがあるはずなので、それを開いてみてください。

ListViewの中の広告をタッチするといかのような画面になると思います。

ScreenShot10

この中にあるインタレストベース広告をオプトアウトという項目にチェックボックスがついています。

ここの値がinfo.isLimitAdTrackingEnabled();になります。

つまりこの値がtrueだった場合、使ってほしくないということなので、使わないようにしましょう。

ちなみに僕がテストした結果だと、ここの値がtrueでもfalseでもAdvertisingIDは取得できました。

実際に使ってみる

ということでエラー処理もなにもありませんので、少しずつましにしていきます。

AdvertisingIDの取得は非同期処理で取得しましょう

しましょうというより、別スレッドでないと、IlligalStateExceptionで取得できませんでした。

僕は簡単にすませたかったのでAsyncTaskを使って実装しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import android.content.Context;
import android.os.AsyncTask;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
AsyncTask<Void, Void, String> adTask = new AsyncTask<Void, Void, String>(){
@Override
protected AdInfo doInBackground(Void... params) {
AdvertisingIdClient.Info info = AdvertisingIdClient.getAdvertisingIdInfo(context);
return info.getId();
}
@Override
protected void onPostExecute(String advertisingID) {
// お好きな処理を...
}
}
adTask.execute();

ExceptionをCatchする処理

AdvertisingIdClientpublist static AdvertisingIdClient.Info getAdvertisingIdInfo(Context context)では以下のExceptionがthrowされます。

  • IOException

    signaling connection to Google Play Services failed.

    GooglePlayServicesへの接続が失敗した

  • IllegalStateException

    indicating this method was called on the main thread.

    メインスレッドで処理が呼ばれた

  • GooglePlayServicesNotAvailableException

    indicating that Google Play is not installed on this device.

    GooglePlayがデバイスにインストールされていない時

  • GooglePlayServicesRepairableException

    indicating that there was a recoverable error connecting to Google Play Services.

    GooglePlayServicesを使う上でエラーが起きた時

ということで、throwされるのでcatchしたいと思います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.IOException;
import android.content.Context;
import android.os.AsyncTask;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
AsyncTask<Void, Void, String> adTask = new AsyncTask<Void, Void, String>(){
@Override
protected AdInfo doInBackground(Void... params) {
try {
AdvertisingIdClient.Info info = AdvertisingIdClient.getAdvertisingIdInfo(context);
return info.getId();
} catch (IOException e) {
// GooglePlayServicesへの接続が失敗
return null;
} catch (IllegalStateException) {
// メインスレッドで処理が呼ばれた
// ここはありえない...。
return null;
} catch (GooglePlaySericesNotAvailableException e) {
// GooglePlayがデバイスにインストールされていなかった
return null;
} catch (GooglePlayServicesRepairableException e) {
// GooglePlayServicesを使ううえでエラーが起きた
return null;
}
}
@Override
protected void onPostExecute(String advertisingID) {
if (advertisingID != null) {
// お好きな処理を...
}
}
}
adTask.execute();

isLimitAdTrackingEnabled()をチェックする

広告IDを使って良いかどうかを判断する値でした。

なので、最初にこれを確認しましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.io.IOException;
import android.content.Context;
import android.os.AsyncTask;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
AsyncTask<Void, Void, String> adTask = new AsyncTask<Void, Void, String>(){
@Override
protected AdInfo doInBackground(Void... params) {
try {
AdvertisingIdClient.Info info = AdvertisingIdClient.getAdvertisingIdInfo(context);
if (info.isLimitAdTrackingEnabled) {
return null;
} else {
return info.getId();
}
} catch (IOException e) {
// GooglePlayServicesへの接続が失敗
return null;
} catch (IllegalStateException) {
// メインスレッドで処理が呼ばれた
// ここはありえない...。
return null;
} catch (GooglePlaySericesNotAvailableException e) {
// GooglePlayがデバイスにインストールされていなかった
return null;
} catch (GooglePlayServicesRepairableException e) {
// GooglePlayServicesを使ううえでエラーが起きた
return null;
}
}
@Override
protected void onPostExecute(String advertisingID) {
if (advertisingID != null) {
// お好きな処理を...
}
}
}
adTask.execute();

となると思います。

番外編(GooglePlayServicesのライブラリがあるか)

えーこれにはまりました。

結局広告のSDKは使ってもらう形になるのですが、GooglePlayServicesのライブラリを追加していない状態でやると落ちるということです。

もちろんcom.google.android.gms.*がないので、ないクラスを参照しようとしてNoClassDefFoundErrorがthrowされるんですよね。

ということでこいつもキャッチしてなくても動作するよう(アプリが落ちない)にしましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.IOException;
import android.content.Context;
import android.os.AsyncTask;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.GooglePlayServicesRepairableException
AsyncTask<Void, Void, String> adTask = new AsyncTask<Void, Void, String>(){
@Override
protected AdInfo doInBackground(Void... params) {
try {
AdvertisingIdClient.Info info = AdvertisingIdClient.getAdvertisingIdInfo(context);
if (info.isLimitAdTrackingEnabled) {
return null;
} else {
return info.getId();
}
} catch (IOException e) {
// GooglePlayServicesへの接続が失敗
return null;
} catch (IllegalStateException) {
// メインスレッドで処理が呼ばれた
// ここはありえない...。
return null;
} catch (GooglePlaySericesNotAvailableException e) {
// GooglePlayがデバイスにインストールされていなかった
return null;
} catch (GooglePlayServicesRepairableException e) {
// GooglePlayServicesを使ううえでエラーが起きた
return null;
} catch (NoClassDefFoundError e) {
// com.google.android.gmsがない
return null;
}
}
@Override
protected void onPostExecute(String advertisingID) {
if (advertisingID != null) {
// お好きな処理を...
}
}
}
adTask.execute();

終わりに

ということでAdvertisingIDが取得できました。

まあこれが取得できたところで使い道はないと思いますが…。

AdMaxSDKでは上記のようにAdvertisingIDを取得してますよってお話でした。