Аутентификация с помощью Google API с помощью AccountManager
-
15-11-2019 - |
Вопрос
Я борюсь с этим уже пару дней.Я пытаюсь совершать звонки в Google Calendar, используя аутентификацию через Android AccountManager
.Я извлекаю токен аутентификации, используя обычный метод:
AccountManager manager = AccountManager.get(this);
String authToken = manager.getAuthToken(account, AUTH_TOKEN_TYPE, true, null, null).getResult().getString(AccountManager.KEY_AUTHTOKEN);
И затем, с помощью этого токена, я создаю Calendar
пример, подобный этому:
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();
Однако, когда я выполняю вызовы API, используя это, я получаю 401 Unauthorized
ошибка, показанная ниже.Обратите внимание, что я включил код для аннулирования токенов аутентификации с истекшим сроком действия, поэтому я не верю, что проблема здесь в этом.
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"
}
Есть какие-нибудь мысли о том, что я, возможно, делаю не так?
Решение
Да, это возможно.Как только у вас будет доступ к учетной записи Google (как вы описали), вам просто нужно запросить токен аутентификации у AccountManager для службы GData.
Если на устройстве Android уже есть токен аутентификации (для конкретной службы GData, к которой вы пытаетесь получить доступ), он будет вам возвращен.Если нет, менеджер аккаунта запросит его и вернет вам.В любом случае, вам не нужно беспокоиться об этом, поскольку AccountManager обрабатывает это.
В следующем примере я использую 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", null, activity, null, null);
try {
Bundle authTokenBundle = amf.getResult();
String authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN);
// do something with the token
InputStream response = sgc.getFeedAsStream(feedUrl, authToken, null, "2.1");
}
и
Пожалуйста, взгляните на пример кода в Google data api.Важная вещь, которую нужно сделать после аутентификации, - это вызвать GoogleHeaders.setGoogleLogin(String).
Я надеюсь, что это поможет.
Другие советы
Я сам столкнулся с подобной проблемой.Я обнаружил, что мне нужно установить xoauth_requestor_id в списке неизвестных ключей (ссылка : http://www.yenlo.nl/2011/google-calendar-api-v3-and-2lo/ )
У меня это сработало:
com.google.api.services.calendar.Calendar.CalendarList.List list = calendar.calendarList().list();
//Set the requestor id
list.getUnknownKeys().put("xoauth_requestor_id", "user@gmail.com");
После этого прошли вызовы API.
Я хотел бы, чтобы было объяснение того, зачем нужен идентификатор запрашивающего.Кто-нибудь может объяснить?