Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BroadcastReceiver trying to return result during a non-ordered broadcast Weird Error

This error started occurring when the app is launched for the first time even though I am not sending a push notification:

 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)

The code for the 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);
    }
}

The error started showing up after I implemented the following code in an IntentService (also doesn't get called on app launch). But also not every time, I.E. after uninstalling and running the app from Android Studio sometimes the error occurs and sometimes it doesn't.

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));
}

In the manifest:

<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" />

After commenting out the line setResultCode(Activity.RESULT_OK); as recommended by the answer to another question the IntentService for push notification received a notification with this content

From-google.com/iid-Title-null-Message-null-ExtraData-null

My case is the same as Weird push message received on app start

like image 987
Rashad.Z Avatar asked Mar 16 '23 20:03

Rashad.Z


2 Answers

According to the answer https://stackoverflow.com/a/30508934/1950784

this is a google related feature which is not a big deal and can be filtered programatically.

@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
                        }
like image 57
Rashad.Z Avatar answered Apr 27 '23 02:04

Rashad.Z


The underlying issue here is that the GCM API has changed. As OP indicates, you can simply filter this new intent out, but by doing so you will miss token refresh notifications.

From the updated 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]
}

The proper way to fix this issue is to update your implementation for the new API as detailed in the updated GCM API docs.

For existing apps that extend a WakefulBroadcastReceiver, Google recommends migrating to GCMReceiver and GcmListenerService. To migrate:

In the app manifest, replace your GcmBroadcastReceiver with "com.google.android.gms.gcm.GcmReceiver", and replace the current service declaration that extends IntentService to the new GcmListenerService

Remove the BroadcastReceiver implementation from your client code

Refactor the current IntentService service implementation to use GcmListenerService

For details, see the example manifest and code samples in this page.

I've posted an answer to a related question that pulls out all of the relevant code required to update from the old implementation here.

like image 42
mpkuth Avatar answered Apr 27 '23 03:04

mpkuth