You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android平台Calendar的resultCode判定问题求助

关于通过onActivityResult判断日历事件是否创建成功的解决方案

嘿,我懂你遇到的这个坑——用ACTION_EDIT拉起系统日历编辑界面后,靠onActivityResult的resultCode根本没法准确判断用户到底有没有真的创建事件,毕竟很多厂商的日历应用返回结果太不统一了,不管是保存还是取消,大概率都给你返回RESULT_OK,完全没参考性。

给你几个实用的解决思路:

  • 通过查询日历数据库做最终验证
    这是最靠谱的方式,毕竟事件真的创建了才会出现在日历数据库里。不过前提是你得先获取READ_CALENDAR和WRITE_CALENDAR的动态权限(Android 6.0及以上需要),然后在onActivityResult里去查询验证。

    比如你可以在拉起日历的时候预设一个唯一的描述或者标记,之后用这个标记去匹配查询:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == RESULT_OK) {
            ContentResolver cr = getContentResolver();
            Uri eventUri = Events.CONTENT_URI;
            // 这里用你预先设置的唯一标识来筛选,比如自定义的描述
            String selection = Events.DESCRIPTION + " = ?";
            String[] selectionArgs = {"我的唯一事件标记"};
            Cursor cursor = cr.query(eventUri, new String[]{Events._ID}, selection, selectionArgs, null);
            
            if (cursor != null && cursor.moveToFirst()) {
                // 查到了,说明事件真的创建成功
                Toast.makeText(this, "日历事件已创建", Toast.LENGTH_SHORT).show();
                cursor.close();
            } else {
                // 没查到,大概率用户取消了保存
                Toast.makeText(this, "日历事件未创建", Toast.LENGTH_SHORT).show();
            }
        }
    }
    

    拉起日历的时候记得把这个唯一标识传进去:

    Intent intCalendar = new Intent(Intent.ACTION_EDIT);
    intCalendar.setType("vnd.android.cursor.item/event");
    intCalendar.putExtra(Events.DESCRIPTION, "我的唯一事件标记");
    startActivityForResult(intCalendar, 1);
    
  • 如果不需要用户编辑,改用ACTION_INSERT直接创建
    要是你不需要让用户手动修改事件内容,只是想快速创建,直接用ACTION_INSERT并带上所有事件参数(标题、时间、地点等),这种方式下部分厂商的日历会返回更准确的resultCode——保存返回RESULT_OK,取消返回RESULT_CANCELED。示例代码:

    Intent insertIntent = new Intent(Intent.ACTION_INSERT)
            .setData(Events.CONTENT_URI)
            .putExtra(Events.TITLE, "周末聚餐")
            .putExtra(Events.DTSTART, System.currentTimeMillis() + 86400000)
            .putExtra(Events.DTEND, System.currentTimeMillis() + 90000000)
            .putExtra(Events.EVENT_LOCATION, "XX餐厅");
    startActivityForResult(insertIntent, 1);
    

    不过还是要提醒你,部分厂商的日历依然不遵循这个规范,所以最好还是结合数据库查询做双重验证。

  • 适配新系统:替换废弃的startActivityForResult
    从Android 10(API 29)开始,startActivityForResult已经被废弃了,推荐用ActivityResultContracts.StartActivityForResult来替代,写法更简洁也更适配新系统:

    // 先注册启动器
    ActivityResultLauncher<Intent> calendarLauncher = registerForActivityResult(
            new StartActivityForResult(),
            result -> {
                if (result.getResultCode() == RESULT_OK) {
                    // 在这里执行数据库查询验证逻辑
                }
            }
    );
    
    // 拉起日历的时候调用launch方法
    Intent intCalendar = new Intent(Intent.ACTION_EDIT);
    intCalendar.setType("vnd.android.cursor.item/event");
    intCalendar.putExtra(Events.DESCRIPTION, "我的唯一事件标记");
    calendarLauncher.launch(intCalendar);
    

内容的提问来源于stack exchange,提问作者Breno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:04:13