安卓Q中google彻底禁止了第三发应用获取imei,并且mac地址返回的地址也变成了02:00:00:00:00:00。
这是官方给出的解决方案:
https://developer.android.com/training/articles/user-data-ids
这是官网的截图:
方法一:
既然这两个都没法获取了,所以想到获取ANDROID_ID:
public static String getAndroidId (Context context) {
String ANDROID_ID = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
return ANDROID_ID;
}
但是发现不同应用的正式包在相同设备上得到的ANDROID_ID结果不同,因此显然该方案不可行。
方法二:
按照google官方意见,是在安装应用时,生成UUID,保存到本地,如果本地已经存在UUID,则不在保存,这样就可以将UUID作为唯一标识符。下面是官方推荐截图:
好的,那么就使用UUID:
String uuidStr = UUID.randomUUID().toString();
将UUID以文件的形式保存在多媒体文件目录下,这样一来各个不同的应用间都能采用同一个UUID。生成UUID。其中 saveFileName 为存放uuid数据的文件名:
/**
* 在媒体文件中 生成fileName文件
* 向Mediastore添加内容
*
* @param saveFileName 保存文件的名称
*/
private void creatUUIDFile(String saveFileName) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, saveFileName);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/*");
// TODO: 2019-10-11 IS_PENDING = 1表示对应的item还没准备好
values.put(MediaStore.Images.Media.IS_PENDING, 1);
ContentResolver resolver = this.getContentResolver();
Uri collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
Uri uri = resolver.insert(collection, values);
try {
//访问 对于单个媒体文件,请使用 openFileDescriptor()。
ParcelFileDescriptor fielDescriptor = resolver.openFileDescriptor(uri, "w", null);
FileOutputStream outputStream = new FileOutputStream(fielDescriptor.getFileDescriptor());
try {
//讲UUID写入到文件中
String uuidStr = UUID.randomUUID().toString();
outputStream.write(uuidStr.getBytes());
outputStream.close();
Log.d(TAG, "写入 uuidStr:" + uuidStr);
} catch (IOException e) {
e.printStackTrace();
}
values.clear();
values.put(MediaStore.Images.Media.IS_PENDING, 0); //设置为0
resolver.update(uri, values, null, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
如果需要判断是否已经存在存放uuid的文件,则用下面的方法:
/**
* 检查文件是否存在
*
* @param saveFileName 保存文件的名称
* @return true 为存在 false为不存在
*/
private boolean checkUUIDFileByUri(String saveFileName) {
Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media._ID
};
//查询
ContentResolver contentResolver = this.getContentResolver();
// 添加筛选条件
String selection = MediaStore.Images.Media.DISPLAY_NAME + "=" + "'" + saveFileName + "'";
Cursor mCursor = contentResolver.query(mImageUri, projection, selection, null, null);
String getSaveContent = "";
if (mCursor != null) {
while (mCursor.moveToNext()) {
int fileIdIndex = mCursor.getColumnIndex(MediaStore.Images.Media._ID);
String thumbPath = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.buildUpon()
.appendPath(String.valueOf(mCursor.getInt(fileIdIndex))).build().toString();
Uri fileUri = Uri.parse(thumbPath);
try {
ParcelFileDescriptor fielDescriptor = contentResolver.openFileDescriptor(fileUri, "r", null);
FileInputStream inputStream = new FileInputStream(fielDescriptor.getFileDescriptor());
getSaveContent = inputStreamToString(inputStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//只有在得到的唯一标识符不为空的情况下才结束循环,否则一直循环
if (!TextUtils.isEmpty(getSaveContent)) {
break;
}
}
mCursor.close();
}
return !getSaveContent.equals("");
}
上面代码中的inputStreamToString()方法为流转字符串,代码如下:
/**
* 流转为字符串
*
* @param is 流
* @return 转换完成的字符串
*/
public String inputStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append("/n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
好的,先这样。