don't receive notifications on android 2.2 using GoogleCloudMessaging - android

I'm using the new GoogleCloudMessaging API (from Play Services library, because old Google cloud messaging for android was deprecated) in my project and I have some bugs. When I send messages from my server to all registered devices, my nexus 4 (android 4.4) receives the notification messages, but my Samsung Galaxy Ace doesn't receive them, That's strange, because there are no exceptions or crashes of my project.
Any ideas?
Thanks.
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="ru.test"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<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="android.permission.VIBRATE"/>
<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" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/MyTheme" >
<service android:name=".GcmIntentService" />
<receiver
android:name=".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.gcm" />
</intent-filter>
</receiver>
<activity
android:name="ru.test.MainActivity"
android:label="#string/app_name"
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
GcmBroadcastReceiver.java
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String regId = intent.getExtras().getString("registration_id");
if(regId != null && !regId.equals("")) {
/* Do what ever you want with the regId eg. send it to your server */
Log.d(MainActivity.tag, "onReceive " + regId);
}
// 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
public class GcmIntentService extends IntentService {
public static int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
static final String TAG = "myLogs";
String title = "";
String message = "";
String subtext = "";
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
title = extras.getString("title");
message = extras.getString("message");
subtext = extras.getString("subtext");
/*
* 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)) {
message = "Send error";
sendNotification(title, message, subtext);
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_DELETED.equals(messageType)) {
message = "Deleted messages on server";
sendNotification(title, message, subtext);
// If it's a regular GCM message, do some work.
} else if (GoogleCloudMessaging.
MESSAGE_TYPE_MESSAGE.equals(messageType)) {
// Post notification of received message.
sendNotification(title, message, subtext);
Log.d(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 title, String message, String subtext) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, SplashScreen.class), 0);
NotificationCompat.BigTextStyle bigxtstyle =
new NotificationCompat.BigTextStyle();
bigxtstyle.bigText(message);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_small)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_large))
.setTicker(message)
.setContentTitle(title)
.setDefaults(Notification.DEFAULT_ALL | Notification.FLAG_AUTO_CANCEL)
//.setContentInfo("Content info")
.setAutoCancel(true)
.setSubText(subtext)
.setWhen(System.currentTimeMillis())
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(++NOTIFICATION_ID, mBuilder.build());
}
}

Your main package name is ru.test, but in the GCM permissions you specified com.example.gcm as the package name. That's why it doesn't work in 2.x Android version (for some reason this mismatch doesn't affect 4.x versions).
The following changes will solve your problem:
<permission android:name="ru.test.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="ru.test.permission.C2D_MESSAGE" />
<receiver
android:name=".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="ru.test" />
</intent-filter>
</receiver>
I also suggest that you change your minSdkVersion from 7 to 8, since GCM is not supported in API level 7.

Your Google Play application is updated in Galaxy Ace? Probably this is the problem.
Another hypothesis would not be logged into any google account on the device. to receive notifications in versions prior to 4.0.4 is mandatory to be logged in at least one regard.

Related

Android notifications not showing up in app

I am writing an app that uses GCM Push Notifications, however when a notification appears, it opens the app but doesn't show the message. When I am in the app though, the messages show up normally. Please help.
This is my Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.amosang.pushtest" >
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- GCM Permissions - Start here -->
<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.example.amosang.pushtest.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.amosang.pushtest.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".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:exported="true"
android:name=".HomeActivity"
android:label="#string/title_activity_home" >
</activity>
<receiver
android:name=".GCMBroadcastReceiver"
android:exported="true"
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" />
<action android:name="com.example.amosang.pushtest" />
</intent-filter>
</receiver>
<service android:name=".GCMNotificationIntentService"
android:exported="false">
</service>
<activity
android:name=".NewRequest"
android:label="#string/title_activity_new_request" >
</activity>
</application>
Notification Code
public class GCMNotificationIntentService extends IntentService{
//set ID for the notification, so it can be updated
public static final int notifyID = 9001;
NotificationCompat.Builder builder;
public GCMNotificationIntentService() {
super("GcmIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
Log.d("GCMN","GCMNTEST");
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)) {
sendNotification("Message Received from Google GCM Server:\n\n"
+ extras.get(AppConstants.MSG_KEY));
}
}
GCMBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg){
Intent resultIntent = new Intent(this, HomeActivity.class);
Log.d("RECEIVEDPT2",msg);
resultIntent.putExtra("msg", msg);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this,0,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mNotifyBuilder;
NotificationManager mNotificationManager;
mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
mNotifyBuilder = new NotificationCompat.Builder(this).setContentTitle("Alert")
.setContentTitle("You've received a new message")
.setSmallIcon(R.drawable.ic_cast_dark);
//Set pending intent
mNotifyBuilder.setContentIntent(resultPendingIntent);
//Set vibration
int defaults = 0;
defaults = defaults | Notification.DEFAULT_LIGHTS;
defaults = defaults | Notification.DEFAULT_VIBRATE;
defaults = defaults | Notification.DEFAULT_SOUND;
mNotifyBuilder.setDefaults(defaults);
// Set the content for Notification
mNotifyBuilder.setContentText("You have new notifications");
// Set autocancel
mNotifyBuilder.setAutoCancel(true);
// Post a notification
mNotificationManager.notify(notifyID, mNotifyBuilder.build());
}
As requested in the comments, please include the code for HomeActivity which handles the notification so we can examine the code and suggest solutions. In the meantime, this is how I'd suggest you process the incoming GCM notification in your HomeActivity class (will update the answer once I see you code, if necessary). In my example, I have a helper method processIntent(Intent intent) which handles the Intent and its Extras. I call this method from both onCreate and onNewIntent methods.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.<layout-id>);
//here I call our processing method
processIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//call our processing method
processIntent(getIntent());
}
/**
* Helper method to process the incoming GCM Notification.
* #param intent
*/
private void processIntent(Intent intent){
if(intent == null) { return; }
Bundle extras = intent.getExtras();
try{
if(extras.containsKey("msg")){
//possibly a message
String message = extras.getString("msg");
Log.i(TAG, "Received Message "+message);
//do whatever with the message, like set as Text of TextView, etc
}
}
catch(Exception e){
Log.e(TAG, "Error Processing GCM Notification Intent", e);
}
}

GCM implement failed

I have big problem.
I create server api-key like at google documentation. Create IntentService and BroadcastReceiver. I put my RegistrationId on my server, but I don't receive push-message from google server.
This my code, can you tell me, what I do wrong?
IntentService:
public class GcmIntentService extends IntentService{
Context context;
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public static final String TAG = "GCM Demo";
public GcmIntentService() {
super(SENDER_ID);//"GcmIntentService");//
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
Bundle extras = intent.getExtras();
String msg = intent.getStringExtra("message");
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());
// 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(500);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work # " + SystemClock.elapsedRealtime());
// Post notification of received message.
//sendNotification("Received: " + extras.toString());
sendNotification(msg);
Log.i(TAG, "Received: " + extras.toString());
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent myintent = new Intent(this, ReceiveActivity.class);
myintent.putExtra("message", msg);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
//new Intent(this, BaseActivity.class), 0);
myintent, PendingIntent.FLAG_UPDATE_CURRENT);
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());
}
}
BroadCast:
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);
}
}
manifest:
package="*.*"
android:versionCode="329"
android:versionName="1.0.3"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<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="*.*.gcm.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="*.*.gcm.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<receiver
android:name="*.*.cgm.GcmBroadcastReceiverCompat"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="*.*.cgm" />
</intent-filter>
</receiver>
<activity android:name=".screens.StartingActivity" android:screenOrientation="portrait"
android:theme="#android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="*.*.cgm.GcmIntentService" />
...
Best Regards.
If your app's package is *.*, the permissions should be :
<permission android:name="*.*.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="*.*.permission.C2D_MESSAGE" />
(without gcm)
The category in the broadcast receiver should also be without gcm :
<category android:name="*.*" />
And if your intent service class is in ..gcm while your app's package is . the following code won't work, since it will look for the intent service in the main package :
ComponentName comp = new ComponentName(context.getPackageName(),
GcmIntentService.class.getName());
You should replace it with :
ComponentName comp = new ComponentName(GCMIntentService.class.getPackage().getName(),
GcmIntentService.class.getName());
Try using onMessage Overridden method, you may receive.
Try creating Browser key instead of Android Key in Google API console and use it.
Use com.google.android.gcm.GCMBroadcastReceiver instead of ..cgm.GcmBroadcastReceiverCompat
Thanks this may help you.

Can't receive messages using Google Cloud Messaging for Android (not the helper library)

Does anybody can help me with a working example for receiving messages from gcm using Google Cloud Messaging for Android. I have tried both ways (helper library and GoogleCloudMessaging class) and nothing seems to work. I'm using a PHP script that shows the following:
Multicast ID: 5.2108110103215E+18
Number of messages processed successfully: 1
Number of messages with processing errors: 0
Canonical IDs: 0
So apparently everithing is OK. I could register the device in both ways, using the helper library (gcm.jar) and using GoogleCloudMessaging class. The problem is that there is no way the message I send via PHP arrives, or at least I don't know how to handle it correctly. Here are the permissions and the receiver from my manifest:
<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<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="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<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.example.gcm" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
Finally here is the service class
public class GCMIntentService extends GCMBaseIntentService {
private static final String PROJECT_ID = "49XXXXXXXX6";
private static final String TAG = "GCM Intent Service";
public GCMIntentService()
{
super(PROJECT_ID);
Log.d(TAG, "GCMIntentService init");
}
#Override
protected void onError(Context ctx, String sError) {
Log.d(TAG, "Error: " + sError);
}
#Override
protected void onMessage(Context ctx, Intent intent) {
Log.d(TAG, "Message Received");
String message = intent.getStringExtra("message");
sendGCMIntent(ctx, message);
}
private void sendGCMIntent(Context ctx, String message) {
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("GCM_RECEIVED_ACTION");
broadcastIntent.putExtra("gcm", message);
ctx.sendBroadcast(broadcastIntent);
}
#Override
protected void onRegistered(Context ctx, String regId) {
Log.d(TAG, regId);
// Notify main UI to update registration status
Intent registrationIntent = new Intent();
registrationIntent.setAction("registered");
registrationIntent.putExtra("regId", regId);
sendBroadcast(registrationIntent);
}
#Override
protected void onUnregistered(Context ctx, String regId) {
//...
}
}
Here is the code when using the GoogleCloudMessaging class (I changed the manifest to use the custom receiver):
public class GCMBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "GCM Receiver";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
private Context ctx;
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Message received");
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
ctx = context;
String messageType = gcm.getMessageType(intent);
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + intent.getExtras().toString());
}
else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ intent.getExtras().toString());
}
else {
sendNotification("Received: " + intent.getExtras().toString());
}
setResultCode(Activity.RESULT_OK);
}
// Put the GCM message into a notification and post it.
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
new Intent(ctx, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
ctx).setSmallIcon(R.drawable.ic_launcher_temp)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
The thing is that everything seems to be ok, but the message never arrives. Any ideas??
Thanks in advance.
Add the following in your manifeast
<permission
android:name="PACKAGE_NAME.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="PACKAGE_NAME.permission.C2D_MESSAGE" />
<!-- App receives GCM messages. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
Your manifest is missing some permissions :
<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" />
EDIT :
In your manifest you are using com.google.android.gcm.GCMBroadcastReceiver. That's a class from the old helper library (gcm.jar) which starts an intent service. If you want to use the helper library you should define the intent service in your manifest.
If you don't want to use the helper library, you should change the package of GCMBroadcastReceiver in the manifest to be the package of the GCMBroadcastReceiver class that you included in your question. Otherwise, that class won't be used.
After correcting the issues above still no push messages. The problem was the 403 error. Looks like that service is not available in Cuba, so the solution is to use a tool like "your freedom" or "thor", etc.
Don't forget to change 'com.example.gcm' to your package name e.g. 'com.yourdomain.yourapp'
You are using GCMBaseIntentService which has been deprecated by Google. (But it should be still working.) I followed the latest tutorial http://developer.android.com/google/gcm/client.html and did receive messages. You can try it too.
Another possible reason is you may have received a message but it was not shown in a notification successfully. Add this line in the method: sendNotification(String msg)
Log.i(TAG, msg);

Android GCMIntentService onMessage context issue

I'm trying to implement GCM to my app in Android. The server and client side setup seems to be right, because the onMessage method is called when I "push" a string from the server side. I can read the extras from the intent, however, using a notification or a Toast message doesn't work. The phone doesn't show anything, even with the app running, so I guess something isn't right with the context object I use from the callback.
Here's the revelvant part of the manifest.xml, where PACKAGE is the base package.
<receiver
android:name="PACKAGE.gcm.GCMReceiver"
android:enabled="true"
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="PACKAGE" />
</intent-filter>
</receiver>
<service
android:name="PACKAGE.gcm.GCMIntentService"
android:enabled="true" />
</application>
<permission
android:name="PACKAGE.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="PACKAGE.C2D_MESSAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 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" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
</manifest>
Now the onMessage Method:
#Override
protected void onMessage(Context context, Intent intent)
{
if (DEBUG)
{
System.out.println("[GCMIntentService] Message Received! " + intent.getStringExtra("message"));
}
Toast.makeText(context, intent.getStringExtra("message"), Toast.LENGTH_SHORT).show();
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
// int icon = R.drawable.notification_icon;
CharSequence tickerText = intent.getStringExtra("message");
long when = System.currentTimeMillis();
Notification notification = new Notification(0, tickerText, when);
CharSequence contentTitle = "Some Notification";
CharSequence contentText = tickerText + " some more text";
notification.setLatestEventInfo(context, contentTitle, contentText, null);
final int HELLO_ID = 1;
mNotificationManager.notify(HELLO_ID, notification);
}
The Toast and the Notification aren't working. I call the service and registration routines in the onCreate of the first Activity, wich is used as Splash and closed after a few seconds. Might that have something to do with it?
This isn't a Context issue.
GCM reciever runs in an intent service which in its self runs on a separate thread.
To show a toast just call from inside a UIThread. Which you can do like so:
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable(){
Toast.makeText(context, intent.getStringExtra("message"), Toast.LENGTH_SHORT).show();
});
This will now post on your UI thread and you will then see the toast!
(You will need to make your local variable's final for them to be executed by the anonymous class)
Cheers!

Launch another activity from my notification receiver

Okay, so, I'll preface this by stating I'm using Titanium, so that'll, I assume, put a bad taste in your mouth. So, I'm sorry for my lack on knowledge on the Android side of things.
So, I've got a thing set up to receive GCM notifications. I can send them correctly to my app, and the code runs and tries to launch my app when it's clicked. However, it's just giving me this in the logcat:
I/ActivityManager( 307): START {act=com.geneca.journaling.mobile.GenecaJournalingActivity cat=[android.intent.category.LAUNCHER] flg=0x34000000 bnds=[0,102][720,230] u=0} from pid -1
W/InputMethodManagerService( 307): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy#427a60a8 attribute=null
I got the C2DM receiving stuff from a third party, and I've tried to modify it to do what I need, but I'm clearly doing something not quite right.
Here's the onMessage:
#Override
protected void onMessage(Context context, Intent intent) {
Log.d(LCAT, "Message received");
HashMap data = new HashMap();
for (String key : intent.getExtras().keySet()) {
Log.d(LCAT, "Message key: " + key + " value: "
+ intent.getExtras().getString(key));
String eventKey = key.startsWith("data.") ? key.substring(5) : key;
data.put(eventKey, intent.getExtras().getString(key));
}
if (C2dmModule.getInstance() == null) {
int icon = 0x7f020000; // get this from R.java
CharSequence tickerText = "Geneca Journaling";
long when = System.currentTimeMillis();
Bundle extras = intent.getExtras();
CharSequence contentTitle = "Rate your journal";
CharSequence contentText = "Notification Content";
String title = extras.getString("title");
String message = extras.getString("message");
if(title != null) {
contentTitle = title;
}
if (message != null) {
contentText = message;
}
//Intent notificationIntent = new Intent(this, C2DMReceiver.class);
Intent launcherintent = new Intent("com.geneca.journaling.mobile.GenecaJournalingActivity");
launcherintent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent. FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
launcherintent
.setComponent(ComponentName
.unflattenFromString("com.geneca.journaling.mobile.GenecaJournalingActivity"));
launcherintent.addCategory("android.intent.category.LAUNCHER");
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
launcherintent, 0);
// the next two lines initialize the Notification, using the
// configurations above
Notification notification = new Notification(icon, tickerText, when);
notification.defaults = Notification.DEFAULT_ALL;
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
mNotificationManager.notify(1, notification);
} else
C2dmModule.getInstance().sendMessage(data);
}
Here's my manifest stuff (I think)
<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>
<activity android:name=".GenecaJournalingActivity"/>
<permission
android:name="com.geneca.journaling.mobile.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="com.geneca.journaling.mobile.permission.C2D_MESSAGE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application>
<service android:name="com.findlaw.c2dm.C2DMReceiver"/>
<receiver
android:name="com.google.android.c2dm.C2DMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.geneca.journaling.mobile"/>
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.geneca.journaling.mobile"/>
</intent-filter>
</receiver>
</application>
</manifest>
</android>
There's also another manifest section in a different place, because of how Titanium handles things:
<android:manifest>
<permission android:name="com.geneca.journaling.mobile.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.geneca.journaling.mobile.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive message -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Send the registration id to the server -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- App must have this permission to use the library -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<activity android:name="com.geneca.journaling.mobile.GenecaJournalingActivity"/>
<application>
<!-- In order to use the c2dm library, an
application must declare a class with the name C2DMReceiver, in its
own package, extending com.google.android.c2dm.C2DMBaseReceiver
It must also include this section in the manifest, replacing
"com.google.android.apps.chrometophone" with its package name.
-->
<service android:name="com.findlaw.c2dm.C2DMReceiver" />
<!-- Only google service can send data messages for the app. If permission is not set -
any other app can generate it -->
<receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<!-- Start receiver on boot -->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.HOME"/>
</intent-filter>
<!-- Receive the actual message -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.geneca.journaling.mobile" />
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.geneca.journaling.mobile" />
</intent-filter>
</receiver>
</application>
</android:manifest>
If the app is already open, it runs some Titanium code, which I think I'll be able to figure out, but if the app is not open, it hits stuff in the onMessage which I can't quite figure out.
Any help would be appreciated. Thanks.
This line:
Intent launcherintent = new Intent("com.geneca.journaling.mobile.GenecaJournalingActivity");
Creates a new Intent with the action com.geneca.journaling.mobile.GenecaJournalingActivity.
Is this what you wanted?
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("com.package.address","com.package.address.MainActivity"));
startActivity(intent);
or
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.package.address");
startActivity(LaunchIntent);

Categories

Resources