I am learning GCM(Google cloud Messaging)
I Completed Following steps
1 - Activated and Obtained a Key for browser apps
2 - added following in manifest
Uses permission : com.google.android.c2dm.permission.RECEIVE
Created permission to prevent other Android applications from registering and receiving the Android application's messages
Created a receiver for com.google.android.c2dm.intent.RECEIVE, with the category set as applicationPackage. The receiver should require the com.google.android.c2dm.SEND permission
3 – in receiver
#Override
public void onReceive(Context context, Intent intent) {
ComponentName comp = new ComponentName(context.getPackageName(),
GcmMessageHandler.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
GcmMessageHandler it’s a Intend Service to show a notification on receive gcm message.following is onHandleIntent Method in GcmMessageHandler.
#Override
protected void onHandleIntent(Intent intent) {
handler.post(new Runnable() {
#Override
public void run() {
NotificationManager manager = (NotificationManager) getApplicationContext()
.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
getApplicationContext());
mBuilder.setSmallIcon(R.drawable.ic_launcher);
mBuilder.setContentTitle("GCM Received");
mBuilder.setContentText("GCM Message");
manager.notify(1, mBuilder.build());
}
});
Log.i("app", "Received ");
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
4 - MainActivity-to register and get clint ID, from log cat I copyed that id.
5 - from browser I make post request to https://android.googleapis.com/gcm/send with authorization,content-type,and registration_ids.
Its gets success message.
But my device not showing notification.
Sorry everyone,
Actually my program is correct. I think it’s a problem with my phone.
(I can’t receive messages from Facebook messenger also,)
but Today morning I surprised, I got every messages from my test app(message that I send 2 days ago), Facebook ,etc.
Thank you everyone.
Follow this and this easy tutorial to send and receive push nothification in Android.
And check package naming and AndroidManifest.xml file configured correctly as explained in this example and set receiver like 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="your package name here" />
</intent-filter>
</receiver>
Related
I am using FCM cloud messaging and it is working fine when the app is in the background but not killed or when the app is running.
Once the app is stopped or killed from recent apps it doesn't receive any notification.
Even it doesn't receive the old messages once the app is started.
code for onMessageReceived()
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String myCustomKey = data.get("Nick");
String myCustomKey1 = data.get("Room");
testNotification(myCustomKey,myCustomKey1);
}
private void testNotification(String message,String title) {
Intent intent = new Intent(this, ChatActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.sham_icon)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
server side code for sending notification
{
"to" : "token-key",
"data" : {
"title":"title",
"body":"body",
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
}
}
manifest code for firebase services and notification
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/narendramodi_icon" />
android:resource="#drawable/sham_icon" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/accent" />
<service android:name=".firebase.MyFirebaseMessagingService"
android:exported="false">
<intent-filter android:priority="10000">
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".firebase.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Any help is appreciated.
This happens because on some devices system doesn't allow starting apps or app services by other apps, For FCM notifications Google Play services starts your app service if your app has been killed, when they are killed (ex. Xiaomi phones with MIUI).
Use your app server and FCM server API: Set the data key only. Can be either collapsible or non-collapsible.
If you are sending the notification from console, then use the particular key to send the notification from the Advanced Option features.
if (getIntent().getExtras() != null) {
// Call your NotificationActivity here..
Intent intent = new Intent(MainActivity.this, NotificationActivity.class);
startActivity(intent);
}
The Android framework advises that apps that have been stopped (not in background) should not be started without explicit user interaction.
FCM follows this recommendation and thus does not deliver messages to stopped apps.
For some phones,Once the app is stopped or killed from recent apps, it was completely stopped by the OS. this can save battery but fcm won't work.
how to set a notification even if the app is not running or closed. I am writing a code in which I am checking for the new data updated in RESTful web services. and if new data is updated it will notify the app user that there is the new item. just like a mail arrived and the user gets notified. I am new to this please suggest.
Use services for background checking and use notification in services so that notification fire even app is closed.
This may help:
http://android-er.blogspot.in/2011/04/start-service-to-send-notification.html
You can create a service class in your package and remember to add it in your manifest. Start the service when your main activity starts or use broadcast reciever and start activity inside broadcast receiver.
#HITESH try this
Main.java
public class BroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ComponentName comp = new ComponentName(context.getPackageName(),
Intent.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Android Manifest file
<receiver
android:name=".BroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.google.android.gcm.demo.app" />
</intent-filter>
</receiver>
<service android:name=".Intent" />
I am developing an Application which is using Push Notification (GCM) ,This application is receiving Push Noifications when app is running ,but when I forced stopped it from Settings ->apps->MyApp(click on it) and click on force stop ,then it is not receiving Push Notifications.
I have tested same with WhatsApp it is receiving Push Notifications when I force stop it .
So how can I implement same with my application .
Note : In code I am receiving PushNotifications in a sub class of WakefulBroadcastReceiver ,I have registered it statically in manifest even it is not called when application force stops.
public class GCM_Receiver extends WakefulBroadcastReceiver {
//Processes Gcm message .
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "GCM_Receiver", Toast.LENGTH_LONG).show();
ComponentName comp = new ComponentName(context.getPackageName(),GCMIntentService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
Edit :
I have registered GCM_Receiver statically in this way :
<receiver
android:name="com.myApp.GCM_Receiver"
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.RETRY" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.myApp" />
</intent-filter>
</receiver>
Edit :
And my GCMIntentService code is below :
public class GCMIntentService extends IntentService{
//Constructor with super().
public GCMIntentService () {
super("GcmIntentService");
}
//Processes gcm messages .
#Override
protected void onHandleIntent(Intent intent) {
Log.d("GCMIntentService ", "GCMIntentService Started");
Toast.makeText(getApplicationContext(), "GCMIntentService Started", Toast.LENGTH_LONG).show();
GCM_Receiver.completeWakefulIntent(intent);
}}
Only Google Play services, through the com.google.android.c2dm.permission.SEND permission, can invoke that particular broadcast receiver. Since I assume that Play services does not include the FLAG_INCLUDE_STOPPED_PACKAGES flag when sending the broadcast, your force-stopped application will not receive the messages.
Interestingly, I don't receive any WhatsApp messages after force-stopping the app. Regardless of the app though, if it can receive messages while force stopped, then it definitely receives broadcasts from an intent with the FLAG_INCLUDE_STOPPED_PACKAGES flag.
I am trying to set up a Google App engine server endpoint that sends Google Cloud Messages to android devices. So far, the device registers using GoogleCloudMessaging.register() and sends the generated regID to the server. The server then can send a message to the regIDs it has saved. Through the log messages I can see that the regIDs are all arriving correctly, and the server is sending messages correctly. The devices though aren't getting any messages.
This is the receiver in the manifest:
<receiver
android:name="---.app.MessageReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.permission.RECEIVE" />
<category android:name="---.app" />
</intent-filter>
</receiver>
This is the code for the receiver:
public class MessageReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("---", "RECIVED A MESSAGE!!!!!!");
// Explicitly specify that GcmIntentService will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GCMReceiverService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
The service never gets started, and the log message here is never shown.
Is there something I'm missing?
EDIT - these are the permissions:
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="---.app.permission.C2D_MESSAGE" />
<permission
android:name="---.app.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
There is a working solution on SO Android GCM basic implementation
The author edited his post, so you should just take it as an example. Basically, without correct permissions set AND correct Broadcast's constructor used, android won't give a damn about messages sent to an application.
Please set your permissions and other things accordingly and try again.
There is really nice post later down the comments, way under accepted one.
Really stupid mistake. Instead of .intent.RECIEVE in the intent filter it was .permission.RECEIVE.
I am attempting to register my device with C2DM and am having major issues. I have followed several tutorials, all of which are very similar. I believe the issue has to do with the registration intent that it sends to the C2DM server. Does anyone have any suggestions. The following is the relevant code:
Manifest: The permissions (outside my application tag):
<!-- Used for C2DM -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="com.companyname.parade.permission.C2D_MESSAGE" />
This is the Intent registration (inside my application tag):
<receiver
android:name=".C2DMReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<!-- Receive the actual message -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.companyname.parade" />
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.companyname.parade" />
</intent-filter>
</receiver>
The following is what I call to register my device to the C2DM server (it starts the service that contacts the C2DM servers that is suppose to send back a registration Intent with my registartionID in it). It is located in a file called C2DMessaging:
public static void register(Context context) {
Intent registrationIntent = new Intent(REQUEST_REGISTRATION_INTENT);
registrationIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT,
PendingIntent.getBroadcast(context, 0, new Intent(), 0));
registrationIntent.putExtra(EXTRA_SENDER, SENDER_ID);
ComponentName name = context.startService(registrationIntent);
if(name == null){
// FAIL!
Log.d(TAG, "FAIL");
}else{
// SUCCESS
Log.d(TAG, "Success");
}
}
The ComponentName info is the following:
com.google.android.gsf/com.google.android.gsf.gtalkservice.PushMessagingRegistrar
There is no logcat output. My receiver (named C2DMReceiver) is the following:
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (C2DMessaging.INTENT_REGISTRATION_CALLBACK.equals(action)) {
// Registration Intent
Log.w(TAG, "Registration Receiver called");
handleRegistration(context, intent);
} else if (action.equals(C2DMessaging.INTENT_RECEIVED_MESSAGE_CALLBACK)) {
Log.w(TAG, "Message Receiver called");
handleMessage(context, intent);
} else if (action.equals(C2DMessaging.INTENT_C2DM_RETRY)) {
C2DMessaging.register(context);
}
}
This does not get called at all.
Edit: This whole thing was a stupid mistake on my part. I simply forgot a step somehow in the tutorials I read. I need to add this to my permissions:
<permission android:name="com.companyname.parade.permission.C2D_MESSAGE" android:protectionLevel="signature" />
Thanks to MisterSquonk for the response.
From the Google docs for C2DM for Creating the Manifest, the manifest needs a <permission> entry to complement the <uses-permission> entry for C2D_MESSAGE.
Something like this...
<permission android:name="com.companyname.parade.permission.C2D_MESSAGE" android:protectionLevel="signature" />
This tutorial worked for me in getting me up to speed:
http://www.vogella.com/articles/AndroidCloudToDeviceMessaging/article.html
I'm not sure why you have two intent filters. I only needed one - com.google.android.c2dm.intent.REGISTRATION (see tutorial above for a complete example manifest)
I'd check your manifest is correctly referencing the receiver class - perhaps try a fully-qualified reference to the class. I had an issue at one point where I moved receiver class in my project structure and all messages stopped.
I'd also check that the C2DM account is set up right, and with the right package name.
I'd also try it on another device, as in my experience some Android devices fall off C2DM and just don't receive messages for a period of time. I find sometimes flicking to airplane mode and back sorts it out, but I found testing on several devices essential to rule out problems with a specific device.