最近有个需求,要获取设备唯一id,Android一直没有什么完善的方案获取设备唯一不变的id,我就结合了几种方案组成了一下:
1. 首先获取IMEI; IMEI获取失败后
2. 获取SN序列号,序列号失败后
3. 随机生成一串UUID存储在内存中
经过测试,在小米手机上存储会提示open failed: EACCES (Permission denied) 查了很多资料,常用的方案都做过尝试,例如:添加android:requestLegacyExternalStorage=”true”到清单中等方案都没有解决问题,下面说说我的解决方案:
给予所有文件读写权限,直接上代码
1. 清单文件中加入
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
这一步特别重要,不给这个权限,跳转后的按钮灰色无法点击
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.
/** * 得到全局唯一UUID */ 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.
/** * sd卡获取下载路径 * @return /storage/emulated/0/Download/ */ 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; } }