当前位置: 移动技术网 > IT编程>移动开发>Android > 详解Android获取设备唯一ID的几种方式

详解Android获取设备唯一ID的几种方式

2019年07月24日  | 移动技术网IT编程  | 我要评论

滚球游戏大全,李本深,不良情侣剧情介绍

先来看看几种比较单一的方式:

imei

方式:telephonymanager.getdeviceid():

问题

  1. 范围:只能支持拥有通话功能的设备,对于平板不可以。
  2. 持久性:返厂,数据擦除的时候不彻底,保留了原来的标识。
  3. 权限:需要权限:android.permission.read_phone_state
  4. bug: 有些厂家的实现有bug,返回一些不可用的数据

 mac地址

access_wifi_state权限

有些设备没有wifi,或者蓝牙,就不可以,如果wifi没有打开,硬件也不会返回mac地址,不建议使用

android_id
2.2(froyo,8)版本系统会不可信,来自主要生产厂商的主流手机,至少有一个普遍发现的bug,这些有问题的手机相同的android_id: 9774d56d682e549c

但是如果返厂的手机,或者被root的手机,可能会变

serial number

从android 2.3 (“gingerbread”)开始可用,可以通过android.os.build.serial获取,对于没有通话功能的设备,它会返回一个唯一的device id,

以下几个是stackoverflow上评论较多的几个,没贴完,还有其他,综合的,用到以上的部分方式:

地址:

有兴趣的朋友可以再仔细看看

支持率比较高的(支持票数157):androidid --> 剔除2.2版本(api 8)中有问题的手机,使用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; 
  } 
} 

根据版本进行判断的方式:serial序列号-->uuid (支持数31)

通过serial 即可,在覆盖率上,你已经成功的获得了98.4%的用户,剩下的1.6%的用户系统是在9 以下的。

通过androidid获取,前面已经说过,在8上,有些商家的手机会有一些bug,返回相同的androidid,如果serial和androidid都不行

/** 
 * 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 phone 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! 
  // http://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 phone, 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 e) 
  { 
    // string needs to be initialized 
    serial = "serial"; // some value 
  } 
 
  // thanks @joe! 
  // http://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(); 
} 

不用read_phone_state权限直接获取rom信息的方式:(支持率较低 16)

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 

最后贴上自己在项目中用的:

public static string getdeviceid(context context) { 
    string deviceid = ""; 
    if (deviceid != null && !"".equals(deviceid)) { 
     return deviceid; 
   } 
    if (deviceid == null || "".equals(deviceid)) { 
      try { 
        deviceid = getlocalmac(context).replace(":", ""); 
      } catch (exception e) { 
        e.printstacktrace(); 
      } 
    } 
    if (deviceid == null || "".equals(deviceid)) { 
      try { 
        deviceid = getandroidid(context); 
      } catch (exception e) { 
        e.printstacktrace(); 
      } 
    } 
    if (deviceid == null || "".equals(deviceid)) { 
       
      if (deviceid == null || "".equals(deviceid)) { 
        uuid uuid = uuid.randomuuid(); 
        deviceid = uuid.tostring().replace("-", ""); 
        writedeviceid(deviceid); 
      } 
    } 
    return deviceid; 
  } 
// imei码 
  private static string getimiestatus(context context) { 
    telephonymanager tm = (telephonymanager) context 
        .getsystemservice(context.telephony_service); 
    string deviceid = tm.getdeviceid(); 
    return deviceid; 
  } 
 
  // mac地址 
  private static string getlocalmac(context context) { 
    wifimanager wifi = (wifimanager) context 
        .getsystemservice(context.wifi_service); 
    wifiinfo info = wifi.getconnectioninfo(); 
    return info.getmacaddress(); 
  } 
 
  // android id 
  private static string getandroidid(context context) { 
    string androidid = settings.secure.getstring( 
        context.getcontentresolver(), settings.secure.android_id); 
    return androidid; 
  } 
 
  public static void savedeviceid(string str) { 
    try { 
      fileoutputstream fos = new fileoutputstream(file); 
      writer out = new outputstreamwriter(fos, "utf-8"); 
      out.write(str); 
      out.close(); 
    } catch (ioexception e) { 
      e.printstacktrace(); 
    } 
  } 
 
  public static string readdeviceid() { 
    stringbuffer buffer = new stringbuffer(); 
    try { 
      fileinputstream fis = new fileinputstream(file); 
      inputstreamreader isr = new inputstreamreader(fis, "utf-8"); 
      reader in = new bufferedreader(isr); 
      int i; 
      while ((i = in.read()) > -1) { 
        buffer.append((char) i); 
      } 
      in.close(); 
      return buffer.tostring(); 
    } catch (ioexception e) { 
      e.printstacktrace(); 
      return null; 
    } 
  } 

对于获取设备唯一id并没有绝对的方案,这一点在android的官方博客中也提到了,不过以上几种方案,应该可以满足平时的需求,大家可以选择其中自己认为比较好的,用于自己的项目中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网