package com.example.android.recipe101; import java.io.IOException; import java.net.URLEncoder; import java.util.Calendar; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerFuture; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.app.Activity; import android.os.Bundle; import android.text.format.Time; import android.util.Log; import android.widget.Toast; import com.google.api.client.apache.ApacheHttpTransport; import com.google.api.client.googleapis.GoogleHeaders; import com.google.api.client.googleapis.GoogleTransport; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpResponse; import com.google.api.client.http.HttpResponseException; import com.google.api.client.http.HttpTransport; import com.google.api.client.xml.atom.AtomParser; public class Recipe101 extends Activity { private static final String GOOGLE_CAL_API_URL = "https://www.google.com/calendar/feeds/"; private static final String CAL_AUTH_TOKEN_TYPE = "cl"; private static final String TAG = "Recipe101"; private static HttpTransport mTransport; private String mAuthToken; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mTransport = GoogleTransport.create(); GoogleHeaders headers = (GoogleHeaders) mTransport.defaultHeaders; // "[company-id]-[app-name]-[app-version]"という形式で // アプリケーション名をセット headers.setApplicationName("gabu-recipe-101"); // バージョンをセット headers.gdataVersion = "2"; // AtomParserを作る AtomParser parser = new AtomParser(); // GoogleCalendarのネームスペースをセット parser.namespaceDictionary = Namespace.DICTIONARY; // GoogleTransportにAtomParserをセット mTransport.addParser(parser); // HttpTransportにApacheHttpTransportのインスタンスをセット // これをやっておかないとExceptionが発生します。 HttpTransport.setLowLevelHttpTransport( ApacheHttpTransport.INSTANCE); // AccountManagerを取得 AccountManager manager = AccountManager.get(this); // Googleアカウントの一覧を取得 Account[] accounts = manager.getAccountsByType("com.google"); // サンプルなので暫定的に1つ目を取得 Account acount = accounts[0]; // 認証のためのauth tokenを取得 AccountManagerFuture<Bundle> f = manager.getAuthToken(acount, CAL_AUTH_TOKEN_TYPE, null, this, null, null); try { Bundle b = f.getResult(); mAuthToken = b.getString(AccountManager.KEY_AUTHTOKEN); // Log.d(TAG, "authToken=" + mAuthToken); } catch (OperationCanceledException e) { e.printStackTrace(); } catch (AuthenticatorException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // GoogleTransportにauth tokenをセット // これで認証ヘッダを自動的に付けてくれます。 ((GoogleHeaders) mTransport.defaultHeaders).setGoogleLogin(mAuthToken); // GoogleTransportからGETリクエストを生成 HttpRequest request = mTransport.buildGetRequest(); // Googleカレンダーの一覧を取得するURLを作成 // 共有しているカレンダーも含む // String url = GOOGLE_CAL_API_URL + "default/allcalendars/full"; // 自分がオーナーのカレンダーのみ String url = GOOGLE_CAL_API_URL + "default/owncalendars/full"; // URLをセット request.setUrl(url); try { // HTTPリクエストを実行してレスポンスをパース CalendarFeed feed = request.execute().parseAs(CalendarFeed.class); for (CalendarEntry entry : feed.entries) { Log.d(TAG, entry.title + ", " + entry.id); } // サンプルのためカレンダーの1つ目を取得 CalendarEntry entry = feed.entries.get(0); // このuserIDがカレンダーを一意に特定するIDになります。 String userID = entry.getUserID(); // 何も指定せずに予定の一覧を取得 url = GOOGLE_CAL_API_URL + userID + "/private/full"; debug(request, url); // 2010年6月の予定の一覧を取得 // url = createMonthlyUrl(userID, 2010, 6); // debug(request, url); // 2010年6月30日の予定の一覧 // url = createDailyUrl(userID, 2010, 6, 30); // debug(request, url); } catch (IOException e) { handleException(e); } } // 指定された日の予定を取得するURLを生成します。 private String createDailyUrl(String userID, int year, int month, int day) { Calendar cal = Calendar.getInstance(); cal.set(year, month - 1, day, 0, 0, 0); Time fromTime = new Time(); fromTime.set(cal.getTimeInMillis()); // RFC 3339フォーマットにします。 String from = fromTime.format3339(true); cal.add(Calendar.DATE, 1); Time toTime = new Time(); toTime.set(cal.getTimeInMillis()); // RFC 3339フォーマットにします。 String to = toTime.format3339(true); return createUrl(userID, from, to); } // 指定された月の予定を取得するURLを生成します。 private String createMonthlyUrl(String userID, int year, int month) { Calendar cal = Calendar.getInstance(); cal.set(year, month - 1, 1, 0, 0, 0); Time fromTime = new Time(); fromTime.set(cal.getTimeInMillis()); // RFC 3339フォーマットにします。 String from = fromTime.format3339(true); cal.add(Calendar.MONTH, 1); Time toTime = new Time(); toTime.set(cal.getTimeInMillis()); // RFC 3339フォーマットにします。 String to = toTime.format3339(true); return createUrl(userID, from, to); } private String createUrl(String userID, String from, String to) { return GOOGLE_CAL_API_URL + userID + "/private/full" + "?start-min=" + URLEncoder.encode(from) + "&start-max=" + URLEncoder.encode(to) + "&orderby=starttime" + "&sortorder=ascending" + "&singleevents=true"; } // リクエストを実行して、結果をログ出力します。 private void debug(HttpRequest request, String url) { try { Log.d(TAG, url); request.setUrl(url); HttpResponse response = RedirectHandler.execute(request); CalendarEventFeed eventFeed = response.parseAs(CalendarEventFeed.class); for (CalendarEventEntry event : eventFeed.entries) { Log.d(TAG, event.title); if (event.when != null) { Log.d(TAG, event.when.startTime); } } } catch (IOException e) { handleException(e); } } private void handleException(IOException e) { if (e instanceof HttpResponseException) { int statusCode = ((HttpResponseException) e).response.statusCode; System.out.println(statusCode); if (statusCode == 401 || statusCode == 403) { AccountManager manager = AccountManager.get(this); // キャッシュを削除 manager.invalidateAuthToken("com.google", mAuthToken); Toast.makeText(getApplicationContext(), "キャッシュを削除しました。アプリを再起動してください。", Toast.LENGTH_LONG).show(); } return; } else { e.printStackTrace(); } } }