Androidデバイスには固有のIDがありますか?その場合、Javaを使用してそれにアクセスするための簡単な方法は何ですか?
Settings.Secure#Android_ID
はAndroid IDをとして返します 各ユーザーに固有64 -ビットの16進文字列。
import Android.provider.Settings.Secure;
private String Android_id = Secure.getString(getContext().getContentResolver(),
Secure.Android_ID);
UPDATE:最近のAndroidバージョンでは、Android_ID
の問題の多くは解決されており、このアプローチは長く必要です。 Anthonyの答え をご覧ください。
完全な開示:私のアプリはもともと以下のアプローチを使用していましたが、このアプローチは使用しなくなり、現在では Android Developer Blog エントリ emmby's answer リンク(つまり、 UUID#randomUUID()
)を生成して保存します。
この質問には多くの回答がありますが、そのほとんどは「一部」の時間でしか機能しませんが、残念ながらそれでは十分ではありません。
デバイスのテスト(すべての電話、少なくとも1つがアクティブ化されていない)に基づく:
TelephonyManager.getDeviceId()
の値を返しましたTelephonyManager.getSimSerialNumber()
の値を返しましたgetSimSerialNumber()
に対してnullを返しました(予想どおり)Android_ID
の値を返しましたAndroid_ID
とTelephonyManager.getDeviceId()
の両方に対して同じ値(または同じ値の派生)を返しました-限りセットアップ中にGoogleアカウントが追加されました。したがって、デバイス自体に固有の何かが必要な場合は、TM.getDeviceId()
shouldで十分です。明らかに、一部のユーザーは他のユーザーよりも妄想的であるため、これらの識別子の1つ以上をハッシュすると、文字列がデバイスに対して実質的に一意であるが、ユーザーの実際のデバイスを明示的に識別しないために役立ちます。たとえば、String.hashCode()
をUUIDと組み合わせて使用します。
final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + Android.provider.Settings.Secure.getString(getContentResolver(), Android.provider.Settings.Secure.Android_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
次のような結果になる可能性があります:00000000-54b3-e7c7-0000-000046bffd97
それは私にとって十分に機能します。
リチャードが以下で言及するように、TelephonyManager
プロパティを読み取るための許可が必要であることを忘れないでください。したがって、これをマニフェストに追加します。
<uses-permission Android:name="Android.permission.READ_PHONE_STATE" />
インポートライブラリ
import Android.content.Context;
import Android.telephony.TelephonyManager;
import Android.view.View;
固有のIDの作成に関するすべてのStack Overflowの投稿、Googleの開発者ブログ、およびAndroidのドキュメントを読んだ後、 'Pseudo ID'が可能な限り最良の選択肢であるように感じます。
疑似コード:
if API >= 9/10: (99.5% of devices)
return unique ID containing serial id (rooted devices may be different)
else
return the unique ID of build information (may overlap data - API < 9)
(このStack Overflowの質問に)すべてのオプションを投稿してくれた@stansultに感謝します。
ユーザーの電子メールアドレス - ソフトウェア
<uses-permission Android:name="Android.permission.GET_ACCOUNTS" />
または<uses-permission Android:name="Android.permission.READ_PROFILE" />
<uses-permission Android:name="Android.permission.READ_CONTACTS" />
( AndroidデバイスのメインのEメールアドレスを取得する方法 )ユーザーの電話番号 - ソフトウェア
<uses-permission Android:name="Android.permission.READ_PHONE_STATE" />
IMEI - ハードウェア (電話のみ、Android.permission.READ_PHONE_STATE
が必要)
<uses-permission Android:name="Android.permission.READ_PHONE_STATE" />
Android ID - ハードウェア (nullにすることも、出荷時設定にリセットすることによって変更することも、根付くデバイスで変更することもできます)
WLAN MACアドレス - ハードウェア (needsAndroid.permission.ACCESS_WIFI_STATE
)
<uses-permission Android:name="Android.permission.ACCESS_WIFI_STATE "/>
Bluetooth MACアドレス - ハードウェア (Bluetooth搭載デバイス、Android.permission.BLUETOOTH
)
<uses-permission Android:name="Android.permission.BLUETOOTH "/>
疑似固有ID - ソフトウェア (すべてのAndroidデバイス用)
パーミッションを使用せずに一意のIDを取得するための「完璧な」方法がないことを私は知っています。しかし、時には私たちは本当にデバイスのインストールを追跡する必要があるだけです。一意のIDを作成する際には、追加の権限を使用せずにAndroid APIから提供される情報のみに基づいて「疑似一意ID」を作成できます。このようにして、私たちはユーザーの尊敬を示し、同様に優れたユーザーエクスペリエンスを提供しようとすることができます。
疑似一意IDを使用すると、類似したデバイスがあるという事実に基づいて重複がある可能性があるという事実に遭遇するだけです。あなたはそれをよりユニークにするために組み合わせた方法を微調整することができます。ただし、一部の開発者はデバイスのインストールを追跡する必要があり、これにより類似のデバイスに基づいたトリックまたはパフォーマンスが得られます。
彼らのAndroidデバイスがAPI 9以上の場合、これは 'Build.SERIAL'フィールドのためにユニークであることが保証されています。
_記憶_ 、技術的に見逃しているのはユーザーの約0.5%だけです APIが9未満の場合 。だからあなたは残りに集中することができます:これはユーザーの99.5%です!
ユーザーのAndroidデバイスがAPI 9より低い場合うまくいけば、彼らは工場出荷時設定へのリセットをしておらず、彼らの 'Secure.Android_ID'は保存されるか 'null'ではないでしょう。 ( http://developer.Android.com/about/dashboards/index.html を参照)
ユーザーがAPI 9より低い(Gingerbreadより低い)場合、デバイスがリセットされているか、または 'Secure.Android_ID'が 'null'を返す場合、それ以外のすべてが失敗した場合、返されるIDは単にAndroidデバイス情報に基づいています。これが衝突が起こる可能性がある場所です。
変更点
以下の方法を見てください。
/**
* Return pseudo unique ID
* @return ID
*/
public static String getUniquePsuedoID() {
// If all else fails, if the user does have lower than API 9 (lower
// than Gingerbread), has reset their device or 'Secure.Android_ID'
// returns 'null', then simply the ID returned will be solely based
// off their Android device information. This is where the collisions
// can happen.
// Thanks http://www.pocketmagic.net/?p=1662!
// Try not to use DISPLAY, Host or ID - these items could change.
// If there are collisions, there will be overlapping data
String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);
// Thanks to @Roman SL!
// https://stackoverflow.com/a/4789483/950427
// Only devices with API >= 9 have Android.os.Build.SERIAL
// http://developer.Android.com/reference/Android/os/Build.html#SERIAL
// If a user upgrades software or roots their device, there will be a duplicate entry
String serial = null;
try {
serial = Android.os.Build.class.getField("SERIAL").get(null).toString();
// Go ahead and return the serial for api => 9
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
// String needs to be initialized
serial = "serial"; // some value
}
// Thanks @Joe!
// https://stackoverflow.com/a/2853253/950427
// Finally, combine the values we have found by using the UUID class to create a unique identifier
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
Google Play開発者コンソールから:
2014年8月1日以降、Google Playデベロッパープログラムポリシーでは、すべての新しいアプリのアップロードおよびアップデートで、広告目的のために他の永続的な識別子の代わりにの広告IDを使用する必要があります。 ] もっと詳しく知る
実装 :
許可:
<uses-permission Android:name="Android.permission.INTERNET" />
コード:
import com.google.Android.gms.ads.identifier.AdvertisingIdClient;
import com.google.Android.gms.ads.identifier.AdvertisingIdClient.Info;
import com.google.Android.gms.common.GooglePlayServicesAvailabilityException;
import com.google.Android.gms.common.GooglePlayServicesNotAvailableException;
import Java.io.IOException;
...
// Do not call this function from the main thread. Otherwise,
// an IllegalStateException will be thrown.
public void getIdThread() {
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
} catch (IOException exception) {
// Unrecoverable error connecting to Google Play services (e.g.,
// the old version of the service doesn't support getting AdvertisingId).
} catch (GooglePlayServicesAvailabilityException exception) {
// Encountered a recoverable error connecting to Google Play services.
} catch (GooglePlayServicesNotAvailableException exception) {
// Google Play services is not available entirely.
}
final String id = adInfo.getId();
final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
}
出典/文書:
http://developer.Android.com/google/play-services/id.htmlhttp://developer.Android.com/reference/com/google/Android/gms/ ads/identifier/AdvertisingIdClient.html
Google Play Servicesが利用可能な場合、広告IDは広告目的での他の識別子の既存の使用法(Settings.SecureでのAndroid_ID の使用など)を完全に置き換えることを目的としています。 Google Playサービスを利用できないケースは、 getAdvertisingIdInfo()によってスローされる GooglePlayServicesNotAvailableExceptionによって示されます。
http://en.kioskea.net/faq/34732-Android-reset-your-advertising-id
私は情報を得たすべてのリンクを参照しようとしました。あなたが行方不明で含まれる必要があるならば、コメントしてください!
Dave Webbが述べているように、 Android Developer Blogはこれをカバーする記事 を持っています。彼らの推奨する解決策はデバイスではなくアプリのインストールを追跡することで、ほとんどのユースケースでうまくいくでしょう。それを機能させるためのコードです。ぜひチェックしてください。
ただし、ブログの投稿では、アプリのインストール識別子ではなくデバイス識別子が必要な場合の解決策について説明しています。あなたがそうする必要がある場合に備えて、私はグーグルの誰かと話をしていくつかの項目についてさらに説明を加えた。前述のブログ記事に記載されていないデバイス識別子について私が発見したのは次のとおりです。
Googleの推奨に基づいて、必要に応じてAndroid_IDをシードとして使用し、必要に応じてTelephonyManager.getDeviceId()にフォールバックし、ランダムに生成された一意のUUIDを使用して各デバイスに一意のUUIDを生成するクラスを実装これはアプリの再起動後も持続します(ただしアプリの再インストールはしません)。
デバイスIDにフォールバックする必要があるデバイスの場合、一意のID _は_ に設定されていても工場出荷時の設定にリセットされます。これは知っておくべきことです。出荷時設定へのリセットによって一意のIDが確実にリセットされるようにする必要がある場合は、デバイスIDではなくランダムなUUIDに直接フォールバックすることを検討してください。
繰り返しますが、このコードはデバイスID用であり、アプリインストールID用ではありません。ほとんどの場合、アプリのインストールIDがおそらくあなたが探しているものです。しかし、デバイスIDが必要な場合は、おそらく以下のコードが役に立ちます。
import Android.content.Context;
import Android.content.SharedPreferences;
import Android.provider.Settings.Secure;
import Android.telephony.TelephonyManager;
import Java.io.UnsupportedEncodingException;
import Java.util.UUID;
public class DeviceUuidFactory {
protected static final String PREFS_FILE = "device_id.xml";
protected static final String PREFS_DEVICE_ID = "device_id";
protected volatile static UUID uuid;
public DeviceUuidFactory(Context context) {
if (uuid == null) {
synchronized (DeviceUuidFactory.class) {
if (uuid == null) {
final SharedPreferences prefs = context
.getSharedPreferences(PREFS_FILE, 0);
final String id = prefs.getString(PREFS_DEVICE_ID, null);
if (id != null) {
// Use the ids previously computed and stored in the
// prefs file
uuid = UUID.fromString(id);
} else {
final String androidId = Secure.getString(
context.getContentResolver(), Secure.Android_ID);
// Use the Android ID unless it's broken, in which case
// fallback on deviceId,
// unless it's not available, then fallback on a random
// number which we store to a prefs file
try {
if (!"9774d56d682e549c".equals(androidId)) {
uuid = UUID.nameUUIDFromBytes(androidId
.getBytes("utf8"));
} else {
final String deviceId = (
(TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE))
.getDeviceId();
uuid = deviceId != null ? UUID
.nameUUIDFromBytes(deviceId
.getBytes("utf8")) : UUID
.randomUUID();
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
// Write the value out to the prefs file
prefs.edit()
.putString(PREFS_DEVICE_ID, uuid.toString())
.commit();
}
}
}
}
}
/**
* Returns a unique UUID for the current Android device. As with all UUIDs,
* this unique ID is "very highly likely" to be unique across all Android
* devices. Much more so than Android_ID is.
*
* The UUID is generated by using Android_ID as the base key if appropriate,
* falling back on TelephonyManager.getDeviceID() if Android_ID is known to
* be incorrect, and finally falling back on a random UUID that's persisted
* to SharedPreferences if getDeviceID() does not return a usable value.
*
* In some rare circumstances, this ID may change. In particular, if the
* device is factory reset a new device ID may be generated. In addition, if
* a user upgrades their phone from certain buggy implementations of Android
* 2.2 to a newer, non-buggy version of Android, the device ID may change.
* Or, if a user uninstalls your app on a device that has neither a proper
* Android ID nor a Device ID, this ID may change on reinstallation.
*
* Note that if the code falls back on using TelephonyManager.getDeviceId(),
* the resulting ID will NOT change after a factory reset. Something to be
* aware of.
*
* Works around a bug in Android 2.2 for many devices when using Android_ID
* directly.
*
* @see http://code.google.com/p/Android/issues/detail?id=10603
*
* @return a UUID that may be used to uniquely identify your device for most
* purposes.
*/
public UUID getDeviceUuid() {
return uuid;
}
}
これがReto Meierが今年の Google I/O プレゼンテーションでユーザーのための一意のIDを取得するために使用したコードです。
private static String uniqueID = null;
private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
public synchronized static String id(Context context) {
if (uniqueID == null) {
SharedPreferences sharedPrefs = context.getSharedPreferences(
PREF_UNIQUE_ID, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
if (uniqueID == null) {
uniqueID = UUID.randomUUID().toString();
Editor editor = sharedPrefs.edit();
editor.putString(PREF_UNIQUE_ID, uniqueID);
editor.commit();
}
}
return uniqueID;
}
これをクラウドにプリファレンスを送信するためのバックアップ戦略(Retoの talk でも説明されています)と組み合わせると、ユーザーが自分に縛られ、デバイスが消去された後、または交換された後でも使用できます。今後の分析でこれを使用することを計画しています(言い換えれば、私はまだその部分をやっていません:)。
また、Wi-FiアダプターのMACアドレスを考慮することもできます。このようにして取得:
WifiManager wm = (WifiManager)Ctxt.getSystemService(Context.WIFI_SERVICE);
return wm.getConnectionInfo().getMacAddress();
マニフェストにAndroid.permission.ACCESS_WIFI_STATE
権限が必要です。
Wi-Fiが接続されていない場合でも利用可能と報告されています。上記の回答のJoeがこれを彼の多くのデバイスで試してみたら、それは素晴らしいことです。
一部のデバイスでは、Wi-Fiがオフになっていると使用できません。
注: Android 6.xから、一貫した偽のMACアドレスを返します:02:00:00:00:00:00
ここにという便利な情報があります。
それは5つの異なるIDタイプをカバーします:
Android.permission.READ_PHONE_STATE
が必要)Android.permission.ACCESS_WIFI_STATE
が必要)Android.permission.BLUETOOTH
が必要)公式のAndroid Developers Blogには、まさにこのテーマに関する記事、App Installationの識別があります。
Google I/O Reto Meierは、これをどのようにアプローチするかについての強力な回答を発表しました。 Anthony Nolanが彼の答えの中で方向性を示しています、しかし、私は他の人がそれをする方法を容易に見ることができるように私は完全なアプローチを書きたいと思いました。
この方法では、匿名で安全なユーザーIDが与えられます。これは、さまざまなデバイス間(Googleのプライマリアカウントに基づく)およびインストール間で永続的に使用されます。基本的な方法は、ランダムなユーザーIDを生成し、それをアプリの共有設定に保存することです。その後、Googleのバックアップエージェントを使用して、Googleアカウントにリンクされている共有設定をクラウドに保存します。
フルアプローチを見ていきましょう。まず、Android Backup Serviceを使用してSharedPreferencesのバックアップを作成する必要があります。 http://developer.Android.com/google/backup/signup.html
経由であなたのアプリを登録することから始めましょう。
Googleは、マニフェストに追加する必要があるバックアップサービスキーを提供します。次のようにBackupAgentを使用するようにアプリケーションに指示する必要もあります。
<application Android:label="MyApplication"
Android:backupAgent="MyBackupAgent">
...
<meta-data Android:name="com.google.Android.backup.api_key"
Android:value="your_backup_service_key" />
</application>
次に、バックアップエージェントを作成し、共有設定にヘルパーエージェントを使用するように指示する必要があります。
public class MyBackupAgent extends BackupAgentHelper {
// The name of the SharedPreferences file
static final String PREFS = "user_preferences";
// A key to uniquely identify the set of backup data
static final String PREFS_BACKUP_KEY = "prefs";
// Allocate a helper and add it to the backup agent
@Override
public void onCreate() {
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, PREFS);
addHelper(PREFS_BACKUP_KEY, helper);
}
}
バックアップを完了するには、メインのアクティビティにBackupManagerのインスタンスを作成する必要があります。
BackupManager backupManager = new BackupManager(context);
最後に、まだ存在しない場合はユーザーIDを作成し、それをSharedPreferencesに保管します。
public static String getUserID(Context context) {
private static String uniqueID = null;
private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";
if (uniqueID == null) {
SharedPreferences sharedPrefs = context.getSharedPreferences(
MyBackupAgent.PREFS, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
if (uniqueID == null) {
uniqueID = UUID.randomUUID().toString();
Editor editor = sharedPrefs.edit();
editor.putString(PREF_UNIQUE_ID, uniqueID);
editor.commit();
//backup the changes
BackupManager mBackupManager = new BackupManager(context);
mBackupManager.dataChanged();
}
}
return uniqueID;
}
ユーザーがデバイスを移動した場合でも、このUser_IDはインストール後も保持されます。
このアプローチの詳細については Reto's talk を参照してください。
バックアップエージェントの実装方法の詳細については、Data Backupを参照してください。バックアップは瞬時には行われないため、テストの一番下にあるセクションを特にお勧めします。そのため、テストするにはバックアップを強制する必要があります。
私はこれがユニークなIDのためのスケルトンを構築する確実な方法であると思います...それをチェックしてください。
すべてのAndroidデバイスで機能する疑似固有ID 一部のデバイスには電話がない(タブレットなど)、または何らかの理由でREAD_PHONE_STATE権限を含めたくない場合があります。 ROMバージョン、製造元名、CPUの種類、およびその他のハードウェアの詳細など、シリアルキーの確認やその他の一般的な目的にIDを使用する場合に適しています。この方法で計算されたIDは一意ではありません。同じIDを持つ2つのデバイス(同じハードウェアとROMイメージに基づく)を見つけることは可能ですが、実際のアプリケーションにおける変更は無視できます。この目的のためにBuildクラスを使うことができます。
String m_szDevIDShort = "35" + //we make this look like a valid IMEI
Build.BOARD.length()%10+ Build.BRAND.length()%10 +
Build.CPU_ABI.length()%10 + Build.DEVICE.length()%10 +
Build.DISPLAY.length()%10 + Build.Host.length()%10 +
Build.ID.length()%10 + Build.MANUFACTURER.length()%10 +
Build.MODEL.length()%10 + Build.PRODUCT.length()%10 +
Build.TAGS.length()%10 + Build.TYPE.length()%10 +
Build.USER.length()%10 ; //13 digits
Buildメンバーの大部分は文字列です。ここで行っているのは、長さを取り、それを1桁のモジュロで変換することです。私たちは13のそのような数字を持っています、そして私たちはIMEIと同じサイズID(15の数字)を持つために前にもう2つを加えています(35)。これらの文字列を見てください。 355715565309247
のようなものを返します。特別な許可は必要ないため、この方法は非常に便利です。
(追加情報:上記のテクニックは Pocket Magic の記事からコピーされたものです。)
次のコードは、非表示のAndroid APIを使用してデバイスのシリアル番号を返します。しかし、 "ro.serialno"がこのデバイスに設定されていないため、このコードはSamsung Galaxy Tabでは機能しません。
String serial = null;
try {
Class<?> c = Class.forName("Android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
}
catch (Exception ignored) {
}
以下のコードを使用すると、Android OSデバイスの一意のデバイスIDを文字列として取得できます。
deviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.Android_ID);
シリアル フィールドは、APIレベル9(Android 2.3 - Gingerbread)のBuild
クラスに追加されました。ドキュメンテーションはそれがハードウェアシリアル番号を表すと言います。したがって、それがデバイス上に存在する場合、それは一意であるべきです。
APIレベルが9以上のすべてのデバイスで実際にサポートされている(= nullでない)かどうかはわかりません。
私が追加する1つのこと - 私はそれらのユニークな状況のうちの1つを持っています。
使用方法
deviceId = Secure.getString(this.getContext().getContentResolver(), Secure.Android_ID);
私のViewsonic G TabletがNullではないDeviceIDを報告しても、全てのG Tabletが同じ番号を報告しているのです。
「ユニークな」DeviceIDに基づいて誰かのアカウントに瞬時にアクセスできるようにする「Pocket Empires」をプレイするのは面白いことです。
私のデバイスは携帯無線機を持っていません。
アプリケーションのインストール元のAndroidデバイスごとに一意の識別子を取得する方法の詳細については、公式のAndroid Developers Blogの投稿アプリのインストールの識別を参照してください。
インストール時に自分で生成し、その後アプリケーションを再起動したときにそれを読むのが最善の方法のようです。
私は個人的にこれは許容できるが理想的ではないと思います。ほとんどの場合、携帯の無線状態(Wi-Fiのオン/オフ、携帯のオン/オフ、Bluetoothのオン/オフ)に依存しているため、Androidが提供する1つの識別子がすべての場合に機能することはありません。 Settings.Secure.Android_ID
のような他のものは製造元によって実装されなければならず、ユニークであることが保証されません。
以下は、アプリケーションがローカルに保存する他のデータと一緒に保管される installation ファイルにデータを書き込む例です。
public class Installation {
private static String sID = null;
private static final String INSTALLATION = "INSTALLATION";
public synchronized static String id(Context context) {
if (sID == null) {
File installation = new File(context.getFilesDir(), INSTALLATION);
try {
if (!installation.exists())
writeInstallationFile(installation);
sID = readInstallationFile(installation);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
return sID;
}
private static String readInstallationFile(File installation) throws IOException {
RandomAccessFile f = new RandomAccessFile(installation, "r");
byte[] bytes = new byte[(int) f.length()];
f.readFully(bytes);
f.close();
return new String(bytes);
}
private static void writeInstallationFile(File installation) throws IOException {
FileOutputStream out = new FileOutputStream(installation);
String id = UUID.randomUUID().toString();
out.write(id.getBytes());
out.close();
}
}
クラスファイルに以下のコードを追加します。
final TelephonyManager tm = (TelephonyManager) getBaseContext()
.getSystemService(SplashActivity.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
Log.v("DeviceIMEI", "" + tmDevice);
tmSerial = "" + tm.getSimSerialNumber();
Log.v("GSM devices Serial Number[simcard] ", "" + tmSerial);
androidId = "" + Android.provider.Settings.Secure.getString(getContentResolver(),
Android.provider.Settings.Secure.Android_ID);
Log.v("androidId CDMA devices", "" + androidId);
UUID deviceUuid = new UUID(androidId.hashCode(),
((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
Log.v("deviceIdUUID universally unique identifier", "" + deviceId);
String deviceModelName = Android.os.Build.MODEL;
Log.v("Model Name", "" + deviceModelName);
String deviceUSER = Android.os.Build.USER;
Log.v("Name USER", "" + deviceUSER);
String devicePRODUCT = Android.os.Build.PRODUCT;
Log.v("PRODUCT", "" + devicePRODUCT);
String deviceHARDWARE = Android.os.Build.HARDWARE;
Log.v("HARDWARE", "" + deviceHARDWARE);
String deviceBRAND = Android.os.Build.BRAND;
Log.v("BRAND", "" + deviceBRAND);
String myVersion = Android.os.Build.VERSION.RELEASE;
Log.v("VERSION.RELEASE", "" + myVersion);
int sdkVersion = Android.os.Build.VERSION.SDK_INT;
Log.v("VERSION.SDK_INT", "" + sdkVersion);
AndroidManifest.xmlに追加します。
<uses-permission Android:name="Android.permission.READ_PHONE_STATE" />
TelephonyManager
とAndroid_ID
を使用した、StringとしてのAndroid OSデバイスの一意のデバイスIDは、次の方法で取得されます。String deviceId;
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
}
else {
deviceId = Secure.getString(
getApplicationContext().getContentResolver(),
Secure.Android_ID);
}
しかし、私はGoogleが提案した方法を強くお勧めします。アプリのインストールの識別を参照してください。
長所と短所があるこれらのAndroid_ID
の問題(時にはnull
でも、特定のモデルのデバイスでも常に同じIDが返される場合があります)を回避するには、さまざまな方法があります。
私は自分でAndroid用の既存のOpenUDID実装( https://github.com/ylechelle/OpenUDID を参照)を使用することを好む( https://github.com/vieux/OpenUDID を参照)。統合するのは簡単で、上記の問題のためのフォールバックでAndroid_ID
を利用します。
私の2セント - NBこれはdevice(err)unique IDのためのものです - Android開発者のブログで議論されたようなインストールのものではありません 。
SharedPreferencesはプロセス間で同期されないため、@ emmbyによって提供される solution はアプリケーションIDごとに分類されることに注意してください( here および here を参照)。だから私はこれを完全に避けました。
代わりに、私は列挙型の中で(デバイス)IDを取得するためのさまざまな戦略をカプセル化しました - 列挙型定数の順序を変更することはIDを取得するさまざまな方法の優先順位に影響します。最初のnull以外のIDが返されるか、例外がスローされます(nullを意味しないというJavaの優良な慣例に従って)。それで例えば私は最初にTELEPHONYを持っています - しかしデフォルトの良い選択はAndroid_ID betaでしょう:
import Android.Manifest.permission;
import Android.bluetooth.BluetoothAdapter;
import Android.content.Context;
import Android.content.pm.PackageManager;
import Android.net.wifi.WifiManager;
import Android.provider.Settings.Secure;
import Android.telephony.TelephonyManager;
import Android.util.Log;
// TODO : hash
public final class DeviceIdentifier {
private DeviceIdentifier() {}
/** @see http://code.google.com/p/Android/issues/detail?id=10603 */
private static final String Android_ID_BUG_MSG = "The device suffers from "
+ "the Android ID bug - its ID is the emulator ID : "
+ IDs.BUGGY_Android_ID;
private static volatile String uuid; // volatile needed - see EJ item 71
// need lazy initialization to get a context
/**
* Returns a unique identifier for this device. The first (in the order the
* enums constants as defined in the IDs enum) non null identifier is
* returned or a DeviceIDException is thrown. A DeviceIDException is also
* thrown if ignoreBuggyAndroidID is false and the device has the Android ID
* bug
*
* @param ctx
* an Android constant (to retrieve system services)
* @param ignoreBuggyAndroidID
* if false, on a device with the Android ID bug, the buggy
* Android ID is not returned instead a DeviceIDException is
* thrown
* @return a *device* ID - null is never returned, instead a
* DeviceIDException is thrown
* @throws DeviceIDException
* if none of the enum methods manages to return a device ID
*/
public static String getDeviceIdentifier(Context ctx,
boolean ignoreBuggyAndroidID) throws DeviceIDException {
String result = uuid;
if (result == null) {
synchronized (DeviceIdentifier.class) {
result = uuid;
if (result == null) {
for (IDs id : IDs.values()) {
try {
result = uuid = id.getId(ctx);
} catch (DeviceIDNotUniqueException e) {
if (!ignoreBuggyAndroidID)
throw new DeviceIDException(e);
}
if (result != null) return result;
}
throw new DeviceIDException();
}
}
}
return result;
}
private static enum IDs {
TELEPHONY_ID {
@Override
String getId(Context ctx) {
// TODO : add a SIM based mechanism ? tm.getSimSerialNumber();
final TelephonyManager tm = (TelephonyManager) ctx
.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null) {
w("Telephony Manager not available");
return null;
}
assertPermission(ctx, permission.READ_PHONE_STATE);
return tm.getDeviceId();
}
},
Android_ID {
@Override
String getId(Context ctx) throws DeviceIDException {
// no permission needed !
final String andoidId = Secure.getString(
ctx.getContentResolver(),
Android.provider.Settings.Secure.Android_ID);
if (BUGGY_Android_ID.equals(andoidId)) {
e(Android_ID_BUG_MSG);
throw new DeviceIDNotUniqueException();
}
return andoidId;
}
},
WIFI_MAC {
@Override
String getId(Context ctx) {
WifiManager wm = (WifiManager) ctx
.getSystemService(Context.WIFI_SERVICE);
if (wm == null) {
w("Wifi Manager not available");
return null;
}
assertPermission(ctx, permission.ACCESS_WIFI_STATE); // I guess
// getMacAddress() has no Java doc !!!
return wm.getConnectionInfo().getMacAddress();
}
},
BLUETOOTH_MAC {
@Override
String getId(Context ctx) {
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
if (ba == null) {
w("Bluetooth Adapter not available");
return null;
}
assertPermission(ctx, permission.BLUETOOTH);
return ba.getAddress();
}
}
// TODO PSEUDO_ID
// http://www.pocketmagic.net/2011/02/Android-unique-device-id/
;
static final String BUGGY_Android_ID = "9774d56d682e549c";
private final static String TAG = IDs.class.getSimpleName();
abstract String getId(Context ctx) throws DeviceIDException;
private static void w(String msg) {
Log.w(TAG, msg);
}
private static void e(String msg) {
Log.e(TAG, msg);
}
}
private static void assertPermission(Context ctx, String perm) {
final int checkPermission = ctx.getPackageManager().checkPermission(
perm, ctx.getPackageName());
if (checkPermission != PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Permission " + perm + " is required");
}
}
// =========================================================================
// Exceptions
// =========================================================================
public static class DeviceIDException extends Exception {
private static final long serialVersionUID = -8083699995384519417L;
private static final String NO_Android_ID = "Could not retrieve a "
+ "device ID";
public DeviceIDException(Throwable throwable) {
super(NO_Android_ID, throwable);
}
public DeviceIDException(String detailMessage) {
super(detailMessage);
}
public DeviceIDException() {
super(NO_Android_ID);
}
}
public static final class DeviceIDNotUniqueException extends
DeviceIDException {
private static final long serialVersionUID = -8940090896069484955L;
public DeviceIDNotUniqueException() {
super(Android_ID_BUG_MSG);
}
}
}
_ imei _ はどうですか。それはAndroidや他のモバイル機器に特有です。
これが私がどのようにしてユニークなIDを生成しているかです:
public static String getDeviceId(Context ctx)
{
TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
String tmDevice = tm.getDeviceId();
String androidId = Secure.getString(ctx.getContentResolver(), Secure.Android_ID);
String serial = null;
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) serial = Build.SERIAL;
if(tmDevice != null) return "01" + tmDevice;
if(androidId != null) return "02" + androidId;
if(serial != null) return "03" + serial;
// other alternatives (i.e. Wi-Fi MAC, Bluetooth MAC, etc.)
return null;
}
もう1つの方法は、パーミッションなしでアプリで/sys/class/Android_usb/Android0/iSerial
を使用することです。
user@creep:~$ adb Shell ls -l /sys/class/Android_usb/Android0/iSerial
-rw-r--r-- root root 4096 2013-01-10 21:08 iSerial
user@creep:~$ adb Shell cat /sys/class/Android_usb/Android0/iSerial
0A3CXXXXXXXXXX5
Javaでこれを行うには、FileInputStreamを使用してiSerialファイルを開き、文字を読み取るだけです。すべてのデバイスにこのファイルがあるわけではないので、必ず例外ハンドラでラップしてください。
少なくとも以下のデバイスがこのファイルを世界的に読み取り可能にすることが知られています。
あなたは私のブログ記事を見ることもできます特権のないアプリにAndroidのハードウェアのシリアル番号を漏らしているここで私は他のどのようなファイルが情報として利用できるかを議論します。
具体的には、Settings.Secure.Android_ID
です。これは、デバイスが最初に起動したときに生成および保存される64ビットの量です。デバイスが消去されるとリセットされます。
Android_ID
は、一意のデバイス識別子に適しています。欠点:まず、2.2 (“Froyo”).
より前のAndroidのリリースでは100%信頼できるわけではありません。また、すべてのインスタンスが同じAndroid_IDを持つ大手メーカーの広く知られた携帯電話に、少なくとも1つの広く見られるバグがあります。
私は次のコードを使用してIMEI
を取得するか、デバイスに電話機能がない場合はSecure .Android_ID
を代わりに使用します。
String identifier = null;
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE));
if (tm != null)
identifier = tm.getDeviceId();
if (identifier == null || identifier .length() == 0)
identifier = Secure.getString(activity.getContentResolver(),Secure.Android_ID);
ここに30以上の答えがあります、そしていくつかは同じですそしていくつかはユニークです。この答えはそれらの答えのいくつかに基づいています。そのうちの1人が@Lenn Dollingの答えです。
これは3つのIDを組み合わせて32桁の16進数ストリングを作成します。それは私にとってとてもうまくいった。
3つのIDは以下のとおりです。
擬似ID - 物理デバイスの仕様に基づいて生成されます。
Android_ID - Settings.Secure.Android_ID
Bluetoothアドレス - Bluetoothアダプタアドレス
それはこのような何かを返すでしょう: 551F27C060712A72730B0A0F734064B1
注:longId
文字列には、いつでもIDを追加できます。たとえば、シリアル番号です。無線LANアダプタのアドレス。 IMEIこのように、あなたはそれをデバイスごとにもっとユニークにしています。
@SuppressWarnings("deprecation")
@SuppressLint("HardwareIds")
public static String generateDeviceIdentifier(Context context) {
String pseudoId = "35" +
Build.BOARD.length() % 10 +
Build.BRAND.length() % 10 +
Build.CPU_ABI.length() % 10 +
Build.DEVICE.length() % 10 +
Build.DISPLAY.length() % 10 +
Build.Host.length() % 10 +
Build.ID.length() % 10 +
Build.MANUFACTURER.length() % 10 +
Build.MODEL.length() % 10 +
Build.PRODUCT.length() % 10 +
Build.TAGS.length() % 10 +
Build.TYPE.length() % 10 +
Build.USER.length() % 10;
String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.Android_ID);
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
String btId = "";
if (bluetoothAdapter != null) {
btId = bluetoothAdapter.getAddress();
}
String longId = pseudoId + androidId + btId;
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(longId.getBytes(), 0, longId.length());
// get md5 bytes
byte md5Bytes[] = messageDigest.digest();
// creating a hex string
String identifier = "";
for (byte md5Byte : md5Bytes) {
int b = (0xFF & md5Byte);
// if it is a single digit, make sure it have 0 in front (proper padding)
if (b <= 0xF) {
identifier += "0";
}
// add number to string
identifier += Integer.toHexString(b);
}
// hex string to uppercase
identifier = identifier.toUpperCase();
return identifier;
} catch (Exception e) {
Log.e("TAG", e.toString());
}
return "";
}
特定のAndroidデバイスをハードウェアで認識するために、MACアドレスを確認することができます。
そうすることができます:
androidManifest.xmlの中の
<uses-permission Android:name="Android.permission.INTERNET" />
今すぐあなたのコードで:
List<NetworkInterface> interfacesList = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface interface : interfacesList) {
// This will give you the interface MAC ADDRESS
interface.getHardwareAddress();
}
すべてのAndroidデバイスで、それらは少なくとも "wlan0"インターフェースの魔女がWI-FIチップです。
P.S。それらはあなたがMACSを含むリストから得るであろう他のインターフェースの束ですしかし、これは電話の間で変わることができます。
GoogleインスタンスID
I/O 2015でリリースされました。 Android上でプレイサービス7.5が必要です。
https://developers.google.com/instance-id/
https://developers.google.com/instance-id/guides/Android-implementation
InstanceID iid = InstanceID.getInstance( context ); // Google docs are wrong - this requires context
String id = iid.getId(); // blocking call
グーグルは、このIDがAndroid、Chrome、そしてiOSのインストールを識別するために使われることを意図しているようです。
これはデバイスではなくインストールを識別しますが、Android_ID(これは受け入れられた回答です)はデバイスを識別しなくなりました。 ARCランタイムでは、この新しいインスタンスIDのように、インストールごとに新しいAndroid_IDが生成されます( 詳細はここ )。また、私たちのほとんどが実際に探しているのは、(デバイスではなく)インストールを識別することです。
インスタンスIDの利点
グーグルはそれをこの目的のために(あなたのインストールを識別するために)使うことを意図している、それはクロスプラットフォームであり、そして他の多くの目的のために使うことができるように思う.
GCMを使用している場合は、GCMトークン(古いGCM登録IDを置き換えるもの)を取得するために必要なので、このインスタンスIDを使用する必要があります。
不利な点/問題
現在の実装(GPS 7.5)では、アプリが要求したときにインスタンスIDがサーバーから取得されます。これは、上記の呼び出しがブロッキング呼び出しであることを意味します。私の科学的でないテストでは、デバイスがオンラインの場合は1〜3秒、オフラインの場合は0.5〜1.0秒かかります。ランダムID)。これは、Android 5.1.1とGPS 7.5を搭載したNexus 5の北米でテストされています。
あなたが彼らが意図する目的のためにIDを使うならば - 例えば。アプリの認証、アプリの識別、GCM - この1〜3秒は迷惑になる可能性があると思います(もちろん、アプリによって異なります)。
AndroidデバイスのMac IDも一意のIDです。MacIDを取得するには次のコードを使用してデバイス自体をフォーマットしても変わりません
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo info = manager.getConnectionInfo();
String address = info.getMacAddress();
また、適切な permissions をあなたの AndroidManifest.xmlに追加することを忘れないでください。
<uses-permission Android:name="Android.permission.ACCESS_WIFI_STATE"/>
TelephonyManger.getDeviceId() GSMの場合はIMEI、CDMA電話の場合はMEIDまたはESNなどの一意のデバイスIDを返します。
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String myAndroidDeviceId = mTelephony.getDeviceId();
しかし、私は使用することをお勧めします:
Settings.Secure.Android_ID これは、Android IDを一意の64ビットの16進数文字列として返します。
String myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.Android_ID);
TelephonyManger.getDeviceId() がnullを返すことがあるので、一意のIDを保証するためにこのメソッドを使用します。
public String getUniqueID(){
String myAndroidDeviceId = "";
TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null){
myAndroidDeviceId = mTelephony.getDeviceId();
}else{
myAndroidDeviceId = Secure.getString(getApplicationContext().getContentResolver(), Secure.Android_ID);
}
return myAndroidDeviceId;
}
Googleは Advertising ID を持っています。
これも使用できますが、以下の点に注意してください。
広告IDは、ユーザー固有の一意のリセット可能なIDです。
そして
ユーザーが自分の識別子をリセットしたり、Google Playアプリ内のインタレストベース広告をオプトアウトしたりできるようにします。
したがって、このIDは変更される可能性がありますが、間もなく 選択できない可能性があります 、このIDの目的によって異なります。
HTH
1.GmsサービスでAndroidデバイスIDにアクセスできます。下記の例を参照してください。
private DeviceInfoProvider mDeviceInfo = new DeviceInfoProvider(Context)
String mDeviceId = DeviceInfoProvider.getDeviceId(Context);
Log.d("DEVICE_ID" , mDeviceId);
固有のID(すなわちIMEI)を提供するテレフォニーマネージャを使用する。例を見てください。
import Android.telephony.TelephonyManager;
import Android.content.Context;
// ...
TelephonyManager telephonyManager;
telephonyManager = (TelephonyManager) getSystemService(Context.
TELEPHONY_SERVICE);
/*
* getDeviceId() returns the unique device ID.
* For example,the IMEI for GSM and the MEID or ESN for CDMA phones.
*/
String deviceId = telephonyManager.getDeviceId();
/*
* getSubscriberId() returns the unique subscriber ID,
*/
String subscriberId = telephonyManager.getSubscriberId();
これにはあなたのユーザーにAndroid.permission.READ_PHONE_STATEが必要ですが、あなたが作ったアプリケーションの種類に従うことを正当化するのは難しいかもしれません。
タブレットのようなテレフォニーサービスを持たないデバイスは、Android 2.3 Gingerbread以降、Android.os.Build.SERIALを介して利用可能な固有のデバイスIDを報告する必要があります。テレフォニーサービスを持つ電話の中には、シリアル番号を定義するものもあります。すべてのAndroidデバイスにシリアル番号が付いているわけではないので、この解決策は信頼できません。
デバイスの初回起動時に、ランダムな値が生成されて保存されます。この値はSettings.Secure.Android_IDから入手できます。これは64ビットの数値なので、デバイスの寿命まで一定に保たれるはずです。 Android_IDは、スマートフォンやタブレットで使用できるため、一意のデバイス識別子として適しています。値を取得するには、次のコードを使用できます。
文字列androidId = Settings.Secure.getString(getContentResolver()、 Settings.Secure.Android_ID);
ただし、デバイスで出荷時設定へのリセットが実行されると、値が変わる可能性があります。すべてのインスタンスが同じAndroid_IDを持つ製造元からの人気のあるハンドセットには既知のバグもあります。明らかに、解決策は100%信頼できません。
SharedPreferences sharedPrefs = context.getSharedPreferences(
PREF_UNIQUE_ID, Context.MODE_PRIVATE);
uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);
DeviceIdはサードパーティの手による追跡として使用できるので推奨されませんが、これは別の方法です。
@SuppressLint("HardwareIds")
private String getDeviceID() {
deviceId = Settings.Secure.getString(getApplicationContext().getContentResolver(),
Settings.Secure.Android_ID);
return deviceId;
}
私は数年前にこの問題に出会い、さまざまな答えに基づいて一般化されたソリューションを実装することを学びました。
私は実世界の製品で、一般化されたソリューションを数年間使用してきました。それは今のところ非常にうまくいっています。これは、提供されたさまざまな回答に基づいたコードスニペットです。
明示的に許可を求めなかったので、getEmail
はほとんどの場合nullを返します。
private static UniqueId getUniqueId() {
MyApplication app = MyApplication.instance();
// Our prefered method of obtaining unique id in the following order.
// (1) Advertising id
// (2) Email
// (2) Android_ID
// (3) Instance ID - new id value, when reinstall the app.
////////////////////////////////////////////////////////////////////////////////////////////
// ADVERTISING ID
////////////////////////////////////////////////////////////////////////////////////////////
AdvertisingIdClient.Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(app);
} catch (IOException e) {
Log.e(TAG, "", e);
} catch (GooglePlayServicesNotAvailableException e) {
Log.e(TAG, "", e);
} catch (GooglePlayServicesRepairableException e) {
Log.e(TAG, "", e);
}
if (adInfo != null) {
String aid = adInfo.getId();
if (!Utils.isNullOrEmpty(aid)) {
return UniqueId.newInstance(aid, UniqueId.Type.aid);
}
}
////////////////////////////////////////////////////////////////////////////////////////////
// EMAIL
////////////////////////////////////////////////////////////////////////////////////////////
final String email = Utils.getEmail();
if (!Utils.isNullOrEmpty(email)) {
return UniqueId.newInstance(email, UniqueId.Type.eid);
}
////////////////////////////////////////////////////////////////////////////////////////////
// Android ID
////////////////////////////////////////////////////////////////////////////////////////////
final String sid = Settings.Secure.getString(app.getContentResolver(), Settings.Secure.Android_ID);
if (!Utils.isNullOrEmpty(sid)) {
return UniqueId.newInstance(sid, UniqueId.Type.sid);
}
////////////////////////////////////////////////////////////////////////////////////////////
// INSTANCE ID
////////////////////////////////////////////////////////////////////////////////////////////
final String iid = com.google.Android.gms.iid.InstanceID.getInstance(MyApplication.instance()).getId();
if (!Utils.isNullOrEmpty(iid)) {
return UniqueId.newInstance(iid, UniqueId.Type.iid);
}
return null;
}
public final class UniqueId implements Parcelable {
public enum Type implements Parcelable {
aid,
sid,
iid,
eid;
////////////////////////////////////////////////////////////////////////////
// Handling Parcelable nicely.
public static final Parcelable.Creator<Type> CREATOR = new Parcelable.Creator<Type>() {
public Type createFromParcel(Parcel in) {
return Type.valueOf(in.readString());
}
public Type[] newArray(int size) {
return new Type[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(this.name());
}
// Handling Parcelable nicely.
////////////////////////////////////////////////////////////////////////////
}
public static boolean isValid(UniqueId uniqueId) {
if (uniqueId == null) {
return false;
}
return uniqueId.isValid();
}
private boolean isValid() {
return !org.yccheok.jstock.gui.Utils.isNullOrEmpty(id) && type != null;
}
private UniqueId(String id, Type type) {
if (org.yccheok.jstock.gui.Utils.isNullOrEmpty(id) || type == null) {
throw new Java.lang.IllegalArgumentException();
}
this.id = id;
this.type = type;
}
public static UniqueId newInstance(String id, Type type) {
return new UniqueId(id, type);
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + id.hashCode();
result = 31 * result + type.hashCode();
return result;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof UniqueId)) {
return false;
}
UniqueId uniqueId = (UniqueId)o;
return this.id.equals(uniqueId.id) && this.type == uniqueId.type;
}
@Override
public String toString() {
return type + ":" + id;
}
////////////////////////////////////////////////////////////////////////////
// Handling Parcelable nicely.
public static final Parcelable.Creator<UniqueId> CREATOR = new Parcelable.Creator<UniqueId>() {
public UniqueId createFromParcel(Parcel in) {
return new UniqueId(in);
}
public UniqueId[] newArray(int size) {
return new UniqueId[size];
}
};
private UniqueId(Parcel in) {
this.id = in.readString();
this.type = in.readParcelable(Type.class.getClassLoader());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(this.id);
parcel.writeParcelable(this.type, 0);
}
// Handling Parcelable nicely.
////////////////////////////////////////////////////////////////////////////
public final String id;
public final Type type;
}
public static String getEmail() {
Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
AccountManager accountManager = AccountManager.get(MyApplication.instance());
Account[] accounts = accountManager.getAccountsByType("com.google");
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
return possibleEmail;
}
}
accounts = accountManager.getAccounts();
for (Account account : accounts) {
if (emailPattern.matcher(account.name).matches()) {
String possibleEmail = account.name;
return possibleEmail;
}
}
return null;
}
これは、AAIDを取得するための簡単な答えです。2019年6月に正常に動作することをテスト済みです
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String token = null;
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (IOException e) {
// ...
} catch ( GooglePlayServicesRepairableException e) {
// ...
} catch (GooglePlayServicesNotAvailableException e) {
// ...
}
String Android_id = adInfo.getId();
Log.d("DEVICE_ID",Android_id);
return Android_id;
}
@Override
protected void onPostExecute(String token) {
Log.i(TAG, "DEVICE_ID Access token retrieved:" + token);
}
};
task.execute();
完全な回答を詳細に読む here :
Androidデバイスで利用可能なユニークIDを理解する。この公式ガイドを使ってください。
一意の識別子のベストプラクティス:
IMEI、Macアドレス、インスタンスID、GUID、SSAID、アドバタイズID、デバイスを検証するためのSafety Net API。
https://developer.Android.com/training/articles/user-data -ids
最新の情報をもっと探している人全員が読むことに向かいます。 Android Oでは、システムがこれらのIDを管理する方法にいくつかの変更があります。
https://Android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html
tl; dr SerialはPHONE許可を必要とし、Android IDはそれらのパッケージ名と署名に基づいて異なるアプリごとに変わります。
また、Googleは、ハードウェアIDとソフトウェアIDをいつ使用するかについての提案を提供するNice文書をまとめました。
https://developer.Android.com/training/articles/user-data -ids.html
通常、アプリにはデバイス固有のIDを使用します。しかしいつか私はIMEIを使います。どちらも固有の番号です。
_ imei _ ( 国際携帯機器識別子 )を取得します。
public String getIMEI(Activity activity) {
TelephonyManager telephonyManager = (TelephonyManager) activity
.getSystemService(Context.TELEPHONY_SERVICE);
return telephonyManager.getDeviceId();
}
デバイス固有のIDを取得する
public String getDeviceUniqueID(Activity activity){
String device_unique_id = Secure.getString(activity.getContentResolver(),
Secure.Android_ID);
return device_unique_id;
}
シリアル番号は、Android.os.Build.SERIALから入手できる固有のデバイスIDです。
public static String getSerial() {
String serial = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
serial = Build.getSerial();
}else{
serial = Build.SERIAL;
}
return serial;
}
GetSerial()を呼び出す前に、READ_PHONE_STATE権限があることを確認してください。
NOTE: - それは電話のないデバイスでは利用できません(wifi専用タブレットのように)です。
ユーザーIDを取得するには、Google Playライセンスライブラリを使用できます。
このライブラリをダウンロードするには、SDK Manager => SDK Toolsを開きます。ダウンロードしたライブラリファイルへのパスは次のとおりです。
path_to_Android_sdk_on_your_pc/extras/google/market_licensing/library
ライブラリをプロジェクトに含めます(ファイルを単にコピーできます)。
次に、Policy
インターフェースの実装が必要です(ライブラリーからの2つのファイルのいずれかを使用できます:ServerManagedPolicy
またはStrictPolicy
)。
ユーザーIDはprocessServerResponse()
関数内で提供されます:
public void processServerResponse(int response, ResponseData rawData) {
if(rawData != null) {
String userId = rawData.userId
// use/save the value
}
// ...
}
次に、ポリシーを使用してLicenseChecker
を構築し、checkAccess()
関数を呼び出す必要があります。方法の例としてMainActivity.Java
を使用します。 MainActivity.Java
はこのフォルダー内にあります。
path_to_Android_sdk_on_your_pc/extras/google/market_licensing/sample/src/com/example/Android/market/licensing
AndroidManifest.xmlにCHECK_LICENSE権限を追加することを忘れないでください。
ライセンスライブラリの詳細: https://developer.Android.com/google/play/licensing
String SERIAL_NUMER = Build.SERIAL;
SERIAL NUMBERを各デバイスで一意の文字列として返します。
Android 9 を含めるために/私はまだうまくいく可能性のあるアイデアを1つだけ持っています。
指紋認証 サーバーを使用することで、デバイスを一意に識別できるようにする必要があります。 最初のインストール時間は、アプリをアンインストールしてから再インストールしない限り変わりません。しかし、これは、デバイスを識別できないようにするために(つまり、工場出荷時設定へのリセット後に)デバイス上のすべてのアプリに対して実行する必要があります。
これは私がそれに取り組む方法です:
これは、Androidからすべてのアプリケーションを抽出する方法です(権限は必要ありません)。
final PackageManager pm = application.getPackageManager();
List<ApplicationInfo> packages =
pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
try {
Log.d(TAG, "Installed package :" + packageInfo.packageName);
Log.d(TAG, "Installed :" + pm.getPackageInfo(packageInfo.packageName, 0).firstInstallTime);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
NB: これはテストされていない証明されていない方法です!私はそれがうまくいくと確信しています、しかしこれがつかまえれば、彼らはそれが何らかの形でそれを閉鎖するであろうこともかなり確かです。
デバイスIDを1回だけ取得してから、データベースまたはファイルに保存します。この場合、アプリの初回起動時にIDを生成して保存します。次回は、ファイルに格納されているIDのみを取ります。
追加する場合:
Settings.Secure.getString(context.contentResolver,
Settings.Secure.Android_ID)
Android Lintは次の警告を表示します。
GetStringを使用してデバイス識別子を取得することはお勧めしません。検査情報:これらのデバイス識別子の使用は、価値の高い不正防止と高度な電話の使用例以外には推奨されません。広告のユースケースにはAdvertisingIdClient $ Info#getIdを使用し、分析にはInstanceId#getIdを使用します。
だから、これを使うことは避けるべきだ。
Android Developer documentation で述べたように:
1:ハードウェア識別子の使用を避けます。
ほとんどのユースケースでは、必要な機能を制限することなく、SSAID(Android ID)やIMEIなどのハードウェア識別子の使用を回避できます。
2:ユーザープロファイリングまたは広告のユースケースにのみ広告IDを使用します。
広告IDを使用するときは、広告追跡に関するユーザーの選択を常に尊重してください。また、IDを個人を特定できる情報(PII)に接続できないようにし、広告IDのリセットの橋渡しを避けます。
3:支払い詐欺防止と電話を除く他のすべてのユースケースでは、可能な限りインスタンスIDまたはプライベートに保存されたGUIDを使用します。
広告以外のユースケースの大半では、インスタンスIDまたはGUIDで十分です。
4:プライバシーリスクを最小限に抑えるために、ユースケースに適したAPIを使用します。
価値の高いコンテンツ保護にはDRM APIを使用し、不正行為保護にはSafetyNet APIを使用します。 SafetyNet APIは、プライバシーリスクを招くことなく、デバイスが本物かどうかを判断する最も簡単な方法です。
完全を期すために、Xamarin.Android
とC#でId
を取得する方法を次に示します。
var id = Settings.Secure.GetString(ContentResolver, Settings.Secure.AndroidId);
あるいはあなたがActivity
の中にいないのなら:
var id = Settings.Secure.GetString(context.ContentResolver, Settings.Secure.AndroidId);
context
は渡されたコンテキストです。