Jodee
Jodee

Reputation: 186

GCM message received but not displayed - Broadcast receiver result=CANCELLED - Service force stop

I have implemented GCM messaging at my app and server and everything works fine but not on every phone!

The main problem is:

I have done a lot of research and i think the cause may be that Huawei P8(the primary testing device) forcefully closes all apps automatically when you swipe them away from the "recent activities" tab. But if that's the case other apps like "Facebook", "Viber" and so on would not send me push notifications.

Manifest.xml

<receiver
        android:name="com.happyhour.gcm.GcmBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.REBOOT"/>
            <action android:name="android.intent.action.PACKAGE_REPLACED"/>
            <action android:name="android.intent.action.BATTERY_CHANGED"/>
            <action android:name="android.intent.action.USER_PRESENT"/>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />                
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            <category android:name="com.happyhour.main" />
        </intent-filter>
    </receiver>
    <service
        android:name="com.happyhour.gcm.GcmIntentService" >
    </service>

    <receiver android:name="com.happyhour.gcm.UpdateReceiver">
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
            <action android:name="android.intent.action.PACKAGE_INSTALL"/>
            <data android:path="com.happyhour.main"
                 android:scheme="package" />
        </intent-filter>
    </receiver>

GCMBroadCastReceiver

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {



@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub

    Log.i("GcmBroadcast",intent.getExtras().toString());


    SharedPreferences settings = context.getSharedPreferences("MyPrefsFile", 0);



        if (settings.getBoolean("my_first_time", true)) {
            //the app is being launched for first time, do something        

                  //do nothing

            // record the fact that the app has been started at least once
            settings.edit().putBoolean("my_first_time", false).commit(); 
        }else{
            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)));
            setResultCode(Activity.RESULT_OK);
        }

    }
}

GCMIntentService

public class GcmIntentService extends IntentService {

private String TAG = "GcmIntent";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;

public GcmIntentService() {
    super("GcmIntentService");
}

@Override
public void onCreate(){
    super.onCreate();
}


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    onHandleIntent(intent);
    return START_STICKY;
}



@Override
protected void onHandleIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    // The getMessageType() intent parameter must be the intent you received
    // in your BroadcastReceiver.
    Log.i(TAG, "Received: " + extras.toString());
    String messageType = gcm.getMessageType(intent);

    Log.i(TAG, "Message type:" + messageType);
    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_MESSAGE.equals(messageType)) {
            Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
            // Post notification of received message.

             sendNotification(extras.getString("message"), extras.getString("title"));

             Log.i(TAG, "Received: " + extras.toString());
        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    GcmBroadcastReceiver.completeWakefulIntent(intent);
}

// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg, String title) {
    mNotificationManager = (NotificationManager)
            this.getSystemService(Context.NOTIFICATION_SERVICE);
    if(title.isEmpty()){
        title="Happy Hour plus";
    }

    PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
            new Intent(this, SplashScreen.class), 0);

    NotificationCompat.Builder mBuilder =
            new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.ic_stat_notification)
    .setContentTitle(title)
    .setStyle(new NotificationCompat.BigTextStyle()
    .bigText(msg))
    .setContentText(msg)
    .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
    .setVibrate(new long[] {250,250,250,250})
    .setAutoCancel(true);


    mBuilder.setContentIntent(contentIntent);
    mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());

}

public boolean checkApp(){
    ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);

    // get the info from the currently running task
    List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);

    ComponentName componentInfo = taskInfo.get(0).topActivity;
    if (componentInfo.getPackageName().equalsIgnoreCase("com.happyhour.main")) {
        return true;
        } else {
            return false;
        }
    }
}

I am confused! I can't find the root of the cause.

Thanks in advance.

Upvotes: 2

Views: 1384

Answers (2)

Jodee
Jodee

Reputation: 186

So apparently seems like EMUI interface of Huawei (P8 in my case) has a special way to handle things.

After installation of each app, it will prompt a toggle button asking you, whether or not, to allow this certain app to run in background.

enter image description here

  • So if an app comes straight from the Google Play store it won't prompt you this "Run in background" allowance button because it's a "trusted source" .

  • If you just export your .apk from Android Studio and install it straight to your phone it will prompt the button as shown above because installing straight on your phone falls in the case of the "untrusted source".

  • Finally if you are using the USB debugger option to install the .apk on the phone it will NEVER prompt the button and it will always act like you have pressed "off". Everytime you close the app it will force close all its tasks.

So, what i did was to transfer my Android-Studio-generated .apk into my phone and install it manually. When it prompted the button i toggled it to "ON" and that's it. I can finally receive GCM messages when app is closed!

I think that's an EMUI bug/special-app-handling problem.

Special thanks @TeChNo_DeViL for his help.

Upvotes: 3

TeChNo_DeViL
TeChNo_DeViL

Reputation: 739

You are using very old libraries. Consider switching to latest official GCM libraries. Make your listener extend GcmListenerService. Look up official docs for the same. Also it's far easier to maintain.

Ensure all TODO's mentioned below are properly done:

  1. Register for the Project in Google Developer Console with a unique project name and package name, your package name for your App and App Project names must match the ones in the Console.
  2. Put the google_services.json configuration file in the app/ directory. Open it and verify whether the API_KEY in the file and one shown on the configuration in the Google Developer Console match, so does your package names. Also check status of google cloud messaging must be 2.
  3. Follow the detailed steps in Set up a GCM Client App on Android. All the listeners must be properly implemented.
  4. Once your app is running, Log the generated GCM Registration token, send it to your server and cross check the one logged in the adb console with the one received on the server, both must match.
  5. Still if nothing works, use this sample app as your reference. You can copy the listeners, RegistrationIntentService.java file and manifest, but don't forget to change the package names to your package name (in the AndroidManifest.xml package name references as well, specially for the listeners)

Upvotes: 2

Related Questions