android - studio - numero de serie lg g4
¿Cómo encontrar el número de serie del dispositivo Android? (15)
Como Dave Webb menciona, el android-developers.blogspot.com/2011/03/… que cubre esto.
Hablé con alguien en Google para obtener aclaraciones adicionales sobre algunos artículos. Esto es lo que descubrí que NO se menciona en la publicación de blog mencionada anteriormente:
- ANDROID_ID es la solución preferida. ANDROID_ID es perfectamente confiable en las versiones de Android <= 2.1 o> = 2.3. Solo 2.2 tiene los problemas mencionados en la publicación.
- Varios dispositivos de varios fabricantes se ven afectados por el error ANDROID_ID en 2.2.
- Hasta donde he podido determinar, todos los dispositivos afectados tienen el mismo ANDROID_ID , que es 9774d56d682e549c . Que también es el mismo ID de dispositivo informado por el emulador, por cierto.
- Google cree que los OEM han solucionado el problema para muchos o la mayoría de sus dispositivos, pero pude verificar que, al menos hasta principios de abril de 2011, todavía es bastante fácil encontrar dispositivos que tengan el ANDROID_ID dañado.
En base a las recomendaciones de Google, implementé una clase que generará un UUID único para cada dispositivo, usando ANDROID_ID como semilla, donde sea apropiado, recurriendo a TelephonyManager.getDeviceId () según sea necesario, y si eso falla, recurriendo a un UUID único generado al azar esto se mantiene en todos los reinicios de la aplicación (pero no en las reinstalaciones de la aplicación).
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;
}
}
Necesito usar una identificación única para una aplicación de Android y pensé que el número de serie para el dispositivo sería un buen candidato. ¿Cómo recupero el número de serie de un dispositivo Android en mi aplicación?
Como dice @haserman:
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
Pero es necesario incluir el permiso en el archivo de manifiesto:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Dado que ninguna respuesta aquí menciona una identificación perfecta a prueba de fallas que sea PERSISTENTE a través de actualizaciones del sistema y exista en TODOS los dispositivos (principalmente debido al hecho de que no hay una solución individual de Google), decidí publicar un método que sea la mejor alternativa combinando dos de los identificadores disponibles, y un cheque para elegir entre ellos en tiempo de ejecución.
Antes del código, 3 hechos:
TelephonyManager.getDeviceId()
(akaIMEI) no funcionará bien o nada para dispositivos que no sean GSM, 3G, LTE, etc., pero siempre devolverá una ID única cuando haya hardware relacionado , incluso cuando no se haya insertado una SIM o incluso cuando no existe ranura SIM (algunos OEM lo han hecho).Dado que Gingerbread (Android 2.3)
android.os.Build.SERIAL
debe existir en cualquier dispositivo que no proporcione IMEI , es decir, no tiene el hardware mencionado anteriormente, según la política de Android.Debido al hecho (2.), al menos uno de estos dos identificadores únicos SIEMPRE estará presente , y SERIAL puede estar presente al mismo tiempo que IMEI.
Nota: Los hechos (1.) y (2.) se basan en declaraciones de Google
SOLUCIÓN
Con los hechos anteriores, siempre se puede tener un identificador único comprobando si hay hardware vinculado al IMEI, y recurrir a SERIAL cuando no lo es, ya que no se puede verificar si el SERIAL existente es válido. La siguiente clase estática presenta 2 métodos para verificar dicha presencia y usar IMEI o 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
usar getCleartextID_HARDCHECK
. Si el reflejo no se pega en su entorno, use el método getCleartextID_SIMCHECK
, pero tenga en cuenta que debe adaptarse a sus necesidades específicas de presencia de SIM.
PD : Tenga en cuenta que los fabricantes de equipos originales han logrado interceptar SERIAL en contra de la política de Google (múltiples dispositivos con el mismo SERIAL) y Google, como se indicó, hay al menos un caso conocido en un OEM grande (no divulgado y no sé qué marca es cualquiera, supongo que Samsung).
Descargo de responsabilidad : Esto responde a la pregunta original de obtener una ID de dispositivo única, pero el OP presentó ambigüedad al afirmar que necesita una ID única para una APLICACIÓN. Incluso si para tales escenarios Android_ID fuera mejor, NO FUNCIONARía después de, digamos, una copia de seguridad de Titanium de una aplicación a través de 2 instalaciones de ROM diferentes (incluso puede ser la misma ROM). Mi solución mantiene la persistencia que es independiente de un flash o restablecimiento de fábrica, y solo fallará cuando la alteración IMEI o SERIAL se produzca a través de modificaciones de hardware / hacks.
El IMEI es bueno, pero solo funciona en dispositivos Android con teléfono. También debe considerar la compatibilidad con tabletas u otros dispositivos Android que no tengan teléfono.
Tienes algunas alternativas como: compilar miembros de la clase, BT MAC, WLAN MAC, o incluso mejor, una combinación de todos estos.
He explicado estos detalles en un artículo en mi blog, ver: http://www.pocketmagic.net/?p=1662
Encontré que la clase de ejemplo publicada por @emmby arriba es un gran punto de partida. Pero tiene un par de defectos, como se menciona en otros carteles. La principal es que persiste el UUID en un archivo XML innecesariamente y, a partir de entonces, siempre lo recupera de este archivo. Esto establece la clase abierta a un truco fácil: cualquier persona con un teléfono rooteado puede editar el archivo XML para obtener un UUID nuevo.
He actualizado el código para que solo persista en XML si es absolutamente necesario (es decir, cuando se usa un UUID generado aleatoriamente) y se vuelve a factorizar la lógica según la respuesta de @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;
}
Hay android-developers.blogspot.com/2011/03/… .
Se recomienda no usar TelephonyManager.getDeviceId()
ya que no funciona en dispositivos Android que no son teléfonos, como tabletas, requiere el permiso READ_PHONE_STATE
y no funciona de manera confiable en todos los teléfonos.
En su lugar, puede usar uno de los siguientes:
- Dirección MAC
- Número de serie
- ANDROID_ID
La publicación analiza los pros y los contras de cada uno y vale la pena su lectura para que pueda determinar cuál sería la mejor para su uso.
Hay problemas con todos los enfoques anteriores. En Google i / o, Reto Meier dio a conocer una respuesta sólida sobre cómo abordar esto, que debería cumplir con la mayoría de los desarrolladores y hacer un seguimiento de los usuarios en las instalaciones.
Este enfoque le dará una identificación de usuario anónima y segura que será persistente para el usuario en diferentes dispositivos (incluidas las tabletas, en base a la cuenta primaria de Google) y entre las instalaciones en el mismo dispositivo. El enfoque básico es generar un ID de usuario aleatorio y almacenarlo en las preferencias compartidas de las aplicaciones. A continuación, utiliza el agente de copia de seguridad de Google para almacenar las preferencias compartidas vinculadas a la cuenta de Google en la nube.
Vamos a pasar por el enfoque completo. Primero, necesitamos crear una copia de seguridad para nuestras Preferencias Compartidas usando el Servicio de Copia de Seguridad de Android. Comience registrando su aplicación a través de este enlace: http://developer.android.com/google/backup/signup.html
Google le dará una clave de servicio de respaldo que debe agregar al manifiesto. También necesita decirle a la aplicación que use BackupAgent de la siguiente manera:
<application android:label="MyApplication"
android:backupAgent="MyBackupAgent">
...
<meta-data android:name="com.google.android.backup.api_key"
android:value="your_backup_service_key" />
</application>
Luego debe crear el agente de respaldo y decirle que use el agente auxiliar para las preferencias compartidas:
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);
}
}
Para completar la copia de seguridad, debe crear una instancia de BackupManager en su actividad principal:
BackupManager backupManager = new BackupManager(context);
Finalmente, cree una ID de usuario, si aún no existe, y almacénela en 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;
}
Este User_ID ahora será persistente en todas las instalaciones, incluso si el usuario cambia de dispositivo.
Para obtener más información sobre este enfoque, consulte la charla de Reto aquí http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html
Y para obtener todos los detalles sobre cómo implementar el agente de respaldo, consulte el sitio para desarrolladores aquí: http://developer.android.com/guide/topics/data/backup.html Recomiendo especialmente la sección de la parte inferior de las pruebas, como lo hace la copia de seguridad no ocurre de forma instantánea, por lo que para probar tiene que forzar la copia de seguridad.
Id. De dispositivo único del dispositivo con sistema operativo Android como cadena.
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);
}
pero recomiendo este método sugerido por Google ::
Otra forma es usar / sys / class / android_usb / android0 / iSerial en una aplicación sin permisos de ningún tipo.
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
Para hacer esto en Java uno simplemente usaría FileInputStream para abrir el archivo iSerial y leer los caracteres. Solo asegúrese de envolverlo en un manejador de excepciones porque no todos los dispositivos tienen este archivo.
Al menos los siguientes dispositivos son conocidos por tener este archivo de lectura mundial:
- Galaxy Nexus
- Nexus S
- Motorola Xoom 3g
- Toshiba AT300
- HTC One V
- Mini MK802
- Samsung Galaxy S II
También puede ver mi publicación en el blog aquí: http://insitusec.blogspot.com/2013/01/leaking-android-hardware-serial-number.html donde discuto qué otros archivos están disponibles para obtener información.
Para un número simple que sea exclusivo del dispositivo y constante durante su ciclo de vida (salvo que se restablezca la Settings.Secure.ANDROID_ID fábrica o piratee), use Settings.Secure.ANDROID_ID .
String id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Para usar el número de serie del dispositivo (el que se muestra en "Configuración del sistema / Acerca de / Estado") si está disponible y retroceda a la ID de Android:
String serialNumber = Build.SERIAL != Build.UNKNOWN ? Build.SERIAL : Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Sé que esta pregunta es antigua, pero se puede hacer en una línea de código
String deviceID = Build.SERIAL;
Sí. Es un número de serie de hardware del dispositivo y es único. Entonces, en el nivel 2.3 de la API, puedes usar android.os.Build.ANDROID_ID para obtenerlo. Para un nivel inferior a 2.3 API, use TelephonyManager.getDeviceID () .
puedes leer esto http://android-developers.blogspot.in/2011/03/identifying-app-installations.html
String deviceId = Settings.System.getString(getContentResolver(),
Settings.System.ANDROID_ID);
Aunque no se garantiza que el ID de Android sea un identificador único.
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) {
}
Este código devuelve el número de serie del dispositivo con una API de Android oculta.
TelephonyManager tManager = (TelephonyManager)myActivity.getSystemService(Context.TELEPHONY_SERVICE);
String uid = tManager.getDeviceId();
getSystemService es un método de la clase Activity. getDeviceID () devolverá el MDN o MEID del dispositivo según la radio que use el teléfono (GSM o CDMA).
Cada dispositivo DEBE devolver un valor único aquí (suponiendo que sea un teléfono). Esto debería funcionar para cualquier dispositivo con una ranura sim o radio CDMA. Estás solo con ese microondas con Android ;-)