3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flutterでカレンダーにアクセスする方法

Posted at

はじめに

Flutterでデバイス標準のカレンダーにアクセスする方法について調べましたので共有します。
サンプルとなるプロジェクトをGithubに作成しましたので、UIも含めたサンプルが欲しい方のご参考になれば幸いです。
(画面遷移にgo_routerriverpodを使っているので、初学者の方には全体像が若干ややこしく感じるかもしれませんが、サンプルプロジェクトのdevice_calendar_page.dartadd_event_page.dartを見ていただければ、内容わかりやすいかと思います)

目次

  1. カレンダーにアクセスできるパッケージ
  2. 設定
  3. カレンダーの取得
  4. カレンダーにイベントを登録
  5. さいごに
  6. 参考文献

カレンダーにアクセスできるパッケージ

device_calendarというパッケージを使えば簡単にデバイスのカレンダーへとアクセスできます。
使う際の設定も、AndroidならAndroidManifest.xml、iOSならInfo.plistに設定を数行追加するだけです。

設定

共通の設定

まずpubspec.yamlにdevice_calendarを追加して、pub getしてください。

Androidの場合

AndroidManifest.xmlに以下を追加してください

<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />

追加する場所は、manifestタグのすぐ下でOKです。

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.xxxxxx">
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    ・
    ・

iOSの場合

Info.plistに以下を追加します

<key>NSCalendarsUsageDescription</key>
<string>Access most functions for calendar viewing and editing.</string>
<key>NSContactsUsageDescription</key>
<string>Access contacts for event attendee editing.</string>

カレンダーの取得

device_calendarを使用すると、スマホ内のすべてのカレンダーの取得ができ、それぞれに読み書きできるようになります。
本記事では、説明簡略化のため、スマホでデフォルトの設定となっているカレンダーのみに絞り、カレンダーにイベントを登録
してみたい
と思います。
デフォルトのカレンダーを取得するメソッドは以下となります。
(メソッドの最後で、_defaultCalendarに代入しているのはクラス内の他の場所で変数として使用したかったからです)

  Future<Calendar> _getDefaultCalender() async {
      var permissionsGranted = await _deviceCalendarPlugin.hasPermissions();
      if (permissionsGranted.isSuccess && !permissionsGranted.data!) {
        permissionsGranted = await _deviceCalendarPlugin.requestPermissions();
        if (!permissionsGranted.isSuccess || !permissionsGranted.data!) {
          throw Exception("Not granted access to your calendar");
        }
      }

      final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars();
      final calendars = calendarsResult?.data;
      if(calendars == null || calendars.isEmpty) {
        throw Exception("Can not get calendars");
      }

      _defaultCalendar = calendars!
        .firstWhere((element) => element.isDefault ?? false);
      return _defaultCalendar!;
  }

コードの解説を行います。
まず、スマホ内のカレンダーは以下の部分で取得しています。

final calendarsResult = await _deviceCalendarPlugin.retrieveCalendars();
final calendars = calendarsResult?.data;

つづいて、
カレンダーは上記で取得可能なのですが、取得の前にカレンダーのアクセス許可があるか確認し、なければ許可を得る必要があります。
そのためのコードが以下です。

var permissionsGranted = await _deviceCalendarPlugin.hasPermissions();
if (permissionsGranted.isSuccess && !permissionsGranted.data!) {
  permissionsGranted = await _deviceCalendarPlugin.requestPermissions();
  if (!permissionsGranted.isSuccess || !permissionsGranted.data!) {
    throw Exception("Not granted access to your calendar");
  }
}

そして、最後に取得したカレンダーにはisDefaultというデフォルト設定のカレンダーかどうかを判定するプロパティがあるのでそのプロパティを元にデフォルトのカレンダーを取得しています。

_defaultCalendar = calendars!.firstWhere((element) => element.isDefault ?? false);

カレンダーの取得に失敗する場合

Emulatorを使用している場合で、カレンダーを使用したことがない場合、取得に失敗します。
Emulatorからカレンダーアプリを開いて、ログインしてからコードを実行してください。

カレンダーにイベントを登録

カレンダーにイベントを登録するメソッドは以下となります。
(自分の環境では実際にカレンダーに表示されるまで時間がかかりました(1~2分くらい?))

  Future<void> _addEvent() async{
    final event = Event(
      widget.defaultCalenderId,
      title: _titleController.text,
      start: TZDateTime.local(2022, 9, 28, 2),
      end: TZDateTime.local(2022, 9, 28, 3),
    );
    final result = await DeviceCalendarPlugin().createOrUpdateEvent(event);
    if(result == null) {
      return;
    }
    if(result.isSuccess){
      return;
    }

    if(!result.hasErrors){
      return;
    }

    throw Exception(result.errors.join());
  }

端的に説明すると、Eventインスタンスを作成し、DeviceCalendarPlugin().createOrUpdateEventメソッドの引数に渡すだけです。
私もすべて把握できていませんが、Eventクラスには場所やリマインダー、終日、出席者などといった設定もできるようです。
GoogleカレンダーやiOSのカレンダーをイメージしていただくとわかりやすいかと思います。

さいごに

DeviceCalendarPluginのメソッドを見ると、カレンダーの追加や、カレンダーに登録したイベントの取得や編集、削除といったことも行えそうです。大変便利なパッケージなので、カレンダーを実装する際は、一からカレンダーの作成をするのも一つの手段ですが、スマホに入っているデフォルトのカレンダーを使用するのもアリだと思いました。

参考文献

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?