2016-09-19 60 views
0

我使用Google-API從Google-Calender中獲取未讀電子郵件和一些事件的數量。我使用了Google的Quick-Start示例代碼,它工作正常(如果未設置,請求範圍權限等)。所以我將它形成了一個服務和一個授權活動,供用戶更改他們的賬戶。我的問題是,用戶不會被要求授權了。該應用程序仍然使用正確的帳戶,如果我選擇一個授權給我的應用程序的帳戶,它仍然有效,但如果我選擇一個新的帳戶,則不會顯示授權表單。要求在Google API中授權

谷歌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秒從google 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

這個錯誤很簡單,因爲你需要處理這個異常與捕捉(UserRecoverableAuthIOException E){ startActivityForResult(e.getIntent(),REQUEST_AUTHORIZATION ); } ... – PN10

+0

我在我的Auth-Activity中無法使用e.getIntent()。有沒有其他的方法來檢索它? –

+0

好像你已經把它整理出來了...不是嗎? – PN10

回答

0

尼斯,這似乎是該問題。但是,我有一個問題需要解決,因爲我的Google服務和我的Google帳戶選取器活動有所不同。我試圖mLastError傳遞給我的活動在意圖並啓動驗證請求存在,但我得到了以下錯誤:

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) 

我的代碼更改在谷歌,服務和GoogleAuthActivity:

Google-服務:

​​ [CODE CHANGES]

意圖startIntent =新意圖(getApplicationContext(),GoogleAuthActivity.class); startIntent.putExtra(「auththis」,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(); 
     }