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

Xamarin Android中已弃用CursorLoader的替代方案及日历列表获取方法

替代CursorLoader获取Xamarin Android日历列表的方案

问题背景

开发Xamarin Android应用时,需要获取系统日历列表,但现有实现使用了已废弃的CursorLoader,需要替代方案。原代码如下:

AndroidCalendarModels _androidCalendarModel = new AndroidCalendarModels();
string[] calendarsProjection = {
    CalendarContract.Calendars.InterfaceConsts.Id,
    CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName,
    CalendarContract.Calendars.InterfaceConsts.AccountName 
};

var calendarsUri = CalendarContract.Calendars.ContentUri;            
var loader = new CursorLoader(Android.App.Application.Context, calendarsUri, calendarsProjection, null, null, null);
var cursor = (ICursor)loader.LoadInBackground();

while (cursor.MoveToNext())
{
    int calId = cursor.GetInt(0);
    string calName = cursor.GetString(1);
    string calAccount = cursor.GetString(2);

    _androidCalendarModel.Calendars.Add(new AndroidCalendarModel()
    {
        Id = calId,
        AccountName = calAccount,
        CalendarDisplayName = calName,
    });
}

替代实现方案

直接使用ContentResolver的Query方法即可替代CursorLoader,这是官方推荐的替代方式,无需依赖已废弃的Loader类。

1. 修改后的核心代码

AndroidCalendarModels _androidCalendarModel = new AndroidCalendarModels();
string[] calendarsProjection = {
    CalendarContract.Calendars.InterfaceConsts.Id,
    CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName,
    CalendarContract.Calendars.InterfaceConsts.AccountName 
};

var calendarsUri = CalendarContract.Calendars.ContentUri;
// 使用ContentResolver.Query替代CursorLoader
using (var cursor = Application.Context.ContentResolver.Query(calendarsUri, calendarsProjection, null, null, null))
{
    if (cursor != null)
    {
        while (cursor.MoveToNext())
        {
            int calId = cursor.GetInt(cursor.GetColumnIndex(CalendarContract.Calendars.InterfaceConsts.Id));
            string calName = cursor.GetString(cursor.GetColumnIndex(CalendarContract.Calendars.InterfaceConsts.CalendarDisplayName));
            string calAccount = cursor.GetString(cursor.GetColumnIndex(CalendarContract.Calendars.InterfaceConsts.AccountName));

            _androidCalendarModel.Calendars.Add(new AndroidCalendarModel()
            {
                Id = calId,
                AccountName = calAccount,
                CalendarDisplayName = calName,
            });
        }
    }
}

2. 关键注意事项

  • 权限申请:必须在AndroidManifest.xml中添加日历读取权限,同时在运行时动态申请:
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    
    动态权限申请代码示例:
    if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadCalendar) != Permission.Granted)
    {
        ActivityCompat.RequestPermissions(this, new string[] { Manifest.Permission.ReadCalendar }, 100);
    }
    
  • Android 11+适配:针对Android 11及以上版本,需要在Manifest中添加查询权限声明,确保能正常访问日历数据:
    <queries>
        <intent>
            <action android:name="android.content.action.VIEW" />
            <data android:mimeType="vnd.android.cursor.dir/event" />
        </intent>
    </queries>
    
  • Cursor资源管理:使用using语句包裹Cursor,确保资源自动释放,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:40:34