android GoogleAuthUtil.getTokenWithNotification意图回调不触发

时间:2016-07-01 23:53:03

标签: android google-play-services google-oauth google-authentication android-broadcastreceiver

我有一个后台服务调用GoogleAuthUtl.getTokenWithNotification并且它正常工作,但我正在尝试实现此函数的回调部分,但是无法正常工作。

我已经实现了广播接收器并将其添加到清单中,我的应用中也有一个活动。以下是相关的代码片段。

GoogleAuthUtil.getTokenWithNotification

GoogleAuthUtil.getTokenWithNotification(this.getContext(), account, "oauth2:" + GmailScopes.GMAIL_SEND, null, new Intent(AuthReceiver.AUTH_INTENT));

AuthReceiver

public class AuthReceiver extends BroadcastReceiver
{
    public final static String AUTH_INTENT = "com.testoauth.AUTH_INTENT";

    public AuthReceiver()
    {
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        Log.d("RECEIVER", "Received Auth broadcast.");
        NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancelAll();
    }
}

AndroidManifest

<receiver android:name=".AuthReceiver" android:enabled="true" android:exported="true">
    <intent-filter>
        <action android:name="com.testoauth.AUTH_INTENT" />
    </intent-filter>
</receiver>

我不知道为什么它没有收到广播。我没有在日志中看到任何异常,并且没有任何迹象表明接收器完全被调用,它在调试时甚至不会在断点处中断。我做错了吗?

修改

我正在使用min sdk 16并定位sdk 25

来自GoogleAuthUtil.getTokenWithNotification API文档:

  

此方法专门用于后台任务。在里面   需要用户干预的错误事件,此方法需要注意   推送相关通知。用户解决后   通知,广播回调。如果用户取消那么   回调没有被解雇。

无论用户是否取消,都不会触发回调。除了ActivityManager说明已显示通知(Displayed com.google.android.gms/.auth.uiflows.gettoken.GetTokenActivity)之外,没有迹象表明已在日志中发送了指定的广播意图(在本例中为com.testoauth.AUTH_INTENT)。 “收到的Auth广播”。日志中也没有消息。

此功能包含的SDK示例(<android-sdk>/extras/google/google_play_services/samples/auth/gau)甚至无效。

4 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

我在Android API 25上尝试了以下错误,但从未调用过回调函数:

  • 没有互联网
  • 用户尚未登录
  • 用户未授权代表他/她发送电子邮件
  • Google Play服务已停用
  • Google Play服务已过期

如果回调方法调用对您的用例并不重要,您可以按照Android Quickstart for Gmail API在Android中代表用户发送电子邮件。检查Sending Email以创建消息。 您还可以查看使用上述教程创建的MyGoogleAuthUtilApplication

希望这有帮助。

答案 2 :(得分:1)

我已经实现demo我使用了最新版本的auth gradle及其工作原理。看起来auth版本可能有问题

public class AuthActivity extends Activity {


    private static final int AUTHORIZATION_CODE = 1993;
    private static final int ACCOUNT_CODE = 1601;

    private AuthPreferences authPreferences;
    private AccountManager accountManager;

    /**
     * change this depending on the scope needed for the things you do in
     * doCoolAuthenticatedStuff()
     */
    private final String SCOPE = "https://www.googleapis.com/auth/googletalk";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        accountManager = AccountManager.get(this);

        authPreferences = new AuthPreferences(this);
        if (authPreferences.getUser() != null
                && authPreferences.getToken() != null) {
            doCoolAuthenticatedStuff();
        } else {
            chooseAccount();
        }
    }

    private void doCoolAuthenticatedStuff() {
        // TODO: insert cool stuff with authPreferences.getToken()

        Log.e("AuthApp", authPreferences.getToken());
        clickSendEmail();
    }

    private void chooseAccount() {
        // use https://github.com/frakbot/Android-AccountChooser for
        // compatibility with older devices
        Intent intent = AccountManager.newChooseAccountIntent(null, null,
                new String[] { "com.google" }, false, null, null, null, null);
        startActivityForResult(intent, ACCOUNT_CODE);
    }

    private void requestToken() {
        Account userAccount = null;
        String user = authPreferences.getUser();
        for (Account account : accountManager.getAccountsByType("com.google")) {
            if (account.name.equals(user)) {
                userAccount = account;
Preferences.setAccount(AuthActivity.this,account.name, account.type);
                break;
            }
        }

        accountManager.getAuthToken(userAccount, "oauth2:" + SCOPE, null, this,
                new OnTokenAcquired(), null);
    }

    /**
     * call this method if your token expired, or you want to request a new
     * token for whatever reason. call requestToken() again afterwards in order
     * to get a new token.
     */
    private void invalidateToken() {
        AccountManager accountManager = AccountManager.get(this);
        accountManager.invalidateAuthToken("com.google",
                authPreferences.getToken());

        authPreferences.setToken(null);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            if (requestCode == AUTHORIZATION_CODE) {
                requestToken();
            } else if (requestCode == ACCOUNT_CODE) {
                String accountName = data
                        .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                authPreferences.setUser(accountName);

                // invalidate old tokens which might be cached. we want a fresh
                // one, which is guaranteed to work
                invalidateToken();

                requestToken();
            }
        }
    }

    private class OnTokenAcquired implements AccountManagerCallback<Bundle> {

        @Override
        public void run(AccountManagerFuture<Bundle> result) {
            try {
                Bundle bundle = result.getResult();

                Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT);
                if (launch != null) {
                    startActivityForResult(launch, AUTHORIZATION_CODE);
                } else {
                    String token = bundle
                            .getString(AccountManager.KEY_AUTHTOKEN);

                    authPreferences.setToken(token);

                    doCoolAuthenticatedStuff();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    private void clickSendEmail()
    {
        final Account account = Preferences.getAccount(this);
        final String token = Preferences.getToken(this);

        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                try
                {

                    Session session = Session.getDefaultInstance(new Properties(), null);

                    MimeMessage email = new MimeMessage(session);

                    email.setFrom(new InternetAddress(account.name));

                    //TODO: change email address to your email address for testing
                    email.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress("nasitraj2@gmail.com"));
                    email.setSubject("TEST OAUTH EMAIL");
                    email.setText("This is a test");
                    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                    email.writeTo(bytes);
                    String encodedEmail = Base64.encodeBase64URLSafeString(bytes.toByteArray());
                    Message message = new Message();
                    message.setRaw(encodedEmail);

                    Intent intent = new Intent(AUTH_INTENT);
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(AuthActivity.this, 0, intent, 0);
                    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
                    alarmManager.set(AlarmManager.RTC_WAKEUP,  System.currentTimeMillis()
                            , pendingIntent);
                    String test = GoogleAuthUtil.getTokenWithNotification(AuthActivity.this, account, "oauth2:" + GmailScopes.GMAIL_SEND, null, intent);
                    GoogleCredential credential = new GoogleCredential();
                    credential.setAccessToken(test);

                    boolean changed = false;
                    if (!test.equals(token))
                    {
                        changed = true;
                        //   Snackbar.make(AuthActivity.this.getView(), "TOKEN CHANGED", Snackbar.LENGTH_LONG).show();
                        Preferences.setToken(AuthActivity.this, test);
                    }



                    Gmail service = new Gmail.Builder(AndroidHttp.newCompatibleTransport(),
                            AndroidJsonFactory.getDefaultInstance(), credential)
                            .setApplicationName("Test OAuth").build();

                    service.users().messages().send("me", message).execute();

                    String msg = "Email sent";
                    if (changed)
                        msg = "TOKEN CHANGED: " + msg;



                }
                catch (MessagingException e)
                {
                    Log.d( "ERROR", e.getMessage());
                }
                catch (GoogleJsonResponseException e)
                {
                    if (e.getDetails().getCode() == 401)
                    {
                        try
                        {
                            Intent intent = new Intent(AUTH_INTENT);
                            GoogleAuthUtil.clearToken(AuthActivity.this, Preferences.getToken(AuthActivity.this));
                            GoogleAuthUtil.getTokenWithNotification(AuthActivity.this, account, "oauth2:" + GmailScopes.GMAIL_SEND, null, intent);
                        }
                        catch (Exception e1)
                        {
                            //ignore
                        }
                    }
                }
                catch (IOException e)
                {
                    //  Snackbar.make(AuthActivity.this.getView(), "ERROR", Snackbar.LENGTH_LONG).show();
                    Log.d( "ERROR", e.getMessage());
                }
                catch (Exception e)
                {
                    //Snackbar.make(AuthActivity.this.getView(), "ERROR", Snackbar.LENGTH_LONG).show();
                    Log.d( "ERROR", e.getMessage());
                }
            }
        }).start();
    }
}

答案 3 :(得分:0)

似乎没有人可以对这个问题给出正确答案;关于如何解决这个问题的大量绝对好的建议,但没有回答实际的问题。我得出结论,这必定是Android或Google Play服务中的错误。不幸的是,我已经向Android问题跟踪器和Google Play服务支持论坛报告了这个问题......两者都指向对方,甚至拒绝查看问题。