Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gcm notification received after hours on some devices

I am trying to use gcm notification. My server code is working fine and I am getting success as acknowledgment.

The problem is notification is getting sent properly :

1) In most of devices notification is received instantaneously. Tested on google nexus,sony phones.

2) Other devices are also receiving notification but after several hours. Yes, hours. Tested on Karbonn, Micromax some phones.

Note:

All the devices are connected to the same wifi so network connectivity not an issue . Using php at server side; There are several unanswered questions regarding this topic . I am hereby listing some of them:

gcm notification is not working on some devices like micromax

One device doesn't receive push notifications (GCM)

Push notifications delay with GCM

Anyone else having similar problem attach your question too.

Failed trials of rectification:

I have also made changes to code after going through several questions in which the developers found their solution like removing this line of code from onHandleIntent()

GcmBroadcastReceiver.completeWakefulIntent(intent);

Or changing delay_while_ideal value to true/false in server code.

Or separately mentioning receiver and registration intent-filter

<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.nothing.gcmclient" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.nothing.gcmclient" />
</intent-filter>

Code: Android.manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.nothing.gcmclient"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="22" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <permission
        android:name="com.nothing.gcmclient.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.nothing.gcmclient.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.nothing.gcmclient.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <uses-permission android:name="ANDROID.PERMISSION.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".RegisterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/app_name" >
        </activity>

        <receiver
            android:name=".GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="com.nothing.gcmclient" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.nothing.gcmclient" />
            </intent-filter>
        </receiver>

        <service android:name=".GCMNotificationIntentService"></service>

        <activity
            android:name=".ChatActivity"
            android:label="@string/title_activity_chat" >
        </activity>
        <activity
            android:name=".RegisterScreen"
            android:label="@string/title_activity_register_screen" >
        </activity>
        <activity
            android:name=".RegisterChatButtonActivity"
            android:label="@string/title_activity_register_chat_button" >
        </activity>
        <activity
            android:name=".ChatHistory"
            android:label="@string/title_activity_chat_history" >
        </activity>
        <activity
            android:name=".MessageScreen"
            android:label="@string/title_activity_message_screen" >
        </activity>
    </application>

</manifest>

Code: GCMNotificationIntentService.java

public class GCMNotificationIntentService extends IntentService {

    public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;

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

    public static final String TAG = "GCMNotificationIntentService";

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {
            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());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
                    .equals(messageType)) {
                String sender=extras.get(Config.SENDER).toString().toLowerCase();
                String message=extras.get(Config.MESSAGE_KEY).toString();

                if(!RegisterActivity.appVisible==true)
                {
                    sendNotification("New message Received from "+ extras.get(Config.SENDER));
                }
            }
        }
        //GcmBroadcastReceiver.completeWakefulIntent(intent);
    }

    private void sendNotification(String msg) {
        Log.d(TAG, "Preparing to send notification...: " + msg);
        mNotificationManager = (NotificationManager) this
                .getSystemService(Context.NOTIFICATION_SERVICE);

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

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this).setSmallIcon(R.drawable.gcm_cloud)
                .setContentTitle("New Notification")
                .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
                .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
        Log.d(TAG, "Notification sent successfully.");
    }
}

Experts please look into the problem and suggest the appropriate cause and solution. My app would be of no use if it works only for certain phones.If you need any more file in our application kindly inform.

PS- Kindly read the entire question and then post your comments or answers or mark duplicate if necessary.

like image 535
user2653926 Avatar asked Jul 27 '15 14:07

user2653926


People also ask

What is GCM service on Google Play?

Google Cloud Messaging (GCM) is a service that allows you to send push notifications from your server to your users' Android devices, and also to receive messages from devices on the same connection.

What is GCM notification?

Google Cloud Messaging (GCM) was a mobile notification service developed by Google that enables third-party application developers to send notification data or information from developer-run servers to applications that target the Google Android Operating System, as well as applications or extensions developed for the ...

Is GCM reliable?

Our findings reveal that the GCM message delivery is unpredictable, namely having a reliable connection to Google's GCM servers on the client device does not guarantee a timely message arrival. Therefore, GCM is not suitable for time sensitive and/or "must-deliver-to-all" app scenarios.

What is APN and GCM?

From this thread, GCM is a service that helps developers send data from servers to their Android applications on Android devices. Same with APN which is a service for app developers to propagate information to iOS (and, indirectly, watchOS), tvOS, and macOS devices.


1 Answers

  • GCM works through Google Play Services
  • Devices connect to Google Play Services through TCP on port 5228
  • Devices should use port 443 as fallback if port 5228 is blocked, but apparently they just don't use the fallback sometimes (happened to multiple of my devices)
  • Device sends a heartbeat packet to Google Play Services every 28 minutes on mobile and 15 minutes on wifi
  • You can check the connection state, heartbeat interval, connection address and port, etc. dialing *#*#426#*#* on a device

How to fix common issues when devices don't connect to Google Play Services on wifi or lose connection frequently:

  1. Open port 5228
  2. Configure your routers, so they don't kill inactive tcp connections before waiting at least 15 minutes

See this post on Google Product Forums for more information.

like image 68
Baris Akar Avatar answered Oct 07 '22 20:10

Baris Akar