I am trying to handle the messaged from FCM(Firebase Cloud Messaging) in andorid;
This is my code
FirebaseMessaging.getInstance().getToken()
.addOnCompleteListener(new OnCompleteListener<String>() {
#Override
public void onComplete(#NonNull Task<String> task) {
if (!task.isSuccessful()) {
Log.w("TAG", "Fetching FCM registration token failed", task.getException());
return;
}
// Get new FCM registration token
String token = task.getResult();
// Log and toast
Log.d("TAG", token);
Toast.makeText(StartActivity.this, token, Toast.LENGTH_SHORT).show();
}
});
FirebaseMessaging.getInstance().setAutoInitEnabled(true);
And i have send messaged from firebase console.
But i want to handle the messages.
So i'have did this doc says https://firebase.google.com/docs/cloud-messaging/android/receive
This is manifest.xml
<service
android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#android:drawable/ic_notification_overlay" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/white" />
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
This is my FirebaseMessagingService extended class
public class MessageService extends FirebaseMessagingService {
private static final String TAG = "MessageService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Toast.makeText(this, "Got it", Toast.LENGTH_SHORT).show();
}
}
But I don't know how to resgister this FirebaseMessagingService class to Firebase messaging
You don't need to register the class of your messaging service, you need to register the application itself. It should be google-services.json configuration file in your project with all necessary info about the project in firebase console. It will make kind of connection between your app and project created in Firebase console.
There are several ways to get this configuration file:
Generate google-services.json via Firebase console https://firebase.google.com/docs/cloud-messaging/android/client#register_your_app_with_firebase
Generate it via Android studio. Tools -> Firebase -> Cloud messaging -> complete wizard "Setup Firebase cloud messaging"
You have done a mistake in manifest.xml file.
You had to replace this
<service
android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#android:drawable/ic_notification_overlay" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/white" />
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
with this
<service android:name=".helpers.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service android:name=".helpers.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
and create these classes
MyFirebaseInstanceIDService
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("TAG", "Refreshed token: " + refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
}
}
and MyFirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "DEEDDEED";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(MyFirebaseMessagingService.this,"Hello",Toast.LENGTH_SHORT).show();
}
});
// ...
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
// scheduleJob();
} else {
// Handle message within 10 seconds
// handleNow();
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
#Override
public void onNewToken(#NonNull String s) {
super.onNewToken(s);
HashMap<String,String> map = new HashMap<>();
Database database = new Database(getApplicationContext());
map.put("user",database.getPhone());
map.put("token",s);
Call<Void> call = new Server().getRetrofitInterface().executeUpdatePTK(map);
call.enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Void> call, Response<Void> response) {
}
#Override
public void onFailure(Call<Void> call, Throwable t) {
}
});
}
}
Related
I am trying to send e-mai in background. I am using this library:library to achieve this, so i've created BroadcastReceiver with library code. But unfortunately i've got errror when i try to send e-mail:Unable to add window -- token null is not valid; is your activity running? I am trying to pass context from Activity, to BroadcastReceiver, but i think that context in Receiver is some kind of seperate only for this statement. Any advice to avoid this error?
Manifest
<receiver
android:name=".service.EmailReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="BackgroundProcessEmail" />
</intent-filter>
</receiver>
BroadcastReceiver
#Override
public void onReceive(final Context context, Intent intent) {
String email=intent.getStringExtra("email");
String password=intent.getStringExtra("password");
String deviceModel = Build.MANUFACTURER
+ " " + Build.MODEL;
assert email != null;
assert password != null;
BackgroundMail.newBuilder(context)
.withUsername(email)
.withPassword(password)
.withSenderName("Full")
.withMailTo("email")
.withType(BackgroundMail.TYPE_PLAIN)
.withSubject("Your device " + deviceModel +" achieved")
.withBody("")
.withSendingMessage("Sending email")
.withOnSuccessCallback(new BackgroundMail.OnSendingCallback() {
#Override
public void onSuccess() {
}
#Override
public void onFail(Exception e) {
Toasty.error(context, "E-mail sent error" + e.getMessage(), Toasty.LENGTH_LONG).show();
}
})
.send();
}
I want to use the SMS Retriever API for automatically getting verification codes, but I'm not receiving SMS content from the API.
I use an emulator for testing, and the SMS is sent to the device correctly, but my program cannot receive and use it.
My SmsReceiver.java class:
public class SmsReceiver extends BroadcastReceiver {
private static final String TAG = "SmsReceiver";
#Override public void onReceive(Context context, Intent intent) {
if(intent == null)
{
return;
}
Log.e(TAG, "onReceive: ");
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status mStatus = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
switch (mStatus.getStatusCode()) {
case CommonStatusCodes.SUCCESS:
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
Log.e(TAG, "onReceive: "+message);
break;
case CommonStatusCodes.TIMEOUT:
Log.e(TAG, "onReceive: failure");
break;
}
}
}
}
MainActivity.java class
public class MainActivity extends AppCompatActivity{
private final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
SmsReceiver smsReceiver = new SmsReceiver();
IntentFilter filter = new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION);
ApplicationLoader.applicationContext.registerReceiver(smsReceiver, filter);
SmsRetrieverClient client = SmsRetriever.getClient(ApplicationLoader.applicationContext);
Task<Void> task = client.startSmsRetriever();
task.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(MainActivity.this, "Success", Toast.LENGTH_SHORT).show();
}
});
}
catch (Exception e)
{
Log.e(TAG, e.toString());
}
}
}
Manifest file:
<application
android:name=".ApplicationLoader"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".SmsReceiver"
android:exported="true"
android:permission="com.google.android.gms.auth.api.phone.permission.SEND">
<intent-filter>
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED"/>
</intent-filter>
</receiver>
</application>
Google Libraries:
implementation 'com.google.android.gms:play-services-auth:17.0.0'
implementation 'com.google.android.gms:play-services-auth-api-phone:17.0.0'
My SMS message:
<#> Your verify code is: 12345
Your SMS message is missing the hash string: https://developers.google.com/identity/sms-retriever/verify#1_construct_a_verification_message
You need to include the verification code and the hash string. See here for how to compute the hash string.
I am fairly new to android. I am trying to send data from my tablet to my phone using a WearableListenerService. This part works well, I can see through logs that the data is sent. The problem is that I receive the data from the tablet in the Listener class and I have to transmit it to Mainactivity in order to update my Views. To do this I use a LocalBroadcaster and I implemented the onReceive method in my MainActivity. So when I give the order to send the data from the phone the onReceive gets called multiple time most of the time between 2 or 3 times and furthermore the activity is recreated because onCreate is triggered by this method (I don't know if this behavior is expected).
Here is the code:
DataLayerListenerService.java (Listener)
public class DataLayerListenerService extends WearableListenerService {
// Tag for Logcat
private static final String TAG = "DataLayerService";
private int notificationId = 001;
private String notif;
// Member for the Wear API handle
GoogleApiClient mGoogleApiClient;
#Override
public void onCreate() {
super.onCreate();
// Start the Wear API connection
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
}
//#Override
public void onDataChanged(DataEventBuffer dataEvents) {
Log.v(TAG, "onDataChanged: " + dataEvents);
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
Log.e(TAG, "DataItem Changed: " + event.getDataItem().toString() + "\n"
+ DataMapItem.fromDataItem(event.getDataItem()).getDataMap());
String path = event.getDataItem().getUri().getPath();
switch (path) {
case DataLayerCommons.NOTIFICATION_PATH:
Log.v(TAG, "Data Changed for NOTIF_PATH: " + event.getDataItem().toString());
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
notif = dataMapItem.getDataMap().getString(DataLayerCommons.NOTIFICATION_KEY);
Intent intent = new Intent(NOTIFICATION_RECEIVED);
intent.putExtra(NOTIFICATION_RECEIVED, notif);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
break;
case DataLayerCommons.COUNT_PATH:
Log.v(TAG, "Data Changed for COUNT_PATH: " + event.getDataItem() + "\n"
+ "Count data = " + DataMapItem.fromDataItem(event.getDataItem())
.getDataMap().getInt(DataLayerCommons.COUNT_KEY));
break;
default:
Log.v(TAG, "Data Changed for unrecognized path: " + path);
break;
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
Log.v(TAG, "DataItem Deleted: " + event.getDataItem().toString());
}
}
}
}
Main Activity
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static final String NOTIFICATION_RECEIVED = "NOTIFICATION_RECEIVED";
private String notif="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG,"OnCreate");
setContentView(R.layout.main_activity);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter(NOTIFICATION_RECEIVED));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "Got message!");
notif = intent.getStringExtra(NOTIFICATION_RECEIVED);
TextView warnView = findViewById(R.id.warningView);
warnView.setText(notif);
}
};
}
AndroidManifest.xml
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat">
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="false" />
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<service android:name=".DataLayerListenerService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.DATA_CHANGED" />
<data
android:host="*"
android:pathPrefix="/notification"
android:scheme="wear" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
<data
android:host="*"
android:pathPrefix="/start-activity"
android:scheme="wear" />
</intent-filter>
</service>
<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>
<intent-filter>
<action android:name="com.example.android.wearable.datalayer.EXAMPLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Thanks for the help
I would suggest using Application class to store your Activity instead of BroadcastReceiver registering.
What I mean:
in Application class create a variable that stores your activity:
class MyApp extends Application {
public static MyActivity activity;
}
to link save into this variable current activity at onCreate and release while onDestroy.
Somehow:
public MyActivity extends Activity {
void onCreate() {
MyApp.activity = this;
}
void onDestroy() {
MyApp.activity = null;
}
void redraw() {
//redraw
}
}
inside the service do something like this:
class MyService extends WearableListenerService {
void onDataChanged() {
if (MyApp.activity != null) {
MyApp.activity.redraw()
}
}
}
do not forget to set application in the manifest:
<application
android:name=".MyApp"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat">
I followed the example from developers.google.com and create simple services for retrieve Token and messages from GCM.
Class for token receive
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
private static final String[] TOPICS = {"global"};
private String projectNumber = "gcm-test-xxxxx";
public RegistrationIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(projectNumber,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
sendRegistrationToServer(token);
subscribeTopics(token);
sharedPreferences.edit().putBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, true).apply();
} catch (IOException e) {
Log.d(TAG, "Failed to complete token refresh", e);
sharedPreferences.edit().putBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, false).apply();
}
Intent registrationComplete = new Intent(QuickstartPreferences.REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
private void subscribeTopics(String token) {
}
private void sendRegistrationToServer(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
}
This class works fine, I can retrieve token and do what i want with it.
I am starting this class as a service from MainActivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, RegistrationIntentService.class));
}
}
Also i have class for retrieving messages from GCM. This class don't work at all.
public class MyGcmListenerService extends GcmListenerService {
String TAG = "MyGcmListenerService";
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
}
}
All this stuff was registered in manifest.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gcm_test.app">
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<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>
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="gcm_test.app" />
</intent-filter>
</receiver>
<service
android:name=".gcm.MyGcmListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
</intent-filter>
</service>
<service
android:name=".gcm.RegistrationIntentService"
android:exported="false">
</service>
</application>
</manifest>
I send messages with postman.
POST https://android.googleapis.com/gcm/send
headers
Content-Type:application/json
Authorization:key= keyFromGoogleDevelopersConsole
{
"to" : "/topics/global",
"data":{
"message": "Hello world!!!"
}
}
After send I receive 200 OK and message ID, but phone did not receive any messages.
What I am doing is wrong? How receive my messages?
I have changed SenderID to numbers from Developers Console but it did not help me. Aslo I have noticed Errors in debug console:
11-21 17:32:58.014 31813-31813/gcm_test.app E/dalvikvm﹕ Could not find class 'android.app.Notification$BigTextStyle', referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zza
11-21 17:32:58.024 31813-31813/gcm_test.app E/dalvikvm﹕ Could not find class 'android.os.UserManager', referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zzap
11-21 17:32:58.027 31813-31813/gcm_test.app E/dalvikvm﹕ Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.GooglePlayServicesUtil.zzb
I thought this service that retrives the messages need somehow register or start. But when I run it like simple service it crashes.
It looks like you are not registering with the correct Sender ID. The documentation explains that the Sender ID is the numerical Project Number listed at the Google Developers Console for your app's project. The string you are using for Sender ID, gcm-test-xxxxx, looks like the Project ID.
On the Dashboard page at the Developers Console, your project data will include a line like this:
ID: jade-segment-123 (#123123123123)
For this example, the Sender ID is 123123123123.
Update:
Note also that you are not using the URL shown in the documentation:
https://gcm-http.googleapis.com/gcm/send
I have developed a push notification application in Android from this tutorial:push notification in android app. The register button is displayed when I run the app. When I click on the register button, and when registration is successful, a notification is displayed on my device.
How can I include it in my own app? My app has one xml parsing example app. Here when any new item is added, I wish to display (the new order is displayed ) a notification message on the device. It is automatically generated here.
I am posting demo application of Google Cloud Messaging.
Make sure you create demo application with API level equal or higher than Android OS 2.2 with Google API
User have to signed in at-least one Google Account to use this service.
First you have to add GCM library.
Than create on class which I named GCMIntentService which extends GCMBaseIntentService as follows:
package com.example.gcmdemo;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMConstants;
public class GCMIntentService extends GCMBaseIntentService {
private static final String TAG = "Push Notification Demo GCMIntentService";
#Override
protected void onError(Context context, String errorId) {
if(GCMConstants.ERROR_ACCOUNT_MISSING.equalsIgnoreCase(errorId)) {
Log.v(TAG, "Error Account Missing");
} else if(GCMConstants.ERROR_AUTHENTICATION_FAILED.equalsIgnoreCase(errorId)) {
Log.v(TAG, "Error Authentication Failed");
} else if(GCMConstants.ERROR_INVALID_PARAMETERS.equalsIgnoreCase(errorId)) {
Log.v(TAG, "Error Invalid Parameters");
} else if(GCMConstants.ERROR_INVALID_SENDER.equalsIgnoreCase(errorId)) {
Log.v(TAG, "Error Invalid Sender");
} else if(GCMConstants.ERROR_PHONE_REGISTRATION_ERROR.equalsIgnoreCase(errorId)) {
Log.v(TAG, "Error Phone Registration Error");
} else if(GCMConstants.ERROR_SERVICE_NOT_AVAILABLE.equalsIgnoreCase(errorId)) {
Log.v(TAG, "Error Service Not Available");
}
}
#Override
protected void onMessage(Context context, Intent intent) {
// App Server Sends message as key value pairs
String value1 = intent.getStringExtra("key1");
String value2 = intent.getStringExtra("key2");
Log.v(TAG, "key1: "+value1 );
Log.v(TAG, "key2: "+value2 );
}
#Override
protected void onRegistered(Context context, String regId) {
Log.v(TAG, "Successfull Registration : "+regId);
}
#Override
protected void onUnregistered(Context context, String regId) {
Log.v(TAG, "Successfully Unregistred : "+regId);
}
#Override
protected String[] getSenderIds(Context context) {
return super.getSenderIds(context);
}
#Override
protected void onDeletedMessages(Context context, int total) {
super.onDeletedMessages(context, total);
}
#Override
protected boolean onRecoverableError(Context context, String errorId) {
return super.onRecoverableError(context, errorId);
}
}
Here is how you should check registration in following demo activity :
package com.example.gcmdemo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import com.google.android.gcm.GCMRegistrar;
public class MainActivity extends Activity {
private static final String TAG = "Push Notification Demo Activity";
private static final String SENDER_ID = "1069713227710";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, SENDER_ID);
} else {
Log.v(TAG, "Already registered : "+regId);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
And finally the demo manifest :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gcmdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<permission
android:name="com.example.gcmdemo.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcmdemo.permission.C2D_MESSAGE" />
<!-- 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" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<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.gcmdemo" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
</application>
</manifest>
Also you will need third party server side script as specified here.
Sending Push Notification using FCM
Google deprecated the Google Cloud Messaging (GCM) and launched new Push notification server that is Firebase Cloud Messaging (FCM). FCM is same like GCM, FCM is also a cross-platform messaging solution for mobile platforms
Firebase Cloud Messaging can send three types of messages (Message types)
1.Notification Message
2.Data Message
3.message with both Notification and Data
Firebase Cloud Messaging Integrating steps:-
1.SetUp New Project or Import project in Firbase Console(https://firebase.google.com/)
2.Add the Same Package Name of App in Firebase App.
3.Get the "google-services.json" file and put that file to your project’s app folder.This file contains all the Urls and the Keys for Google service's, So don't change or edit this file.
4.Add new Gradle dependencies in Project for Firebase.
//app/build.gradle
dependencies {
compile 'com.google.firebase:firebase-messaging:9.6.0'
}
apply plugin: 'com.google.gms.google-services'
5.Create a Class that contains all the constant values that we use across the app for FCM.
public class Config {
public static final String TOPIC_GLOBAL = "global";
// broadcast receiver intent filters
public static final String REGISTRATION_COMPLETE = "registrationComplete";
public static final String PUSH_NOTIFICATION = "pushNotification";
// id to handle the notification in the notification tray
public static final int NOTIFICATION_ID = 100;
public static final int NOTIFICATION_ID_BIG_IMAGE = 101;
public static final String SHARED_PREF = "ah_firebase";
}
6. Create a class named MyFirebaseInstanceIDService.java which will receives the firebase registration id which will be unique to each app. Registration id is used to send message to a single device.
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = MyFirebaseInstanceIDService.class.getSimpleName();
#Override
public void onTokenRefresh() {
super.onTokenRefresh();
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
// Saving reg id to shared preferences
storeRegIdInPref(refreshedToken);
// sending reg id to your server
sendRegistrationToServer(refreshedToken);
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(Config.REGISTRATION_COMPLETE);
registrationComplete.putExtra("token", refreshedToken);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
private void sendRegistrationToServer(final String token) {
// sending gcm token to server
Log.e(TAG, "sendRegistrationToServer: " + token);
}
private void storeRegIdInPref(String token) {
SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
SharedPreferences.Editor editor = pref.edit();
editor.putString("regId", token);
editor.commit();
}
}
7.Create one more service class named MyFirebaseMessagingService.java. This will receive firebase messages.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = MyFirebaseMessagingService.class.getSimpleName();
private NotificationUtils notificationUtils;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "From: " + remoteMessage.getFrom());
if (remoteMessage == null)
return;
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.e(TAG, "Notification Body: " + remoteMessage.getNotification().getBody());
handleNotification(remoteMessage.getNotification().getBody());
}
}
private void handleNotification(String message) {
if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
}else{
// If the app is in background, firebase itself handles the notification
}
}
/**
* Showing notification with text only
*/
private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent);
}
/**
* Showing notification with text and image
*/
private void showNotificationMessageWithBigImage(Context context, String title, String message, String timeStamp, Intent intent, String imageUrl) {
notificationUtils = new NotificationUtils(context);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notificationUtils.showNotificationMessage(title, message, timeStamp, intent, imageUrl);
}
}
8.In the AndroidManifest.xml add these two firebase services MyFirebaseMessagingService and MyFirebaseInstanceIDService.
<!-- Firebase Notifications -->
<service android:name=".service.MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".service.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<!-- ./Firebase Notifications -->
Now simply Send your First Message
Notes :
*1.Read the Google Doc for Firebase Cloud Messaging *
2.If you want to Migrate a GCM Client App for Android to Firebase Cloud Messaging follow these steps and Doc (Migrate a GCM Client
App)
3.Android Sample tutorial and Code (Receive Reengagement Notifications)
personally suggest you that instead of GCM there is also other library named Parse for PushNotification, it works same as Google Cloud Messaging but it is so so so so much easy then GCM
You have to just download JAR file and simple two-three line of code for PUSH-NOTIFICATION
to learn use this site https://parse.com/tutorials/android-push-notifications
Even you don't have to use PHP or any kind of server side code it provide you facility
look i will give u demo
Parse.initialize(this, "YOUR_APP_ID", "YOUR_CLIENT_KEY");
PushService.setDefaultPushCallback(this, YourDefaultActivity.class);
from above code is enough for receiving push notification
if you want to send notification they provide nice UI look the picture of UI they provide