如何使用 Java 访问我的 Mac 上的日历?

How can I access calendars on my Mac with Java?

我想读取 Mac (12.1 Monterey) 上的 Apple 日历应用本地存储的数据。 数据存储在 ~/Library/Calendars/ 的子目录中,每个日历一个子目录。 问题:当我尝试从那里获取文件列表时,Java returns null:

String userHomeDir = System.getProperty("user.home");
File calendarRoot = new File(userHomeDir + "/Library/Calendars/");
File[] calendars = calendarRoot.listFiles();
System.out.println("Number of files: " + calendars.length); // NPE thrown here

文件权限如下:

Library 中列出文件工作正常。

如何访问该文件夹?

简答

放弃吧。 Apple 几乎不可能优雅地获得一个 Java 应用程序来读取日历数据。

长答案

由于某些版本(Catalina?),目录 ~/Library/Calendars/ 和所有子目录(以及其中的文件)受 MacOS 使用扩展属性保护,即 com.apple.quarantine.

过去可以使用系统设置授予应用程序访问日历数据的特定权限 - 安全和隐私 - 隐私 - 日历。但是,手动 +-按钮现在已经消失了。

我要做的是使用一些 zsh 脚本将所需的日历事件导出到另一个目录,并从那里也删除 com.apple.quarantine 属性。

这并不优雅,离开了 Java 世界,但就我而言,有一个 Java 命令行应用程序从指定的 shell 脚本启动,它工作得很好.

这是我想出的:

#!/bin/zsh

calendars="/Users/yourUserName/Library/Calendars"
target="/Users/yourUserName/some/other/directory/Calendar_Export"

cd ${calendars}

calsource=""
for f in *.calendar
do
    linesFound=`grep -c '<string>Your Calendar Name</string>' ${f}/Info.plist`
    if [[ ${linesFound} -eq 1 ]]
    then
        echo "The relevant calendar resides at " ${f}", copying all events"
        calsource=${calendars}/${f}/Events
    fi
done

if [[ ${calsource} != "" ]]
then
    rm ${target}/*
    cp ${calsource}/* ${target}/
    xattr -d com.apple.quarantine ${target}/*
fi