使用googleapi-client-java操作gtasks(二)

對於很多第三方的機器沒有安裝Google賬戶管理,要訪問GTasks,那麼可以使用OAuth 2.0的認證方式。
OAuth 2.0的認證流程:
1.得到授權碼
2.使用授權碼獲得真正的數據訪問令牌

其中數據訪問令牌一般有效期爲60分鐘,在得到此訪問令牌的時候還會得到一個刷新令牌,當訪問令牌過期後可以用此刷新令牌自動獲得一個新的。

1.授權碼的獲得:
用瀏覽器打開一個url,這個url是由要訪問的服務以及其他一些相關信息生成的。

/*
* https://code.google.com/oauthplayground 可以找到一個scope列表。
*/
private final static String SCOPE = "https://www.googleapis.com/auth/tasks";
/*以下信息來自於https://code.google.com/apis/console
*創建一個Project,然後選擇要激活的Service,我激活了Calendar和Tasks API
*選擇API Access,可以設置OAuth 2.0,進而得到相關信息。
*創建id時選擇for installed applications。
*/
private final static String CLIENT_ID = "你的id.apps.googleusercontent.com";
private final static String CLIENT_SECRET = "你的secret";
private static final String CALLBACK_URL = "urn:ietf:wg:oauth:2.0:oob";

private void requestAuthCode() {
String authorizeUrl = new GoogleAuthorizationRequestUrl(CLIENT_ID, CALLBACK_URL, SCOPE).build();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(authorizeUrl));
startActivity(intent);
}

用戶看到一個瀏覽器打開的頁面,輸入用戶名和密碼後就可以得到授權碼,不過要手工複製一下,然後到程序中粘貼。
授權碼是時刻在變的,即使是同一個設備同一個ap去獲取同一個賬戶的授權碼也是在變的。

2.數據訪問令牌的獲取
用授權碼作爲參數,獲取後保存。

private boolean requestToken(String authCode) {
GoogleAuthorizationCodeGrant authRequest = new GoogleAuthorizationCodeGrant(mTransport,
new JacksonFactory(), CLIENT_ID, CLIENT_SECRET, authCode, CALLBACK_URL);
authRequest.useBasicAuthorization = false;
AccessTokenResponse authResponse;
try {
authResponse = authRequest.execute(); //發出請求
mAccessToken = authResponse.accessToken;
mRefreshToken = authResponse.refreshToken;
return true;
} catch( HttpResponseException he) {
he.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}


3.讀取數據
使用token構造一個可以進行訪問保護資源的對象。
然後構造一個Tasks對象。
執行tasks的execute()方法就可以獲得數據了。
當獲取數據時,token有可能過期,這個時候會得到401的響應值,此時需要刷新一下token,然後再獲取數據。

if(mAccessProtectedResource == null) {
mAccessProtectedResource = new GoogleAccessProtectedResource(mAccessToken,
mTransport, new JacksonFactory(), CLIENT_ID, CLIENT_SECRET, mRefreshToken);
}
if(mService == null) mService = new Tasks(mTransport, mAccessProtectedResource, new JacksonFactory());
mTaskListNames.clear();
try {
List<TaskList> lists = mService.tasklists.list().execute().items;
for(TaskList tl : lists) {
mTaskListNames.add(tl.title);
}
mAdapter.notifyDataSetChanged();
} catch(HttpResponseException he) {
if(he.getResponse().getStatusCode() == 401) {
//token 過期,刷新token
try {
mAccessProtectedResource.refreshToken();
mAccessToken = mAccessProtectedResource.getAccessToken();
mRefreshToken = mAccessProtectedResource.getRefreshToken();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
}


另外此種方法訪問用戶數據因爲Client_ID沒有改變,所以每個Ap的限額仍然是每日5000次,即使訪問的是不同賬戶的數據。
那麼解決限額的方法只能是交錢買更多的,或者Ap裏面多內置幾個Client_ID,隨機選用了,當然這些Client_ID必須是隸屬於不同賬戶的。
或者就好像(一)中提到的,讓用戶自己輸入自己的API KEY,不過這個太專業了,一般人不好搞。
直接通過HttpClient走REST協議似乎可以不用client_id和api key,可參見:
https://code.google.com/apis/explorer 應該也不行,在獲取授權碼的時候就要client id

如果授權失敗返回的錯誤碼是401,如果是超限額返回的錯誤碼是403。
另外如果使用proguard,那麼要增加配置:
(來自於http://code.google.com/p/google-api-java-client/wiki/Setup)

# Needed by google-api-client to keep generic types and @Key annotations accessed via reflection

-keepclassmembers class * {
@com.google.api.client.util.Key <fields>;
}

-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault

# Needed by Guava

-dontwarn sun.misc.Unsafe

# See https://groups.google.com/forum/#!topic/guava-discuss/YCZzeCiIVoI
-dontwarn com.google.common.collect.MinMaxPriorityQueue

PS:經試驗task的title的長度最大爲1024字節;note的最大長度爲8192字節。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章