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
相关产品推荐
相关产品推荐

