Android notification using Firebase - android

I'm developing a android application and different users will be use it.
I need to give some notification to a user when another user do some activity. I planed to do it with firebase cloud messaging(FCM). but i don't know how to detect the relevant device.

Step 1: Register with Firebase Developers Console
In order to use FCM, you need to login to console. You should be given a choice on the right-hand side as to whether to create a new project or import an existing Google app into Firebase.
Click on Add App and then copy the google-services.json file that will get downloaded into yourapp/ dir. This file includes the project information and API keys needed to connect to Firebase. Make sure to preserve the filename, since it will be used in the next step.
Finally, add the Google services to your root build.gradle file's classpath:
buildscript {
dependencies {
// Add this line
classpath 'com.google.gms:google-services:3.0.0'
}
}
Add to your existing app/build.gradle at the end of the file:
apply plugin: 'com.google.gms.google-services'
Step 2 - Download Google Play Services
First, let's download and setup the Google Play Services SDK. Open Tools->Android->SDK Manager and check whether or not you have already downloaded Google Play Services under the Extras section. Make sure to update to the latest version to ensure the Firebase package is available.
Step 3 - Add Google Repository
Also open Tools->Android->SDK Manager and click on the SDK Tools tab. Make sure that under Support Repository you have installed the Google Repository. If you forget this step, you are not likely to be able to include the Firebase messaging library in the next step.
Step 4 - Update to SDK Tools
Also make sure to upgrade to SDK Tools 25.2.2. You may have Firebase authentication issues with lower SDK Tools version.
Step 6 - Import Firebase Messaging Library
Add the following to your Gradle file:
dependencies {
compile 'com.google.firebase:firebase-messaging:9.4.0'
}
Step 7 - Implement a Registration Intent Service
You will want to implement an Intent Service, which will execute as a background thread instead of being tied to the lifecycle of an Activity. In this way, you can ensure that push notifications can be received by your app if a user navigates away from the activity while this registration process is occuring.
First, you will need to create a RegistrationIntentService class and make sure it is declared in your AndroidManifest.xml file and within the application tag:
<service android:name=".RegistrationIntentService" android:exported="false"/>
Inside this class, you will need to request an instance ID from Google that will be a way to uniquely identify the device and app. Assuming this request is successful, a token that can be used to send notifications to the app should be generated too.
public class RegistrationIntentService extends IntentService {
// abbreviated tag name
private static final String TAG = "RegIntentService";
public RegistrationIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
// Make a call to Instance API
FirebaseInstanceId instanceID = FirebaseInstanceId.getInstance();
String senderId = getResources().getString(R.string.gcm_defaultSenderId);
try {
// request token that will be used by the server to send push notifications
String token = instanceID.getToken();
Log.d(TAG, "FCM Registration Token: " + token);
// pass along this data
sendRegistrationToServer(token);
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
}
You will want to record whether the token was sent to the server and may wish to store the token in your Shared Preferences:
public static final String SENT_TOKEN_TO_SERVER = "sentTokenToServer";
public static final String FCM_TOKEN = "FCMToken";
#Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
// Fetch token here
try {
// save token
sharedPreferences.edit().putString(FCM_TOKEN, token).apply();
// pass along this data
sendRegistrationToServer(token);
} catch (IOException e) {
Log.d(TAG, "Failed to complete token refresh", e);
// If an exception happens while fetching the new token or updating our registration data
// on a third-party server, this ensures that we'll attempt the update at a later time.
sharedPreferences.edit().putBoolean(SENT_TOKEN_TO_SERVER, false).apply();
}
}
private void sendRegistrationToServer(String token) {
// send network request
// if registration sent was successful, store a boolean that indicates whether the generated token has been sent to server
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
sharedPreferences.edit().putBoolean(SENT_TOKEN_TO_SERVER, true).apply();
}
You will want to make sure to dispatch this registration intent service when starting up your main activity. There is a Google Play Services check that may require your activity to be launched in order to display a dialog error message, which is why it is being initiated in the activity instead of application.
public class MyActivity extends AppCompatActivity {
/**
* Check the device to make sure it has the Google Play Services APK. If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings.
*/
private boolean checkPlayServices() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
#Override
protected void onCreate() {
if(checkPlayServices()) {
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
}
Step 8 - Create a InstanceID ListenerService
According to this Google official documentation, the instance ID server issues callbacks periodically (i.e. 6 months) to request apps to refresh their tokens. To support this possibility, we need to extend from InstanceIDListenerService to handle token refresh changes. We should create a file called MyInstanceIDListenerService.java that will override this base method and launch an intent service for RegistrationIntentService to fetch the token:
public class MyInstanceIDListenerService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify of changes
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
You also need to add the service to your AndroidManifest.xml file within the application tag:
<service
android:name="com.example.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
Step 9 - Listening for push notifications
Let's define FCMMessageHandler.java that extends from FirebaseMessagingService that will process the message received:
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import android.app.NotificationManager;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
public class FCMMessageHandler extends FirebaseMessagingService {
public static final int MESSAGE_NOTIFICATION_ID = 435345;
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String from = remoteMessage.getFrom();
Notification notification = remoteMessage.getNotification();
createNotification(notification);
}
// Creates notification based on title and body received
private void createNotification(Notification notification) {
Context context = getBaseContext();
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(notification.getTitle())
.setContentText(notification.getBody());
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(MESSAGE_NOTIFICATION_ID, mBuilder.build());
}
}
We need to register the receiver class with FCM in the AndroidManifest.xml tagging the type of request (category) of the push:
<application
...>
<!-- ... -->
<activity
...>
</activity>
<service
android:name=".FCMMessageHandler"
android:exported="false" >
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>

Related

How to confirm if application has been installed from deeplink / referlink?

I'd like to know if there is a way maybe with firebase or appsFLyer etc or natively to know if user came from a deeplink and installed my application is there a way to know the deeplink ?
Basically i'd like an intent passed to me after the user installs the app from the play store (assuming the user got to the play store from a deepLink or some referer link).
Lets imagine the user did not have my automobile app but saw an ad about cars that i had put up. he then clicks that ad and is directed to install my app. after installing my app i'd like the user to see the car they were looking at initially in the ad.
Good example was described in that post
You have to create specific BroadcastReceiver
Add in Manifest:
<receiver android:name="your.package.InstallListener" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
and create BroadcastReceiver class which will catch deeplink
public class InstallListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String rawReferrerString = intent.getStringExtra("referrer");
if (rawReferrerString != null) {
Log.i("MyApp", "Received the following intent " + rawReferrerString);
}
}
}
And add referrer parameter to url using js like this:
var fallbackFunction = function() {
window.location.replace('market://details?id=io.branch.testbed&referrer=specialparam');
};
var addIFrame = function() {
var iframe = document.createElement("iframe");
iframe.style.border = "none";
iframe.style.width = "1px";
iframe.style.height = "1px";
iframe.src = 'your_uri_scheme://';
document.body.appendChild(iframe);
};
addIFrame();
setTimeout(fallbackFunction, 250);
By the way if that method does not work you can try to get specific parameter of phone in js (like vendor, model, etc) and save it in cloud database like firebase. Then after user installed application (PACKAGE_INSTALLED BroadcastReceiver or just first launch) you can check database for last data for his specific parameter and get his deeplink.
If you dont have too much users that will work correctly enough.

Android: Firebase token is null at first run

I am using FCM to provide notifications in my app. Everything worked well, but now I realised that, when I install my application using Android Studio (not from GooglePlay) the token is null at first run. When I close my app and restart it, the token is not null anymore. What cause this problem and how can I avoid it?
InstanceIDService:
public class InstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
String token = FirebaseInstanceId.getInstance().getToken();
registerToken(token);
}
private void registerToken(String token) {
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("Token",token)
.build();
Request request = new Request.Builder()
.url("url_to_registration_script")
.post(body)
.build();
try {
client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In MainActivity:
FirebaseMessaging.getInstance().subscribeToTopic("topic");
String token = FirebaseInstanceId.getInstance().getToken();
Log.d("TOKEN", token);
Last log returns null when app is installed and started for the first time
Registration script:
<?php
if (isset($_POST["Token"])) {
$_uv_Token=$_POST["Token"];
$conn = mysqli_connect("localhost","user","pass","db") or die("Error connecting");
$q="INSERT INTO users (Token) VALUES ( '$_uv_Token') "
." ON DUPLICATE KEY UPDATE Token = '$_uv_Token';";
mysqli_query($conn,$q) or die(mysqli_error($conn));
mysqli_close($conn);
}
?>
The token is fetched asynchronously on first app start. You have to wait for onTokenRefresh() to be called in your FirebaseInstanceIdService before the token can be accessed.
uninstall the app from emulator and run again , so that the onTokenRefreshed method will be called again .
To check wether you are already registered and you just want to know the FCM TOken
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
add the above line in MyFirebaseMessagingService class any where(in oncreate method ) and just Toast or log the refreshedToken.
Just replace:
String token = instanceID.getToken();
with:
String token = instanceID.getToken($SENDER_ID, "FCM");
and it will work.
I was facing the same problem. I looked through a lot of SO posts and other forums and I found a solution that worked for me. FCM documentation says to use this method to get a token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
I found a post online (I apologize, I don't remember which one. I found it a while ago) that used this method instead:
String refreshedToken = FirebaseInstanceId.getInstance().getToken() (String authorizedEntity, String scope);
FCM documentation describes the first method as:
Return the master token for the default Firebase project.
While the second one is described as:
Returns a token that authorizes an Entity to perform an action on behalf of the application identified by Instance ID.
This is similar to an OAuth2 token except, it applies to the application instance instead of a user.
For example, to get a token that can be used to send messages to an application via FirebaseMessaging, set to the sender ID, and set to "FCM".
I have been looking into why the first method call takes a longer time to return a token, but I haven't found an answer yet. Hope this helps.
Even I had the same issue. I had given the Log statement to print token in onCreate of my launcher activity. It takes time to refresh the token once you uninstall the app. Thats why you get null. You have to wait for a bit to get the token refreshed.
Sometimes network issues may occur, even internet is working fine....
check your FirebaseInstancId class defined in Manifest file in your android project.
I just fell in same issue and this is the way I fixed it. Call the block somewhere in onCreate() method of your activity. I want to sent the Token to my Parse server so you must change it based on your needs.
This is the sample I followed.
private void subscribeUserToParse() {
String deviceToken = FirebaseInstanceId.getInstance().getToken();
if (TextUtils.isEmpty(deviceToken)) {
Intent intent = new Intent(this, MyFirebaseInstanceIDService.class);
startService(intent);
return;
}
User user = UserUtil.retrieveUserFromDB(mRealm);
String objectId = user.getParseObjectId();
if (!TextUtils.isEmpty(objectId)) {
ParseUtils.subscribeWithUsersObjectId(objectId, deviceToken);
}
}
The biggest issue i faced after writing the correct code is:-
not the latest version of google play services in build-gradle,
So always use the google-play-services version shown by firebase in setting up dialog
I was having the same problem in a Android 4.2 device.
So, to solve the problem, first, check if your service, in the manifest, if it have a priority like this:
<service
android:name=".other.MyFirebaseInstanceIDService"
android:exported="false">
<intent-filter android:priority="1000">
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
Second, use a broadcast intent to notify your MainActivity that changed the token:
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
final Intent intent = new Intent("tokenReceiver");
final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
intent.putExtra("token",refreshedToken);
broadcastManager.sendBroadcast(intent);
}
Then in MainActivity, in the onCreate, add this:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
LocalBroadcastManager.getInstance(this).registerReceiver(tokenReceiver,
new IntentFilter("tokenReceiver"));
}
and, in the MainActivity, add a new BroadcastReceiver:
BroadcastReceiver tokenReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String token = intent.getStringExtra("token");
if(token != null)
{
Log.e("firebase", String.valueOf(token));
// send token to your server
}
}
};
Since the getToken() method is deprecated, you have to replace it with a listener.
Just replace String token = FirebaseInstanceId.getInstance().getToken(); by the following code snippet:
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
// Log and toast
String msg = getString(R.string.msg_token_fmt, token);
Log.d(TAG, msg);
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
});
You can find the official google documentation here: https://firebase.google.com/docs/cloud-messaging/android/client
And a nice medium post will help you out as well: https://medium.com/#cdmunoz/fcm-getinstance-gettoken-in-android-is-now-deprecated-how-to-fix-it-3922a94f4fa4

How to handle FirebaseInstanceId.getInstance().getToken() = null

I have just migrated to FCM. I have added my class that extends from FirebaseInstanceIdService to receive a refreshedToken as and when appropriate.
My question is specific to the case when user installs my app first time and due to some reason, unable to receive a registration Id from onTokenRefresh. How are we supposed to handle this? Can I set a broadcast receiver from my FirebaseInstanceIdService class which will notify the Main activity when a registration Id is received?
if your device have no connection to the internet onTokenRefresh() is never called and you should notify to user his/her device has no internet connection
firebase has its own network change listener and when a device connected to the internet then try to get token and return it, at this time you can tell your main activity by sending a local broadcast receiver that registration token is received.
use below codes:
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d("FCN TOKEN GET", "Refreshed token: " + refreshedToken);
final Intent intent = new Intent("tokenReceiver");
// You can also include some extra data.
final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
intent.putExtra("token",refreshedToken);
broadcastManager.sendBroadcast(intent);
}
in your main activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
LocalBroadcastManager.getInstance(this).registerReceiver(tokenReceiver,
new IntentFilter("tokenReceiver"));
}
BroadcastReceiver tokenReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String token = intent.getStringExtra("token");
if(token != null)
{
//send token to your server or what you want to do
}
}
};
}
Change this in manifest.xml file
tools:node="replace"
to
tools:node="merge".
As far as I know, token will be null only when you try to run your app on emulator on which google play service is not there and when you are using dual email id on you google play store(on you actual device), but only one email id is verified for the usage. Those are the cases which will give you null token and I have already implemented FCM in my new project. So for rest of any cases , token won't be null.
Use this class extends with..
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
#Override
public void onTokenRefresh() {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
Toast.makeText(MyFirebaseInstanceIDService.this,refreshedToken,Toast.LENGTH_LONG).show();
}
}
I was facing the same problem. I looked through a lot of SO posts and other forums and I found a solution that worked for me. FCM documentation says to use this method to get a token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
I found a post online (I apologize, I don't remember which one. I found it a while ago) that used this method instead:
String refreshedToken = FirebaseInstanceId.getInstance().getToken() (String authorizedEntity, String scope);
FCM documentation describes the first method as:
Return the master token for the default Firebase project.
While the second one is described as:
Returns a token that authorizes an Entity to perform an action on behalf of the application identified by Instance ID.
This is similar to an OAuth2 token except, it applies to the application instance instead of a user.
For example, to get a token that can be used to send messages to an application via FirebaseMessaging, set to the sender ID, and set to "FCM".
I have been looking into why the first method call takes a longer time to return a token, but I haven't found an answer yet. Hope this helps.
depending on your application logic you can write the code to handle the "new" token directly in the FirebaseInstanceIdService.onTokenRefresh() method, or you can use a LocalBroadcast to send this information to your activity if you need to change the UI when this event happens.
Note that when onTokenRefresh() is called your activity could be closed.
A possible implementation could a mix of the two options:
add some logic in onTokenRefresh() to send the token to your server
use a LocalBroadcastReceiver to inform your activity, if you have a piece of UI that need to change when the token is available.
If you are running it on your emulator, check that you have Google play services enabled in Tools -> Android -> SDK Manager -> SDK Tools -> Google play services
Once installed, reboot both Android Studio and your emulator
It worked for me

GCM: Should I start InstanceIDListenerService by myself in Android?

From the official website , I download an example of GCM, there is a service that can detect the refresh Token, the code is as follows:
public class MyInstanceIDListenerService extends InstanceIDListenerService {
private static final String TAG = "MyInstanceIDLS";
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. This call is initiated by the
* InstanceID provider.
*/
// [START refresh_token]
#Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
// [END refresh_token]
}
My question is : Should I write a code to start the service by myself?
just like:
startService(new Intent(getActivity(), MyInstanceIDListenerService.class));
No. This service is started when necessary by Google Play services. Just be sure to define the service in your AndroidManifest.xml file. Also if you are just starting out you may want to have a look at the easier to implement FCM.
See a sample of FCM here.

Non deprecated GCM Cloud Endpoints example 2016

Last year when you added a Cloud Endpoints plus GCM module to an Android Studio project, the IDE created some sample code both in the backend and the app that showed how to use GCM with Cloud Endpoints.
However, with the newer versions of Android Studio you only get the backend part added for you. So I went back into my old projects and dug up some of the convenient app code which registered, and sent GCM push notifications in Android.
Here is what that code looks like:
GcmBroadcastReceiver.java
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// 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 {
android.support.v4.app.NotificationCompat.Builder notification;
public GcmIntentService() {
super("GcmIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
// The getMessageType() intent parameter must be the intent you received
// in your BroadcastReceiver.
String messageType = gcm.getMessageType(intent);
if (extras != null && !extras.isEmpty()) { // has effect of unparcelling Bundle
// Since we're not using two way messaging, this is all we really to check for
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
Logger.getLogger("GCM_RECEIVED").log(Level.INFO, extras.toString());
showToast(extras.getString("message"));
sendNotification(extras.getString("message"));
}
}
//call to the API and get new data.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
protected void showToast(final String message) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
});
}
private void sendNotification(String msg) {
notification = new android.support.v4.app.NotificationCompat.Builder(this);
//set number of notifications count
//notification.setNumber(x);
//cancels notification when app is opened.
notification.setAutoCancel(true);
//build the notification
notification.setSmallIcon(R.drawable.greenicon);
notification.setTicker("This is the ticker!");
//set time
notification.setWhen(System.currentTimeMillis());
notification.setContentTitle("New message!");
notification.setContentText(msg);
notification.setSound((Settings.System.DEFAULT_NOTIFICATION_URI));
//LED
notification.setLights(Color.RED, 3000, 3000);
// intent
Intent intent = new Intent(this, MainActivity.class);
//give phone access to perform this intent b/c they may be in another part of their phone.
//aka gives phone access to the intents in our app
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//what to do when notification is clicked:
notification.setContentIntent(pendingIntent);
//Builds notification and issues it (sends it to device). Can build and send out notifcations
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//send out notification with uniqueID
nm.notify(2158, notification.build());
}
}
GcmRegistrationAsyncTask
class GcmRegistrationAsyncTask extends AsyncTask<Void, Void, String> {
private static Registration regService = null;
private GoogleCloudMessaging gcm;
private Context context;
// TODO: change to your own sender ID to Google Developers Console project number, as per instructions above
private static final String SENDER_ID = "1026567774990";
public GcmRegistrationAsyncTask(Context context) {
this.context = context;
}
#Override
protected String doInBackground(Void... params) {
if (regService == null) {
Registration.Builder builder = new Registration.Builder(AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), null)
// Need setRootUrl and setGoogleClientRequestInitializer only for local testing,
// otherwise they can be skipped
.setRootUrl("https://push-notif-45657747.appspot.com/_ah/api/")
.setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
#Override
public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest)
throws IOException {
abstractGoogleClientRequest.setDisableGZipContent(true);
}
}) ;
// end of optional local run code
regService = builder.build();
}
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
String regId = gcm.register(SENDER_ID);
msg = "Device registered, registration ID=" + regId;
// You should send the registration ID to your server over HTTP,
// so it can use GCM/HTTP or CCS to send messages to your app.
// The request to your server should be authenticated if your app
// is using accounts.
regService.register(regId).execute();
} catch (IOException ex) {
ex.printStackTrace();
msg = "Error: " + ex.getMessage();
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
Logger.getLogger("REGISTRATION").log(Level.INFO, msg);
}
}
However, I am getting some deprecated errors in Android Studio now:
gcm.register(SENDER_ID); is deprecated and so is GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.
This GCM stuff is pretty confusing to begin with and while there is some information here on how to use it, I was wondering if anyone had any currently working non-deprecated examples or maybe you could suggest some edits to the above code if you know what you are doing...? Much thanks!
Wanted to give people a little guide here in case they were lost.
First check out and stay up to date with this Google Cloud Messaging Android example:
https://github.com/google/gcm
To make it work you will have to generate a google-services.json file which you can do here:
https://developers.google.com/mobile/add
Make sure you are logged into the google developers console before you go that link. It will load your projects for you and automatically set up the gcm api key for you in your projects credentials.
Copy/paste the google-services.json into the /app directory of your Android project.
Add a cloud endpoints with gcm module to the android project.
Enter your gcm api key (which you can view on your credentials page on developers console) into the webapp-WEB_INF/appengine-web.xml file in your cloud endpoints backend:
<property name="gcm.api.key" value="your-api-key-here"/>
This way, inside the Android client and MessagingEndpoint the code will automatically get the api key (in the endpoint it will be the line Sender sender = new Sender(API_KEY); for example, which will just retrieve it for you).
Run the sample gcm android project and it should work. Send a push notification with the API's explorer you deployed.
BIG NOTE: when you are ready to use the sample code in your own app make sure the RegistrationIntentService is in the root of your package or it won't work! Took a while to figure that out... Not sure if it is a bug or what.

Categories

Resources