java 唯一标识 短_解决Android10 唯一标识的问题

一,Android常见的唯一标识

IMEI,MEID,ESN,IMSI,android_id 目前用的最多的就是IMEI 现在Android10 是真的获取不到IMEI标识了!现在移动安全联盟出的那个架包 目前只支持国内手机,三星手机不支持,而且 国内手机也不一定全部支持

二,生成UUID保存在本地,

在Android10 之前,可以创建一个文件保存一个编号,多个应用都能访问,但是没删除掉了 或者 刷机,或者恢复出厂设置了 都不能用了,现在Android 储存权限更一步提升,保存的文件 应用卸载 文件就删除了!除非用mediaStore 保存多媒体文件,但是多个应用不能共享使用,这个问题非常头疼

三,解决方案

1,本地生成一个UUID当唯一标识

2,获取硬件的所有硬件编码和UUID进行绑定,上传数据库,如果应用本删除或者卸载,下次进入应用根据硬件编码 获取UUID,下面直接贴代码

一,生成UUID

//生成15位唯一性的订单号

private static String getUUID() {

//随机生成一位整数

int random = (int) (Math.random() * 9 + 1);

String valueOf = String.valueOf(random);

//生成uuid的hashCode值

int hashCode = UUID.randomUUID().toString().hashCode();

//可能为负数

if (hashCode < 0) {

hashCode = -hashCode;

}

String value = valueOf + String.format("%014d", hashCode);

return value;

}

二,获取目前能获取的唯一编号和硬件编码

public static String getDeviceInformJson() {

DeviceInformModel deviceInformModel = new DeviceInformModel();

deviceInformModel.setMac(DeviceId.getMacAddress());//获取mac

deviceInformModel.setAndroid_id(DeviceId.getAndroidID(App.getsInstance()));//获取AndroidId

deviceInformModel.setSerial_no(DeviceId.getSerialNo());//获取Sim卡编码

deviceInformModel.setImsi(DeviceId.getSubscriberId());//获取Imsi编码

deviceInformModel.setSimserial(DeviceId.getSimSerialNumber());

deviceInformModel.setFingerprint(DeviceId.getFingerprint());//获取指纹编码

deviceInformModel.setSplitNo(DeviceId.getSplitNo());//多个字段拼接的编码

deviceInformModel.setPhysics_info(HexUtil.long2Hex(PhysicsInfo.getHash(App.getsInstance())));//获取硬件编码信息

deviceInformModel.setDark_physics_info(HexUtil.long2Hex(DarkPhysicsInfo.getHash(App.getsInstance())));//获取物理编码Hash值

return GsonUtil.getInstance().GsonString(deviceInformModel);

}

上面代码是获取硬件编码并转化成json字符串 和uuId一块传给后台的

三 ,获取硬件编码的代码

package com.xhs.baselibrary.utils.device;

import android.Manifest;

import android.annotation.SuppressLint;

import android.content.Context;

import android.content.pm.PackageManager;

import android.os.Build;

import android.provider.Settings;

import android.telephony.TelephonyManager;

import android.text.TextUtils;

import android.util.Log;

import androidx.core.app.ActivityCompat;

import com.xhs.baselibrary.App;

import com.xhs.baselibrary.utils.Encryption;

import java.lang.reflect.Method;

import java.net.NetworkInterface;

import java.util.Enumeration;

import java.util.UUID;

public class DeviceId {

private static final byte[] HEX_DIGITS = {

'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'

};

private static final String INVALID_MAC_ADDRESS = "02:00:00:00:00:00";

private static final String INVALID_ANDROID_ID = "9774d56d682e549c";

private static final String INVALID_Serial_No = "unknown";

private static byte[] getMacInArray() {

try {

Enumeration enumeration = NetworkInterface.getNetworkInterfaces();

if (enumeration == null) {

return null;

}

while (enumeration.hasMoreElements()) {

NetworkInterface netInterface = enumeration.nextElement();

if (netInterface.getName().equals("wlan0")) {

return netInterface.getHardwareAddress();

}

}

} catch (Exception e) {

Log.e("tag", e.getMessage(), e);

}

return null;

}

public static long getLongMac() {

byte[] bytes = getMacInArray();

if (bytes == null || bytes.length != 6) {

return 0L;

}

long mac = 0L;

for (int i = 0; i < 6; i++) {

mac |= bytes[i] & 0xFF;

if (i != 5) {

mac <<= 8;

}

}

return mac;

}

public static String getMacAddress() {

String mac = formatMac(getMacInArray());

if (TextUtils.isEmpty(mac) || mac.equals(INVALID_MAC_ADDRESS)) {

return "";

}

return mac;

}

private static String formatMac(byte[] bytes) {

if (bytes == null || bytes.length != 6) {

return "";

}

byte[] mac = new byte[17];

int p = 0;

for (int i = 0; i <= 5; i++) {

byte b = bytes[i];

mac[p] = HEX_DIGITS[(b & 0xF0) >> 4];

mac[p + 1] = HEX_DIGITS[b & 0xF];

if (i != 5) {

mac[p + 2] = ':';

p += 3;

}

}

return new String(mac);

}

public static String getAndroidID(Context context) {

if (context != null) {

@SuppressLint("HardwareIds")

String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);

if (!TextUtils.isEmpty(androidId) && !INVALID_ANDROID_ID.equals(androidId)) {

return androidId;

}

}

return "";

}

/**

* 获取手机序列号

*

* @return 手机序列号

*/

public static String getSerialNo() {

String serial = "";

try {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+

if (ActivityCompat.checkSelfPermission(App.getsInstance(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {

serial = Build.getSerial();

}

} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+

serial = Build.SERIAL;

} else {//8.0-

Class> c = Class.forName("android.os.SystemProperties");

Method get = c.getMethod("get", String.class);

serial = (String) get.invoke(c, "ro.serialno");

}

} catch (Exception e) {

e.printStackTrace();

Log.e("e", "读取设备序列号异常:" + e.toString());

}

if (!TextUtils.isEmpty(serial) && !INVALID_Serial_No.equals(serial)) {

return serial;

}

return "";

}

public static String getSubscriberId() {

TelephonyManager mTelephonyMgr = (TelephonyManager) App.getsInstance().getSystemService(Context.TELEPHONY_SERVICE);

if (ActivityCompat.checkSelfPermission(App.getsInstance(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {

String imsi = mTelephonyMgr.getSubscriberId();

if (!TextUtils.isEmpty(imsi)) {

return imsi;

}

return imsi;

}

return "";

}

public static String getSimSerialNumber() {

TelephonyManager mTelephonyMgr = (TelephonyManager) App.getsInstance().getSystemService(Context.TELEPHONY_SERVICE);

//返回SIM卡的序列号

if (ActivityCompat.checkSelfPermission(App.getsInstance(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {

String simSerialNumber = mTelephonyMgr.getSimSerialNumber();

if (!TextUtils.isEmpty(simSerialNumber)) {

return simSerialNumber;

}

}

return "";

}

public static String getSplitNo() {

String serial = "";

String m_szDevIDShort = "35" +

Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +

Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +

Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +

Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +

Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +

Build.USER.length() % 10; //13 位

serial = getSerialNo();

//使用硬件信息拼凑出来的15位号码

return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();

}

public static String getFingerprint() {

return Encryption.encrypByMD5(android.os.Build.FINGERPRINT);

}

}

四, 后台逻辑

1,App 请求参数是本地uuId或者刚生成的UUId 和所有App硬件编码标识

2,后台先根据uuId查询是否存在这个编码,如果存在就返回 这条信息,如果没有 根据硬件编码标识 如果不为空,而且硬件编码标识和数据库里面 有两条一样的 那么把这条记录返回给客户端,那么返回的uuId 就是 之前保存的那个uuId

代码还有很多如果需要 我贴github上面,如果不明白其中逻辑的,可以评论咨询,时间忙 记录一下这个方案

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值