テレフォニーマネージャーからIMEI ID nullを取得しています。何をすべきか?
そのための回避策はありますか?
Android Qでは、IMEIとシリアル番号の両方へのアクセスが制限されています。特別なキャリア権限を持つプラットフォームとアプリでのみ利用できます。また、READ_PRIVILEGED_PHONE_STATE権限は、プラットフォーム以外のアプリでは使用できません。
アクセスしようとすると、例外がスローされます
Java.lang.SecurityException: getImeiForSlot: The user 10180 does not meet the requirements to access device identifiers.
ドキュメントを参照してください: https://developer.Android.com/preview/privacy/data-identifiers#device-ids
これは、Android=の時点では機能しません。Q。サードパーティのアプリは、IMEIや電話のシリアル番号、およびその他のリセットできないデバイス識別子を使用できません。
それらを使用できる唯一の権限はREAD_PRIVILEGED_PHONE_STATEであり、サードパーティのアプリ-製造およびソフトウェアアプリケーションでは使用できません。そのメソッドを使用すると、エラーSecurity例外が発生するか、nullが取得されます。
以下を使用して、一意のIDの取得を試みることができます。
import Android.provider.Settings.Secure;
private String Android_id = Secure.getString(getContext().getContentResolver(),Secure.Android_ID);
ベストプラクティスが示唆するように。 「必要な機能を制限することなく、SSAID(Android ID)やIMEIなどのハードウェア識別子の使用を回避できます。」
むしろString uniqueID = UUID.randomUUID().toString();
やFirebaseInstanceId.getInstance().getId();
などのインスタンスIDを取得します
アプリがAndroid 10以上を対象とする場合、SecurityExceptionが発生します。
次のモジュールが影響を受けます...
Build
getSerial()
TelephonyManager
getImei()
getDeviceId()
getMeid()
getSimSerialNumber()
getSubscriberId()
= Android 10の場合、IMEI noを取得できません。Android IDのように、別の一意の識別子を使用する必要があります
デバイスに固有の64ビット16進数
private String Android_id = Secure.getString(getContext()。getContentResolver()、Secure.Android_ID);
あなたは他の方法で変更することができます、私はuuidを使ってデバイスIDを置き換えます。
String uniquePseudoID = "35" +
Build.BOARD.length() % 10 +
Build.BRAND.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 serial = Build.getRadioVersion();
String uuid = new UUID(uniquePseudoID.hashCode(), serial.hashCode()).toString();
AppLog.d("Device ID",uuid);
IMEI番号については不明ですが、この方法でsimSerialNumberおよびその他の携帯通信会社情報を取得できます。
getSimSerialNumber()にはAndroid 10以降)の特権権限が必要です。サードパーティのアプリはこの権限を登録できません。
参照: https://developer.Android.com/about/versions/10/privacy/changes#non-resettable-device-ids
可能な解決策は、Android 5.1からTELEPHONY_SUBSCRIPTION_SERVICEを使用して、SIMシリアル番号を取得することです。以下の手順:
サブスクリプションオブジェクトからシムの詳細を取得します。
if ( isPermissionGranted(READ_PHONE_STATE) ) {
String simSerialNo="";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop_MR1) {
SubscriptionManager subsManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> subsList = subsManager.getActiveSubscriptionInfoList();
if (subsList!=null) {
for (SubscriptionInfo subsInfo : subsList) {
if (subsInfo != null) {
simSerialNo = subsInfo.getIccId();
}
}
}
} else {
TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
simSerialNo = tMgr.getSimSerialNumber();
}
}
これが役立つかどうかを確認してください
ターゲティングAndroid Q、サードパーティのアプリはIMEIにまったくアクセスできません。Android Qのドキュメントは、
Android Q以降、IMEIとシリアル番号の両方を含むデバイスのリセット不可能な識別子にアクセスするには、アプリにREAD_PRIVILEGED_PHONE_STATE特権権限が必要です。 https:// developer。 Android.com/preview/privacy/data-identifiers#device-ids
しかし、実際に実装しようとすると、次の例外が発生します。
Java.lang.SecurityException: getDeviceId: The user 10132 does not meet the requirements to access device identifiers.
誰かがこれをGoogleの課題追跡に報告しており、Google社員はこれは意図された動作であり、Q +のIMEIはシステムレベルのアプリでのみ利用できると述べています。
ステータス:修正されません(意図された動作)これは意図したとおりに機能しています。 IMEIは個人の識別子であり、ポリシーの問題としてアプリに付与されることはありません。回避策はありません。
Google docs によると。
リセットできないデバイス識別子の制限
Android 10以降、IMEIとシリアル番号の両方を含むデバイスのリセットできない識別子にアクセスするには、アプリにREAD_PRIVILEGED_PHONE_STATE特権権限が必要です。
注意:Google Playストアからインストールされたサードパーティアプリは、特権付きのアクセス許可を宣言できません。
したがって、imeiの代わりにAndroid一意のIDを取得できます。
String imei = "";
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
if (telephonyManager != null) {
try {
imei = telephonyManager.getImei();
} catch (Exception e) {
e.printStackTrace();
imei = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.Android_ID);
}
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
}
} else {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
if (telephonyManager != null) {
imei = telephonyManager.getDeviceId();
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
}
}
必要に応じて、携帯電話に仕事用プロファイルをインストールし、同じパッケージにアプリを含めたり、その逆を試みたりできます。
私が試してみましたが、このリポジトリをフォローすれば簡単です: https://github.com/googlesamples/Android-testdpc
仕事用プロファイルをインストールすると、アプリがこのプロファイルにインストールされ、IMEIにアクセスできるようになります。
そして今、昨日Android 10: https://github.com/Android/enterprise-samples/pull/29 に修正された別の例があります
彼らが述べた:アプリがデバイスまたはプロファイルの所有者のアプリである場合、アプリがAndroid= 10以上を対象としている場合でも、リセットできないデバイス識別子にアクセスするには、READ_PHONE_STATE権限のみが必要です。
デバイス所有者アプリとしてEMMを介して展開を試みましたが、成功しませんでした。
回答を投稿するのが遅いです。私の答えが誰かを助けると私はまだ信じています。 Android 10開発者がIMEI番号にアクセスすることを制限されています。
ソフトウェアIDを取得することで、代替ソリューションを利用できます。ソフトウェアIDを一意のIDとして使用できます。アプリケーションで使用するコードを以下に示します。
public static String getDeviceId(Context context) {
String deviceId;
if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.Android_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
} else {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.Android_ID);
}
}
return deviceId;
}