我有一个后台服务调用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
)甚至无效。
答案 0 :(得分:1)
从GoogleAuthUtil和Plus.API迁移
如果您过去使用GoogleAuthUtil.getToken或Plus.API与Google登录集成,则应迁移到最新的登录API,以获得更高的安全性和更好的用户体验。
参考: https://developers.google.com/identity/sign-in/android/migration-guide
还要检查一下是否有帮助
答案 1 :(得分:1)
我在Android API 25上尝试了以下错误,但从未调用过回调函数:
如果回调方法调用对您的用例并不重要,您可以按照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服务支持论坛报告了这个问题......两者都指向对方,甚至拒绝查看问题。