【移動(dòng)應(yīng)用開發(fā)技術(shù)】android如何獲取設(shè)備唯一標(biāo)識(shí)_第1頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android如何獲取設(shè)備唯一標(biāo)識(shí)_第2頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android如何獲取設(shè)備唯一標(biāo)識(shí)_第3頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android如何獲取設(shè)備唯一標(biāo)識(shí)_第4頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android如何獲取設(shè)備唯一標(biāo)識(shí)_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

【移動(dòng)應(yīng)用開發(fā)技術(shù)】android如何獲取設(shè)備唯一標(biāo)識(shí)

這篇文章主要介紹了android如何獲取設(shè)備唯一標(biāo)識(shí),具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。具體如下:/**

*

deviceID的組成為:渠道標(biāo)志+識(shí)別符來源標(biāo)志+hash后的終端識(shí)別符

*

*

渠道標(biāo)志為:

*

1,andriod(a)

*

*

識(shí)別符來源標(biāo)志:

*

1,

wifi

mac地址(wifi);

*

2,

IMEI(imei);

*

3,

序列號(hào)(sn);

*

4,

id:隨機(jī)碼。若前面的都取不到時(shí),則隨機(jī)生成一個(gè)隨機(jī)碼,需要緩存。

*

*

@param

context

*

@return

*/

public

static

String

getDeviceId(Context

context)

{

StringBuilder

deviceId

=

new

StringBuilder();

//

渠道標(biāo)志

deviceId.append("a");

try

{

//wifi

mac地址

WifiManager

wifi

=

(WifiManager)

context.getSystemService(Context.WIFI_SERVICE);

WifiInfo

info

=

wifi.getConnectionInfo();

String

wifiMac

=

info.getMacAddress();

if(!isEmpty(wifiMac)){

deviceId.append("wifi");

deviceId.append(wifiMac);

PALog.e("getDeviceId

:

",

deviceId.toString());

return

deviceId.toString();

}

//IMEI(imei)

TelephonyManager

tm

=

(TelephonyManager)

context.getSystemService(Context.TELEPHONY_SERVICE);

String

imei

=

tm.getDeviceId();

if(!isEmpty(imei)){

deviceId.append("imei");

deviceId.append(imei);

PALog.e("getDeviceId

:

",

deviceId.toString());

return

deviceId.toString();

}

//序列號(hào)(sn)

String

sn

=

tm.getSimSerialNumber();

if(!isEmpty(sn)){

deviceId.append("sn");

deviceId.append(sn);

PALog.e("getDeviceId

:

",

deviceId.toString());

return

deviceId.toString();

}

//如果上面都沒有,

則生成一個(gè)id:隨機(jī)碼

String

uuid

=

getUUID(context);

if(!isEmpty(uuid)){

deviceId.append("id");

deviceId.append(uuid);

PALog.e("getDeviceId

:

",

deviceId.toString());

return

deviceId.toString();

}

}

catch

(Exception

e)

{

e.printStackTrace();

deviceId.append("id").append(getUUID(context));

}

PALog.e("getDeviceId

:

",

deviceId.toString());

return

deviceId.toString();

}

/**

*

得到全局唯一UUID

*/

public

static

String

getUUID(Context

context){

SharedPreferences

mShare

=

getSysShare(context,

"sysCacheMap");

if(mShare

!=

null){

uuid

=

mShare.getString("uuid",

"");

}

if(isEmpty(uuid)){

uuid

=

UUID.randomUUID().toString();

saveSysMap(context,

"sysCacheMap",

"uuid",

uuid);

}

PALog.e(tag,

"getUUID

:

"

+

uuid);

return

uuid;

}有時(shí)需要對(duì)用戶設(shè)備進(jìn)行標(biāo)識(shí),所以希望能夠得到一個(gè)穩(wěn)定可靠并且唯一的識(shí)別碼。雖然Android系統(tǒng)中提供了這樣設(shè)備識(shí)別碼,但是由于android系統(tǒng)版本、廠商定制系統(tǒng)中的Bug等限制,穩(wěn)定性和唯一性并不理想。而通過其他硬件信息標(biāo)識(shí)也因?yàn)橄到y(tǒng)版本、手機(jī)硬件等限制存在不同程度的問題。下面收集了一些“有能力”或“有一定能力”作為設(shè)備標(biāo)識(shí)的串碼。DEVICE_ID這是Android系統(tǒng)為開發(fā)者提供的用于標(biāo)識(shí)手機(jī)設(shè)備的串號(hào),也是各種方法中普適性較高的,可以說幾乎所有的設(shè)備都可以返回這個(gè)串號(hào),并且唯一性良好。這個(gè)DEVICE_ID可以同通過下面的方法獲?。篢elephonyManager

tm

=

(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

String

DEVICE_ID

=

tm.getDeviceId();假設(shè)我們確實(shí)需要用到真實(shí)設(shè)備的標(biāo)識(shí),可能就需要用到DEVICE_ID。在以前,我們的Android設(shè)備是手機(jī),這個(gè)DEVICE_ID可以同通過TelephonyManager.getDeviceId()獲取,它根據(jù)不同的手機(jī)設(shè)備返回IMEI,MEID或者ESN碼,但它在使用的過程中會(huì)遇到很多問題:非手機(jī)設(shè)備:如果只帶有Wifi的設(shè)備或者音樂播放器沒有通話的硬件功能的話就沒有這個(gè)DEVICE_ID權(quán)限:獲取DEVICE_ID需要READ_PHONE_STATE權(quán)限,但如果我們只為了獲取它,沒有用到其他的通話功能,那這個(gè)權(quán)限有點(diǎn)大才小用bug:在少數(shù)的一些手機(jī)設(shè)備上,該實(shí)現(xiàn)有漏洞,會(huì)返回垃圾,如:zeros或者asterisks的產(chǎn)品MACADDRESS可以使用手機(jī)Wifi或藍(lán)牙的MAC地址作為設(shè)備標(biāo)識(shí),但是并不推薦這么做,原因有以下兩點(diǎn):硬件限制:并不是所有的設(shè)備都有Wifi和藍(lán)牙硬件,硬件不存在自然也就得不到這一信息。獲取的限制:如果Wifi沒有打開過,是無法獲取其Mac地址的;而藍(lán)牙是只有在打開的時(shí)候才能獲取到其Mac地址。獲取WifiMac地址:獲取藍(lán)牙Mac地址:SimSerialNumber裝有SIM卡的Android2.3設(shè)備,可以通過下面的方法獲取到SimSerialNumber:TelephonyManager

tm

=

(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

String

SimSerialNumber

=

tm.getSimSerialNumber();注意:對(duì)于CDMA設(shè)備,返回的是一個(gè)空值!ANDROID_ID在設(shè)備首次啟動(dòng)時(shí),系統(tǒng)會(huì)隨機(jī)生成一個(gè)64位的數(shù)字,并把這個(gè)數(shù)字以16進(jìn)制字符串的形式保存下來,這個(gè)16進(jìn)制的字符串就是ANDROID_ID,當(dāng)設(shè)備被wipe后該值會(huì)被重置??梢酝ㄟ^下面的方法獲?。篿mport

vider.Settings;

String

ANDROID_ID

=

Settings.System.getString(getContentResolver(),

Settings.System.ANDROID_ID);ANDROID_ID可以作為設(shè)備標(biāo)識(shí),但需要注意:廠商定制系統(tǒng)的Bug:不同的設(shè)備可能會(huì)產(chǎn)生相同的ANDROID_ID:9774d56d682e549c。廠商定制系統(tǒng)的Bug:有些設(shè)備返回的值為null。設(shè)備差異:對(duì)于CDMA設(shè)備,ANDROID_ID和TelephonyManager.getDeviceId()返回相同的值。它在Android<=2.1orAndroid>=2.3的版本是可靠、穩(wěn)定的,但在2.2的版本并不是100%可靠的SerialNumberAndroid系統(tǒng)2.3版本以上可以通過下面的方法得到SerialNumber,且非手機(jī)設(shè)備也可以通過該接口獲取。String

SerialNumber

=

android.os.Build.SERIAL;以上幾種方式都或多或少存在一定的局限性或者Bug,如果并不是確實(shí)需要對(duì)硬件本身進(jìn)行綁定,使用自己生成的UUID也是一個(gè)不錯(cuò)的選擇,因?yàn)樵摲椒o需訪問設(shè)備的資源,也跟設(shè)備類型無關(guān)。InstalltionID這種方式的原理是在程序安裝后第一次運(yùn)行時(shí)生成一個(gè)ID,該方式和設(shè)備唯一標(biāo)識(shí)不一樣,不同的應(yīng)用程序會(huì)產(chǎn)生不同的ID,同一個(gè)程序重新安裝也會(huì)不同。所以這不是設(shè)備的唯一ID,但是可以保證每個(gè)用戶的ID是不同的??梢哉f是用來標(biāo)識(shí)每一份應(yīng)用程序的唯一ID(即InstalltionID),可以用來跟蹤應(yīng)用的安裝數(shù)量等。GoogleDeveloperBlog提供了這樣的一個(gè)框架: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();

}

}設(shè)備唯一ID上文可以看出,Android系統(tǒng)中并沒有可以可靠獲取所有廠商設(shè)備唯一ID的方法,各個(gè)方法都有自己的使用范圍和局限性,這也是目前流行的Android系統(tǒng)版本過多,設(shè)備也是來自不同廠商,且沒有統(tǒng)一標(biāo)準(zhǔn)等原因造成的。從目前發(fā)展來看,Android系統(tǒng)多版本共存還會(huì)持續(xù)較長的時(shí)間,而Android系統(tǒng)也不會(huì)被某個(gè)設(shè)備生產(chǎn)廠商壟斷,長遠(yuǎn)看Android基礎(chǔ)系統(tǒng)將會(huì)趨于穩(wěn)定,設(shè)備標(biāo)識(shí)也將會(huì)作為系統(tǒng)基礎(chǔ)部分而標(biāo)準(zhǔn)化,屆時(shí)這一問題才有望徹底解決。目前的解決辦法,比較可行的是一一適配,在保證大多數(shù)設(shè)備方便的前提下,如果獲取不到,使用其他備選信息作為標(biāo)識(shí),即自己再封裝一個(gè)設(shè)備ID出來,通過內(nèi)部算法保證盡量和設(shè)備硬件信息相關(guān),以及標(biāo)識(shí)的唯一性??偨Y(jié)綜合以上所述,為了實(shí)現(xiàn)在設(shè)備上更通用的獲取設(shè)備唯一標(biāo)識(shí),我們可以實(shí)現(xiàn)這樣的一個(gè)類,為每個(gè)設(shè)備產(chǎn)生唯一的UUID,以ANDROID_ID為基礎(chǔ),在獲取失敗時(shí)以TelephonyManager.getDeviceId()為備選方法,如果再失敗,使用UUID的生成策略。重申下,以下方法是生成DeviceID,在大多數(shù)情況下InstalltionID能夠滿足我們的需求,但是如果確實(shí)需要用到DeviceID,那可以通過以下方式實(shí)現(xiàn):import

android.content.Context;

import

android.content.SharedPreferences;

import

vider.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))

{

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

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論