Android 기기의 일련 번호를 찾는 방법은 무엇입니까?
Android 앱에 고유 ID를 사용해야하고 장치의 일련 번호가 좋은 후보라고 생각했습니다. 내 앱에서 Android 기기의 일련 번호를 어떻게 검색합니까?
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
getSystemService는 Activity 클래스의 메소드입니다. getDeviceID ()는 휴대 전화가 사용하는 라디오 (GSM 또는 CDMA)에 따라 장치의 MDN 또는 MEID를 반환합니다.
각 장치는 여기에 고유 한 값을 반환해야합니다 (전화라고 가정). 이것은 SIM 슬롯 또는 CDMA 라디오가있는 모든 Android 장치에서 작동합니다. 당신은 그 안드로이드 구동 전자 레인지를 스스로 소유하고 있습니다. ;-)
Dave Webb가 언급했듯이 Android 개발자 블로그에는 이를 다루는 기사 가 있습니다.
몇 가지 항목에 대한 추가 설명을 얻기 위해 Google의 누군가와 이야기했습니다. 위에서 언급 한 블로그 게시물에서 언급되지 않은 것을 발견했습니다.
- ANDROID_ID가 선호되는 솔루션입니다. ANDROID_ID는 Android <= 2.1 또는> = 2.3 버전에서 완벽하게 신뢰할 수 있습니다. 게시물에 언급 된 문제는 2.2 만입니다.
- 여러 제조업체의 여러 장치가 2.2의 ANDROID_ID 버그의 영향을받습니다.
- 내가 결정할 수있는 한, 영향을받는 모든 장치는 동일한 ANDROID_ID 인 9774d56d682e549c 입니다. 에뮬레이터에서보고 한 것과 동일한 장치 ID 인 btw도 있습니다.
- Google은 OEM이 대부분 또는 대부분의 기기에서이 문제를 해결했다고 생각하지만, 2011 년 4 월 초부터 ANDROID_ID가 손상된 기기를 찾는 것이 여전히 쉬운 지 확인할 수있었습니다.
Google의 권장 사항을 바탕으로 ANDROID_ID를 적절한 시드로 사용하여 필요에 따라 TelephonyManager.getDeviceId ()로 돌아가고 실패하면 임의로 생성 된 고유 UUID를 사용하여 각 장치에 대해 고유 한 UUID를 생성하는 클래스를 구현했습니다. 이는 앱을 다시 시작해도 지속되지만 앱을 다시 설치하지는 않습니다.
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 static volatile 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;
}
}
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 API를 사용하여 장치 일련 번호를 반환합니다.
String deviceId = Settings.System.getString(getContentResolver(),
Settings.System.ANDROID_ID);
그러나 Android ID가 고유 식별자라는 보장은 없습니다.
이 이 문제를 논의 안드로이드 개발자 블로그에 우수 게시물 .
그것은 사용을 권장하지 TelephonyManager.getDeviceId()
가 태블릿으로 전화하지 안드로이드 장치에 대한 작업을하지 않는 한, 그것은 필요 READ_PHONE_STATE
권한과 모든 휴대폰에서 안정적으로 작동하지 않습니다.
대신 다음 중 하나를 사용할 수 있습니다.
- 맥 주소
- 일련 번호
- ANDROID_ID
이 게시물은 각각의 장단점에 대해 설명하고 읽을 가치가 있으므로 사용하기에 가장 적합한 것을 해결할 수 있습니다.
장치에 고유하고 수명이 일정 (공장 초기화 또는 해킹 제외) 된 단순한 숫자의 경우 Settings.Secure.ANDROID_ID를 사용하십시오 .
String id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
사용 가능한 경우 기기 일련 번호 ( "시스템 설정 / 정보 / 상태"에 표시된 번호)를 사용하고 Android ID로 폴백하려면 :
String serialNumber = Build.SERIAL != Build.UNKNOWN ? Build.SERIAL : Secure.getString(getContentResolver(), Secure.ANDROID_ID);
IMEI는 양호하지만 휴대 전화가있는 Android 기기에서만 작동합니다. 전화가없는 태블릿 또는 기타 Android 기기에 대한 지원도 고려해야합니다.
다음과 같은 대안이 있습니다. 클래스 멤버, BT MAC, WLAN MAC 또는 더 나은 빌드-이들 모두의 조합.
내 블로그의 기사에서 이러한 세부 사항을 설명했습니다. http://www.pocketmagic.net/?p=1662
여기에는 시스템 업데이트를 통해 영구적이며 모든 장치에 존재하는 완벽한 실패 방지 ID에 대한 답변이 없기 때문에 (주로 Google의 개별 솔루션이 없기 때문에) 다음과 같은 방법을 게시하기로 결정했습니다. 사용 가능한 두 가지 식별자를 결합하여 런타임에 가장 적합한 항목을 선택하여 다음으로 가장 좋습니다.
코드 전에 3 가지 사실 :
TelephonyManager.getDeviceId()
(akaIMEI)는 비 GSM, 3G, LTE 등의 기기에서는 제대로 작동하지 않거나 전혀 작동 하지 않지만 SIM이 삽입되지 않았거나 SIM 슬롯이없는 경우에도 관련 하드웨어가있는 경우 항상 고유 ID를 반환 합니다 ( 일부 OEM 은이 작업을 수행했습니다).Gingerbread (Android 2.3)
android.os.Build.SERIAL
는 Android 정책에 따라 IMEI를 제공하지 않는 ( 즉, 위에서 언급 한 하드웨어 가없는) 모든 기기에 존재해야합니다 .사실 (2.)로 인해이 두 고유 식별자 중 하나 이상이 항상 존재 하며 SERIAL 은 IMEI와 동시에 존재할 수 있습니다.
참고 : 사실 (1.) 및 (2.)는 Google 진술을 기반으로합니다.
해결책
위의 사실을 통해 IMEI 바인딩 하드웨어가 있는지 확인하여 고유 식별자를 항상 가질 수 있으며 기존 SERIAL이 유효한지 확인할 수 없으므로 SERIAL로 넘어갑니다. 다음 정적 클래스는 이러한 존재를 확인하고 IMEI 또는 SERIAL을 사용하는 두 가지 방법을 제공합니다.
import java.lang.reflect.Method;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
public class IDManagement {
public static String getCleartextID_SIMCHECK (Context mContext){
String ret = "";
TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
if(isSIMAvailable(mContext,telMgr)){
Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId());
return telMgr.getDeviceId();
}
else{
Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);
// return Settings.Secure.ANDROID_ID;
return android.os.Build.SERIAL;
}
}
public static String getCleartextID_HARDCHECK (Context mContext){
String ret = "";
TelephonyManager telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
if(telMgr != null && hasTelephony(mContext)){
Log.i("DEVICE UNIQUE IDENTIFIER",telMgr.getDeviceId() + "");
return telMgr.getDeviceId();
}
else{
Log.i("DEVICE UNIQUE IDENTIFIER", Settings.Secure.ANDROID_ID);
// return Settings.Secure.ANDROID_ID;
return android.os.Build.SERIAL;
}
}
public static boolean isSIMAvailable(Context mContext,
TelephonyManager telMgr){
int simState = telMgr.getSimState();
switch (simState) {
case TelephonyManager.SIM_STATE_ABSENT:
return false;
case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
return false;
case TelephonyManager.SIM_STATE_PIN_REQUIRED:
return false;
case TelephonyManager.SIM_STATE_PUK_REQUIRED:
return false;
case TelephonyManager.SIM_STATE_READY:
return true;
case TelephonyManager.SIM_STATE_UNKNOWN:
return false;
default:
return false;
}
}
static public boolean hasTelephony(Context mContext)
{
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null)
return false;
//devices below are phones only
if (Build.VERSION.SDK_INT < 5)
return true;
PackageManager pm = mContext.getPackageManager();
if (pm == null)
return false;
boolean retval = false;
try
{
Class<?> [] parameters = new Class[1];
parameters[0] = String.class;
Method method = pm.getClass().getMethod("hasSystemFeature", parameters);
Object [] parm = new Object[1];
parm[0] = "android.hardware.telephony";
Object retValue = method.invoke(pm, parm);
if (retValue instanceof Boolean)
retval = ((Boolean) retValue).booleanValue();
else
retval = false;
}
catch (Exception e)
{
retval = false;
}
return retval;
}
}
사용에 대한 조언을 드리겠습니다 getCleartextID_HARDCHECK
. 반사가 사용자 환경에 들러 붙지 않으면 getCleartextID_SIMCHECK
방법을 대신 사용 하지만 특정 SIM 존재 요구에 맞게 조정해야합니다.
추신 : OEM은 Google 정책 (동일한 SERIAL을 가진 여러 장치) 에 대해 SERIAL을 버그로 처리 했으며 Google은 큰 OEM에서 알려진 사례가 하나 이상 있음을 밝혔습니다 (공개되지 않으며 어떤 브랜드를 모릅니다) 삼성이라고 생각합니다).
면책 조항 : 이것은 고유 한 장치 ID를 얻는 원래의 질문에 대답하지만 OP는 APP의 고유 ID가 필요하다는 말로 모호성을 도입했습니다. 이러한 시나리오의 경우 Android_ID가 더 좋더라도 2 개의 다른 ROM 설치를 통해 앱의 티타늄 백업 (같은 ROM 일 수도 있음) 후에는 작동하지 않습니다. 내 솔루션은 플래시 또는 공장 초기화와 무관 한 지속성을 유지하며 해킹 / 하드웨어 모드를 통해 IMEI 또는 SERIAL 탬 퍼링이 발생하는 경우에만 실패합니다.
위의 모든 접근 방식에는 문제가 있습니다. Google i / o에서 Reto Meier는 대부분의 개발자가 설치 과정에서 사용자를 추적해야하는이 문제에 접근하는 방법에 대한 강력한 답변을 발표했습니다.
이 방법을 사용하면 익명의 안전한 사용자 ID를 제공하여 다른 기기 (기본 Google 계정 기반의 태블릿 포함)와 동일한 기기의 설치에서 지속적으로 유지됩니다. 기본 접근 방식은 임의의 사용자 ID를 생성하고이를 앱 공유 환경 설정에 저장하는 것입니다. 그런 다음 Google 백업 에이전트를 사용하여 Google 계정에 연결된 공유 환경 설정을 클라우드에 저장합니다.
전체 접근 방식을 살펴 보겠습니다. 먼저 Android 백업 서비스를 사용하여 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는 이제 사용자가 장치를 전환하더라도 설치 전체에서 지속됩니다.
이 방법에 대한 자세한 내용은 http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html에서 Reto의 대화를 참조 하십시오 .
백업 에이전트를 구현하는 방법에 대한 자세한 내용은 개발자 사이트 ( http://developer.android.com/guide/topics/data/backup.html)를 참조 하십시오. 백업과 마찬가지로 테스트 하단의 섹션을 특히 권장합니다 즉시 발생하지 않으므로 테스트하려면 백업을 수행해야합니다.
다른 방법은 권한이없는 앱에서 / 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 파일을 열고 문자를 읽으십시오. 모든 장치에이 파일이있는 것은 아니기 때문에 예외 처리기로 래핑해야합니다.
최소한 다음 장치는이 파일을 세계에서 읽을 수있는 것으로 알려져 있습니다.
- 갤럭시 넥서스
- 넥서스 S
- 모토로라 Xoom 3g
- 도시바 AT300
- HTC 하나 V
- 미니 MK802
- 삼성 갤럭시 S II
또한 내 블로그 게시물을 볼 수 있습니다 : http://insitusec.blogspot.com/2013/01/leaking-android-hardware-serial-number.html 여기서 정보에 사용할 수있는 다른 파일에 대해 논의합니다.
@haserman이 말한 것처럼 :
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
그러나 매니페스트 파일에 권한을 포함해야합니다.
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
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이 제안한이 방법을 강력하게 권장합니다.
Build.SERIAL
비우 거나 때로는 장치 설정에서 볼 수 있는 것과 다른 값 ( proof 1 , proof 2 )을 반환 할 수 있으므로 완전히 신뢰할 수는 없지만 가장 간단한 방법 입니다.
장치 제조업체 및 Android 버전에 따라 그 수를 얻는 방법은 여러 가지가 있으므로 단일 gist 에서 찾을 수있는 모든 가능한 솔루션을 컴파일하기로 결정했습니다 . 다음은 간단한 버전입니다.
public static String getSerialNumber() {
String serialNumber;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serialNumber = (String) get.invoke(c, "gsm.sn1");
if (serialNumber.equals(""))
serialNumber = (String) get.invoke(c, "ril.serialnumber");
if (serialNumber.equals(""))
serialNumber = (String) get.invoke(c, "ro.serialno");
if (serialNumber.equals(""))
serialNumber = (String) get.invoke(c, "sys.serialnumber");
if (serialNumber.equals(""))
serialNumber = Build.SERIAL;
// If none of the methods above worked
if (serialNumber.equals(""))
serialNumber = null;
} catch (Exception e) {
e.printStackTrace();
serialNumber = null;
}
return serialNumber;
}
이 질문은 오래되었지만 한 줄의 코드로 수행 할 수 있음을 알고 있습니다.
String deviceID = Build.SERIAL;
위의 @emmby에 의해 게시 된 예제 클래스가 훌륭한 출발점이라는 것을 알았습니다. 그러나 다른 포스터에서 언급했듯이 몇 가지 결함이 있습니다. 가장 중요한 것은 UUID를 불필요하게 XML 파일로 유지 한 다음 항상이 파일에서 UUID를 검색한다는 것입니다. 이것은 클래스를 쉽게 해킹 할 수있는 기회를 제공합니다. 루팅 된 전화를 가진 사람은 누구나 XML 파일을 편집하여 새로운 UUID를 만들 수 있습니다.
나는 코드가 절대적으로 필요한 경우에만 (즉 무작위로 생성 된 UUID를 사용할 때) XML로 유지되도록 @Brill Pappin의 답변에 따라 논리를 다시 팩토링하도록 코드를 업데이트했습니다.
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 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) || (androidId == null) ) {
final String deviceId = ((TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE )).getDeviceId();
if (deviceId != null)
{
uuid = UUID.nameUUIDFromBytes(deviceId.getBytes("utf8"));
}
else
{
uuid = UUID.randomUUID();
// Write the value out to the prefs file so it persists
prefs.edit().putString(PREFS_DEVICE_ID, uuid.toString() ).commit();
}
}
else
{
uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8"));
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
}
}
}
/**
* 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;
}
예. 장치 하드웨어 일련 번호이며 고유합니다. 따라서 API 레벨 2.3 이상에서는 android.os.Build.ANDROID_ID 를 사용 하여 얻을 수 있습니다. 2.3 API 레벨 미만의 경우 TelephonyManager.getDeviceID ()를 사용하십시오 .
이 http://android-developers.blogspot.in/2011/03/identifying-app-installations.html을 읽을 수 있습니다
참고 URL : https://stackoverflow.com/questions/2322234/how-to-find-serial-number-of-android-device
'IT story' 카테고리의 다른 글
PreferenceFragmentCompat에는 preferenceTheme을 설정해야합니다. (0) | 2020.07.23 |
---|---|
iOS 설정 번들에 라이센스 섹션을 추가하는 가장 좋은 방법 (0) | 2020.07.23 |
SQL Server 데이터베이스에서 ID 증가 (0) | 2020.07.23 |
div 안에 범위 요소를 가로로 가운데에 배치하는 방법 (0) | 2020.07.23 |
번들을 통해 객체를 보내는 방법 (0) | 2020.07.23 |