即使我没有发送推送通知,第一次启动应用时也会发生此错误:
BroadcastReceiver trying to return result during a non-ordered broadcast
java.lang.RuntimeException: BroadcastReceiver trying to return result during a non-ordered broadcast
at android.content.BroadcastReceiver.checkSynchronousHint(BroadcastReceiver.java:799)
at android.content.BroadcastReceiver.setResultCode(BroadcastReceiver.java:565)
at com.pushnotification.GcmBroadcastReceiver.onReceive(GcmBroadcastReceiver.java:17)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2712)
at android.app.ActivityThread.access$1700(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5696)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
BroadcastReceiver的代码:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
/* the crash is pointing to this line */
setResultCode(Activity.RESULT_OK);
}
}
在IntentService中实现以下代码后,错误开始出现(在应用启动时也没有调用)。但也不是每一次,I.E。从Android Studio卸载并运行应用程序后,有时会发生错误,有时它不会。
BroadcastReceiver receiver;
public void DownloadListener(final String ZipFile) {
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadReference);
Cursor c = downloadManager.query(query);
if (c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
DismissProgressDialog();
ShowProgress("Almost Done", "Unzipping And Installing Database", pd.STYLE_SPINNER);
}
}
}
}
};
context.registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
在清单中:
<receiver
android:name="com.pushnotification.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.geovision.ffmsnativeprototype" />
</intent-filter>
</receiver>
<service android:name=".WebServiceCommunication.SystemDatabaseService" />
根据another question的答案建议注释掉setResultCode(Activity.RESULT_OK);
行后,推送通知的IntentService会收到包含此内容的通知
From-google.com/iid-Title-null-Message-null-ExtraData-null
相同
答案 0 :(得分:4)
根据答案https://stackoverflow.com/a/30508934/1950784
这是一个谷歌相关的功能,这不是什么大问题,可以编程过滤。
@Override
protected void onHandleIntent(Intent intent) //RECEIVE THE PUSHNOTIFICATION
{
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
/*
* Filter messages based on message type. Since it is likely that GCM
* will be extended in the future with new message types, just ignore
* any message types you're not interested in, or that you don't
* recognize.
*/
if (GoogleCloudMessaging.
MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
// sendNotification("Send error: " + extras.toString());
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
// sendNotification("Deleted messages on server: " +
// extras.toString());
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
Log.i(TAG, "PUSHNOTIFICATION RECEIVED @ " + SystemClock.elapsedRealtime());
extraData=extras.getString("extraData");
from=extras.getString("from");
title=extras.getString("title");
message=extras.getString("message");
Log.i(TAG, "Received: " + extras.toString()+" M"+messageType);
if(title!=null) {
if(from.equals("google.com/iid")) { //related to google ... DO NOT PERFORM ANY ACTION } else { //HANDLE THE RECEIVED NOTIFICATION }
答案 1 :(得分:3)
此处的根本问题是GCM API已更改。如OP所示,您可以简单地过滤掉这个新意图,但通过这样做您将错过令牌刷新通知。
来自更新后的GCM sample code。
的AndroidManifest.xml
<service
android:name=".MyInstanceIdListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
MyInstanceIdListenerService.java
public class MyInstanceIDListenerService extends InstanceIDListenerService {
private static final String TAG = "MyInstanceIDLS";
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. This call is initiated by the
* InstanceID provider.
*/
// [START refresh_token]
@Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
// [END refresh_token]
}
解决此问题的正确方法是更新新API的实施,详见更新后的GCM API docs。
对于扩展WakefulBroadcastReceiver的现有应用程序,Google 建议迁移到GCMReceiver和GcmListenerService。至 迁移:
在应用清单中,将GcmBroadcastReceiver替换为 “com.google.android.gms.gcm.GcmReceiver”,并替换当前 将IntentService扩展到新的服务声明 GcmListenerService
从客户端代码中删除BroadcastReceiver实现
重构要使用的当前IntentService服务实现 GcmListenerService
有关详细信息,请参阅此页面中的示例清单和代码示例。
我发布了一个相关问题的答案,该问题提取了从旧实施here更新所需的所有相关代码。