2012-02-17 38 views
4

我正在尝试使用ICS的新内容提供程序为日历创建日历。由于日历创建只能在SyncAdapter做,我创建了一个:使用Android 4.0(ICS)内容提供程序创建日历

public class CalendarSyncAdapter extends AbstractThreadedSyncAdapter 
{ 

    public CalendarSyncAdapter(Context context, boolean autoInitialize) 
    { 
     super(context, autoInitialize); 
    } 

    @Override 
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) 
    { 
     Log.i(Debug.TAG, "onPerformSync()"); 
    } 

    public void doCreateCalendar(Account account) 
    { 
      ContentResolver cr = getContext().getContentResolver(); 

      ContentValues values = new ContentValues(); 
      values.put(Calendars.ACCOUNT_NAME, account.name); 
      values.put(Calendars.ACCOUNT_TYPE, account.type); 
      values.put(Calendars.NAME, "newesttest"); 
      values.put(Calendars.CALENDAR_DISPLAY_NAME, "newestTest"); 
      values.put(Calendars.CALENDAR_COLOR, 0xFFFFFFFF); 
      values.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER); 
      values.put(Calendars.OWNER_ACCOUNT, account.name); 

      values.put(Calendars.SYNC_EVENTS, 1); 
      values.put(Calendars.VISIBLE, 1); 

      Uri creationUri = asSyncAdapter(Calendars.CONTENT_URI, account.name, account.type); 
      Uri created = cr.insert(creationUri, values); 
      long id = Long.parseLong(created.getLastPathSegment()); 

      Log.i(Debug.TAG, "Calendar created: " + id + " - " + created); 
    } 

    private Uri asSyncAdapter(Uri uri, String account, String accountType) 
    { 
     return uri.buildUpon() 
     .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER,"true") 
     .appendQueryParameter(Calendars.ACCOUNT_NAME, account) 
     .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build(); 
    } 
} 

但它不服务中运行就像我看到无处不在,因为我要的是用它来插入一个新的日历。在服务中运行不是必需的吗?似乎不是。

反正我实例化它在我的活动,并呼吁我的方法:

public void createCalendar(View v) 
{ 
    m_syncAdapter.doCreateCalendar(this, m_account); 
} 

它成功,没有怨言执行,但它返回的URI始终是相同的。当我解析它的行ID时,它总是12.当我检查我的日历时,没有什么新东西。

在我的清单我的一切设置:

... 

<application 

... 

    <activity android:name="Setup" android:label="@string/activity_title_setup"> 
     <intent-filter> 
      <action android:name="android.content.SyncAdapter" /> 
     </intent-filter> 
     <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/calendar_sync_adapter" /> 
    </activity> 

而且calendar_sync_adapter.xml:

<?xml version="1.0" encoding="utf-8"?> 
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" 
    android:contentAuthority="com.android.calendar" 
    android:accountType="com.google" 
    android:userVisible="true" 
/> 

所以不知道我在做什么错在这里。但是,这是我在日志中看到,当我执行它:

02-17 16:43:07.783: I/ActivityManager(184): Start proc com.android.providers.calendar for content provider com.android.providers.calendar/.CalendarProvider2: pid=20132 uid=10008 gids={3003, 1015} 
02-17 16:43:07.806: I/ActivityThread(20132): Pub com.android.calendar: com.android.providers.calendar.CalendarProvider2 
02-17 16:43:07.869: I/ActivityManager(184): Start proc com.google.android.calendar for service com.google.android.calendar/com.google.android.syncadapters.calendar.CalendarSyncAdapterService: pid=20145 uid=10007 gids={3003} 
02-17 16:43:07.900: I/ActivityThread(20145): Pub com.google.android.calendar.CalendarRecentSuggestionsProvider: com.android.calendar.CalendarRecentSuggestionsProvider 

// This is my print of the returned URI 
02-17 16:43:08.009: I/C3(19995): Calendar created: 12 - content://com.android.calendar/calendars/12?caller_is_syncadapter=true&account_name=xxx%40gmail.com&account_type=com.google 

02-17 16:43:08.876: I/CalendarProvider2(20132): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://com.android.calendar } 
02-17 16:43:08.876: W/ContentResolver(20132): Failed to get type for: content://com.android.calendar (Unknown URL content://com.android.calendar) 

回答

3

最直接的答案是: 同步适配器必须与业务相关联。服务实例化onCreate()中的同步适配器,并将一个IBinder返回到onBind()中的同步适配器。当想要运行同步适配器时,SyncManager会调用服务。

同步适配器由Android系统控制,特别是由SyncManager控制,而不是由您的应用程序控制。

SampleSyncAdapter示例应用程序显示了如何编写同步适配器和服务。如果您不想进行身份验证,则可以放弃该部分。您只需实现扩展AbstractThreadedSyncAdapter的类以及与其绑定的Service类以及同步适配器的XML文件即可。

更好的答案是: 同步适配器可以帮助您在服务器和设备之间同步数据。如果您只想将日历数据从服务器下载到设备中,则可以使用将数据从服务器中删除并将其写入日历提供程序的应用程序。这不是同步;你不能保证你会做更多的下载或上传。当然,如果你要保持同步两个数据源,一个同步适配器具有以下优点:

  • 系统会定期运行,无需用户干预。
  • 系统在尝试运行同步之前确保网络可用。但请注意,系统无法阻止您在网络服务脱机时尝试对服务器进行身份验证等愚蠢的行为。
  • 该系统确保在开始同步时,同一服务器和内容提供商不会运行其他同步。
  • 当用户想要添加一个帐户时,系统提供了一个显示可用同步适配器的标准工具。
+0

感谢您的回应!雅,我试图做的是在Google日历中创建一个新的日历。正如您所指出的那样,这不是Sync Adapter所具有的功能:P很遗憾,新的Google Calendar Provider不支持此操作。据我所知,几乎必须通过网站的桌面版本来完成。 – Adam 2012-02-22 04:31:21

+1

@Adam 2014年,即使官方Google日历应用程序也没有这项功能。您必须使用网络应用来创建日历。这种情况证实了Joe所暗示的意思:同步适配器只是用来完成同步任务,在这种情况下,日历创建似乎是一个功能,他们没有在API中找到更好的位置来放置... – 2014-06-30 16:09:51

2

是的,日历API不适合创建新的日历。该设备旨在成为云的一面镜子。