安卓:问题来访问谷歌的任务使用OAuth [英] Android: Problem to access google tasks with OAuth

查看:118
本文介绍了安卓:问题来访问谷歌的任务使用OAuth的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

随着谷歌的任务没有任何公开的API,我想写像浏览器的解决方法,并请求数据,然后分析结果进一步显示。

As google tasks has no public api I want to write workaround and request data like a browser and then parse results to further display.

要访问数据,我已经实现了与谷歌的一个OAuth认证访问此网址: https://mail.google。 COM /

To access data I've implemented a OAuth authentication with google to access this url: https://mail.google.com/

有关OAuth的我已经使用登录后的图书馆和它工作得很好。

For OAuth I've used sign-post library and it works well.

现在的问题是,当我试图访问 https://mail.google.com/tasks/ig 的有签名的请求返回我登陆,而不是与任务所需的列表页面。

The problem is when I am trying to access https://mail.google.com/tasks/ig with signed request it returns me login page instead of desired list with tasks.

要更具体,这里是我code:

To be more specific here is my code:

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

The first OAuth stage

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的舞台和试图访问谷歌的任务

The second OAuth stage and attempt to access google tasks

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

我可以看到我收到登录页

I can see that I receive "Login page"

我想原因是,谷歌并没有提供访问该服务,甚至我已经使用OAuth验证它限制我使用这些资源(即使我已经确定的范围为的 https://mail.google.com/ )。我不知道怎么现在执行它,但它看起来像我需要模拟浏览器,它究竟是如何与谷歌(检索和发送适当的coockies)进行交互。但我要问,因为我不知道如何为int这种情况,因为正如我所提到的谷歌任务API没有公开的API(SOAP,REST或其他),所以它不是很明显,我如何实现客户端,这功能...

I think the reason is that google doesn't provide access to this service and even I've already authenticated with OAuth it restricts my access to this resource (even I've defined scope as https://mail.google.com/). I am not sure how to implement it right now but it looks like I need to simulate browser exactly how it interacts with google (retrieve and send appropriate coockies). But I am asking, because I am not sure how to be int this situation, because as I've mentioned google tasks API has no public API (soap, rest or any other) so it's not obvious for me how to implement client for this feature...

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

If somebody has examples where app access google resources without public API I will be very happy to see that.

谢谢,hoply有人知道答案!

Thanks, hoply somebody knows the answer!

推荐答案

[更新5/11推荐的API,4/6正常使用的ClientLogin代替饼干]

现在有一个谷歌任务API !使用该相反,这是一个极大的方便,您的code会更容易维护。考虑这个答案只是后人的其余部分。

there's now a Google Tasks API! use that instead, it's a lot easier and your code will be more maintainable. consider the rest of this answer for posterity only.

不幸的是,你是在正确的轨道。有一个为谷歌的任务没有API都还没有,OAuth的或以其他方式,所以你必须做一些HTML刮的。 :/ AFAIK,这就是所有其他第三方任务的客户做对了。它的ClientLogin用于身份验证工作,虽然,这样的东西最少。

unfortunately, you're on the right track. there's no API for google tasks at all yet, OAuth or otherwise, so you'll have to do a bit of HTML scraping. :/ afaik, that's what all other third party tasks clients do right now. ClientLogin does work for auth, though, so that's something at least.

下面是一些shell脚本code,这是否: http://privacylog.blogspot.com/2010/09/updated-google-tasks-api.html 。详情如下。

here's some shell script code that does this: http://privacylog.blogspot.com/2010/09/updated-google-tasks-api.html . details below.

首先, POST www.google.com/accounts/ClientLogin 中的 HTTP://$c$c.google.com/apis/accounts/docs/ AuthForInstalledApps.html#申请得到一个身份验证令牌。使用 goanna_mobile 作为服务名。 (这很重要!)

first, POST to www.google.com/accounts/ClientLogin as described in http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request to get an auth token. use goanna_mobile as the service name. (this is important!)

那么, GET https://mail.google.com/tasks/m 并通过授权:你上面收到的身份验证令牌的GoogleLogin 头。你会得到的HTML回来。提取个人任务列表的ID。他们是形式04291568652951293844的0:0

then, GET https://mail.google.com/tasks/m and pass the Authorization:GoogleLogin header with the auth token you received above. you'll get HTML back. extract the ids of the individual task lists. they're of the form 04291568652951293844:0:0.

你会再发送帖子用JSON-CN codeD身体 https://mail.google.com/tasks/r/d 获得每个列表的内容。这里有一个例子体:

you'll then send POSTs with JSON-encoded body to https://mail.google.com/tasks/r/d to get the contents of each list. here's an example body:

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连接codeD于r%3D
  • 包含头文件'AT:1。没有它的任务返回401未授权。
  • the latest_sync_point: 0 to get all tasks
  • the = in r= is not url encoded to r%3D
  • include the header 'AT: 1'. without it tasks returns 401 Unauthorized.

输出更加JSON,例如:

the output is more JSON, e.g.:

{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
   },
   ...

这篇关于安卓:问题来访问谷歌的任务使用OAuth的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆