Flutter设备日历访问插件persistent_device_calendar的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter设备日历访问插件persistent_device_calendar的使用

特性

此包包含一个设备日历插件的包装器,该插件添加了持久性和生活质量改进,减少了常见用例中的样板代码,并提高了代码的可读性和简洁性。

注意:此包目前仅旨在提供基本的日历功能,事件的重复尚未与该包一起测试且不被支持。

示例

void usage() async {
  var calPlugin = PersistentDeviceCalendar();
  if (!await calPlugin.setup()) return; // 检查权限是否已授予,如果没有则返回

  var start = TZDateTime.now(getLocation("America/Detroit")); // 设置常量调试时间
  var end = start.add(const Duration(hours: 2));

  var calendar = await calPlugin.getCalendar<CustomEvent>(
      name: "Custom Events",
      builder: (event, calendarId, eventId) => Event(
            calendarId,
            eventId: eventId,
            title: event.name,
            start: start,
            end: end,
          ),
      idSelector: (event) => event.id
  );
  await calendar.prune(); // 可选:移除已在设备上删除的注册事件

  var events = [
    CustomEvent(id: "a", name: "Event A"),
    CustomEvent(id: "b", name: "Event B"),
    CustomEvent(id: "c", name: "Event C")
  ];
  await calendar.put(events); // 将事件写入日历,可能替换旧版本
}

class CustomEvent {
  String id;
  String name;

  CustomEvent({
    required this.id,
    required this.name,
  });
}

时区处理(来自device_calendar)

由于收到的反馈,从4.0.0开始,我们将使用timezone包来更好地处理所有时区数据。

这已经在本包中包含了。但是,每次需要使用该包时,你需要添加以下导入语句:

import 'package:timezone/timezone.dart';

如果你的应用程序不需要任何特定时区的功能,你可以使用flutter_native_timezone来获取设备的当前时区,然后将之前的DateTime转换为当前时区。

import 'package:flutter_native_timezone/flutter_native_timezone.dart';

// 例如,我们的默认时区是UTC。
Location _currentLocation = getLocation('Etc/UTC');

Future setCurentLocation() async {
  String timezone = 'Etc/UTC';
  try {
    timezone = await FlutterNativeTimezone.getLocalTimezone();
  } catch (e) {
    print('无法获取本地时区');
  }
  _currentLocation = getLocation(timezone);
  setLocalLocation(_currentLocation);
}

...

event.start = TZDateTime.from(oldDateTime, _currentLocation);

对于其他用例、反馈或未来的开发,请随时在GitHub上发起讨论。

平台设置(来自device_calendar)

Android集成

要在你的应用中指示需要修改日历的权限,需要将以下内容添加到AndroidManifest.xml文件中:

<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
Proguard / R8异常

默认情况下,所有Android应用程序在构建发布版本时都会通过R8进行文件缩减。当前,它会干扰一些函数,如retrieveCalendars()

你可以在ProGuard规则文件proguard-rules.pro中添加以下设置(感谢Britannio Jarrett)。更多关于问题的信息可以在这里查看。

-keep class com.builttoroam.devicecalendar.** { *; }

有关详细设置,可以参考这里。

更多信息,请参阅Android开发者指南。

AndroidX迁移

v.1.0以来,此版本已迁移到使用AndroidX而不是已弃用的Android支持库。当使用0.10.0及更高版本的插件时,请确保您的应用程序已按照此处的指南进行了迁移。

iOS集成

为了支持iOS 10及以上版本,你需要修改Info.plist文件以添加以下键值对:

<key>NSCalendarsUsageDescription</key>
<string>访问日历查看和编辑的大部分功能。</string>

<key>NSContactsUsageDescription</key>
<string>访问联系人用于活动参与者编辑。</string>

更多关于Flutter设备日历访问插件persistent_device_calendar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter设备日历访问插件persistent_device_calendar的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用persistent_device_calendar插件来访问设备日历的一个示例代码案例。这个插件允许你读取和写入设备的日历事件。

步骤 1: 添加依赖

首先,你需要在pubspec.yaml文件中添加persistent_device_calendar依赖:

dependencies:
  flutter:
    sdk: flutter
  persistent_device_calendar: ^x.y.z  # 请替换为最新版本号

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

步骤 2: 配置Android和iOS权限

Android

android/app/src/main/AndroidManifest.xml文件中添加以下权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">
    
    <uses-permission android:name="android.permission.READ_CALENDAR"/>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
    
    <application
        ... >
        ...
    </application>
</manifest>

iOS

ios/Runner/Info.plist文件中添加以下权限:

<key>NSCalendarsUsageDescription</key>
<string>需要访问您的日历以添加和管理事件</string>

步骤 3: 请求权限并访问日历

在你的Flutter代码中,你可以这样请求权限并访问日历:

import 'package:flutter/material.dart';
import 'package:persistent_device_calendar/persistent_device_calendar.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  CalendarPlugin? _calendarPlugin;
  bool _hasReadPermission = false;
  bool _hasWritePermission = false;

  @override
  void initState() {
    super.initState();
    _calendarPlugin = CalendarPlugin();
    _requestPermissions();
  }

  Future<void> _requestPermissions() async {
    var readStatus = await _calendarPlugin!.requestReadPermission();
    var writeStatus = await _calendarPlugin!.requestWritePermission();

    setState(() {
      _hasReadPermission = readStatus;
      _hasWritePermission = writeStatus;
    });

    if (_hasReadPermission && _hasWritePermission) {
      _fetchEvents();
    }
  }

  Future<void> _fetchEvents() async {
    var events = await _calendarPlugin!.retrieveEvents(
      DateTime.now().subtract(Duration(days: 30)),
      DateTime.now().add(Duration(days: 30)),
    );

    print('Fetched events: $events');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Calendar Access Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'Read Permission: $_hasReadPermission',
                style: TextStyle(fontSize: 20),
              ),
              SizedBox(height: 20),
              Text(
                'Write Permission: $_hasWritePermission',
                style: TextStyle(fontSize: 20),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

注意事项

  1. 权限请求结果:在请求权限后,你需要检查用户是否授予了权限,并据此决定是否继续执行后续操作。
  2. 错误处理:在实际应用中,应该添加错误处理逻辑,以处理例如权限被拒绝或网络错误等情况。
  3. 事件写入:示例中只展示了如何读取事件,写入事件的代码类似,可以使用createOrUpdateEvent方法。

这是一个基础示例,展示了如何使用persistent_device_calendar插件来请求权限并访问设备日历。你可以根据实际需求进一步扩展和修改代码。

回到顶部