精华内容
下载资源
问答
  • 获取移动设备唯一标识 原文:获取移动设备唯一标识 前段时间开发中 ,客户提出一个问题就是把用户的登录记录和设备绑定一起,就是每个人都是固定的设备(可能是安全因素吧)。...
    原文:获取移动设备唯一标识

    前段时间开发中 ,客户提出一个问题就是把用户的登录记录和设备绑定到一起,就是每个人都是固定的设备(可能是安全因素吧)。一开始想的是回去设备的IMEI号和用户账号绑定起来,结果发现华为平板IMEI不对外开发,只能另寻他法,最后通过获取设备序列号作为唯一标识。话不多说,直接上代码

    var serial = '';
    var app = {
    	    initialize: function() {
    	        document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
    	    },
    	    onDeviceReady: function() {
    	      this.deviceVersion();
    	    },
    	    deviceVersion: function() {
    	    serial = device.serial;
    	    }
    	};
    	app.initialize();

    导入cordova.js就可以用了

    posted on 2019-01-06 23:10 NET未来之路 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/lonelyxmas/p/10230936.html

    展开全文
  • 项目开发中,多少会遇到这种需求:获得设备唯一标识DeviceId,用于: 1.标识一个唯一的设备,做数据精准下发或者数据统计分析; 2.账号与设备绑定; 3..... 二、 这类文章,网上有许多资料,例如:使用IMEI、MAC等...

     

    一、

    项目开发中,多少会遇到这种需求:获得设备唯一标识DeviceId,用于:
    1.标识一个唯一的设备,做数据精准下发或者数据统计分析;
    2.账号与设备绑定;
    3.....

    二、

    这类文章,网上有许多资料,例如:使用IMEI、MAC等作为设备标识使用。
    不过,看过这些文章或者深入调研的同学应该都清楚,这些数据均存在缺陷:有的因为权限无法获取到,有的获取出来是重复的,有的完全获取不到,也就是说不能完美的解决设备唯一的问题。

    、什么数据才是表示设备唯一呢?

    三、

    方案1:UUID + SharePreference(存取)

    APP首次使用时,创建UUID,并保存到SharePreference中。
    以后再次使用时,直接从SharePreference取出来即可;

    优点:数据唯一、不需要权限;
    缺点:会随APP一起删除,即:重新安装APP,DeviceId值会改变(新UUID);

    方案2:UUID + SD卡(存取)

    APP首次使用时,创建UUID,并保存到SD卡中。
    以后再次使用时,直接从SD卡取出来即可;
    很多APP就是这么做的;
    
    优点:数据唯一、不随APP一起删除;
    缺点:需要SD卡读写权限;防不住用户手动删除SD卡的文件;

    方案3:imei + android_id + serial + 硬件uuid(自生成)

    如果,又想唯一,又不想因用户的删除而重新生成UUID,该怎么做呢?

    不依赖随机的UUID,咱们根据硬件标识来创建唯一的数据;

    我们可以将多个可获得的硬件标识拼接起来(尽可能不依赖权限),最大程度上降低重复性。
    以imei、android_id、serial为例,如果能取到值,每个数据几乎可以代表唯一。
    如果这些数据都能获取到,拼起来的数据重复性降到极低(UUID也存在重复性,重复性极低而已)

    那么,哪些硬件标识合适呢?

    AndroidId : 如:df176fbb152ddce,无需权限,极个别设备获取不到数据或得到错误数据;
    serial:如:LKX7N18328000931,无需权限,极个别设备获取不到数据;
    IMEI : 如:23b12e30ec8a2f17,需要权限;
    Mac: 如:6e:a5:....需要权限,高版本手机获得数据均为 02:00.....(不可使用)
    Build.BOARD  如:BLA  主板名称,无需权限,同型号设备相同
    Build.BRAND  如:HUAWEI  厂商名称,无需权限,同型号设备相同
    Build.HARDWARE  如:kirin970  硬件名称,无需权限,同型号设备相同
    Build......更多硬件信息,略

    分析了这么多硬件标识,我们就使用imei + android_id + serial + 硬件UUID(使用Build属性生成,如果硬件信息不变,则UUID值不变)。这是我们项目的实际方案,大家也可根据自己的需要自由组合硬件标识。

    那么,问题又来了,不同设备的硬件标识长度不同,拼接处理的DeviceId字符串长度不同,怎么才能统一长度呢?

    也很简单,我们先拼接好DeviceId数据,取其SHA1值,再转16进制即可(统一40位长度)

    四、

    import android.content.Context;
    import android.os.Build;
    import android.provider.Settings;
    import android.telephony.TelephonyManager;
    
    import java.security.MessageDigest;
    import java.util.Locale;
    import java.util.UUID;
    
    /**
     * @date 2019/10/17
     * @desc
     */
    public class DeviceIdUtil {
        /**
         * 获得设备硬件标识
         *
         * @param context 上下文
         * @return 设备硬件标识
         */
        public static String getDeviceId(Context context) {
            StringBuilder sbDeviceId = new StringBuilder();
    
            //获得设备默认IMEI(>=6.0 需要ReadPhoneState权限)
            String imei = getIMEI(context);
            //获得AndroidId(无需权限)
            String androidid = getAndroidId(context);
            //获得设备序列号(无需权限)
            String serial = getSERIAL();
            //获得硬件uuid(根据硬件相关属性,生成uuid)(无需权限)
            String uuid = getDeviceUUID().replace("-", "");
    
            //追加imei
            if (imei != null && imei.length() > 0) {
                sbDeviceId.append(imei);
                sbDeviceId.append("|");
            }
            //追加androidid
            if (androidid != null && androidid.length() > 0) {
                sbDeviceId.append(androidid);
                sbDeviceId.append("|");
            }
            //追加serial
            if (serial != null && serial.length() > 0) {
                sbDeviceId.append(serial);
                sbDeviceId.append("|");
            }
            //追加硬件uuid
            if (uuid != null && uuid.length() > 0) {
                sbDeviceId.append(uuid);
            }
    
            //生成SHA1,统一DeviceId长度
            if (sbDeviceId.length() > 0) {
                try {
                    byte[] hash = getHashByString(sbDeviceId.toString());
                    String sha1 = bytesToHex(hash);
                    if (sha1 != null && sha1.length() > 0) {
                        //返回最终的DeviceId
                        return sha1;
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
    
            //如果以上硬件标识数据均无法获得,
            //则DeviceId默认使用系统随机数,这样保证DeviceId不为空
            return UUID.randomUUID().toString().replace("-", "");
        }
    
        //需要获得READ_PHONE_STATE权限,>=6.0,默认返回null
        private static String getIMEI(Context context) {
            try {
                TelephonyManager tm = (TelephonyManager) 
    context.getSystemService(Context.TELEPHONY_SERVICE);
                return tm.getDeviceId();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return "";
        }
    
        /**
         * 获得设备的AndroidId
         *
         * @param context 上下文
         * @return 设备的AndroidId
         */
        private static String getAndroidId(Context context) {
            try {
                return Settings.Secure.getString(context.getContentResolver(), 
    Settings.Secure.ANDROID_ID);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return "";
        }
    
        /**
         * 获得设备序列号(如:WTK7N16923005607), 个别设备无法获取
         *
         * @return 设备序列号
         */
        private static String getSERIAL() {
            try {
                return Build.SERIAL;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return "";
        }
    
        /**
         * 获得设备硬件uuid
         * 使用硬件信息,计算出一个随机数
         *
         * @return 设备硬件uuid
         */
        private static String getDeviceUUID() {
            try {
                String dev = "3883756" +
                        Build.BOARD.length() % 10 +
                        Build.BRAND.length() % 10 +
                        Build.DEVICE.length() % 10 +
                        Build.HARDWARE.length() % 10 +
                        Build.ID.length() % 10 +
                        Build.MODEL.length() % 10 +
                        Build.PRODUCT.length() % 10 +
                        Build.SERIAL.length() % 10;
                return new UUID(dev.hashCode(), 
    Build.SERIAL.hashCode()).toString();
            } catch (Exception ex) {
                ex.printStackTrace();
                return "";
            }
        }
    
        /**
         * 取SHA1
         * @param data 数据
         * @return 对应的hash值
         */
        private static byte[] getHashByString(String data)
        {
            try{
                MessageDigest  messageDigest = MessageDigest.getInstance("SHA1");
                messageDigest.reset();
                messageDigest.update(data.getBytes("UTF-8"));
                return messageDigest.digest();
            } catch (Exception e){
                return "".getBytes();
            }
        }
    
        /**
         * 转16进制字符串
         * @param data 数据
         * @return 16进制字符串
         */
        private static String bytesToHex(byte[] data){
            StringBuilder sb = new StringBuilder();
            String stmp;
            for (int n = 0; n < data.length; n++){
                stmp = (Integer.toHexString(data[n] & 0xFF));
                if (stmp.length() == 1)
                    sb.append("0");
                sb.append(stmp);
            }
            return sb.toString().toUpperCase(Locale.CHINA);
        }
    }

    五、

    String deviceId = DeviceIdUtil.getDeviceId(application);
    
    结果输出:FE00DDE9298310CDFEEFE69229B8DB248534710F

    总结

    方案1局限性较大,不建议使用;
    方案2是很多软件采用的方案,因很少有人删除SD卡文件;但需要注意权限;
    方案3相较于前两种方案,限制性较小,只要硬件信息不变结果就不变。而且该方案可自行定制组合。

    究竟哪种方案合适,大家应根据自己的项目需求,合理选择才是。

    展开全文
  • 获取设备唯一标识

    2020-05-22 09:58:35
    原文据说首发在《人人都是...UDID,即先获取IDFA,获取不到在获取IDFV,获取不到IDFV时,再获取UDID,然后使用相关算法生成一个设备ID。 苹果.png Android Android系统历经多次升级,对权限控制越来越严格,...

    原文据说首发在《人人都是产品经理》

    iOS

    苹果系统,可用于识别唯一设备的标识不多,如下图。综合起来,苹果系统生成设备ID的标识符顺序应该是IDFA -> IDFV ->UDID,即先获取IDFA,获取不到在获取IDFV,获取不到IDFV时,再获取UDID,然后使用相关算法生成一个设备ID。

    苹果.png
    Android

    Android系统历经多次升级,对权限控制越来越严格,唯一识别手机的方法也在发生变化。下面整理一下安卓系统适合做设备唯一标识符的几个标识符,以及其特性:

    安卓

    从表格中看出,IMEI是最适合做设备唯一标识的,奈何获取IMEI需要授予权限且Android 10以后不再开放IMEI的权限。综合起来,安卓系统中,应该按照IMEI ->OAID -> ANDROID_ID的顺序生成设备ID。即先获取IMEI号,获取不到IMEI时获取OAID,获取不到OAID时,再获取ANDROID_ID,然后使用相关算法生成设备ID。

    微信小程序

    通常做法使用openid作为设备ID,当然也可以自己生产一个ID,作为设备ID。如果用过openid作为设备ID,需要注意微信小程序的冷启动问题(获取 openid 是一个异步的操作,所以会导致数据上报的时候,可能还没获取到openid,这就是导致设备ID为空)。

    Web网站

    Web网站,使用cookie_id作为设备ID,并存储在浏览器的cookie中。

    展开全文
  • android获取设备唯一标识

    千次阅读 2019-04-30 14:49:06
    我的设备是TV,获取不到IMEI,但是有以太网口,所以最好的办法是获取以太网mac作为唯一标识。 public class MobileInfoUtil { private static String wifiTag = "wlan0";//无线标志,关闭wifi开关后获取不到 ...

    这里列举了获取所有可以获取到的设备唯一识别码:getDeviceId()。
    我的设备是TV,获取不到IMEI,但是有以太网口,所以最好的办法是获取以太网mac作为唯一标识。

    public class MobileInfoUtil {
    
        private static String wifiTag = "wlan0";//无线标志,关闭wifi开关后获取不到
        private static String localTag = "eth0";//有线标志,插不插网线都能获取到
        
        public static String getDeviceId(Context context) {
            StringBuilder deviceId = new StringBuilder();
            try {
                String wifiMac = getMachineHardwareAddress();//因为我的设备是tv 系统是7.0以上 所以直接不再判断系统来选择获取方案,如果不确定系统版本则使用getMac(context)
                if(!isEmpty(wifiMac) && !"02:00:00:00:00:00".equals(wifiMac)){
                    deviceId.append("wifi");
                    deviceId.append(wifiMac);
                    Logc.e("getDeviceId : "+deviceId.toString());
                    return deviceId.toString();
                }
                //IMEI(imei)
                TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                @SuppressLint("MissingPermission") String imei = tm.getDeviceId();
                if(!isEmpty(imei)){
                    deviceId.append("imei");
                    deviceId.append(imei);
                    Logc.e("getDeviceId : "+deviceId.toString());
                    return deviceId.toString();
                }
                //序列号(sn)
                @SuppressLint("MissingPermission") String sn = tm.getSimSerialNumber();
                if(!isEmpty(sn)){
                    deviceId.append("sn");
                    deviceId.append(sn);
                    Logc.e("getDeviceId : "+deviceId.toString());
                    return deviceId.toString();
                }
    
                //设备号(deviceId)
                @SuppressLint("MissingPermission") String d = tm.getDeviceId();
                if(!isEmpty(d)){
                    deviceId.append("d");
                    deviceId.append(d);
                    Logc.e("getDeviceId : "+ deviceId.toString());
                    return deviceId.toString();
                }
    
                //TX3 mini电视盒子只能获取Android_id
                String ANDROID_ID = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
                if(!isEmpty(ANDROID_ID)){
                    deviceId.append("ANDROID_ID");
                    deviceId.append(ANDROID_ID);
                    Logc.e("getDeviceId : "+deviceId.toString());
                    return deviceId.toString();
                }
    
                //如果上面都没有, 则生成一个id:随机码
                String uuid = getUUID(context);
                if(!isEmpty(uuid)){
                    deviceId.append("id");
                    deviceId.append(uuid);
                    Logc.e("getDeviceId : ", deviceId.toString());
                    return deviceId.toString();
                }
            } catch (Exception e) {
                e.printStackTrace();
                deviceId.append("id").append(getUUID(context));
            }
            Logc.e("getDeviceId : ", deviceId.toString());
            return deviceId.toString();
        }
    
    
        /**
         * 得到全局唯一UUID
         */
        public static String getUUID(Context context){
    //        SharedPreferences mShare = getSysShare(context, "sysCacheMap");
    //        if(mShare != null){
    //            uuid = mShare.getString("uuid", "");
    //        }
    //        if(isEmpty(uuid)){
    //            uuid = UUID.randomUUID().toString();
    //            saveSysMap(context, "sysCacheMap", "uuid", uuid);
    //        }
    //        Logc.e(tag, "getUUID : " + uuid);
            return "2222";
        }
    
    
    
        public static String getMac(Context context) {
    
            String strMac = null;
    
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                Log.e("=====", "6.0以下");
                Toast.makeText(context, "6.0以下", Toast.LENGTH_SHORT).show();
                strMac = getLocalMacAddressFromWifiInfo(context);
                return strMac;
            } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N
                    && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                Log.e("=====", "6.0以上7.0以下");
                Toast.makeText(context, "6.0以上7.0以下", Toast.LENGTH_SHORT).show();
                strMac = getMacAddress(context);
                return strMac;
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                Log.e("=====", "7.0以上");
                if (!TextUtils.isEmpty(getMacAddress())) {
                    Log.e("=====", "7.0以上1");
                    Toast.makeText(context, "7.0以上1", Toast.LENGTH_SHORT).show();
                    strMac = getMacAddress();
                    return strMac;
                } else if (!TextUtils.isEmpty(getMachineHardwareAddress())) {
                    Log.e("=====", "7.0以上2");
                    Toast.makeText(context, "7.0以上2", Toast.LENGTH_SHORT).show();
                    strMac = getMachineHardwareAddress();
                    return strMac;
                } else {
                    Log.e("=====", "7.0以上3");
                    Toast.makeText(context, "7.0以上3", Toast.LENGTH_SHORT).show();
                    strMac = getLocalMacAddressFromBusybox();
                    return strMac;
                }
            }
    
            return "02:00:00:00:00:00";
        }
    
    	//6.0以下方法,Google提供的公有方法,需要权限
    	//<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        /**
         * 根据wifi信息获取本地mac
         * @param context
         * @return
         */
        public static String getLocalMacAddressFromWifiInfo(Context context){
            WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            WifiInfo winfo = wifi.getConnectionInfo();
            String mac =  winfo.getMacAddress();
            return mac;
        }
    
     	//    android 6.0及以上、7.0以下
    	//    android 6.0以后 将不再能通过 wifimanager 获取mac,获取到的mac将是固定的:02:00:00:00:00:00 。
    	//    然而我开发的sdk就是通过wifimanager获取的mac。
    	//    android sdk后来做了6.0适配,通过cat /sys/class/net/wlan0/address,可以在6.0上获取mac地址。
    
        /**
         * android 6.0及以上、7.0以下 获取mac地址
         * @param context
         * @return
         */
        public static String getMacAddress(Context context) {
    
            // 如果是6.0以下,直接通过wifimanager获取
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                String macAddress0 = getMacAddress0(context);
                if (!TextUtils.isEmpty(macAddress0)) {
                    return macAddress0;
                }
            }
            String str = "";
            String macSerial = "";
            try {
                Process pp = Runtime.getRuntime().exec(
                        "cat /sys/class/net/wlan0/address");
                InputStreamReader ir = new InputStreamReader(pp.getInputStream());
                LineNumberReader input = new LineNumberReader(ir);
                for (; null != str; ) {
                    str = input.readLine();
                    if (str != null) {
                        macSerial = str.trim();// 去空格
                        break;
                    }
                }
            } catch (Exception ex) {
                Log.e("----->" + "NetInfoManager", "getMacAddress:" + ex.toString());
            }
            if (macSerial == null || "".equals(macSerial)) {
                try {
                    return loadFileAsString("/sys/class/net/eth0/address")
                            .toUpperCase().substring(0, 17);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e("----->" + "NetInfoManager",
                            "getMacAddress:" + e.toString());
                }
    
            }
            return macSerial;
        }
    
        private static String getMacAddress0(Context context) {
            if (isAccessWifiStateAuthorized(context)) {
                WifiManager wifiMgr = (WifiManager) context
                        .getSystemService(Context.WIFI_SERVICE);
                WifiInfo wifiInfo = null;
                try {
                    wifiInfo = wifiMgr.getConnectionInfo();
                    return wifiInfo.getMacAddress();
                } catch (Exception e) {
                    Log.e("----->" + "NetInfoManager",
                            "getMacAddress0:" + e.toString());
                }
    
            }
            return "";
    
        }
    
        /**
         * Check whether accessing wifi state is permitted
         *
         * @param context
         * @return
         */
        private static boolean isAccessWifiStateAuthorized(Context context) {
            if (PackageManager.PERMISSION_GRANTED == context
                    .checkCallingOrSelfPermission("android.permission.ACCESS_WIFI_STATE")) {
                Log.e("----->" + "NetInfoManager", "isAccessWifiStateAuthorized:"
                        + "access wifi state is enabled");
                return true;
            } else
                return false;
        }
    
        private static String loadFileAsString(String fileName) throws Exception {
            FileReader reader = new FileReader(fileName);
            String text = loadReaderAsString(reader);
            reader.close();
            return text;
        }
    
        private static String loadReaderAsString(Reader reader) throws Exception {
            StringBuilder builder = new StringBuilder();
            char[] buffer = new char[4096];
            int readLength = reader.read(buffer);
            while (readLength >= 0) {
                builder.append(buffer, 0, readLength);
                readLength = reader.read(buffer);
            }
            return builder.toString();
        }
    
    
        //    android 7.0 后,通过上述适配的方法,将获取不到mac地址。
        //
        //    经过调研和测试,7.0上仍有办法回去mac地址:
        //
        //    总共分为三种方式:
        //   1)通过ip地址来获取绑定的mac地址
        //
        //  (2)扫描各个网络接口获取mac地址
        //
        //  (3)通过busybox获取本地存储的mac地址
        /**
         * 根据IP地址获取MAC地址
         *
         * @return
         */
        public static String getMacAddress() {
            String strMacAddr = null;
            try {
                // 获得IpD地址
                InetAddress ip = getLocalInetAddress();
                byte[] b = NetworkInterface.getByInetAddress(ip)
                        .getHardwareAddress();
                StringBuffer buffer = new StringBuffer();
                for (int i = 0; i < b.length; i++) {
                    if (i != 0) {
                        buffer.append(':');
                    }
                    String str = Integer.toHexString(b[i] & 0xFF);
                    buffer.append(str.length() == 1 ? 0 + str : str);
                }
                strMacAddr = buffer.toString().toUpperCase();
            } catch (Exception e) {
            }
            return strMacAddr;
        }
        /**
         * 获取移动设备本地IP
         *
         * @return
         */
        private static InetAddress getLocalInetAddress() {
            InetAddress ip = null;
            try {
                // 列举
                Enumeration<NetworkInterface> en_netInterface = NetworkInterface
                        .getNetworkInterfaces();
                while (en_netInterface.hasMoreElements()) {// 是否还有元素
                    NetworkInterface ni = (NetworkInterface) en_netInterface
                            .nextElement();// 得到下一个元素
                    Enumeration<InetAddress> en_ip = ni.getInetAddresses();// 得到一个ip地址的列举
                    while (en_ip.hasMoreElements()) {
                        ip = en_ip.nextElement();
                        if (!ip.isLoopbackAddress()
                                && ip.getHostAddress().indexOf(":") == -1)
                            break;
                        else
                            ip = null;
                    }
    
                    if (ip != null) {
                        break;
                    }
                }
            } catch (SocketException e) {
    
                e.printStackTrace();
            }
            return ip;
        }
    
        /**
         * 获取本地IP
         *
         * @return
         */
        private static String getLocalIpAddress() {
            try {
                for (Enumeration<NetworkInterface> en = NetworkInterface
                        .getNetworkInterfaces(); en.hasMoreElements(); ) {
                    NetworkInterface intf = en.nextElement();
                    for (Enumeration<InetAddress> enumIpAddr = intf
                            .getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress()) {
                            return inetAddress.getHostAddress().toString();
                        }
                    }
                }
            } catch (SocketException ex) {
                ex.printStackTrace();
            }
            return null;
        }
    
    
        /**
         * android 7.0及以上 (2)扫描各个网络接口获取mac地址,包括有线网口(电视盒子)和无线网
         * 获取设备HardwareAddress地址
         *
         * @return
         */
        public static String getMachineHardwareAddress() {
            Enumeration<NetworkInterface> interfaces = null;
            try {
                interfaces = NetworkInterface.getNetworkInterfaces();
            } catch (SocketException e) {
                e.printStackTrace();
            }
            String hardWareAddress = "02:00:00:00:00:00";
            NetworkInterface iF = null;
            if (interfaces == null) {
                return null;
            }
            while (interfaces.hasMoreElements()) {
                iF = interfaces.nextElement();
                if (!iF.getName().equalsIgnoreCase(localTag)) continue;//有线网即以太网mac不会丢失,wifi mac在wifi关闭时获取不到,而且wifi mac可能会变
                try {
                    hardWareAddress = bytesToString(iF.getHardwareAddress());
                    if (hardWareAddress != null)
                        break;
                } catch (SocketException e) {
                    e.printStackTrace();
                }
            }
            return hardWareAddress;
        }
    
        /***
         * byte转为String
         *
         * @param bytes
         * @return
         */
        private static String bytesToString(byte[] bytes) {
            if (bytes == null || bytes.length == 0) {
                return null;
            }
            StringBuilder buf = new StringBuilder();
            for (byte b : bytes) {
                buf.append(String.format("%02X:", b));
            }
            if (buf.length() > 0) {
                buf.deleteCharAt(buf.length() - 1);
            }
            return buf.toString();
        }
    
    
        /**
         * android 7.0及以上 (3)通过busybox获取本地存储的mac地址
         *
         */
    
        /**
         * 根据busybox获取本地Mac
         *
         * @return
         */
        public static String getLocalMacAddressFromBusybox() {
            String result = "";
            String Mac = "";
            result = callCmd("busybox ifconfig", "HWaddr");
            // 如果返回的result == null,则说明网络不可取
            if (result == null) {
                return "网络异常";
            }
            // 对该行数据进行解析
            // 例如:eth0 Link encap:Ethernet HWaddr 00:16:E8:3E:DF:67
            if (result.length() > 0 && result.contains("HWaddr") == true) {
                Mac = result.substring(result.indexOf("HWaddr") + 6,
                        result.length() - 1);
                result = Mac;
            }
            return result;
        }
    
        private static String callCmd(String cmd, String filter) {
            String result = "";
            String line = "";
            try {
                Process proc = Runtime.getRuntime().exec(cmd);
                InputStreamReader is = new InputStreamReader(proc.getInputStream());
                BufferedReader br = new BufferedReader(is);
    
                while ((line = br.readLine()) != null
                        && line.contains(filter) == false) {
                    result += line;
                }
    
                result = line;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result;
        }
    }
    
    展开全文
  • 苹果官方对于iOS设备唯一标识的官方文档链接: https://developer.apple.com/reference/uikit/uidevice/1620059-identifierforvendor近日因为公司app有“一账号一设备”的需求,外包已完成此功能,个人也研究了一下...
  • android 6.0以下,获取设备信息需要动态申请权限,直接在manifest中注册即可,而且能获取到设备相关信息 android6.0以上 10以下 获取设备信息需要动态申请权限,但是imei,deviceId可能无法获取到 android 10...
  • iOS 获取设备唯一标识

    千次阅读 2016-09-06 11:14:10
    利用keyChain和UUID永久获得设备唯一标识 开发者可以在应用第一次启动时调用一 次,然后将该串存储起来,以便以后替代UDID来使用。但是,如果用户删除该应用再次安装时,又会生成新的字符串,所以能保证唯一...
  • 关于Android设备唯一标识符号 前言 由于在开发中需要开发游客模式,在用户没有登录的情况下必须确保设备的唯一性,于是惯性思维想到的肯定是使用DevicesId 来作为设备的唯一标识,用以代替用户登录以后的唯一...
  • 本文介绍了浅谈android获取设备唯一标识完美解决方案,分享给大家,具体如下: /** * deviceID的组成为:渠道标志+识别符来源标志+hash后的终端识别符 * * 渠道标志为: * 1,andriod(a) * * 识别符来源...
  • uni-app获取设备唯一标识

    千次阅读 2020-08-18 10:41:28
    uni-app根据不同手机平台获取设备唯一标识,由于获取的方式是异步的,当前页面执行一定能拿。建议存在缓存,其他地方可以用调用缓存的方式获取存在的话在执行一下方法获取,已保证一定能获取。 //...
  • 按照正常的获取在Android 8.0 之前都是可以拿到我们的Imei码的,就是广为流传的那些形式,我就意义赘述了,到了Android 9.0 之后就出现了部分手机厂商的机型获取不到我们的IMEI码,例如 '‘一加’'等厂商,而且其他厂商的...
  • 无论是pc端的软件还是安卓端的软件,有时候在出售时如果没有被买断或者购买版权,那么就...那么在安卓端没有硬盘就需要获取一些其它硬件的参数来唯一标识设备。 1.获取IMEI标识码:IMEI(International Mobile Eq...
  • 项目之前用的是getDeviceId,在安卓Q貌似授权了也拿不到,所以采用getAndroidId,DEVICE_ID = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID)。 但是尝试...
  • 前言 由于在开发中需要开发游客模式,在用户没有登录的情况下必须确保设备的唯一性,于是惯性思维想到的肯定是使用DevicesId 来作为设备的唯一标识,用以代替用户登录以后的唯一...一、一些常用的获取设备唯一标识符
  • Unity3d获取IOS设备唯一标识,以及IDFA

    万次阅读 2015-09-02 18:57:32
    之前苹果设备获取唯一标识符,可以通过获取Mac地址。但是现在苹果把这条路堵死了。 不过没关系,苹果已经给出了替代方案,可以调用相应的接口,生成一串字符串,用生成的 字符串来代替之前的Mac地址。 ...
  • /** * deviceID的组成为:渠道标志+识别符来源标志+hash后的终端识别符 * * 渠道标志为: * 1,andriod(a) * * 识别符来源标志: ...若前面的都取不到时,则随机生成一个随机码,需要缓存。 * ...
  • FCUUID,需要注意的是,原来 OpenUDID 记录的设备 id (40位)是能直接迁移 FCUUID 的,尽管 FCUUID 提供了这样的接口,因为 OpenUDID 保存的设备 id 并是直接来自系统的 UUID,而是经过OpenUDID 处理过的,...
  • /** * deviceID的组成为:渠道标志+识别符来源标志+hash后的终端识别符 * * 渠道标志为: * 1,andriod(a) * * 识别符来源标志: * 1, ...若前面的都取不到时,则随机生成一个随机码,需要缓存。 * 
  • /** * deviceID的组成为:渠道标志+识别符来源标志+hash后的终端识别符 *  * 渠道标志为: * 1,andriod(a) * * 识别符来源标志: ...若前面的都取不到时,则随机生成一个随机码,需要缓存。 *
  • 苹果总是把用户的隐私看的很重要。...Xcode5甚至不会允许你编译包含了指引-[UIDevice uniqueIdentifier]的app。 此外,iOS7之前的使用了-[UIDevice uniqueIdentifier] 的app如果在iOS7上运行,它
  • 第一种方式是获取IMEI,但是有的手机如果不是正品的话,就获取不到所以通过这一种方式还是会出现有的设备是没有唯一标识的 第二种方式获取手机卡的序列号,当然这种也不是唯一的,因为有的手机是双卡双待的所以可能...
  • imei是设备的一个编号值,获取比较方便,不过有些设备设备编号获取不到,这种方式已经没有多少人会采用。下面就讲讲怎么获取imei编号。 UUID生成的原理,先获取设备标识信息,如果能够获取到就使用该获取到的值...
  • 1.许多应用都有这样的需求获取你的手机唯一标识,当你卸载软件重新安装的时候也要保证这个唯一标识不变,所以只能根据手机硬件的去获取到唯一标识. 2.有好多跟硬件相关都会有各种权限问题。一种很简单直接获取到...
  • 安卓10 获取唯一标识

    千次阅读 2020-01-03 11:36:37
    .Android 10中获取设备相关标识的方案 根据上文对几个常见设备标识的分析我们可以看出列出的几种设备标识都有...ANDROID_ID的获取不需要任何权限,并且可以很好地保证唯一性,缺点就是无法保证稳定性,即一些操...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 131
精华内容 52
关键字:

获取不到设备唯一标识