1
votes

I have created my Android app to get Registration Id from GCM and receive a downstream notification. Registration part is working perfectly here. (RegID is sent to me by opening an email and I'm hard coding it in my 3rd party server.) But the thing is when I send a message from my server my app never receives it. Following is my Code.

NotificationMainActivity - (Registers the app in GCM successfully)

public class NotificationMainActivity extends Activity {
	
	public static final String EXTRA_MESSAGE = "message";
	public static final String PROPERTY_REG_ID = "registration_id";
	private static final String PROPERTY_APP_VERSION = "appVersion";
	private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
	
    String SENDER_ID = "1030512389658";

    static final String TAG = "Kanrich GCM Notification";

    public TextView mDisplay;
    GoogleCloudMessaging gcm;
    AtomicInteger msgId = new AtomicInteger();
    SharedPreferences prefs;
    Context context;

    String regid;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        setContentView(R.layout.activity_notification_main);
        mDisplay = (TextView) findViewById(R.id.regID);
        context = getApplicationContext();

        // Check device for Play Services APK. If check succeeds, proceed with
        //  GCM registration.
        if (checkPlayServices()) {
            gcm = GoogleCloudMessaging.getInstance(this);
            regid = getRegistrationId(context);
            
            System.out.println("**********PLAY ******************************************************");

            if (regid.isEmpty()) {
                registerInBackground();
            }
        } else {
            Log.i(TAG, "No valid Google Play Services APK found.");
        }
    }
    
    @Override
    protected void onResume(){
    	super.onResume();
    	checkPlayServices();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.notification_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
   //Get Registratiom ID If exists..
    private String getRegistrationId(Context context) {
        final SharedPreferences prefs = getGCMPreferences(context);
        String registrationId = prefs.getString(PROPERTY_REG_ID, "");
        if (registrationId.isEmpty()) {
            Log.i(TAG, "Registration not found.");
            return "";
        }
        // Check if app was updated; if so, it must clear the registration ID
        // since the existing registration ID is not guaranteed to work with
        // the new app version.
        int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
        int currentVersion = getAppVersion(context);
        if (registeredVersion != currentVersion) {
            Log.i(TAG, "App version changed.");
            return "";
        }
        return registrationId;
    }
    
    //GEt App Version..(To know whether the app is updated.. If yes REg.ID isempty,.)
    private static int getAppVersion(Context context) {
        try {
            PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
        } catch (NameNotFoundException e) {
            // should never happen
            throw new RuntimeException("Could not get package name: " + e);
        }
    }
    
    
    //Register in Background..
    private void registerInBackground() {   	
    	new AsyncTask<Void, Void, String>() { 
    		
            @Override
            protected String doInBackground(Void... voids) {
            	String msg = "";
            	
            	try{
            		if (gcm == null) {
                        gcm = GoogleCloudMessaging.getInstance(context);
                    }
                    regid = gcm.register(SENDER_ID);
                    msg = "Device registered, registration ID=" + regid;
                    System.out.println(msg);
                    
                    storeRegistrationId(context, regid);
            	}
            	catch(IOException ex){
                    msg = "Error :" + ex.getMessage();                   
            	}
            	
                return msg;
            }

            @Override
            protected void onPostExecute(String result) {
            	mDisplay.append(result + "\n");
            }
        }.execute();
    	
    }
           
    //Check Google play service.
    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.i(TAG, "This device is not supported.");
                finish();
            }
            return false;
        }
        return true;
    }
    
  //Shared Preferences...
    private SharedPreferences getGCMPreferences(Context context) {
        return getSharedPreferences(NotificationMainActivity.class.getSimpleName(),
                Context.MODE_PRIVATE);
    }
    
    private void storeRegistrationId(Context context, String regId) {
        final SharedPreferences prefs = getGCMPreferences(context);
        int appVersion = getAppVersion(context);
        Log.i(TAG, "Saving regId on app version " + appVersion);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(PROPERTY_REG_ID, regId);
        editor.putInt(PROPERTY_APP_VERSION, appVersion);
        editor.commit();
    }
    
    public void sendRegID(View v){ 	
    	try{
    		final Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("text/plain");
            intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"[email protected]"});
            intent.putExtra(Intent.EXTRA_SUBJECT, "GCM reg ID");
            intent.putExtra(Intent.EXTRA_TEXT, regid);
            NotificationMainActivity.this.startActivity(intent);
    	}
    	catch(Exception e){
    		System.out.println("###-Attach to Gmail Error-- "+e.toString());
    	}
    }
}

GcmBroadcastReceiver.java

package com.example.kanrichgcmnotification;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
		
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		// 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)));
        setResultCode(Activity.RESULT_OK);
	}

}

GcmIntentService.java

package com.example.kanrichgcmnotification;

import com.google.android.gms.gcm.GoogleCloudMessaging;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

public class GcmIntentService extends IntentService {
	
	public static final int NOTIFICATION_ID = 1;
    private NotificationManager mNotificationManager;
    NotificationCompat.Builder builder;
	
	static final String TAG = "Kanrich GCM Notification";
	
	public GcmIntentService() {
        super("GcmIntentService");
    }

	@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.
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {  // has effect of unparcelling Bundle
            /*
             * Filter messages based on the 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)) {
                // This loop represents the service doing some work.
                for (int i=0; i<5; i++) {
                    Log.i(TAG, "Working... " + (i+1)
                            + "/5 @ " + SystemClock.elapsedRealtime());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                    }
                }
                Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
                // Post notification of received message.
                sendNotification("Received: " + extras.toString());
                Log.i(TAG, "Received: " + extras.toString());
            }
        }
        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);		
	}
		
	 private void sendNotification(String msg) {
	        mNotificationManager = (NotificationManager)
	                this.getSystemService(Context.NOTIFICATION_SERVICE);

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

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

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

And Here is my Manifest.xml file. (with But I'm not sure I have insert it properly.)

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

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="21" />
    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    
    <permission android:name="com.example.gcm.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
        
        
        <activity
            android:name=".NotificationMainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </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.example.kanrichgcmnotification" />
            </intent-filter>
        </receiver>
        <service android:name=".GcmIntentService" />
        
    </application>
 
</manifest>
++++++++++ Later Edit : Here is my PHP script which sends the message.(It is working for a 3rd party app which receives json gcm messages.)

<?php

// API access key from Google API's Console
define( 'API_ACCESS_KEY', 'AIzaSyBfHNkFdyoLMYAOOyoiD_pWZ4OjFJkASZg' );


$registrationId = array('APA91bEmd2SikqaRi7jkvq5dw_Wz566x-ijKl6pTMdyJ_ukEZCHLRrW5-bOp8MSAq0mWjih-UbQsHVHrK6tg2IyoLALBNO4z2kROcMKIWzdoMbKMiBgMqjvttULxjz0h7v3Tv8mlNrbWSdh2XPb63fdKs7obs_mUKAz0pkbfDiOxDYzM5FT8aO4');

// prep the bundle

$msg = array
(
	'message' 	=> 'here is a message. message',
	'title'		=> 'This is a title. title',
	'subtitle'	=> 'This is a subtitle. subtitle',
	'tickerText'	=> 'Ticker text here...Ticker text here...Ticker text here',
	'vibrate'	=> 1,
	'sound'		=> 1,
	'largeIcon'	=> 'large_icon',
	'smallIcon'	=> 'small_icon'
);

//$msg = "please note this..";

$fields = array
(
	'registration_ids' 	=> $registrationId,
	'data'			=> $msg
);
 
$headers = array
(
	'Authorization: key=' . API_ACCESS_KEY,
	'Content-Type: application/json',
        'delay_while_idle: true',
);
 
try{
    $ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );

echo $result;

}
catch(Exception $e){
    echo $e;
    echo "inside catch";
}

++++++++++ Thank you very much for your help and for spending your valuable time for me..!

1
What is printed out by echo $result? - Koh
@koh -Thanks. It's working without problems. echo $result {"multicast_id":5195787601557841624,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1426674959871687%6051335af9fd7ecd"}]} - user2881604
Interesting... Does the issue still occur? You can perform quick checks like here. Also, try it with other Android devices. It could be your device has an intermittent connection. - Koh

1 Answers

0
votes

replace all com.example.gcm in manifest.xml to your package name.
or change package name to com.example.gcm