2009-05-11 15 views

答えて

8

これらの答えは良いですが、それらはすべてハードコーディング(私は別のAndroidデバイス間で三つの異なる化身で見てきた)Calendar URIを伴います。

URIが(どのハードコードクラスの名前とフィールドの代わりに)このようなものになるだろうことを得るためのより良い方法:

Class<?> calendarProviderClass = Class.forName("android.provider.Calendar"); 
Field uriField = calendarProviderClass.getField("CONTENT_URI"); 
Uri calendarUri = (Uri) uriField.get(null); 

これは、彼らならば(それが壊れる完璧ではありませんandroid.provider.CalendarクラスまたはCONTENT_URIフィールドを削除します)が、単一のURIハード​​コードより多くのプラットフォームで動作します。

これらのリフレクションメソッドは、呼び出しメソッドによってキャッチまたは再スローされる必要があるexceptionsをスローすることに注意してください。

+0

これはAPI 14の時点では機能しません。カレンダー(14+)の公式APIはこちら[http://developer.android.com/guide/topics/providers/calendar-provider.html#intents )新しい[[CalendarContract](http://developer.android.com/reference/android/provider/CalendarContract.html) 'クラスの使用を伴う – syklon

3

カレンダーコンテンツプロバイダ(com.android.providers.calendar.CalendarProvider)を使用できます。例:


ContentResolver contentResolver = context.getContentResolver(); 
Cursor cursor = contentResolver.query(Uri.parse("content://calendar/events"), null, null, null, null); 

while(cursor.moveToNext()) { 
    String eventTitle = cursor.getString(cursor.getColumnIndex("title")); 
    Date eventStart = new Date(cursor.getLong(cursor.getColumnIndex("dtstart"))); 
    // etc. 
} 

編集:あなたはそれがプライベートAPIだとして(Isaac's postを参照)ラッパーでこれを置くことをお勧めします。

+1

はい、これはいつでも破損する可能性のあるプライベートAPIです。 –

+1

あなたは本当に正しいですし、あなたのラッパーは明らかに非常に良いアイデアですが、あなたがまだ何かを変えたときにあなたのアプリのコードに戻る必要があるとしても。 APIが公開されると、ラッパーはとにかに時代遅れになる可能性があります。 –

3

現在のところ、プライベートAPIを使用しないとこれはできません(Josefの記事を参照してください)。カレンダープロバイダはありますが、まだ公開されていません。それはいつでも変更することができ、あなたのアプリを壊すことができます。
しかし、おそらく変更されません(私は彼らが "カレンダー"から変更されるとは思わない)ので、あなたはそれを使用することができるかもしれません。しかし、私のお勧めは次のような別のクラスを使用することです:

そして、文字列の代わりにそれらを直接使用してください。これにより、APIが変更された場合や公開された場合に非常に簡単に変更できます。

+1

ありがとう! Btw、DevToolsの最新のSDK(1.5 R1)を使用してカレンダー(ソースから2 apkをビルドする)と「Google Login Service」を使用できますか? – brunoqc

+1

GoogleログインサービスはGoogle独自のもので、実際の電話がない限り常にクラッシュします。私はカレンダーを試していない。 –

1

変更可能なAPIについてContentProviderのアプローチ全体がすぐに変更されることはないため、文字列を更新するだけですでに多くの問題を克服することができます。そのため、プロジェクト全体で再利用する定数を作成します。

public static final String URI_CONTENT_CALENDAR_EVENTS = "content://calendar/events"; 

ContentResolver contentResolver = context.getContentResolver(); 
Cursor cursor = contentResolver.query(Uri.parse(URI_CONTENT_CALENDAR_EVENTS), null, null, null, null); 
    //etc 

あなたはPOJOと、このようないくつかのサービスを作成する必要があります適切なプライベートAPIたい場合は、次のように

public class CalendarEvent { 
    private long id; 
    private long date; 
    //etc... 
} 

public interface CalendarService { 

    public Set<CalendarEvent> getAllCalendarEvents(); 

    public CalendarEvent findCalendarEventById(long id); 

    public CalendarEvent findCalendarEventByDate(long date); 

} 

をして。これにより、APIが変更された場合に備えて、CalendarEventオブジェクトとこのサービスを更新するだけで済みます。

9

カレンダーにアクセスするためのJosefとIsaacのソリューションは、Android 2.1以前でのみ動作します。 Googleは、2.2の基本コンテンツURIを「content:// calendar」から「content://com.android.calendar」に変更しました。この変更は、古いベースURIを使用してカーソルを取得し、戻されたカーソルがヌルの場合は、新しいベースURIを試行することをお勧めします。

Shane ConderとLauren DarceyがWorking With The Android Calendarの記事を提供しているopen source test codeからこのアプローチを得ました。

private final static String BASE_CALENDAR_URI_PRE_2_2 = "content://calendar"; 
private final static String BASE_CALENDAR_URI_2_2 = "content://com.android.calendar"; 
/* 
* Determines if we need to use a pre 2.2 calendar Uri, or a 2.2 calendar Uri, and returns the base Uri 
*/ 
private String getCalendarUriBase() { 
    Uri calendars = Uri.parse(BASE_CALENDAR_URI_PRE_2_2 + "/calendars"); 
    try { 
     Cursor managedCursor = managedQuery(calendars, null, null, null, null); 
     if (managedCursor != null) { 
      return BASE_CALENDAR_URI_PRE_2_2; 
     } 
     else { 
      calendars = Uri.parse(BASE_CALENDAR_URI_2_2 + "/calendars"); 
      managedCursor = managedQuery(calendars, null, null, null, null); 

      if (managedCursor != null) { 
       return BASE_CALENDAR_URI_2_2; 
      } 
     } 
    } catch (Exception e) { /* eat any exceptions */ } 

    return null; // No working calendar URI found 
} 
1

NickのソリューションにはmanagedQueryが含まれていますが、Contextクラスでは定義されていません。バックグラウンドで物事を実行しているときは、コンテキストオブジェクトを使用することが多いでしょう。

パブリック文字列getCalendarUriBase(){

リターン(android.os.Build.VERSION.SDK_INT> = 8):ここでは修正版ですか? "content://com.android.calendar": "content:// calendar"; }

ここでは、managedQueryが以前に成功した場合でも例外がさらに発生する可能性があるため、nullキャッチはここでは実行しないでください。

関連する問題