Android 如何獲取設(shè)備唯一標識
一. 先簡單總結(jié)一下比較常見的幾個解決方案的弊端:
1. IMEI
Android 10 中官方明確說明第三方應用無法獲取到IMEI碼:Android 10 中的隱私權(quán)變更,
Android 10 以下的版本,需要申請READ_PHONE_STATE權(quán)限。
2. Android ID
Android ID 不具有真正的唯一性,
ROOT、刷機、恢復出廠設(shè)置、不同簽名的應用等都會導致獲取的 Android ID 發(fā)生改變,
并且不同廠商定制的系統(tǒng)的BUG會導致不同的設(shè)備可能會產(chǎn)生相同的 Android ID。
3. MAC地址
Android 10 中 MAC地址具有隨機化的特征:Android 10 中的隱私權(quán)變更—MAC地址,
雖然目前大部分手機還不支持這個特性,但是隨著廠商的跟進,這個方案就會逐漸作廢
在上面這些設(shè)備自帶的標識不夠滿足需求時,我們就要采用另外的方法了。
二. uuid + 本地文件,實現(xiàn)一個通用解決方案
1. 思路
啟動APP時,檢查并讀取根目錄下保存有uuid的文件,若沒有該文件,則視為一臺新設(shè)備,創(chuàng)建文件并寫入uuid。
并且要確保卸載應用時,該文件不會被系統(tǒng)攜帶著刪除(這也是為什么要在根目錄下創(chuàng)建的原因)。
2. 解決手機訪問SDK權(quán)限問題
Android 6 以下,添加權(quán)限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Android 6 及其以上,則需要在此基礎(chǔ)上申請動態(tài)權(quán)限。
Android 10 及其以上,文件存儲機制修改成了沙盒模式,即應用只能訪問自己沙盒下的文件和公共媒體文件。
“得益”于沙盒機制,應用創(chuàng)建的文件屬于自己的沙盒,那么當應用卸載時,也會隨之刪除。
目前可以添加以下一行代碼解決沙盒問題:
<application ... android:requestLegacyExternalStorage="true">
這樣我們就能在“根目錄”創(chuàng)建自己文件了。
3. 適配 Android 11
Android 11 會強制執(zhí)行沙盒模式,在這之前存儲權(quán)限可以簡單的分為“禁止”和“允許”,在這之后存儲權(quán)限可以簡單的分為“禁止”、“允許訪問媒體文件”和“允許訪問所有文件”。
“允許訪問媒體文件”這是絕大多數(shù)應用能夠申請到的,而“允許訪問所有文件”只有文件管理類應用可以申請到。假如你不是該類應用但又申請了該權(quán)限,那么就會通不過Google Play的審核。
允許訪問所有文件:android.permission.MANAGE_EXTERNAL_STORAGE
介紹到這兒,其實一個方案已經(jīng)出來了:直接申請“允許訪問所有文件”權(quán)限,后果就是不能通過Google Play的審核。
另外還有一個辦法:我們暫時不升級SDK,針對 Android 10 (SDK 29)來開發(fā)應用,這樣的話由于“向后兼容機制”,我們的應用是能夠正常跑在 Android 11 系統(tǒng)上的。
4. Flutter 代碼實踐
import 'dart:io';
import 'package:uuid/uuid.dart';
// 本地持久化存儲uuid代碼實踐
class Storage {
static File file;
// 入口
static Future<String> init() async {
bool boolCreateFile = await createFile();
if (boolCreateFile) {
String uuid = await readData();
return uuid;
} else {
await writeData();
String uuid = await readData();
return uuid;
}
}
// 創(chuàng)建文件
static Future<bool> createFile() async {
file = File('/storage/emulated/0/uuid.ini'); // 指向根目錄下的文件uuid
bool exists = await file.exists();
return exists;
}
// 寫入數(shù)據(jù)
static writeData() async {
// 如果文件存在,會將原來的內(nèi)容覆蓋, 如果不存在,則創(chuàng)建文件
String uuid = await getUuid();
file.writeAsString('$uuid');
}
// 讀取文件
static Future<String> readData() async {
try {
String uuid = await file.readAsString();
return uuid;
} catch (e) {
return null;
}
}
// 獲取uuid,采用的插件:uuid
static Future<String> getUuid() async {
Uuid uuidObj = Uuid();
String uuid = uuidObj.v1();
return uuid;
}
}
以上就是Android 如何獲取設(shè)備唯一標識的詳細內(nèi)容,更多關(guān)于Android 獲取設(shè)備唯一標識的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android使用BroadcastReceiver監(jiān)聽網(wǎng)絡連接狀態(tài)的改變
這篇文章主要為大家詳細介紹了Android使用BroadcastReceiver監(jiān)聽網(wǎng)絡連接狀態(tài)的改變,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android ApplicationInfo 應用程序信息的詳解
這篇文章主要介紹了Android ApplicationInfo 應用程序信息的詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-10-10
6步輕松實現(xiàn)兩個listView聯(lián)動效果
這篇文章主要為大家詳細介紹了教大家通過6步輕松實現(xiàn)兩個listView聯(lián)動效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04

