iOS获取设备唯一标识的实现步骤

目录
  • 1. 常用的UUID
  • 2. MAC 地址
    • 2.1 首先导入下面几个库:
    • 2.2 新建一个文件,继承NSObject,在.m文件导入头文件,以及定义一些宏
  • 3.UUID+自己存储
    • 3.1 获取UUID的两个方法
    • 3.2 首先在项目中添加 KeyChain Sharing
    • 3.3 导入第三方库 Security.framework
    • 3.4 核心代码(代码有点多)
    • 3.4 创建新类,引用 SSKeychain 封装

1. 常用的UUID

UDID是一个40位十六进制序列(越狱的设备通过某些工具可以改变设备的 UDID),移动网络可以利用 UDID 来识别移动设备。

许多开发者把 UDID 跟用户的个人信息关联起来,网络窥探者会从多个应用收集这些数据,然后顺藤摸瓜得到这个人的许多隐私数据,同时大部分应用确实在频繁传输 UDID 和私人信息。 为了避免集体诉讼,苹果最终决定在 iOS 5 的时候,将这一惯例废除。

获取UUID的方法:

/**  卸载应用重新安装后会不一致*/
+ (NSString *)getUUID{
    return [UIDevice currentDevice].identifierForVendor.UUIDString;;
}

2. MAC 地址

MAC地址,用来表示互联网上每一个站点的标示符,是一个六个字节(48位)的十六进制序列。前三个字节是由 IEEE 的注册管理机构 RA 负责给不同厂家分配的”编制上唯一的标示符,后三个字节由各厂家自行指派给生产的适配器接口。

MAC 地址在网络上用来区分设备的唯一性,接入网络的设备都有一个MAC地址,他们肯定都是唯一的。一部 iPhone 上可能有多个 MAC 地址,包括 WIFI 的、SIM 的等,但是 iTouch 和 iPad 上就有一个 WIFI 的,因此只需获取 WIFI 的 MAC 地址就好了。一般会采取 MD5(MAC 地址 + bundleID)获取唯一标识。

但是 MAC 地址和 UDID 一样,存在隐私问题, iOS 7 之后,所有设备请求 MAC 地址会返回一个固定值,这个方法也不攻自破了。

获取MAC在github找到一个挺好的方法:

2.1 首先导入下面几个库:

2.2 新建一个文件,继承NSObject,在.m文件导入头文件,以及定义一些宏

#import "XWGetMAC.h"
#import <ifaddrs.h>
#import <resolv.h>
#import <arpa/inet.h>
#import <net/if.h>
#import <netdb.h>
#import <netinet/ip.h>
#import <net/ethernet.h>
#import <net/if_dl.h>

#define MDNS_PORT       5353
#define QUERY_NAME      "_apple-mobdev2._tcp.local"
#define DUMMY_MAC_ADDR  @"02:00:00:00:00:00"
#define IOS_CELLULAR    @"pdp_ip0"
#define IOS_WIFI        @"en0"
#define IOS_VPN         @"utun0"
#define IP_ADDR_IPv4    @"ipv4"
#define IP_ADDR_IPv6    @"ipv6"
+ (NSString *)getMAC:(BOOL)preferIPv4 {

    return [[XWGetMAC alloc] getIPAddress:preferIPv4];
}

/*
 * 获取设备当前网络IP地址
 */
- (NSString *)getIPAddress:(BOOL)preferIPv4
{
    NSArray *searchArray = preferIPv4 ?
    @[ IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
    @[ IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;

    NSDictionary *addresses = [self getIPAddr];

    __block NSString *address;
    [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL * _Nonnull stop) {
        address = addresses[key];
        //筛选出IP地址格式
        if([self isValidatIP:address]) *stop = YES;
    }];
    return address ? address : @"0.0.0.0";
}

- (BOOL)isValidatIP:(NSString *)ipAddress {
    if (ipAddress.length == 0) {
        return NO;
    }
    NSString *urlRegEx = @"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
    "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";

    NSError *error;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:urlRegEx options:0 error:&error];

    if (regex != nil) {
        NSTextCheckingResult *firstMatch=[regex firstMatchInString:ipAddress options:0 range:NSMakeRange(0, [ipAddress length])];
        return firstMatch;
    }
    return NO;
}

- (NSDictionary *)getIPAddr
{
    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];

    // retrieve the current interfaces - returns 0 on success
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)) {
        // Loop through linked list of interfaces
        struct ifaddrs *interface;
        for(interface=interfaces; interface; interface=interface->ifa_next) {
            if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                continue; // deeply nested code harder to read
            }
            const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
            char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
            if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                NSString *type;
                if(addr->sin_family == AF_INET) {
                    if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv4;
                    }
                } else {
                    const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                    if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv6;
                    }
                }
                if(type) {
                    NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                    addresses[key] = [NSString stringWithUTF8String:addrBuf];
                }
            }
        }
        // Free memory
        freeifaddrs(interfaces);
    }
    return [addresses count] ? addresses : nil;
}
/*
 * 获取设备物理地址
 */
- (nullable NSString *)getMacAddress {
    res_9_init();
    int len;
    //get currnet ip address
    NSString *ip = [self currentIPAddressOf:IOS_WIFI];
    if(ip == nil) {
        fprintf(stderr, "could not get current IP address of en0\n");
        return DUMMY_MAC_ADDR;
    }//end if

    //set port and destination
    _res.nsaddr_list[0].sin_family = AF_INET;
    _res.nsaddr_list[0].sin_port = htons(MDNS_PORT);
    _res.nsaddr_list[0].sin_addr.s_addr = [self IPv4Pton:ip];
    _res.nscount = 1;

    unsigned char response[NS_PACKETSZ];

    //send mdns query
    if((len = res_9_query(QUERY_NAME, ns_c_in, ns_t_ptr, response, sizeof(response))) < 0) {

        fprintf(stderr, "res_search(): %s\n", hstrerror(h_errno));
        return DUMMY_MAC_ADDR;
    }//end if

    //parse mdns message
    ns_msg handle;
    if(ns_initparse(response, len, &handle) < 0) {
        fprintf(stderr, "ns_initparse(): %s\n", hstrerror(h_errno));
        return DUMMY_MAC_ADDR;
    }//end if

    //get answer length
    len = ns_msg_count(handle, ns_s_an);
    if(len < 0) {
        fprintf(stderr, "ns_msg_count return zero\n");
        return DUMMY_MAC_ADDR;
    }//end if

    //try to get mac address from data
    NSString *macAddress = nil;
    for(int i = 0 ; i < len ; i++) {
        ns_rr rr;
        ns_parserr(&handle, ns_s_an, 0, &rr);

        if(ns_rr_class(rr) == ns_c_in &&
           ns_rr_type(rr) == ns_t_ptr &&
           !strcmp(ns_rr_name(rr), QUERY_NAME)) {
            char *ptr = (char *)(ns_rr_rdata(rr) + 1);
            int l = (int)strcspn(ptr, "@");

            char *tmp = calloc(l + 1, sizeof(char));
            if(!tmp) {
                perror("calloc()");
                continue;
            }//end if
            memcpy(tmp, ptr, l);
            macAddress = [NSString stringWithUTF8String:tmp];
            free(tmp);
        }//end if
    }//end for each
    macAddress = macAddress ? macAddress : DUMMY_MAC_ADDR;
    return macAddress;
}//end getMacAddressFromMDNS

- (nonnull NSString *)currentIPAddressOf: (nonnull NSString *)device {
    struct ifaddrs *addrs;
    NSString *ipAddress = nil;

    if(getifaddrs(&addrs) != 0) {
        return nil;
    }//end if

    //get ipv4 address
    for(struct ifaddrs *addr = addrs ; addr ; addr = addr->ifa_next) {
        if(!strcmp(addr->ifa_name, [device UTF8String])) {
            if(addr->ifa_addr) {
                struct sockaddr_in *in_addr = (struct sockaddr_in *)addr->ifa_addr;
                if(in_addr->sin_family == AF_INET) {
                    ipAddress = [self IPv4Ntop:in_addr->sin_addr.s_addr];
                    break;
                }//end if
            }//end if
        }//end if
    }//end for

    freeifaddrs(addrs);
    return ipAddress;
}//end currentIPAddressOf:

- (nullable NSString *)IPv4Ntop: (in_addr_t)addr {
    char buffer[INET_ADDRSTRLEN] = {0};
    return inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)) ?
    [NSString stringWithUTF8String:buffer] : nil;
}//end IPv4Ntop:

- (in_addr_t)IPv4Pton: (nonnull NSString *)IPAddr {
    in_addr_t network = INADDR_NONE;
    return inet_pton(AF_INET, [IPAddr UTF8String], &network) == 1 ?
    network : INADDR_NONE;
}//end IPv4Pton:

如果出现 “_res_9_ninit", referenced from:”这种报错,是因为没有添加步骤1的几个库

3.UUID+自己存储

3.1 获取UUID的两个方法

/**  卸载应用重新安装后会不一致*/
+ (NSString *)getUUID{
    CFUUIDRef uuid = CFUUIDCreate(NULL);
    NSString *UUID = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, uuid);
    CFRelease(uuid);
    return UUID;
}

/**  卸载应用重新安装后会不一致*/
+ (NSString *)getUUID{
    return [UIDevice currentDevice].identifierForVendor.UUIDString;;
}

很明显UUID已经不足以支持设备的唯一性了,目前很多App都有新用户的优惠,但是又要保证每台设备绑定一个账户,如果单纯使用UUID的话已经满足不了这个需求,所以,这里需要用keychain保存,这样即使卸载app在安装,获取到的UUID也是唯一性的。

3.2 首先在项目中添加 KeyChain Sharing

3.3 导入第三方库 Security.framework

3.4 核心代码(代码有点多)

在github搜索SSKeychain可以找到,只要 SSKeychain.h 和 SSKeychain.m 文件即可

#import <Foundation/Foundation.h>
#import <Security/Security.h>

/** Error codes that can be returned in NSError objects. */
typedef enum {
	/** No error. */
	SSKeychainErrorNone = noErr,

	/** Some of the arguments were invalid. */
	SSKeychainErrorBadArguments = -1001,

	/** There was no password. */
	SSKeychainErrorNoPassword = -1002,

	/** One or more parameters passed internally were not valid. */
	SSKeychainErrorInvalidParameter = errSecParam,

	/** Failed to allocate memory. */
	SSKeychainErrorFailedToAllocated = errSecAllocate,

	/** No trust results are available. */
	SSKeychainErrorNotAvailable = errSecNotAvailable,

	/** Authorization/Authentication failed. */
	SSKeychainErrorAuthorizationFailed = errSecAuthFailed,

	/** The item already exists. */
	SSKeychainErrorDuplicatedItem = errSecDuplicateItem,

	/** The item cannot be found.*/
	SSKeychainErrorNotFound = errSecItemNotFound,

	/** Interaction with the Security Server is not allowed. */
	SSKeychainErrorInteractionNotAllowed = errSecInteractionNotAllowed,

	/** Unable to decode the provided data. */
	SSKeychainErrorFailedToDecode = errSecDecode
} SSKeychainErrorCode;

extern NSString *const kSSKeychainErrorDomain;

/** Account name. */
extern NSString *const kSSKeychainAccountKey;

/**
 Time the item was created.

 The value will be a string.
 */
extern NSString *const kSSKeychainCreatedAtKey;

/** Item class. */
extern NSString *const kSSKeychainClassKey;

/** Item description. */
extern NSString *const kSSKeychainDescriptionKey;

/** Item label. */
extern NSString *const kSSKeychainLabelKey;

/** Time the item was last modified.

 The value will be a string.
 */
extern NSString *const kSSKeychainLastModifiedKey;

/** Where the item was created. */
extern NSString *const kSSKeychainWhereKey;

/**
 Simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system
 Keychain on Mac OS X and iOS.

 This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors.
 SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it).
 */
@interface SSKeychain : NSObject

///-----------------------
/// @name Getting Accounts
///-----------------------

/**
 Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts.

 See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
 dictionaries returned by this method.

 @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
 accounts. The order of the objects in the array isn't defined.

 @see allAccounts:
 */
+ (NSArray *)allAccounts;

/**
 Returns an array containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
 accounts.

 See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
 dictionaries returned by this method.

 @param error If accessing the accounts fails, upon return contains an error that describes the problem.

 @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
 accounts. The order of the objects in the array isn't defined.

 @see allAccounts
 */
+ (NSArray *)allAccounts:(NSError **)error;

/**
 Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any
 accounts for the given service.

 See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
 dictionaries returned by this method.

 @param serviceName The service for which to return the corresponding accounts.

 @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain
 doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined.

 @see accountsForService:error:
 */
+ (NSArray *)accountsForService:(NSString *)serviceName;

/**
 Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any
 accounts for the given service.

 @param serviceName The service for which to return the corresponding accounts.

 @param error If accessing the accounts fails, upon return contains an error that describes the problem.

 @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain
 doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined.

 @see accountsForService:
 */
+ (NSArray *)accountsForService:(NSString *)serviceName error:(NSError **)error;

///------------------------
/// @name Getting Passwords
///------------------------

/**
 Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a
 password for the given parameters.

 @param serviceName The service for which to return the corresponding password.

 @param account The account for which to return the corresponding password.

 @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't
 have a password for the given parameters.

 @see passwordForService:account:error:
 */
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;

/**
 Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a
 password for the given parameters.

 @param serviceName The service for which to return the corresponding password.

 @param account The account for which to return the corresponding password.

 @param error If accessing the password fails, upon return contains an error that describes the problem.

 @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't
 have a password for the given parameters.

 @see passwordForService:account:
 */
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;

/**
 Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data
 for the given parameters.

 @param serviceName The service for which to return the corresponding password.

 @param account The account for which to return the corresponding password.

 @param error If accessing the password fails, upon return contains an error that describes the problem.

 @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't
 have data for the given parameters.

 @see passwordDataForService:account:error:
 */
+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account;

/**
 Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data
 for the given parameters.

 @param serviceName The service for which to return the corresponding password.

 @param account The account for which to return the corresponding password.

 @param error If accessing the password fails, upon return contains an error that describes the problem.

 @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't
 have a password for the given parameters.

 @see passwordDataForService:account:
 */
+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;

///-------------------------
/// @name Deleting Passwords
///-------------------------

/**
 Deletes a password from the Keychain.

 @param serviceName The service for which to delete the corresponding password.

 @param account The account for which to delete the corresponding password.

 @return Returns `YES` on success, or `NO` on failure.

 @see deletePasswordForService:account:error:
 */
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;

/**
 Deletes a password from the Keychain.

 @param serviceName The service for which to delete the corresponding password.

 @param account The account for which to delete the corresponding password.

 @param error If deleting the password fails, upon return contains an error that describes the problem.

 @return Returns `YES` on success, or `NO` on failure.

 @see deletePasswordForService:account:
 */
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;

///------------------------
/// @name Setting Passwords
///------------------------

/**
 Sets a password in the Keychain.

 @param password The password to store in the Keychain.

 @param serviceName The service for which to set the corresponding password.

 @param account The account for which to set the corresponding password.

 @return Returns `YES` on success, or `NO` on failure.

 @see setPassword:forService:account:error:
 */
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;

/**
 Sets a password in the Keychain.

 @param password The password to store in the Keychain.

 @param serviceName The service for which to set the corresponding password.

 @param account The account for which to set the corresponding password.

 @param error If setting the password fails, upon return contains an error that describes the problem.

 @return Returns `YES` on success, or `NO` on failure.

 @see setPassword:forService:account:
 */
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;

/**
 Sets arbirary data in the Keychain.

 @param password The data to store in the Keychain.

 @param serviceName The service for which to set the corresponding password.

 @param account The account for which to set the corresponding password.

 @param error If setting the password fails, upon return contains an error that describes the problem.

 @return Returns `YES` on success, or `NO` on failure.

 @see setPasswordData:forService:account:error:
 */
+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account;

/**
 Sets arbirary data in the Keychain.

 @param password The data to store in the Keychain.

 @param serviceName The service for which to set the corresponding password.

 @param account The account for which to set the corresponding password.

 @param error If setting the password fails, upon return contains an error that describes the problem.

 @return Returns `YES` on success, or `NO` on failure.

 @see setPasswordData:forService:account:
 */
+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;

///--------------------
/// @name Configuration
///--------------------

#if __IPHONE_4_0 && TARGET_OS_IPHONE
/**
 Returns the accessibility type for all future passwords saved to the Keychain.

 @return Returns the accessibility type.

 The return value will be `NULL` or one of the "Keychain Item Accessibility Constants" used for determining when a
 keychain item should be readable.

 @see accessibilityType
 */
+ (CFTypeRef)accessibilityType;

/**
 Sets the accessibility type for all future passwords saved to the Keychain.

 @param accessibilityType One of the "Keychain Item Accessibility Constants" used for determining when a keychain item
 should be readable.

 If the value is `NULL` (the default), the Keychain default will be used.

 @see accessibilityType
 */
+ (void)setAccessibilityType:(CFTypeRef)accessibilityType;
#endif

@end

3.4 创建新类,引用 SSKeychain 封装

#import "GetKeychain.h"
#import "SSKeychain.h"

@implementation GetKeychain

+ (NSString *)getDeviceUUID {
    NSString *currentDeviceUUIDStr = [SSKeychain passwordForService:@"项目boudle id" account:@"uuid"];
    if (currentDeviceUUIDStr == nil || [currentDeviceUUIDStr isEqualToString:@""])
    {
        NSUUID *currentDeviceUUID  = [UIDevice currentDevice].identifierForVendor;
        currentDeviceUUIDStr = currentDeviceUUID.UUIDString;
        currentDeviceUUIDStr = [currentDeviceUUIDStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
        currentDeviceUUIDStr = [currentDeviceUUIDStr lowercaseString];
        [SSKeychain setPassword: currentDeviceUUIDStr forService:@"项目boudle id" account:@"uuid"];
    }

    return currentDeviceUUIDStr;
}

@end

以上就是iOS获取设备唯一标识的实现步骤的详细内容,更多关于iOS获取设备唯一标识的资料请关注我们其它相关文章!

(0)

相关推荐

  • iOS获取设备唯一标识的8种方法

    8种iOS获取设备唯一标识的方法,希望对大家有用. UDID UDID(Unique Device Identifier),iOS 设备的唯一识别码,是一个40位十六进制序列(越狱的设备通过某些工具可以改变设备的 UDID),移动网络可以利用 UDID 来识别移动设备. 许多开发者把 UDID 跟用户的真实姓名.密码.住址.其它数据关联起来,网络窥探者会从多个应用收集这些数据,然后顺藤摸瓜得到这个人的许多隐私数据,同时大部分应用确实在频繁传输 UDID 和私人信息. 为了避免集体诉讼,苹果最终决

  • 浅谈android获取设备唯一标识完美解决方案

    本文介绍了浅谈android获取设备唯一标识完美解决方案,分享给大家,具体如下: /** * deviceID的组成为:渠道标志+识别符来源标志+hash后的终端识别符 * * 渠道标志为: * 1,andriod(a) * * 识别符来源标志: * 1, wifi mac地址(wifi): * 2, IMEI(imei): * 3, 序列号(sn): * 4, id:随机码.若前面的都取不到时,则随机生成一个随机码,需要缓存. * * @param context * @return */ p

  • Android 如何获取设备唯一标识

    一. 先简单总结一下比较常见的几个解决方案的弊端: 1. IMEI Android 10 中官方明确说明第三方应用无法获取到IMEI码:Android 10 中的隐私权变更, Android 10 以下的版本,需要申请READ_PHONE_STATE权限. 2. Android ID Android ID 不具有真正的唯一性, ROOT.刷机.恢复出厂设置.不同签名的应用等都会导致获取的 Android ID 发生改变, 并且不同厂商定制的系统的BUG会导致不同的设备可能会产生相同的 Andro

  • iOS获取设备唯一标识的实现步骤

    目录 1. 常用的UUID 2. MAC 地址 2.1 首先导入下面几个库: 2.2 新建一个文件,继承NSObject,在.m文件导入头文件,以及定义一些宏 3.UUID+自己存储 3.1 获取UUID的两个方法 3.2 首先在项目中添加 KeyChain Sharing 3.3 导入第三方库 Security.framework 3.4 核心代码(代码有点多) 3.4 创建新类,引用 SSKeychain 封装 1. 常用的UUID UDID是一个40位十六进制序列(越狱的设备通过某些工具可

  • iOS 获取设备唯一标示符的方法详解

    在开发中会遇到应用需要记录设备标示,即使应用卸载后再安装也可重新识别的情况,在这写一种实现方式--读取设备的UUID(Universally Unique Identifier)并通过KeyChain记录. 首先iOS中获取设备唯一标示符的方法一直随版本的更新而变化.iOS 2.0版本以后UIDevice提供一个获取设备唯一标识符的方法uniqueIdentifier,通过该方法我们可以获取设备的序列号,这个也是目前为止唯一可以确认唯一的标示符.好景不长,因为该唯一标识符与手机一一对应,苹果觉得

  • 详解Android获取设备唯一ID的几种方式

    先来看看几种比较单一的方式: IMEI 方式:TelephonyManager.getDeviceId(): 问题 范围:只能支持拥有通话功能的设备,对于平板不可以. 持久性:返厂,数据擦除的时候不彻底,保留了原来的标识. 权限:需要权限:Android.permission.READ_PHONE_STATE bug: 有些厂家的实现有bug,返回一些不可用的数据  Mac地址 ACCESS_WIFI_STATE权限 有些设备没有WiFi,或者蓝牙,就不可以,如果WiFi没有打开,硬件也不会返回

  • android获取手机唯一标识的方法

    复制代码 代码如下: import android.provider.Settings.Secure; private String android_id = Secure.getString(getContext().getContentResolver(),Secure.ANDROID_ID); UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hash

  • iOS App开发中通过UIDevice类获取设备信息的方法

    UIDevice提供了多种属性.类函数及状态通知,帮助我们全方位了解设备状况.从检测电池电量到定位设备与临近感应,UIDevice所做的工作就是为应用程序提供用户及设备的一些信息.UIDevice类还能够收集关于设备的各种具体细节,例如机型及iOS版本等.其中大部分属性都对开发工作具有积极的辅助作用.下面的代码简单的使用UIDevice获取手机属性. 简单示例:设备相关信息的获取    NSString *strName = [[UIDevice currentDevice] name];   

  • android手机获取唯一标识的方法

    获取手机唯一标识 拼接的方式获取手机唯一标识 第一种方式是获取IMEI,但是有的手机如果不是正品的话,就获取不到所以通过这一种方式还是会出现有的设备是没有唯一标识的 第二种方式获取手机卡的序列号,当然这种也不是唯一的,因为有的手机是双卡双待的所以可能会出现空的情况 第三种方式是万能的也就是UUID,随机生成一个标识,但是必须保存在本地,防止下一次进入的时候再次生成随机码 进行三层判断,来获取手机的唯一标识. //获取手机的唯一标识 public String getPhoneSign(){ St

  • android 获取APP的唯一标识applicationId的实例

    使用getIdentifier()方法可以方便的获各应用包下的指定资源ID. 方式一 int indentify = getResources().getIdentifier("com.test.demo:drawable/icon",null,null); 第一个参数格式是:包名 + : +资源文件夹名 + / +资源名:是这种格式 然后其他的可以为null 方式二 intindentify= getResources().getIdentifier("icon"

随机推荐