我使用Google-API从Google-Calender获取未读电子邮件和一些事件的数量。我使用了谷歌的快速入门示例代码并且工作正常(如果没有设置请求范围权限等)。因此,我将其形成为服务和Auth-Activity,以便用户更改其帐户。我的问题是用户不再被要求授权。该应用程序仍然使用正确的帐户,如果我选择一个授权我的应用程序的帐户,它仍然有效,但如果我选择一个新帐户,则不会显示授权表单。
Google AuthUtil错误:
09-19 13:13:54.114: D/DEBUG_TEST(7072): ERROR: UserRecoverableErrorNeedPermission
这是我更改帐户的活动。每当用户选择Google帐户时,静态变量" gAccountDaten"(GoogleAccountCredential对象)都会更新。
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.gmail.GmailScopes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class GoogleAuthActivity extends Activity implements EasyPermissions.PermissionCallbacks {
static GoogleAccountCredential gAccountDaten;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = { GmailScopes.GMAIL_LABELS, GmailScopes.GMAIL_READONLY , GmailScopes.MAIL_GOOGLE_COM, CalendarScopes.CALENDAR_READONLY};
private Boolean verbunden = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.googleauthactivitylayout);
gAccountDaten = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES)).setBackOff(new ExponentialBackOff());
chooseAccount();
}
private String getGoogleAccountNameSettings(){
String toReturn = getPreferences(Context.MODE_PRIVATE)
.getString(PREF_ACCOUNT_NAME, null);
Log.d("ACCOUNT_DEBUG", "FUNC: getGoogleAccountNameSettings --> " + toReturn);
return toReturn;
}
private boolean setGoogleAccountNameSettings(String accountName){
try{
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.apply();
Log.d("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> " + accountName);
}catch (Exception exc){
Log.e("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> ERROR");
return false;
}finally {
Log.e("ACCOUNT_DEBUG", "FUNC: setGoogleAccountNameSettings --> ERROR");
return true;
}
}
private boolean removeGoogleAccountNameSettings(){
try{
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.remove(PREF_ACCOUNT_NAME);
editor.apply();
GoogleService.EMAIL_COUNT = 0;
GoogleService.lstKalender.clear();
Log.d("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> " + "rennt");
}catch (Exception exc){
Log.e("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> ERROR");
return false;
}finally {
Log.e("ACCOUNT_DEBUG", "FUNC: removeGoogleAccountNameSettings --> ERROR");
return true;
}
}
@AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
private void chooseAccount( ) {
removeGoogleAccountNameSettings();
if (EasyPermissions.hasPermissions(
this, android.Manifest.permission.GET_ACCOUNTS)) {
String accountName = getGoogleAccountNameSettings();
if (accountName != null) {
gAccountDaten.setSelectedAccountName(accountName);
this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
Log.d("AUTH_DEBUG", "Already authed" + " | " + gAccountDaten.getScope());
//finish();
} else {
// Start a dialog from which the user can choose an account
startActivityForResult(
gAccountDaten.newChooseAccountIntent(),
REQUEST_ACCOUNT_PICKER);
}
} else {
// Request the GET_ACCOUNTS permission via a user dialog
EasyPermissions.requestPermissions(
this,
"This app needs to access your Google account .",
REQUEST_PERMISSION_GET_ACCOUNTS,
android.Manifest.permission.GET_ACCOUNTS);
}
}
@Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode != RESULT_OK) {
//mOutputText.setText(
// "This app requires Google Play Services. Please install " +
// "Google Play Services on your device and relaunch this app.");
} else {
//getResultsFromApi();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
String accountName =
data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
setGoogleAccountNameSettings(accountName);
gAccountDaten.setSelectedAccountName(accountName);
Log.d("AUTH_DEBUG", "Authed after Picker -->" + accountName + " | " + gAccountDaten.getScope());
this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
finish();
}
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == RESULT_OK) {
Log.d("AUTH_DEBUG", "started aufter authorization -->" + resultCode + " | " + gAccountDaten.getScope());
this.startService(new Intent(this, GoogleService.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK));
finish();
}
break;
}
}
/////PERMISSION CALLBACKS
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(
requestCode, permissions, grantResults, this);
}
/**
* Callback for when a permission is granted using the EasyPermissions
* library.
* @param requestCode The request code associated with the requested
* permission
* @param list The requested permission list. Never null.
*/
@Override
public void onPermissionsGranted(int requestCode, List<String> list) {
// Do nothing.
}
/**
* Callback for when a permission is denied using the EasyPermissions
* library.
* @param requestCode The request code associated with the requested
* permission
* @param list The requested permission list. Never null.
*/
@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
Log.d("DEBUG_TEST", "NO PERM");
}
}
这是我的Google服务代码。它将每隔60秒从谷歌api收集信息并将其写入静态变量。
import android.*;
import android.app.Dialog;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.RemoteViews;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.CalendarList;
import com.google.api.services.calendar.model.CalendarListEntry;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import com.google.api.services.calendar.model.Events;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.gmail.model.Label;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class GoogleService extends Service implements EasyPermissions.PermissionCallbacks{
GoogleAccountCredential gAccountDaten;
static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;
private static final String PREF_ACCOUNT_NAME = "accountName";
static String testj = "";
static ArrayList<Kalender> lstKalender = new ArrayList<>();
static int EMAIL_COUNT = 0;
//GOOGLE BERECHTIGUNGEN
private static final String[] SCOPES = { GmailScopes.GMAIL_LABELS, GmailScopes.GMAIL_READONLY , GmailScopes.MAIL_GOOGLE_COM, CalendarScopes.CALENDAR_READONLY};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("DEBUG_TEST", "onStartCommand");
gAccountDaten = GoogleAuthActivity.gAccountDaten;
if(gAccountDaten == null){
Log.d("DEBUG_TEST", "gAccountDaten == NULL!");
return 0;
}
getResultsFromApi();
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
getResultsFromApi();
handler.postDelayed(this, 60000);
}
};
handler.postDelayed(runnable, 60000);
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onPermissionsGranted(int requestCode, List<String> perms) {
}
@Override
public void onPermissionsDenied(int requestCode, List<String> perms) {
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
}
//HELFER FUNKTIONEN
private void getResultsFromApi() {
if (! isGooglePlayServicesAvailable()) {
acquireGooglePlayServices();
} else if (gAccountDaten.getSelectedAccountName() == null) {
Log.d("DEBUG_TEST", "ChooseAccount");
} else if (! isDeviceOnline()) {
//Gerät Offline
} else {
Log.d("DEBUG_TEST", "MakeRequestTask -->" + gAccountDaten.getSelectedAccountName());
new MakeRequestTask(gAccountDaten).execute();
}
}
//CHECK: GERÄT ONLINE ?
private boolean isDeviceOnline() {
ConnectivityManager connMgr =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
//CHECK: GOOGLE SERVICE ONLINE ?
private boolean isGooglePlayServicesAvailable() {
GoogleApiAvailability apiAvailability =
GoogleApiAvailability.getInstance();
final int connectionStatusCode =
apiAvailability.isGooglePlayServicesAvailable(this);
return connectionStatusCode == ConnectionResult.SUCCESS;
}
private void acquireGooglePlayServices() {
GoogleApiAvailability apiAvailability =
GoogleApiAvailability.getInstance();
final int connectionStatusCode =
apiAvailability.isGooglePlayServicesAvailable(this);
}
/////////////////////////MAKE REQUEST KLASSE////////////////////////////////////
private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
private com.google.api.services.gmail.Gmail mService = null;
private com.google.api.services.calendar.Calendar mServiceKalender = null;
private Exception mLastError = null;
public MakeRequestTask(GoogleAccountCredential credential) {
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
HttpTransport transport2 = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory2 = JacksonFactory.getDefaultInstance();
mService = new com.google.api.services.gmail.Gmail.Builder(
transport, jsonFactory, credential)
.setApplicationName("Gmail API Android Quickstart")
.build();
mServiceKalender = new com.google.api.services.calendar.Calendar.Builder(
transport2, jsonFactory2, credential)
.setApplicationName("Google Calendar API Android Quickstart")
.build();
Log.d("DEBUG_TEST", "mService und mServiceKalender Objecte instanzieren --> " + credential.getSelectedAccountName());
}
/**
* Background task to call Gmail API.
* @param params no parameters needed for this task.
*/
@Override
protected List<String> doInBackground(Void... params) {
try {
return getDataFromApi();
} catch (Exception e) {
mLastError = e;
cancel(true);
return null;
}
}
/**
* Fetch a list of Gmail labels attached to the specified account.
* @return List of Strings labels.
* @throws IOException
*/
private List<String> getDataFromApi() throws IOException {
// Get the labels in the user's account.
String user = "me";
List<String> labels = new ArrayList<String>();
Label label = mService.users().labels().get(user, "INBOX").execute();
Log.d("DEBUG_TEST", "getDataFromApi() --> " + user );
//EMAIL_COUNT = label.getMessagesUnread();
EMAIL_COUNT = label.getMessagesTotal();
labels.add("E-Mails: " + EMAIL_COUNT);
lstKalender.clear();
String pageToken = null;
do {
CalendarList calendarList = mServiceKalender.calendarList().list().setPageToken(pageToken).execute();
List<CalendarListEntry> items = calendarList.getItems();
for (CalendarListEntry calendarListEntry : items) {
String KALENDERNAME = calendarListEntry.getSummary();
String KALENDER_ID = calendarListEntry.getId();
Kalender neuerKalender = new Kalender();
neuerKalender.setKalenderName(KALENDERNAME);
neuerKalender.setKalenderId(KALENDER_ID);
Log.d("KALENDER_DEBUG", "Kalender: " + KALENDERNAME + "wurde angelegt! ID: " + KALENDER_ID);
String pageToken2 = null;
do {
Events events = mServiceKalender.events().list(KALENDER_ID).setPageToken(pageToken2).execute();
List<Event> items2 = events.getItems();
for (Event event : items2) {
String calName = event.getSummary();
EventDateTime calStart = event.getStart();
EventDateTime calEnde = event.getEnd();
String calLocation = event.getLocation();
String calID = event.getId();
if(neuerKalender.addEvent(calName,calStart,calEnde,calLocation,calID)){
//Log.d("KALENDER_DEBUG", "Event: " + calName + " wurde zum Kalender " + KALENDERNAME + " hinzugefügt!");
}
}
pageToken2 = events.getNextPageToken();
} while (pageToken2 != null);
lstKalender.add(neuerKalender);
Log.d("KALENDER_DEBUG", "Kalender: " + neuerKalender.getKalenderName() + " durchgelaufen und zur Globalen Liste hinzugefügt!");
}
pageToken = calendarList.getNextPageToken();
} while (pageToken != null);
DaWidgetProvider.updateEventList(getBaseContext());
UpdateService updateService = new UpdateService();
updateService.buildUpdate(getBaseContext());
DaWidgetProvider.updateAllWidgets(getBaseContext());
return labels;
}
@Override
protected void onPreExecute() {
}
@Override
protected void onPostExecute(List<String> output) {
if (output == null || output.size() == 0) {
// mOutputText.setText("No results returned.");
} else {
//output.add(0, "Data retrieved using the Gmail API:");
//mOutputText.setText(TextUtils.join("\n", output));
//mProgress.dismiss();
Context mContext = getApplicationContext();
}
}
@Override
protected void onCancelled() {
if (mLastError != null) {
if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
} else if (mLastError instanceof UserRecoverableAuthIOException) {
Log.d("DEBUG_TEST", "ERROR: UserRecoverableError" + mLastError.getMessage());
} else {
Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
}
} else {
Log.d("DEBUG_TEST", "abgebrochen");
}
}
}
}
谢谢, J. Doe;)
答案 0 :(得分:0)
好看,这似乎是问题所在。但我有一个问题要解决它,因为我的Google服务和我的Google帐户选择器活动是不同的。我试图将mLastError传递给我在Intent中的Activity并在那里启动Authentication-Request但是我得到以下错误:
09-19 13:44:18.508: E/AndroidRuntime(7959): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException)
我的代码在Google服务和GoogleAuthActivity中发生了变化:
谷歌-服务:
protected void onCancelled() {
if (mLastError != null) {
if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
} else if (mLastError instanceof UserRecoverableAuthIOException) {
Log.d("DEBUG_TEST", "ERROR: UserRecoverableError" + mLastError.getCause().getMessage());
//KEINE BERECHTIGUNG GESETZT
[代码更改]
Intent startIntent = new Intent(getApplicationContext(),GoogleAuthActivity.class); startIntent.putExtra(&#34; auththis&#34;,mLastError); startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(startIntent);
[/代码更改] } else {
Log.d("DEBUG_TEST", "ERROR: " + mLastError.getMessage());
}
} else {
Log.d("DEBUG_TEST", "abgebrochen");
}
}
GoogleAuthActivity:
//EXTRA DATA???
if(getIntent().hasExtra("auththis")){
Intent edIntent = getIntent();
Bundle extras = edIntent.getExtras();
UserRecoverableAuthIOException mLastError = null;
mLastError = (UserRecoverableAuthIOException) extras.get("auththis");
startActivityForResult(
mLastError.getIntent(),
GoogleAuthActivity.REQUEST_AUTHORIZATION);
}else{
chooseAccount();
}