最近有个需求,要获取设备唯一id,Android一直没有什么完善的方案获取设备唯一不变的id,我就结合了几种方案组成了一下:
1. 首先获取IMEI; IMEI获取失败后
2. 获取SN序列号,序列号失败后
3. 随机生成一串UUID存储在内存中
经过测试,在小米手机上存储会提示open failed: EACCES (Permission denied) 查了很多资料,常用的方案都做过尝试,例如:添加android:requestLegacyExternalStorage=”true”到清单中等方案都没有解决问题,下面说说我的解决方案:
给予所有文件读写权限,直接上代码
1. 清单文件中加入
这一步特别重要,不给这个权限,跳转后的按钮灰色无法点击
2. 只贴所有文件读写权限代码,基本读写权限还是需要动态申请的
private static final int REQUEST_CODE = 1024;
//Android 11需要申请所有文件读写权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//是否有所有问读写权限
if (Environment.isExternalStorageManager()) {
//有所有文件读写权限 TODO something
}else {
//跳转到打开权限页面
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + mContext.getPackageName()));
startActivityForResult(intent, REQUEST_CODE);
}
}else {
//TODO something
}
3. 开启权限后返回
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode) {
case REQUEST_CODE:
if (Environment.isExternalStorageManager()) {
//有了权限 TODO
}else {
ToastUtil.showMessage("用户拒绝权限");
}
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
到这里,文件读写权限就有了
下面为我的获取设备唯一不变id的代码
1 、
public static String getDeviceId() {
StringBuilder deviceId = new StringBuilder();
// 渠道标志
deviceId.append("a");
try {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imeis;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
imeis = tm.getImei();
} else {
imeis = tm.getDeviceId();
}
if (!TextUtils.isEmpty(imeis)) {
deviceId.append("imei");
deviceId.append(imeis);
Log.e("getDeviceId : ", deviceId.toString());
return deviceId.toString();
}
//序列号(sn)
String sn = tm.getSimSerialNumber();
if (!TextUtils.isEmpty(sn)) {
deviceId.append("sn");
deviceId.append(sn);
Log.e("getDeviceId : ", deviceId.toString());
return deviceId.toString();
}
//如果上面都没有, 则生成一个id:随机码
String uuid = getUUID(context);
if (!TextUtils.isEmpty(uuid)) {
deviceId.append("sdid");
deviceId.append(uuid);
Log.e("getDeviceId : ", deviceId.toString());
return deviceId.toString();
}
} catch (Exception e) {
e.printStackTrace();
deviceId.append("esdid").append(getUUID(context));
}
Log.e("getDeviceId : ", deviceId.toString());
return deviceId.toString();
}
2.
public static String getUUID() {
try {
String uuid = loadData();
if (TextUtils.isEmpty(uuid)) {
uuid = UUID.randomUUID().toString();
saveData(uuid);
}
Log.e("tag", "getUUID : " + uuid);
return uuid;
} catch (IOException e) {
e.printStackTrace();
}
return UUID.randomUUID().toString()+"catch";
}
3.
private static final String FILENAME = "data.txt";
public static void saveData(String uuid) throws IOException {
File sdCard = new File(getDownloadPath());
FileOutputStream out = new FileOutputStream(sdCard);
Writer writer = new OutputStreamWriter(out);
try {
writer.write(uuid);
} finally {
writer.close();
}
}
public static String loadData() throws IOException {
BufferedReader reader = null;
StringBuilder data = new StringBuilder();
Environment.getExternalStorageDirectory().getAbsolutePath();
try {
File sdCard = new File(getDownloadPath());
FileInputStream in = new FileInputStream(sdCard);
reader = new BufferedReader(new InputStreamReader(in));
String line = new String();
while ((line = reader.readLine()) != null) {
data.append(line);
}
return data.toString();
} catch (FileNotFoundException e) {
return null;
} finally {
if (reader != null) {
reader.close();
}
}
}
4.
public static String getDownloadPath() {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + Environment.DIRECTORY_DOWNLOADS + File.separator + "MyFile/");
if (!file.exists()) {
file.mkdirs();
}
return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + Environment.DIRECTORY_DOWNLOADS + File.separator + "MyFile/"+ FILENAME;
} else {
String apkFilePath=Environment.getDataDirectory().getAbsolutePath() + File.separator + "local" +File.separator+"tmp"+File.separator+ "MyFile/" + FILENAME;
String[] command = { "chmod", "777", apkFilePath };
ProcessBuilder builder = new ProcessBuilder(command);
try
{
builder.start();
}
catch (IOException e)
{
e.printStackTrace();
}
File file = new File(Environment.getDataDirectory().getAbsolutePath() + File.separator + "local" +File.separator+"tmp"+File.separator+ "MyFile/");
if (!file.exists()) {
file.mkdirs();
}
return apkFilePath;
}
}



