Java – use the account manager to authenticate using the Google API
I've been trying to solve this problem for days I'm trying to dial Google calendar using authentication through Android's account manager I use the usual method to retrieve authentication tokens:
AccountManager manager = AccountManager.get(this); String authToken = manager.getAuthToken(account,AUTH_TOKEN_TYPE,true,null,null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
Then, using this token, I create a calendar instance:
HttpTransport transport = AndroidHttp.newCompatibleTransport(); JacksonFactory jsonFactory = new JacksonFactory(); GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessToken); Calendar calendar = Calendar.builder(transport,jsonFactory).setApplicationName("MyApp/1.0").setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() { @Override public void initialize(JsonHttpRequest request) { CalendarRequest calendarRequest = (CalendarRequest) request; calendarRequest.setKey(API_KEY); } }).setHttpRequestInitializer(accessProtectedResource).build();
However, when I use it for API calls, I receive the 401 unauthorized error I see below Please note that I have included code to invalidate expired auth tokens, so I don't think this is the problem
com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized { "code" : 401,"errors" : [ { "domain" : "global","location" : "Authorization","locationType" : "header","message" : "Invalid Credentials","reason" : "authError" } ],"message" : "Invalid Credentials" }
Any idea of what I might have done wrong?
Solution
Yes, it is possible Once you have a Google account (as you described), you only need to request an authentication token for the gdata service from the account manager
If the Android device already has an authentication token (for the specific gdata service you are trying to access), it will be returned to you If not, the account manager will request one and return it to you Either way, you don't have to worry about this because the account manager handles it
In the following example, I use the Google spreadsheets API:
ArrayList<Account> googleAccounts = new ArrayList<Account>(); // Get all accounts Account[] accounts = accountManager.getAccounts(); for(Account account : accounts) { // Filter out the Google accounts if(account.type.compareToIgnoreCase("com.google")) { googleAccounts.add(account); } } AccountManager accountManager = AccountManager.get(activity); // Just for the example,I am using the first google account returned. Account account = googleAccounts.get(0); // "wise" = Google Spreadheets AccountManagerFuture<Bundle> amf = accountManager.getAuthToken(account,"wise",activity,null); try { Bundle authTokenBundle = amf.getResult(); String authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN); // do something with the token InputStream response = sgc.getFeedAsStream(FeedUrl,authToken,"2.1"); }
and
Please check the sample code in the Google data API The important thing to do after authentication is to call Google headers setGoogleLogin(String).
I hope it helps