Android GCMIntentService onMessage issue - android

I am new to Android. I am trying to send message (GCM) from my server (Java) to android phone. On debugging the server code, I found that the messages are successfully sent to android phones. But I was not able to receive any messages in phone. I tried to have a break-point in onMessage(), but there was no use.
Once after the every message from server, my phone is only getting an alert box something like: "PROJECT is not responding. Would you like to close it?" It has 2 buttons in the alert box: wait and OK.
Can anyone please help me on this. Even though, my server sent messages successfully, Why I was not receiving any messages in phone. My client and server code are as follows:
Server:
public void sendPushNotification(String theRegistrationId, String thePushMsg)
{
//Used to transmit messages to the Google Cloud Messaging service.
Sender aGcmSender = new Sender(API_KEY);
//Constructing message which need to be transmitted to android device.
Message aMessage = new Message.Builder().addData("message", thePushMsg).build();
try
{
Result result = aGcmSender.send(aMessage, theRegistrationId, 1);
}
catch (Exception theException)
{
}
}
Client:
AndroidManifest.xml:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<permission android:name="com.test.app.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.test.app.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.SET_DEBUG_APP"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
android:theme="#style/AppTheme"
android:name="MyApplication">
<uses-library android:name="com.google.android.maps" />
<activity
android:name=".view.welcome.WelcomeView"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.test.app" />
</intent-filter>
</receiver>
<service android:name="com.test.app.GCMIntentService" />
</application>
GCMIntentService:
package com.test.app;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.google.android.gcm.GCMBaseIntentService;
public class GCMIntentService extends GCMBaseIntentService
{
private static final String TAG = "===GCMIntentService===";
private static String GCM_SENDER_ID = "697532398835"; //Project id in Google API Console
public GCMIntentService()
{
super(GCM_SENDER_ID);
Log.d(TAG, "GCMIntentService init");
}
#Override
protected void onRegistered(Context theContext, String theRegistrationId)
{
Log.i(TAG, "Device registered: regId = " + theRegistrationId);
}
#Override
protected void onUnregistered(Context theContext, String theArg)
{
Log.i(TAG, "unregistered = "+theArg);
}
#Override
protected void onMessage(Context theContext, Intent theIntent)
{
Log.i(TAG, "new message= ");
String aMessage = theIntent.getStringExtra("message");
sendGCMIntent(theContext, aMessage);
}
private void sendGCMIntent(Context theContext, String theMessage)
{
Intent aBroadcastIntent = new Intent();
aBroadcastIntent.setAction("GCM_RECEIVED_ACTION");
aBroadcastIntent.putExtra("gcm", theMessage);
theContext.sendBroadcast(aBroadcastIntent);
}
#Override
protected void onError(Context theContext, String theErrorId)
{
Log.i(TAG, "Received error: " + theErrorId);
}
#Override
protected boolean onRecoverableError(Context theContext, String theErrorId)
{
return super.onRecoverableError(theContext, theErrorId);
}
}
My activity:
package com.test.app.view.welcome;
import java.net.MalformedURLException;
import java.net.URL;
import com.google.android.gcm.GCMRegistrar;
public class LoginView extends Activity implements Runnable {
Typeface itsTypeFace;
IntentFilter gcmFilter;
String broadcastMessage = "No broadcast message";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.login);
gcmFilter = new IntentFilter();
gcmFilter.addAction("GCM_RECEIVED_ACTION");
}
private BroadcastReceiver gcmReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
broadcastMessage = intent.getExtras().getString("gcm");
if (broadcastMessage != null)
{
System.out.println(broadcastMessage);
}
}
};
/**
* Method to avoid back key press for a higher api level 2.0 and above
*/
#Override
public void onBackPressed() {}
/** If the user changes the orientation of his phone, the current activity
is destroyed, and then re-created. This means that our broadcast message
will get wiped out during re-orientation.
So, we save the broad cast message during an onSaveInstanceState()
event, which is called prior to the destruction of the activity.
*/
#Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putString("BroadcastMessage", broadcastMessage);
}
/** When an activity is re-created, the os generates an onRestoreInstanceState()
event, passing it a bundle that contains any values that you may have put
in during onSaveInstanceState()
We can use this mechanism to re-display our last broadcast message.
*/
#Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
broadcastMessage = savedInstanceState.getString("BroadcastMessage");
}
/** If our activity is paused, it is important to UN-register any
broadcast receivers.
*/
#Override
protected void onPause()
{
unregisterReceiver(gcmReceiver);
super.onPause();
}
/** When an activity is resumed, be sure to register any
broadcast receivers with the appropriate intent
*/
#Override
protected void onResume()
{
super.onResume();
registerReceiver(gcmReceiver, gcmFilter);
}
/**
* The call to GCMRegistrar.onDestroy()
*/
#Override
public void onDestroy()
{
GCMRegistrar.onDestroy(this);
super.onDestroy();
}
}
Can anyone please help me on this issue. Even though, my server sent messages successfully, Why I was not receiving any messages in phone.

I found a solution for this problem. On deploying my application (server side), I found there was some problem with json-simple.jar.
I have upgraded the jar to json-simple-1.1.1.jar and it worked!
And also as NickT suggested, I have updated my canonicalid as follows:
Sender aGcmSender = new Sender(API_KEY);
//Constructing message which need to be transmitted to android device.
Message aMessage = new Message.Builder().addData("message", thePushMsg).build();
Result result = aGcmSender.send(aMessage, REG_ID, 1); //Transmitting message to android device
if(result != null)
{
if(result.getMessageId() != null)
{
String aCanonicalRegistrationId = result.getCanonicalRegistrationId();
if(aCanonicalRegistrationId != null)
{
//Updated my database with aCanonicalRegistrationId (replaced REG_ID)
}
}
else
{
String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
// application has been removed from device - unregister database
}
}
}
}
Thank You.

Related

How to receive the driving start and stop activity with Android in an energy efficient manner which works even offline?

I would like to receive the Android location call backs for Driving Start and Stop. I have tried the Activity Detection API by Google but it doesn't seem to be reliable enough. As well as, I have looked into using Neura's API to detect the location events but it only works when the device is online which is not sufficient in my case.
You could use google's FenceApi in order to declare a driving fence.
Though this approach seems good, i've faced with the fact that this api didn't tell me sometimes when user starts/finishes driving, and sometimes it took a long time after i started driving that the api told me of that event.
a. include dependency to your app's build.gradle file :
compile 'com.google.android.gms:play-services-location:+'
compile 'com.google.android.gms:play-services-contextmanager:+'
b. Manifest definitions :
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme" >
<meta-data
android:name="com.google.android.awareness.API_KEY"
android:value="PUT_YOUR_AWARENESS_KEY_HERE" />
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
PUT_YOUR_AWARENESS_KEY_HERE : You need to generate a key here.
c. Your MainActivity class - explanations attached to the code :
public class MainActivity extends Activity {
private GoogleApiClient mGoogleApiClient;
private PendingIntent mPendingIntent;
private FenceReceiver mFenceReceiver;
// The intent action which will be fired when your fence is triggered.
private final String FENCE_RECEIVER_ACTION = BuildConfig.APPLICATION_ID + "FENCE_RECEIVER_ACTION";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(Awareness.API).build();
mGoogleApiClient.connect();
// Set up the PendingIntent that will be fired when the fence is triggered.
mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(FENCE_RECEIVER_ACTION), 0);
// The broadcast receiver that will receive intents when a fence is triggered.
mFenceReceiver = new FenceReceiver();
registerReceiver(mFenceReceiver, new IntentFilter(FENCE_RECEIVER_ACTION));
createFence(DetectedActivityFence.IN_VEHICLE, "InVehicleFence");
}
#Override
public void onDestroy() {
try {
unregisterReceiver(mFenceReceiver); //Don't forget to unregister the receiver
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy();
}
private void createFence(int detectedActivityFence, final String fenceKey) {
AwarenessFence fence = DetectedActivityFence.during(detectedActivityFence);
// Register the fence to receive callbacks.
Awareness.FenceApi.updateFences(
mGoogleApiClient, new FenceUpdateRequest.Builder().addFence(fenceKey, fence, mPendingIntent)
.build()).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
Log.i(getClass().getSimpleName(), "Successfully registered.");
} else {
Log.e(getClass().getSimpleName(), "Could not be registered: " + status);
}
}
});
}
// Handle the callback on the Intent.
public class FenceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
FenceState fenceState = FenceState.extract(intent);
switch (fenceState.getCurrentState()) {
case FenceState.TRUE:
Log.i(fenceState.getFenceKey(), "Driving");
break;
case FenceState.FALSE:
Log.i(fenceState.getFenceKey(), "Not driving");
break;
}
}
}
}

Not receiving push notification from local server

I really need a help figure it out what really is wrong with my code. I am a newbie in android.
really no message from gcm to my android device. I cannot really receive any push notification. No activity in my logcat when i try to send a message from my local server as stated from androidhive tutorial. Please help.
Here some of the code:
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidhive.pushnotifications"
android:versionCode="1"
android:versionName="1.0" >
<!-- GCM requires Android SDK version 2.2 (API level 8) or above. -->
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<!-- GCM connects to Internet Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Main activity. -->
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<!-- Register Activity -->
<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>
<!-- Main Activity -->
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name" >
</activity>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.androidhive.pushnotifications" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService"/>
</application>
</manifest>
Main Activity:
package com.androidhive.pushnotifications;
import static com.androidhive.pushnotifications.CommonUtilities.DISPLAY_MESSAGE_ACTION;
import static com.androidhive.pushnotifications.CommonUtilities.EXTRA_MESSAGE;
import static com.androidhive.pushnotifications.CommonUtilities.SENDER_ID;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gcm.GCMRegistrar;
public class MainActivity extends Activity {
// label to display gcm messages
TextView lblMessage;
// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;
// Alert dialog manager
AlertDialogManager alert = new AlertDialogManager();
// Connection detector
ConnectionDetector cd;
public static String name;
public static String email;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(MainActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Getting name, email from intent
Intent i = getIntent();
name = i.getStringExtra("name");
email = i.getStringExtra("email");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
GCMRegistrar.checkManifest(this);
lblMessage = (TextView) findViewById(R.id.lblMessage);
registerReceiver(mHandleMessageReceiver, new IntentFilter(
DISPLAY_MESSAGE_ACTION));
// Get GCM registration id
final String regId = GCMRegistrar.getRegistrationId(this);
// Check if regid already presents
if (regId.equals("")) {
// Registration is not present, register now with GCM
GCMRegistrar.register(this, SENDER_ID);
} else {
// Device is already registered on GCM
if (GCMRegistrar.isRegisteredOnServer(this)) {
// Skips registration.
Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
} else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Register on our server
// On server creates a new user
ServerUtilities.register(context, name, email, regId);
return null;
}
#Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
}
/**
* Receiving push messages
* */
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
/**
* Take appropriate action on this message
* depending upon your app requirement
* For now i am just displaying it on the screen
* */
// Showing received message
lblMessage.append(newMessage + "\n");
Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show();
// Releasing wake lock
WakeLocker.release();
}
};
#Override
protected void onDestroy() {
if (mRegisterTask != null) {
mRegisterTask.cancel(true);
}
try {
unregisterReceiver(mHandleMessageReceiver);
GCMRegistrar.onDestroy(this);
} catch (Exception e) {
Log.e("UnRegister Receiver Error", "> " + e.getMessage());
}
super.onDestroy();
}
}

Push Notification not Received in android

I am new to push notifications and I'm trying to send a push notification to a particular device which has already been registered to GCM service. I implemented my app according to this example
and modified accordingly in my program. However, I am not able to receive push notifications on the device.
Here is my code:
package com.markattendence.activites;
import static com.markattendence.activites.CommonUtilities.DISPLAY_MESSAGE_ACTION;
import static com.markattendence.activites.CommonUtilities.EXTRA_MESSAGE;
import static com.markattendence.activites.CommonUtilities.SENDER_ID;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gcm.GCMRegistrar;
import com.markattendence.activites.MainActivity.YourAsyncTaskLogin;
import com.markattendence.markattendence.R;
public class NotificationActivity extends Activity {
// label to display gcm messages
TextView lblMessage;
// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;
// Alert dialog manager
AlertDialogManager alert = new AlertDialogManager();
// Connection detector
ConnectionDetector cd;
private String userFName;
private String latitude;
private String longitude;
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_FNAME = "fname";
private static String KEY_EMAIL = "email";
private static String KEY_LNAME = "lname";
UserFunctions userFunction;
private JSONObject json;
public static String name;
public static String email;
SharedPreferences prefs;
public static final String MyPREFERENCES = "MyPrefs";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
cd = new ConnectionDetector(getApplicationContext());
prefs = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
if (prefs.contains("message")) {
lblMessage.setText(prefs.getString("message", ""));
}
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(NotificationActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
// Getting name, email from intent
Intent i = getIntent();
name = i.getStringExtra("uFName");
userFName = i.getStringExtra("uFName");
email = i.getStringExtra("email");
latitude = i.getStringExtra("latitude");
longitude = i.getStringExtra("longitude");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
GCMRegistrar.checkManifest(this);
lblMessage = (TextView) findViewById(R.id.lblMessage);
registerReceiver(mHandleMessageReceiver, new IntentFilter(
DISPLAY_MESSAGE_ACTION));
// Get GCM registration id
final String regId = GCMRegistrar.getRegistrationId(this);
// Check if regid already presents
if (regId.equals("")) {
// Registration is not present, register now with GCM
GCMRegistrar.register(this, SENDER_ID);
} else {
// Device is already registered on GCM
if (GCMRegistrar.isRegisteredOnServer(this)) {
// Skips registration.
Toast.makeText(getApplicationContext(),
"Already registered with GCM", Toast.LENGTH_LONG)
.show();
} else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
// Register on our server
// On server creates a new user
ServerUtilities.register(context, name, email, regId);
return null;
}
#Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
if(name != null){
userFunction = new UserFunctions();
new YourAsyncTaskLogin().execute();
}
}
/**
* Receiving push messages
* */
private final WakefulBroadcastReceiver mHandleMessageReceiver = new WakefulBroadcastReceiver() {
#Override
public void onReceive(Context context, Intent 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);
String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
// Waking up mobile if it is sleeping
WakeLocker.acquire(getApplicationContext());
/**
* Take appropriate action on this message depending upon your app
* requirement For now i am just displaying it on the screen
* */
// Showing received message
lblMessage.append(newMessage + "\n");
Toast.makeText(getApplicationContext(),
"New Message: asd" + newMessage, Toast.LENGTH_LONG).show();
prefs = context.getSharedPreferences(MyPREFERENCES,
Context.MODE_PRIVATE);
Editor editor = prefs.edit();
editor.putString("message", lblMessage.getText().toString());
editor.commit();
// Releasing wake lock
WakeLocker.release();
}
};
#Override
protected void onDestroy() {
if (mRegisterTask != null) {
mRegisterTask.cancel(true);
}
try {
unregisterReceiver(mHandleMessageReceiver);
GCMRegistrar.onDestroy(this);
} catch (Exception e) {
Log.e("UnRegister Receiver Error", "> " + e.getMessage());
}
super.onDestroy();
}
class YourAsyncTaskLogin extends AsyncTask<Void, Void, Void> {
private ProgressDialog _ProgressDialog;
private String userId;
#Override
protected void onPreExecute() {
// show your dialog here
_ProgressDialog = ProgressDialog.show(NotificationActivity.this,
"", "Loading", true);
}
#Override
protected Void doInBackground(Void... params) {
try {
json = userFunction.sendMessage(userFName,
" has marked attendence of ", "CheckIN", latitude,
longitude);
/*
* HttpClient Client = new DefaultHttpClient(); String
* SetServerString = "";
*
* // Create Request to server and get response
*
* HttpGet httpget = new HttpGet(
* "http://wibman.com/pnt/send_message.php?message=" + name +
* "checked in&Latitude=" + latitude + "&Longitude=" +
* longitude); ResponseHandler<String> responseHandler = new
* BasicResponseHandler(); SetServerString =
* Client.execute(httpget, responseHandler);
*/
// Show response on activity
// content.setText(SetServerString);
} catch (Exception ex) {
ex.printStackTrace();
// content.setText("Fail!");
}
return null;
}
protected void onPostExecute(Void result) {
try {
Log.e("aaaaaaaaaaaaaaaaaaaaaaaaaaa",
json.getString(KEY_SUCCESS));
if (json.getString(KEY_SUCCESS) != null) {
// loginErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if (Integer.parseInt(res) == 1) {
/*userId = json.getString(KEY_UID);
userFName = json.getString(KEY_FNAME);
userFName.replace("\"", "");
userId.replace("\"", "");
Log.e("uid=aaa", userId);
Log.e("nameuser", userFName);*/
Intent dashboard = new Intent(getApplicationContext(),
MainActivity.class);
// Close all views before launching
// Dashboard
startActivity(dashboard);
// Close Login Screen
finish();
} else {
// Error in login
// loginErrorMsg.setText("Incorrect username/password");
_ProgressDialog.cancel();
alert.showAlertDialog(NotificationActivity.this,
"Attendence Failed..",
"Mark Attendence Failed.", false);
// loginStatusTxtView.setText("Incorrect username/password");
}
} else {
// Error in login
// loginErrorMsg.setText("Incorrect username/password");
_ProgressDialog.cancel();
alert.showAlertDialog(NotificationActivity.this,
"Attendence Failed..", "Mark Attendence Failed.",
false);
// loginStatusTxtView.setText("Incorrect username/password");
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("error", e.getMessage());
}
_ProgressDialog.dismiss();
}
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.markattendence.markattendence"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.markattendence.markattendence.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.markattendence.markattendence.permission.C2D_MESSAGE" />
<uses-permission android:name="com.markattendence.activites.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/mmes_logo"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.markattendence.markattendence.MainActivity"
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="com.markattendence.markattendence.MarkAttendenceActivity" >
</activity>
<activity android:name="com.markattendence.markattendence.NotificationActivity" >
</activity>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.markattendence.markattendence" />
</intent-filter>
</receiver>
<service android:name="com.markattendence.markattendence.GCMIntentService" />
</application>
I am having a problem in receiving the notification. Server side code is working correctly.
My log cat says:
{"multicast_id":5884981605957538237,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1393495991926450%978fee92f9fd7ecd"}]}
The major problem is that, if device has the example app it get notification in that application rather than my customized application. And if I remove that application i don't get any notification. So i am confused that notification has to be received in my app rather than that of androidhive application but push notification is displayed in androidhive application. Please help me to solve this issue. Thanks in advance.
For sending the push to a specific device. First of all you need to pick the token from the FCM :
String token = FirebaseInstanceId.getInstance().getToken();
Then this unique token is used to send the push request from server post request. Please find the headers of the post request along with required structure of the body.
Headers
Content-Type 'application/json'
Authorization 'key=(server-key)'
Note: Not other than these values are allowed in headers. And here the 'server-key' is your browser key provide from FCM console.
Body For Push Request
{
"data": {
"NotificationDetailsID": 1131,
"MessageGroup": "HR",
"Message": "this is notification"
},
"to": "firebase-token-of-androidDevice"
}
This is the server side implementation and this will definitely work. As we have tested at our end. You will receive the push while the app is even closed.
You have some errors in your manifest that only cause problems on old Android versions :
Your packagge name is com.markattendence.markattendence.
Therefore you should change this :
<permission android:name="com.markattendence.markattendence.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
To this:
<permission android:name="com.markattendence.markattendence.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.markattendence.markattendence.permission.C2D_MESSAGE" />
And this:
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.markattendence.activites" />
</intent-filter>
</receiver>
To this:
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.markattendence.markattendence" />
</intent-filter>
</receiver>
IF you could send a notification and configure a GCM so the problem should be with network. Try to look if your ports are not blocked for notification (I had similar problem - I could send but not receive notification after unlocking ports I received notifications).

GCM: onMessage() from GCMIntentService is called very few times

I am implementing GCM in my application. I have followed all the steps given in GCM tutorial from developer.android.com
My application's build target is pointing to Goolge API 8 (Android 2.2 version).
I am able to get the register ID from GCM successfully, and I am passing this ID to my application server. So the registration step is performed successfully.
Now when my application server sends a PUSH message to my device, the server gets the message as SUCCESS=1 FAILURE=0, etc., i.e. Server is sending message successfully, but my device never receives the message.
After searching alot about this, I came to know that GCM pushes messages on port number 5228, 5229 or 5230.
Initially, my device and laptop was restricted for some websites, but then I was granted all the permissions to access all websites, so I guess these port numbers are open for my device.
So my question is: Very few times, I am receiving PUSH message from GCM. Why Google is so uncertain in delivering messages?
What could be the reason?
Please see my following code and guide me accordingly:
I have declared following in my manifest:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<permission
android:name="package.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="package.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="packageName" />
</intent-filter>
</receiver>
<receiver
android:name=".ReceiveBroadcast"
android:exported="false" >
<intent-filter>
<action android:name="GCM_RECEIVED_ACTION" />
</intent-filter>
</receiver>
<service
android:name=".GCMIntentService"
/>
/**
* #author Shrikant.
*
*/
public class GCMIntentService extends GCMBaseIntentService {
/**
* The Sender ID used for GCM.
*/
public static final String SENDER_ID = "myProjectID";
/**
* This field is used to call Web-Service for GCM.
*/
SendUserCredentialsGCM sendUserCredentialsGCM = null;
public GCMIntentService() {
super(SENDER_ID);
sendUserCredentialsGCM = new SendUserCredentialsGCM();
}
#Override
protected void onRegistered(Context arg0, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
sendUserCredentialsGCM.sendRegistrationID(registrationId);
}
#Override
protected void onUnregistered(Context context, String arg1) {
Log.i(TAG, "unregistered = " + arg1);
sendUserCredentialsGCM
.unregisterFromGCM(LoginActivity.API_OR_BROWSER_KEY);
}
#Override
protected void onMessage(Context context, Intent intent) {
Log.e("GCM MESSAGE", "Message Recieved!!!");
String message = intent.getStringExtra("message");
if (message == null) {
Log.e("NULL MESSAGE", "Message Not Recieved!!!");
} else {
Log.i(TAG, "new message= " + message);
sendGCMIntent(context, message);
}
}
private void sendGCMIntent(Context context, String message) {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("GCM_RECEIVED_ACTION");
broadcastIntent.putExtra("gcm", message);
context.sendBroadcast(broadcastIntent);
}
#Override
protected void onError(Context context, String errorId) {
Log.e(TAG, "Received error: " + errorId);
Toast.makeText(context, "PUSH Notification failed.", Toast.LENGTH_LONG)
.show();
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
return super.onRecoverableError(context, errorId);
}
}
Thanks.
Check whether the debug certificate is expired or not, If it is then create new certificate and generate new key.
Try to change your class names as full names with package names. Like:
<service android:name="com.xx.xx.xx" />
And dont forget to put your package name here:
<category android:name="packageName" />
Make sure your app name and the name you registered on the google console for getting api key are same name.Same name in the sense that exactly the same

GCM register didnot work on my emulator

I had use GCM service on my app , I did my code after more resarches also from stack overflow members , and when I try to test the code on my emulator I didn't find any regiser info that tell me that my emulator is registered .Also I created my account on Google API to recienve any reports but I didn't find any thing. So I need your help on:
1- please check my code and till my when the error I will feedback you with complete example :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.elarabygroup"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<permission
android:name="com.example.elarabygroup.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.elarabygroup.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<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" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".ElarabyGroup"
android:label="#string/title_activity_elaraby_group" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.elarabygroup" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
<!--
android:name=".GCMIntentService"
android:enabled="true" />
-->
</application>
</manifest>
package com.example.elarabygroup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebView;
import com.google.android.gcm.GCMRegistrar;
public class ElarabyGroup extends Activity {
private String TAG;
private String SENDER_ID = "222874571774";
private WebView webView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_elaraby_group);
try {
Intent registrationIntent = new Intent(
"com.google.android.c2dm.intent.REGISTER");
/* Registering for GCM /An Android application needs to register with GCM servers before it can receive messages*/
registrationIntent.putExtra("app",
PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", SENDER_ID);
startService(registrationIntent);
Log.i(TAG, "[checkNotifRegistration] checkDevice");
GCMRegistrar.checkDevice(this);
Log.i(TAG, "[checkNotifRegistration] checkManifest");
GCMRegistrar.checkManifest(this);
if (GCMRegistrar.isRegistered(this)) {
Log.i(TAG,
"[checkNotifRegistration] reg id : "
+ GCMRegistrar.getRegistrationId(this));
}
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
// SENDER_ID is my project id into google account url
GCMRegistrar.register(this, SENDER_ID);
Log.i(TAG,
"[checkNotifRegistration] reg id : "
+ GCMRegistrar.getRegistrationId(this));
} else {
Log.i(TAG, "[checkNotifRegistration] already registered as : "
+ regId);
}
} catch (Exception e) {
Log.e(TAG, "[checkNotifRegistration] Exception : " + e.getMessage());
e.printStackTrace();
}
/*
* GCMRegistrar.checkDevice(this); GCMRegistrar.checkManifest(this);
*
*
* final String regId = GCMRegistrar.getRegistrationId(this); if
* (regId.equals("")) { GCMRegistrar.register(this, "1111111111"); }
* else { Log.v(TAG, "Already registered"); }
*/
try {
ConnectivityManager con = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (con.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED
&& con.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("No Internet connection");
AlertDialog alert = builder.create();
alert.show();
} else
{
webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://m.elarabygroup.com");
}
} catch (Exception e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(e.getMessage().toString());
AlertDialog alert = builder.create();
String url = "http://m.elarabygroup.com/";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
}
/*
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public final void onReceive(Context context, Intent intent) {
GCMIntenetService.runIntentInService(context, intent);
setResult(Activity.RESULT_OK, null, null);
}
}
*/
}
/*
* #Override public boolean onCreateOptionsMenu(Menu menu) {
* getMenuInflater().inflate(R.menu.activity_elaraby_group, menu); return true;
* } }
*/
package com.example.elarabygroup;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.provider.Settings.Secure;
import android.util.Log;
public class GCMIntenetService extends GCMBaseIntentService {
private static String GCM_SENDER_ID = "1111111111111";
public GCMIntenetService() {
super();
}
#Override
protected void onRegistered(Context context, String registrationId) {
Log.i(TAG, "Device registered: regId = " + registrationId);
GCMRegistrar.setRegisteredOnServer(context, true);
}
#Override
protected void onUnregistered(Context context, String registrationId) {
Log.i(TAG, "Device unregistered");
if (GCMRegistrar.isRegisteredOnServer(context)) {
String regId = "";
Log.i(TAG, "unregistering device (regId = " + regId + ")");
GCMRegistrar.setRegisteredOnServer(context, false);
} else {
// This callback results from the call to unregister made on
// ServerUtilities when the registration to the server failed.
Log.i(TAG, "Ignoring unregister callback");
}
}
#Override
protected void onError(Context context, String errorId) {
// push error processing
}
#Override
protected void onMessage(Context arg0, Intent arg1) {
Log.i(TAG, "Received message");
Log.i(TAG, "EXTRAS" + arg1.getExtras());
// String message = getString(R.string.gcm_message);
generateNotification(arg0,
arg1.getStringExtra("Please download our new updates"));
// notifies user about message
}
private void generateNotification(Context arg0, String stringExtra) {
// TODO Auto-generated method stub
}
public static void registerInGCMService(Context context) {
GCM_SENDER_ID = Secure.getString(context.getContentResolver(),
Secure.ANDROID_ID);
if (!checkIsGCMServiceAvailable(context)) {
return;
}
final String regId = GCMRegistrar.getRegistrationId(context);
if (regId.equals("")) {
try {
GCMRegistrar.register(context, GCM_SENDER_ID);
} catch (Exception ex) {
}
} else {
// Already registered
}
}
public static boolean checkIsGCMServiceAvailable(Context context) {
try {
GCMRegistrar.checkDevice(context);
GCMRegistrar.checkManifest(context);
return true;
} catch (Throwable th) {
return false;
}
}
}
I had attached my log cat message
2- what about status in my Google API account
Service Status
Google Cloud Messaging for Android No known issues
first set your emulator target to Google API and add an google account to your emulator.
add google account to your emulator:
setting->account&sync-> Add account (from #curious_mind comment)
If the emulator is running Android 4.0.4 or later, this step is optional as GCM does not require an account from this version on.
for me it fixed the problem.
just you can use this emulator and test your application in this emulator i think it will work fine.
You can use an emulator for GCM functionality but you need to track some points as your emulator version should be 2.2 or above and contains Google API(must). Once you created this emulator AVD then follow the followig steps in emulator:
1.) goto Settings --> Accounts & Sync,
2.) then add a Google account and sync is on.
3.) Define internet permission in manifest file
<manifest xlmns:android...>
...
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
4.) Define GCM related permissions in manifest
Once this is done, you should be ready to register for GCM and receive messages from it.
Go to your android SDK folder and open SDK Manager and install Google Cloud Messaging for Android Library under Extras section. (If you don’t see Google Cloud Messaging for Android Library update your SDK manager to latest version)
After installing the library it will create gcm.jar file in your Andoird_SDK_Folder\extras\google\gcm\gcm-client\dist. Later you need to add this .jar file to your android project.
First set your emulator target to Google API.
After launching emulator press Menu button goto Settings. Select Accounts & Sync. And then press Add Account button and add a Google account
Finally Test your Application on Simulator.

Categories

Resources