Android:使用OAuth访问google任务的问题

Android:使用OAuth访问google任务的问题,android,Android,由于GoogleTasks没有公共api,我想编写变通方法,像浏览器一样请求数据,然后解析结果以进一步显示 为了访问数据,我使用google实现了OAuth身份验证以访问此url: 对于OAuth,我使用了sign post库,它运行良好 问题是,当我试图通过已签名的请求访问时,它会返回我的登录页面,而不是所需的任务列表 更具体地说,这里是我的代码: public class GoogleOAuthActivity extends Activity { private static fi

由于GoogleTasks没有公共api,我想编写变通方法,像浏览器一样请求数据,然后解析结果以进一步显示

为了访问数据,我使用google实现了OAuth身份验证以访问此url:

对于OAuth,我使用了sign post库,它运行良好

问题是,当我试图通过已签名的请求访问时,它会返回我的登录页面,而不是所需的任务列表

更具体地说,这里是我的代码:

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();
        }
    }

}
第一阶段

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阶段,尝试访问google任务

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);
我可以看到我收到“登录页面”

我认为原因是google不提供对该服务的访问,即使我已经通过OAuth的身份验证,它也限制了我对该资源的访问(即使我已经将范围定义为)。我现在不知道如何实现它,但看起来我需要准确地模拟浏览器如何与google交互(检索并发送适当的coockies)。但我在问,因为我不知道如何在这种情况下,因为正如我所提到的谷歌任务API没有公共API(soap,rest或任何其他),所以我不清楚如何实现这个特性的客户端

如果有人有应用程序访问谷歌资源而不使用公共API的例子,我会很高兴看到这一点

谢谢,希望有人知道答案

[于11月5日更新,建议使用API,4/6使用普通客户端登录,而不是cookie]

现在有一个!相反,使用它更容易,代码也更易于维护。只考虑后代的答案。< /强>

不幸的是,你在正确的轨道上。目前还没有用于google任务的API,OAuth或其他,因此您必须执行一些HTML抓取操作。:/好了,这是所有其他第三方任务客户端现在都在做的事情。不过,ClientLogin确实适用于auth,所以至少是这样

下面是一些执行此操作的shell脚本代码:。详情如下

首先,
POST
www.google.com/accounts/ClientLogin
,如中所述,以获取身份验证令牌。使用
goanna\u mobile
作为服务名称。(这很重要!)

然后,
获取
并使用上面收到的auth令牌传递
授权:GoogleLogin
标题。你会得到HTML的。提取各个任务列表的ID。他们的表格是04291565652951293844:0:0

然后,您将使用JSON编码的正文将帖子发送到
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
  }
重要提示:

  • 最新的\u同步\u点:0以获取所有任务
  • r=中的=未编码为r%3D的url
  • 包括标题“AT:1”。没有it,任务返回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
   },
   ...

他们确实有一个API,因为几周后现在检查

是的,现在有一个API。。。除非您愿意付款,否则每天的请求限制为5000次。要么应用程序的收入可以弥补成本,要么JSON仍然是一条路要走。