У меня есть приложение для Android, для которого требуется разрешение пользователя на доступ к его электронным таблицам Google (область действия - это API-интерфейс Google Analytics)., работающий с google OAuth 2.0 в android
При первом запуске приложения все хорошо, я могу получить электронные таблицы. Я сохраняю адрес электронной почты, который пользователь выбирает для общих настроек.
Я хочу, чтобы в следующий раз, когда пользователь запускает приложение (после первого раза), приложение получит только токен (потому что у меня уже есть адрес электронной почты пользователя) без пользователя снова пройти учетную запись.
Я предполагаю, что это было сделано раньше, потому что пользователь должен выбрать его только один раз. тем не менее, я не мог понять, что для него лучше всего.
Он является Google OAuth 2.0 класс
прямо здесь http://developer.android.com/google/auth/http-auth.html
public class GoogleAccountActivity extends Activity {
static final int REQUEST_CODE_PICK_ACCOUNT = 1000;
static final int REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR = 1001;
static final int REQUEST_CODE_RECOVER_FROM_AUTH_ERROR = 1002;
String mEmail;
private static final String SCOPE =
"oauth2:https://spreadsheets.google.com/feeds/";
private Intent homeIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
homeIntent=new Intent(this, HomeActivity.class);
// next activity tto launch
pickUserAccount();
}
private void getUsername() {
if (mEmail == null) {
pickUserAccount();
} else {
if (isDeviceOnline()) {
new GetUsernameTask(this, mEmail, SCOPE).execute();
} else {
Toast.makeText(this, R.string.not_online, Toast.LENGTH_LONG).show();
}
}
}
public boolean isDeviceOnline() {
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
return true;
} else {
return false;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
// Receiving a result from the AccountPicker
if (resultCode == RESULT_OK) {
mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
// With the account name acquired, go get the auth token
getUsername();
} else if (resultCode == RESULT_CANCELED) {
// The account picker dialog closed without selecting an account.
// Notify users that they must pick an account to proceed.
Toast.makeText(this, R.string.pick_account, Toast.LENGTH_SHORT).show();
}
} else if ((requestCode == REQUEST_CODE_RECOVER_FROM_AUTH_ERROR ||
requestCode == REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR)
&& resultCode == RESULT_OK) {
// Receiving a result that follows a GoogleAuthException, try auth again
getUsername();
}
}
private void pickUserAccount() {
String[] accountTypes = new String[]{"com.google"};
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
accountTypes, false, null, null, null, null);
startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
}
public void handleException(final Exception e) {
// Because this call comes from the AsyncTask, we must ensure that the following
// code instead executes on the UI thread.
runOnUiThread(new Runnable() {
@Override
public void run() {
if (e instanceof GooglePlayServicesAvailabilityException) {
// The Google Play services APK is old, disabled, or not present.
// Show a dialog created by Google Play services that allows
// the user to update the APK
int statusCode = ((GooglePlayServicesAvailabilityException)e)
.getConnectionStatusCode();
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(statusCode,
GoogleAccountActivity.this,
REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
dialog.show();
} else if (e instanceof UserRecoverableAuthException) {
// Unable to authenticate, such as when the user has not yet granted
// the app access to the account, but the user can fix this.
// Forward the user to an activity in Google Play services.
Intent intent = ((UserRecoverableAuthException)e).getIntent();
startActivityForResult(intent,
REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
}
}
});
}
public class GetUsernameTask extends AsyncTask<Void, Void, String>{
Activity mActivity;
String mScope;
String mEmail;
GetUsernameTask(Activity activity, String name, String scope) {
this.mActivity = activity;
this.mScope = scope;
this.mEmail = name;
}
/**
* Executes the asynchronous job. This runs when you call execute()
* on the AsyncTask instance.
*/
@Override
protected String doInBackground(Void... params) {
try {
String token = fetchToken();
if (token != null) {
homeIntent.putExtra("userToken", token);
startActivity(homeIntent); // starting the Home Activity
}
} catch (IOException e) {
// The fetchToken() method handles Google-specific exceptions,
// so this indicates something went wrong at a higher level.
// TIP: Check for network connectivity before starting the AsyncTask.
}
return null;
}
/**
* Gets an authentication token from Google and handles any
* GoogleAuthException that may occur.
*/
protected String fetchToken() throws IOException {
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException userRecoverableException) {
// GooglePlayServices.apk is either old, disabled, or not present
// so we need to show the user some UI in the activity to recover.
handleException(userRecoverableException);
} catch (GoogleAuthException fatalException) {
// Some other type of unrecoverable exception has occurred.
// Report and log the error as appropriate for your app.
}
return null;
}
}
}
Он отлично работает для первого запуска, но я не уверен, что делать в следующий раз.
Подводя итог:
Я хочу понять, если мне нужно, чтобы получить маркер каждый раз, когда я запускаю приложение ??
, и если да, то как мне сделать только выборку токенов (и исключений обработки) без выбора учетной записи и других вещей, необходимых для первого запуска.
Нужно ли мне работать с токеном обновления? потому что я читал об этом, но не видел в нем никакого примера.
любая помощь будет принята с благодарностью.
Спасибо, Офек
благодарит за ваш ответ! несколько вопросов: при нажатии кнопки google + пользователь должен только один раз войти в систему? после того, как он впервые запустит приложение и примет участие, всегда ли он будет подписан? и если да, то как мне получить токен доступа в не-google-auth-активности (скажем, мой HomeActivity)? потому что при первом запуске пользователь будет входить в систему и получать токен, но в следующие моменты я хочу направить пользователя на другую активность (на мой домашний адрес, без хавига, чтобы снова увидеть активность google), поэтому я хочу знать, как я могу получить токен в другой деятельности? спасибо –
Вам нужно войти через Google +, чтобы получить информацию из профиля google.Вам необходимо отправить токен на свой сервер, а затем проверить его там. Позже вы отправляете свой собственный токен своему клиенту, и Google не будет участвовать в нем. Ток google имеет некоторое время истечения срока действия. –
Вы также можете получить токен обновления из Google на свой сервер и сохранить его в своем приложении и получить доступ к нему через свой сервер для дальнейшего входа. –