Flutter联系人管理插件flutter_contact的使用

Flutter联系人管理插件flutter_contact的使用

pub package Coverage Status

一个用于访问和管理设备原生联系人的Flutter插件。

使用

要使用此插件,需要在 pubspec.yaml 文件中添加 flutter_contact 依赖。例如:

dependencies:
    flutter_contact: ^0.6.1

权限

Android

AndroidManifest.xml 中添加以下权限:

<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />

iOS

Info.plist 文件中设置 NSContactsUsageDescription

<key>NSContactsUsageDescription</key>
<string>您的应用需要访问联系人信息。</string>

注意

flutter_contact 不处理请求和检查权限的过程。为了检查和请求用户访问联系人的权限,可以尝试使用以下插件:flutter_simple_permissionspermission_handler

如果没有请求用户权限或权限未被授予,应用程序将失败。对于测试目的,您可以在设备上手动为您的测试应用设置权限。对于Android,进入 “设置” -> “应用” -> 选择您的测试应用 -> “权限” -> 然后打开 “联系人” 的开关。

统一与单个联系人

有两个主要的入口点:SingleContactsUnifiedContacts。它们共享相同的API,并且大部分底层代码相同,但有以下区别:

  • SingleContacts 将与每个平台上的未链接的原始联系人进行交互。
  • UnifiedContacts 将与每个平台上的已链接/聚合的联系人进行交互。

内存效率

该插件试图成为内存和CPU友好的。它不会将整个通讯录加载到内存中,而是提供一些更友好内存的方式迭代联系人:

流式处理

import 'package:flutter_contact/contact.dart';

// 默认情况下,这将使用每页20个联系人的方式遍历所有联系人。
await Contacts.streamContacts().forEach((contact) {
    print("${contact.displayName}"); // 打印联系人的显示名称
});

// 您可以手动调整缓冲区大小
Stream<Contact> contacts = await Contacts.streamContacts(bufferSize: 50);

分页列表

另一种选项是分页列表,它也使用底层的分页缓冲区,但不需要管理任何订阅,并且具有其他一些功能,如总数:

import 'package:flutter_contact/contact.dart';

final contacts = Contacts.listContacts();
final total = await contacts.length;

// 这将获取该联系人所属的页面,并返回该联系人
final contact = await contacts.get(total - 1);

while(await contacts.moveNext()) {
    final contact = await contacts.current;
}

示例

以下是一些使用 flutter_contact 插件的示例代码:

// 导入包
import 'package:flutter_contact/contact.dart';

// 获取设备上所有联系人作为流
Stream<Contact> contacts = await Contacts.streamContacts();

// 获取设备上所有不带缩略图的联系人(更快)
Iterable<Contact> contacts = await Contacts.streamContacts(withThumbnails: false);

// 获取匹配字符串的联系人
Stream<Contact> johns = await Contacts.streamContacts(query: "john");

// 添加联系人
// 联系人必须具有firstName / lastName才能成功添加
await Contacts.addContact(newContact);

// 删除联系人
// 联系人必须具有有效的标识符
await Contacts.deleteContact(contact);

// 更新联系人
// 联系人必须具有有效的标识符
await Contacts.updateContact(contact);

// 懒加载联系人头像数据而不将其缓存在联系人实例中
final contact = Contacts.getContact(contactId);
final Uint8List avatarData = await contact.getOrFetchAvatar();

完整示例

以下是一个完整的示例代码,展示了如何使用 flutter_contact 插件来请求权限并列出联系人:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_contact_example/people_list_page.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:logging/logger.dart';
import 'package:logging_config/logging_config.dart';
import 'package:permission_handler/permission_handler.dart';

import 'add_contact_page.dart';

void main() {
  configureLogging(LogConfig.root(Logger.level.INFO));
  runApp(ContactsExampleApp());
}

class ContactsExampleApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: <String, WidgetBuilder>{
        '/': (context) => const HomePage(),
        '/add': (BuildContext context) => AddContactPage(),
        '/contactsList': (BuildContext context) => PeopleListPage(),
      },
    );
  }
}

class HomePage extends StatefulWidget {
  [@override](/user/override)
  _HomePageState createState() => _HomePageState();

  const HomePage();
}

class _HomePageState extends State<HomePage> {
  bool? _hasPermission;

  [@override](/user/override)
  void initState() {
    super.initState();
    _askPermissions();
  }

  Future<void> _askPermissions() async {
    PermissionStatus? permissionStatus;
    while (permissionStatus != PermissionStatus.granted) {
      try {
        permissionStatus = await _getContactPermission();
        if (permissionStatus != PermissionStatus.granted) {
          _hasPermission = false;
          _handleInvalidPermissions(permissionStatus);
        } else {
          _hasPermission = true;
        }
      } catch (e) {
        if (await showPlatformDialog(
                context: context,
                builder: (context) {
                  return PlatformAlertDialog(
                    title: Text('联系人权限'),
                    content: Text(
                        '我们无法获取权限。您想打开应用设置来修复吗?'),
                    actions: [
                      PlatformDialogAction(
                        onPressed: () {
                          Navigator.pop(context, false);
                        },
                        child: Text('关闭'),
                      ),
                      PlatformDialogAction(
                        onPressed: () {
                          Navigator.pop(context, true);
                        },
                        child: Text('设置'),
                      ),
                    ],
                  );
                }) ==
            true) {
          await openAppSettings();
        }
      }
    }

    await Navigator.of(context).pushReplacementNamed('/contactsList');
  }

  Future<PermissionStatus> _getContactPermission() async {
    final status = await Permission.contacts.status;
    if (!status.isGranted) {
      final result = await Permission.contacts.request();
      return result;
    } else {
      return status;
    }
  }

  void _handleInvalidPermissions(PermissionStatus permissionStatus) {
    if (permissionStatus == PermissionStatus.denied) {
      throw PlatformException(
          code: 'PERMISSION_DENIED',
          message: '访问联系人数据被拒绝',
          details: null);
    } else if (permissionStatus == PermissionStatus.restricted) {
      throw PlatformException(
          code: 'PERMISSION_DISABLED',
          message: '设备上未提供联系人数据',
          details: null);
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('联系人插件示例')),
      body: _hasPermission == null
          ? Center(child: PlatformCircularProgressIndicator())
          : SafeArea(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  ElevatedButton(
                    child: const Text('联系人列表'),
                    onPressed: () =>
                        Navigator.pushNamed(context, '/contactsList'),
                  ),
                  ElevatedButton(
                    child: const Text('原生联系人选择器'),
                    onPressed: () =>
                        Navigator.pushNamed(context, '/nativeContactPicker'),
                  ),
                ],
              ),
            ),
    );
  }
}

更多关于Flutter联系人管理插件flutter_contact的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter联系人管理插件flutter_contact的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


Flutter 提供了许多插件来简化开发过程,其中一个有用的插件是 flutter_contacts,它允许你在 Flutter 应用中访问和管理设备的联系人。以下是使用 flutter_contacts 插件的详细步骤。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 flutter_contacts 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  flutter_contacts: ^1.0.0  # 使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 请求权限

访问联系人需要用户权限,因此在访问联系人之前,你需要请求相应的权限。在 Android 上,你需要 READ_CONTACTSWRITE_CONTACTS 权限。在 iOS 上,你需要 Contacts 权限。

你可以使用 permission_handler 插件来请求权限。

首先,添加 permission_handler 插件的依赖:

dependencies:
  permission_handler: ^10.0.0  # 使用最新版本

然后请求权限:

import 'package:permission_handler/permission_handler.dart';

Future<void> requestContactsPermission() async {
  if (await Permission.contacts.request().isGranted) {
    // 权限已授予
  } else {
    // 权限被拒绝
  }
}

3. 使用 flutter_contacts 插件

初始化

在请求权限后,你可以使用 flutter_contacts 插件来访问联系人。

import 'package:flutter_contacts/flutter_contacts.dart';

Future<void> getContacts() async {
  if (await Permission.contacts.request().isGranted) {
    List<Contact> contacts = await FlutterContacts.getContacts();
    for (var contact in contacts) {
      print(contact.displayName);
    }
  } else {
    print('Permission denied');
  }
}

添加联系人

你可以使用 flutter_contacts 插件来添加新的联系人。

Contact newContact = Contact()
  ..name.firstName = 'John'
  ..name.lastName = 'Doe'
  ..phones = [Phone('1234567890')];

await FlutterContacts.insertContact(newContact);

更新联系人

你可以更新现有的联系人。

Contact contactToUpdate = await FlutterContacts.getContact(contactId);
contactToUpdate.phones[0].number = '0987654321';

await FlutterContacts.updateContact(contactToUpdate);

删除联系人

你可以删除联系人。

await FlutterContacts.deleteContact(contactId);

4. 完整示例

import 'package:flutter/material.dart';
import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ContactsScreen(),
    );
  }
}

class ContactsScreen extends StatefulWidget {
  [@override](/user/override)
  _ContactsScreenState createState() => _ContactsScreenState();
}

class _ContactsScreenState extends State<ContactsScreen> {
  List<Contact> contacts = [];

  Future<void> getContacts() async {
    if (await Permission.contacts.request().isGranted) {
      List<Contact> fetchedContacts = await FlutterContacts.getContacts();
      setState(() {
        contacts = fetchedContacts;
      });
    } else {
      print('Permission denied');
    }
  }

  [@override](/user/override)
  void initState() {
    super.initState();
    getContacts();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Contacts'),
      ),
      body: ListView.builder(
        itemCount: contacts.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(contacts[index].displayName),
            subtitle: contacts[index].phones.isNotEmpty
                ? Text(contacts[index].phones.first.number)
                : null,
          );
        },
      ),
    );
  }
}
回到顶部