由于google任务没有公共API,我想编写解决方法并像浏览器一样请求数据,然后解析结果以进一步显示.
要访问数据,我已经通过Google实施了OAuth身份验证来访问此网址:https://mail.google.com/
对于OAuth,我使用了sign-post库,效果很好.
问题是,当我尝试使用已签名的请求访问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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
第一个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;
}
}
Run Code Online (Sandbox Code Playgroud)
第二个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;
}
}
Run Code Online (Sandbox Code Playgroud)
在这一行:
String xml = ConvertUtils.convertStreamToString(response.getEntity().getContent(), true);
Log.d(TAG, "XML = " + xml);
Run Code Online (Sandbox Code Playgroud)
我可以看到我收到"登录页面"
我认为原因是google不提供对此服务的访问权限,即使我已经使用OAuth进行身份验证,也限制了我对此资源的访问权限(即使我已将范围定义为https://mail.google.com/) .我不知道如何立即实现它,但看起来我需要模拟浏览器与谷歌的交互方式(检索和发送适当的coockies).但我问,因为我不确定如何处理这种情况,因为我已经提到google tasks API没有公共API(肥皂,休息或任何其他)所以对我来说如何为此实现客户端并不明显特征...
如果某人有应用程序访问谷歌资源而没有公共API的示例,我将非常高兴看到这一点.
谢谢,有人知道答案!
[在5/11更新推荐API,4/6使用普通ClientLogin而不是cookie]
现在有一个Google Tasks API!使用它,它更容易,你的代码将更易于维护.只考虑后代的其余部分.
不幸的是,你走在正确的轨道上.谷歌任务还没有API,OAuth或其他,所以你必须做一些HTML抓取.:/ afaik,这就是客户现在所做的所有其他第三方任务.ClientLogin确实适用于auth,所以这至少是这样的.
这里有一些执行此操作的shell脚本代码:http://privacylog.blogspot.com/2010/09/updated-google-tasks-api.html.详情如下.
首先,POST要www.google.com/accounts/ClientLogin在描述http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request得到一个身份验证令牌.使用goanna_mobile的服务名称.(这个很重要!)
然后,使用您在上面收到的身份验证令牌传递标头.你会得到HTML回来.提取各个任务列表的ID.它们的形式为04291568652951293844:0:0.GET https://mail.google.com/tasks/mAuthorization:GoogleLogin
然后,您将发送带有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
}
Run Code Online (Sandbox Code Playgroud)
重要笔记:
输出更多是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
},
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2073 次 |
| 最近记录: |