【问题标题】:Opening Android App from Calendar从日历打开 Android 应用程序
【发布时间】:2017-09-21 19:38:43
【问题描述】:

我正在开发的应用程序需要能够在所选日历中创建事件,然后当用户在他们的日历查看应用程序中查看这些事件时,它会提供一个选项以返回到我的应用程序以查看有关它的更多信息以及与之相关的数据。

使用 Calendar Provider 我可以创建事件并将 Uri 存储到事件中以供以后使用/删除,但我还没有找到在日历查看应用程序中从这些事件中打开我的应用程序的好方法。

我考虑的 2 个选项是在事件描述中包含一个自定义 URL,单击该 URL 时将被我的应用程序中的意图过滤器捕获(例如 myapp://event/1000),或者我可以设置 @987654322创建事件时来自 CalendarContract 的 @ 值。

我对第一个选项的问题是,我认为我不能保证日历查看应用程序会正确地将我的自定义 URL 视为链接并让用户点击它(在我的 Google 日历中不起作用)药片)。第二个选项看起来更有希望,但我找不到太多解释如何使用它的文档。

有谁知道如何正确地做到这一点?任何帮助表示赞赏!

【问题讨论】:

  • 能否提供信息。关于如何实现您提供从日历返回应用程序的选项?
  • 嗨,伍斯特曼!您能否向我们提供有关您从日历返回应用程序的实现机制的信息,以查看有关它的更多信息。

标签: android android-calendar


【解决方案1】:

如果可以接受以 Jelly Bean (API 16+) 为目标,那么使用 CUSTOM_APP_PACKAGE 是最佳解决方案。添加新日历事件时,您只需填写CUSTOM_APP_PACKAGECUSTOM_APP_URI 字段(分别使用您的包名称和标识事件的URI):

ContentValues values = new ContentValues();
values.put(CalendarContract.Events.CALENDAR_ID, 1);
values.put(CalendarContract.Events.TITLE, "Check *.com");
values.put(CalendarContract.Events.DTSTART, beginTime.getTimeInMillis());
values.put(CalendarContract.Events.DTEND, endTime.getTimeInMillis());
values.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());

values.put(CalendarContract.Events.CUSTOM_APP_PACKAGE, getPackageName());
values.put(CalendarContract.Events.CUSTOM_APP_URI, "myAppointment://1");

getContentResolver().insert(CalendarContract.Events.CONTENT_URI, values);       

然后您需要指定作为 AndroidManifest.xml 的一部分(如 the documentation 解释的那样)将从日历应用程序调用以显示详细视图的 Activity,例如

    <activity android:name=".ShowCalendarDetailActivity">
        <intent-filter>
            <action android:name="android.provider.calendar.action.HANDLE_CUSTOM_EVENT" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="vnd.android.cursor.item/event" />
        </intent-filter>            
    </activity>

ShowCalendarDetailActivity 将在点击出现的按钮时启动,并将传递一个带有操作"android.provider.calendar.action.HANDLE_CUSTOM_EVENT" 的 Intent,其 URI 将是日历项 URI。

您提供的自定义 URI 在 extras 中,键为 CalendarContract.EXTRA_CUSTOM_APP_URI

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    String myCustomUri = getIntent().getStringExtra(CalendarContract.EXTRA_CUSTOM_APP_URI);

    ...
}

如果您想查看日历应用构建此意图的代码,请参阅EventInfoFragment.java 中的EventInfoFragment.updateCustomAppButton()

【讨论】:

  • 我还没有让它工作,因为日历中没有显示打开应用程序的按钮。我只使用 Intent(在额外内容中包含 CUSTOM_APP_PACKAGE 和 CUSTOM_APP_URI),而不是日历提供程序......这也是可能的还是我必须切换到日历提供程序?
  • 嗨@friday 我还没有实际测试过它,但是我在使用意图而不是内容提供者时遇到了其他问题(例如,添加联系人时)。因此,如果它不起作用,我不会感到惊讶...:/
【解决方案2】:

您列出的第一个选项在我的 Nexus S 上运行良好。我现在刚刚尝试过,以确保它在默认的 Google 日历应用程序中运行。

在我的例子中,我没有截取myapp://event/1000,我截取的是一个更像https://myspecialdomain.com/blahblah 的实际网址。浏览器开始加载,但在它有时间加载任何东西之前,它被我的应用程序换掉了。

如果你愿意,我明天可以给你看我的代码。

【讨论】:

  • 感谢您的快速回复(尽管我需要一段时间才能回复)。我最终使用了您对 API 级别低于 16 的建议,然后使用 CUSTOM_APP_PACKAGE 和 CUSTOM_APP_URI 用于 API 级别 16 或以上。虽然我希望有类似 CUSTOM_APP_PACKAGE 的东西适用于较低的 API 级别,但我很高兴在我完成实施工作之前听到您的建议有效。谢谢!
  • @Stephan 我完全按照你的建议做,出于某种原因,只打开了浏览器。当单击电子邮件、推文和 whatsapp 消息中的相同链接时,相同的意图过滤器可以完美运行。
  • 这是我的意图过滤器。知道这里有什么问题。
最近更新 更多