五、通讯录权限

五、通讯录权限

首先导入框架#import <Contacts/Contacts.h>,并在info.plist中配置NSContactsUsageDescription字段。

  • 获取当前App授权状态
    使用CNContactStore类的类方法authorizationStatusForEntityType:获取授权状态,参数传入CNEntityTypeContacts,授权状态枚举为:
typedef NS_ENUM(NSInteger, CNAuthorizationStatus)
{
    CNAuthorizationStatusNotDetermined = 0, // 未决定
    CNAuthorizationStatusRestricted, // 受限制
    CNAuthorizationStatusDenied, // 拒绝
    CNAuthorizationStatusAuthorized // 允许
}
  • 当未请求过授权时的操作
    当授权状态枚举值为CNAuthorizationStatusNotDetermined时,可以使用CNContactStore类的实例对象调用实例方法requestAccessForEntityType:completionHandler:来请求授权(即展示授权弹框,此时最好长期持有该对象以防止超出作用域后被销毁而导致的弹框一闪而逝),参数传入CNEntityTypeContacts,block回调用户选择的授权状态。

上述为iOS9.0后的方法,下面介绍iOS9.0前的方法。

9.0前需要使用#import <AddressBook/AddressBook.h>框架的内容,使用ABAddressBookGetAuthorizationStatus()函数获得当前授权状态,该状态为枚举类型

typedef CF_ENUM(CFIndex, ABAuthorizationStatus) {
    // 未决定
    kABAuthorizationStatusNotDetermined = 0,    // deprecated, use CNAuthorizationStatusNotDetermined
    // 受限制
    kABAuthorizationStatusRestricted,           // deprecated, use CNAuthorizationStatusRestricted
    // 拒绝
    kABAuthorizationStatusDenied,               // deprecated, use CNAuthorizationStatusDenied
    // 允许
    kABAuthorizationStatusAuthorized            // deprecated, use CNAuthorizationStatusAuthorized
}

同样在枚举值为kABAuthorizationStatusNotDetermined时使用函数ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {}来请求授权,其中第一个参数为ABAddressBookRef类型是函数ABAddressBookCreate()返回值,block中回调用户授权BOOL值。

完整逻辑代码为:

- (void)addressbook:(void(^)(BOOL allow))callback
{
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0
    /**
     iOS 9后支持该框架, 使用前需导入#import <Contacts/Contacts.h>框架
     */
    CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    if (status == CNAuthorizationStatusNotDetermined) // 用户未决定
    {
        CNContactStore *store = [[CNContactStore alloc] init];
        /** 请求用户授权使用通讯录前需要确保在info.plist中配置了如下字段, 否则会导致crash
         <key>NSContactsUsageDescription</key>
         <string>自定义提示信息可不填</string>
         */
        [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            NSLog(@"[通讯录]授权状态是:%@", granted ? @"允许" : @"不允许");
            if (callback) {
                dispatch_async(dispatch_get_main_queue(), ^{//用GCD的方式,保证在主线程上更新UI
                    callback(granted);
                });
            }
        }];
    }
    else if (status == CNAuthorizationStatusRestricted || status == CNAuthorizationStatusDenied) // 限制或禁止
    {
        NSLog(@"[通讯录]授权状态是:受限或不允许");
        if (callback) {
            callback(NO);
        }
    }
    else // 允许
    {
        NSLog(@"[通讯录]授权状态是:允许");
        if (callback) {
            callback(YES);
        }
    }
#else
    /**
     iOS 9以下使用通讯录时貌似需要添加字段, 需导入对应的#import <AddressBook/AddressBook.h>框架
     */
    ABAddressBookRef ref = ABAddressBookCreate();
    ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
    if (status != kABAuthorizationStatusAuthorized) { // 不是允许状态时
        // 进行弹框请求用户授权
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (error) {
                    NSLog(@"Error: %@", (__bridge NSError *)error);
                    if (callback) {
                        callback(NO);
                    }
                } else {
                    if (callback) {
                        callback(YES);
                    }
                }
            });
        });
    }else { // 允许
        if (callback) {
            callback(YES);
        }
    }
#endif
1. 在AndroidManifest.xml文件中添加权限: ```xml <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> ``` 2. 在Activity中申请权限: ```java if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 1); } else { // 已经有权限,可以执行读取通讯录操作 } if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_CONTACTS}, 2); } else { // 已经有权限,可以执行写入通讯录操作 } ``` 3. 处理权限申请结果: ```java @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case 1: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意了读取通讯录权限,可以执行读取通讯录操作 } else { // 用户拒绝了读取通讯录权限,无法执行读取通讯录操作 } break; case 2: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意了写入通讯录权限,可以执行写入通讯录操作 } else { // 用户拒绝了写入通讯录权限,无法执行写入通讯录操作 } break; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值