2010-11-18 46 views
3

由於Google任務沒有公開API,我想要像瀏覽器一樣編寫解決方法和請求數據,然後解析結果以進一步顯示。Android:使用OAuth訪問Google任務時出現問題

訪問數據,我已經實現與谷歌OAuth認證訪問此網址:https://mail.google.com/

是OAuth我已經使用登錄後庫,它工作得很好。

問題是當我試圖訪問帶簽名請求的https://mail.google.com/tasks/ig時,它返回了我的登錄頁面而不是任務所需的列表。

更具體地講,這裏是我的代碼:

public class GoogleOAuthActivity extends Activity { 
    private static final String TAG = GoogleOAuthActivity.class.getSimpleName(); 
    private CommonsHttpOAuthProvider provider; 
    private CommonsHttpOAuthConsumer consumer; 

    @Override 
    @SuppressWarnings("unchecked") 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     provider = new CommonsHttpOAuthProvider(OAuthPrefs.GET_REQUEST_TOKEN_URL, OAuthPrefs.GET_ACCESS_TOKEN_URL, 
       OAuthPrefs.TOKEN_AUTHORIZATION_URL); 
     consumer = new CommonsHttpOAuthConsumer(OAuthPrefs.CONSUMER_KEY, OAuthPrefs.CONSUMER_SECRET); 
     consumer.setMessageSigner(new HmacSha1MessageSigner()); 

     Log.v(TAG, "Starting google authentication activity"); 
     new RequestGoogleOAuth(this, provider, consumer).execute(); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public void onNewIntent(Intent intent) { 
     super.onNewIntent(intent); 
     final Uri uri = intent.getData(); 
     if (uri != null && uri.getScheme().equals(OAuthPrefs.CALLBACK_SCHEME)) { 
      Log.v("OAUTH MAIN", "STARTING STAGE TWO"); 
      new ConfirmGoogleOAuthTask(this, provider, consumer).execute(uri); 
      finish(); 
     } 
    } 

} 

第一OAuth的階段

public class RequestGoogleOAuth extends OAuthGoogleTask { 
    public static final String TAG = RequestGoogleOAuth.class.getSimpleName(); 

    public RequestGoogleOAuth(Context context, CommonsHttpOAuthProvider provider, CommonsHttpOAuthConsumer consumer) { 
     super(context, provider, consumer); 
    } 

    protected Object doInBackground(Object... params) { 
     final String TAG = getClass().getName(); 
     try { 
      final String url = provider.retrieveRequestToken(consumer, OAuthPrefs.CALLBACK_URL); 
      Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP 
        & Intent.FLAG_ACTIVITY_NO_HISTORY & Intent.FLAG_FROM_BACKGROUND); 
      context.startActivity(intent); 
      Log.v(TAG, "Request google authentication"); 
     } catch (Exception e) { 
      Log.e(TAG, "ERROR during google authentication request", e); 
     } 
     return null; 
    } 
} 

第二OAuth的階段,並嘗試訪問谷歌的任務

public class ConfirmGoogleOAuthTask extends OAuthGoogleTask { 
    public ConfirmGoogleOAuthTask(Context context, CommonsHttpOAuthProvider provider, CommonsHttpOAuthConsumer consumer) { 
     super(context, provider, consumer); 
    } 

    @Override 
    public Object doInBackground(Object... params) { 
     final Uri uri = (Uri) params[0]; 
     final String TAG = getClass().getName(); 

     final SharedPreferences prefs = context.getSharedPreferences(OAuthPrefs.PREF_NAME, Context.MODE_PRIVATE); 
     final String oauthVerifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER); 

     try { 
      provider.retrieveAccessToken(consumer, oauthVerifier); 
      final Editor edit = prefs.edit(); 
      edit.putString(OAuth.OAUTH_TOKEN, consumer.getToken()); 
      edit.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret()); 
      edit.commit(); 

      CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(OAuthPrefs.CONSUMER_KEY, OAuthPrefs.CONSUMER_SECRET); 
      consumer.setMessageSigner(new HmacSha1MessageSigner()); 
      consumer.setTokenWithSecret(consumer.getToken(), consumer.getTokenSecret()); 

      HttpClient httpClient = HttpUtils.createHttpClient(); 
      HttpGet httpGet = new HttpGet(consumer.sign("https://mail.google.com/tasks/ig")); 
      HttpResponse response = httpClient.execute(httpGet); 
      int statusCode = response.getStatusLine().getStatusCode(); 
      Log.d(TAG, "Status code = " + statusCode); 
      if (statusCode == HttpStatus.SC_OK) { 
       String xml = ConvertUtils.convertStreamToString(response.getEntity().getContent(), true); 
       Log.d(TAG, "XML = " + xml); 
      } 

      Log.v(TAG, "Successfully receive access token"); 
     } catch (Exception e) { 
      Log.e(TAG, "ERROR during request for access token", e); 
     } 
     return null; 
    } 
} 

在這line:

String xml = ConvertUtils.convertStreamToString(response.getEntity().getContent(), true); 
        Log.d(TAG, "XML = " + xml); 

我可以看到,我收到「登錄頁」

我想原因是,谷歌不提供訪問該服務,甚至我已經通過OAuth認證它限制了我的這個資源訪問(即使我已將範圍定義爲https://mail.google.com/)。我不知道如何實現它,但它看起來像我需要模擬瀏覽器究竟如何與谷歌互動(檢索和發送適當的coockies)。但我問,因爲我不知道如何處理這種情況,因爲正如我所提到的谷歌任務API沒有公共API(肥皂,休息或任何其他),所以這對我來說並不明顯如何爲此實現客戶端功能...

如果有人有應用程序訪問谷歌資源沒有公共API的例子,我會很高興看到這一點。

謝謝,嗨,有人知道答案!

回答

5

[更新5/11推薦的API,4/6正常使用的ClientLogin來代替餅乾]

有現在Google Tasks API!相反,使用它會容易得多,並且您的代碼將更易於維護。只考慮爲子孫後代的其餘部分。

不幸的是,你在正確的軌道上。目前還沒有用於谷歌任務的API,OAuth或其他,所以你必須做一些HTML抓取。 :/ afaik,這就是客戶現在執行的所有其他第三方任務。不過,ClientLogin確實可以用於身份驗證,所以至少是這樣。

這是一些shell腳本代碼,它可以這樣做:http://privacylog.blogspot.com/2010/09/updated-google-tasks-api.html。詳情如下。

第一個,POST到​​,如http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request中所述,以獲得認證令牌。使用goanna_mobile作爲服務名稱。 (這個很重要!)

然後,GET https://mail.google.com/tasks/m並將Authorization:GoogleLogin標頭與上面收到的驗證令牌一起傳遞。你會得到HTML回來。提取各個任務列表的ID。他們的形式是04291568652951293844:0:0。

然後,您將發送帶有JSON編碼體的POST到https://mail.google.com/tasks/r/d以獲取每個列表的內容。這裏有一個例子體:

r={action_list: 
    [{action_type: get_all, 
    action_id: 5, 
    list_id: 0429158965...:0:0, 
    get_deleted: false, 
    date_start: 1969-12-31, 
    get_archived: true 
    }], 
    client_version: 1256686 
    } 

重要說明:

  • 的latest_sync_point:0獲得所有任務
  • r中的= =是 URL編碼在r%3D
  • 包括標題'AT:1'。沒有它任務返回401未經授權。

輸出更加JSON,如:

{latest_sync_point: 1263000002293000, response_time:1263077227, results:[], tasks: 
    [{id: 04291589652955....:0:38, 
    last_modified: 1263000002281, 
    name: foo bar 
    notes: , 
    type: TASK, 
    deleted: false, 
    list_id: [0429158965...:0:0], 
    completed: false 
    }, 
    {id: 0429158965295...:0:37, 
    last_modified: 1262929947949, 
    name: baz 
    notes: , 
    type: TASK, 
    deleted:false, 
    list_id: [0429158965295...:0:0], 
    completed: false 
    }, 
    ... 
+0

是的,現在有一個API ......限於每5000要求除非你願意付錢。無論是來自您的應用程序的收入都可以支付成本,還是JSON仍然是您的選擇。 – RedGlyph 2013-03-19 21:13:24

1

他們確實有,因爲幾個星期的API現在檢查here

相關問題