2010-11-18 3 views
3

Google 작업에 공용 API가 없으므로 브라우저와 같은 데이터를 요청하고 해결 방법을 작성하고 결과를 더 자세히 표시하려면 구문 분석을 수행하고 싶습니다. 내가 로그인 후 라이브러리를 사용했습니다 OAuth를 들어 https://mail.google.com/Android : OAuth를 사용하여 Google 작업에 액세스 할 때의 문제

잘 작동 :

내가이 URL을 액세스하기 위해 구글과의 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; 
    } 
} 

에 액세스 시도 줄 :

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

내가 나는 이유는 구글이 서비스에 대한 액세스를 제공하지 않는다는 것입니다 생각, 심지어 이미 OAuth를 사용하여 인증 한 그것은이 자원에 대한 나의 접근 (제한 "로그인 페이지"

를받을 것을 볼 수있다 심지어 범위를 https://mail.google.com/으로 정의했습니다.) 나는 지금 그것을 구현하는 방법을 잘 모르겠지만 브라우저를 정확히 시뮬레이트하여 구글과 상호 작용하는 방법 (검색하고 적절한 코키를 보내는 방법)이 필요한 것처럼 보입니다. 하지만 나는이 상황을 어떻게해야할지 모르므로 물어 본다. Google 작업 API에 공용 API (비누, 휴식 또는 기타)가 없다는 것을 언급했기 때문에 이것이 내게 클라이언트를 구현하는 방법이 분명하지 않기 때문이다. 기능 ...

누군가가 공개 API없이 앱이 Google 자원에 액세스하는 예가 있으면 그 사실을 매우 기쁘게 생각합니다.

감사합니다. 분명히 누군가가 대답을 알고 있습니다!

답변

5

지금 Google Tasks API있다 [일반 대신 쿠키하여 ClientLogin을 사용하는 API, 4/6을 추천 5/11에 업데이트]! 그 대신에 훨씬 쉽고 코드를 유지 보수 할 수 있습니다. 후손을 위해서만이 답변의 나머지 부분을 고려하십시오.

불행히도, 당신은 올바른 길을 가고 있습니다. 아직 Google 작업을위한 API가 없기 때문에 OAuth 또는 기타 방법으로 HTML 스크래핑을해야합니다. :/afaik, 그게 바로 다른 모든 제 3 자 작업 고객들이 지금하는 일입니다. ClientLogin은 인증을 위해 작동하지만 적어도 그렇게해야합니다.

다음은이 작업을 수행하는 쉘 스크립트 코드입니다 : http://privacylog.blogspot.com/2010/09/updated-google-tasks-api.html. 아래 세부 정보.

먼저 http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request에 설명 된대로 POST에서 www.google.com/accounts/ClientLogin까지 인증 토큰을 얻습니다. 서비스 이름으로 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에
  • =를 얻을 수 =이다 R의 %로 인코딩 된 하지 URL을 3D
  • 'AT : 1'헤더를 포함하십시오. 그것이없는 작업은 401 Unauthorized를 반환합니다.

출력이 더 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

1

그들은 몇 주 이후 API를해야합니까 지금 here

관련 문제