I am trying to understand the code behind Google's GCM quickstart example. Specifically, I don't understand how the code checks whether registration is already done.
MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
if (checkPlayServices()) {
// Start IntentService to register this application with GCM.
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
RegistrationIntentService:
#Override
protected void onHandleIntent(Intent intent)
{
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
// [START register_for_gcm]
// Initially this call goes out to the network to retrieve the token, subsequent calls
// are local.
// [START get_token]
InstanceID instanceID = InstanceID.getInstance(this);
// R.string.gcm_defaultSenderId (the Sender ID) is typically derived from google-services.json.
// See https://developers.google.com/cloud-messaging/android/start for details on this file.
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// [END get_token]
Log.i(TAG, "GCM Registration Token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token);
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
sharedPreferences.edit().putBoolean(AppSharedPreferences.SENT_TOKEN_TO_SERVER, true).apply();
// [END register_for_gcm]
} catch (Exception 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(AppSharedPreferences.SENT_TOKEN_TO_SERVER, false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(QuickstartPreferences.REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
In RegistrationIntentService, the comments say that initially the call goes to retrieve the token, but subsequent calls are local. Does this mean that it will simply check to see if the app already has the token and not make the call anymore? I really don't understand this portion and I don't see anywhere in this example code where it checks for the existence of the token.
For that logic, you can refer to my working sample code:
public class MainActivity extends AppCompatActivity {
private final Context mContext = this;
private final String SENDER_ID = "425...."; // Project Number at https://console.developers.google.com/project/....
private final String SHARD_PREF = "com.example.gcmclient_preferences";
private final String GCM_TOKEN = "gcmtoken";
private final String LOG_TAG = "GCM";
public static TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences appPrefs = mContext.getSharedPreferences(SHARD_PREF, Context.MODE_PRIVATE);
String token = appPrefs.getString(GCM_TOKEN, "");
if (token.isEmpty()) {
try {
getGCMToken();
} catch (Exception e) {
e.printStackTrace();
}
}
mTextView = (TextView) findViewById(R.id.textView);
}
private void getGCMToken() {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
InstanceID instanceID = InstanceID.getInstance(mContext);
String token = instanceID.getToken(SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
if (token != null && !token.isEmpty()) {
SharedPreferences appPrefs = mContext.getSharedPreferences(SHARD_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = appPrefs.edit();
prefsEditor.putString(GCM_TOKEN, token);
prefsEditor.apply();
}
Log.i(LOG_TAG, token);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
}
You can read my answer at the following for more information
Adding Google Cloud Messagin (GCM) for Android - Registration process
Hope this helps!
InstanceID which is part of the Google Play Services library will check if there is a cached token and return that when getToken is called. If there is no cached token then it will go out to the network to retrieve a new token and return that.
Thus your application has to handle the possibility of that calling InstanceID.getToken will result in a network call. Hence the reason it is called in an IntentService.
Related
I had UrbanAirship implemented in version 1 of the app.
Now I extended FirebaseMessagingService in version 2 of the app.
I am not getting a call in onNewToken() to be able to send the token to my servers.
My boilerplate code looks like
AndroidManifest.xml
<service
android:name=".services.fcm.PushMessageReceiver"
android:enabled="true"
android:exported="true"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
and Receiver
public class PushMessageReceiver extends FirebaseMessagingService { ...
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
...
}
#Override
public void onNewToken(String s) {
Log.i(Config.LOGTAG, "######**** new token for fcm called");
Context ctx =ApplicationCustom.getContext();
SharedPreferences preferences = ctx.getSharedPreferences(Config.SHARED_PREFERENCES, Context.MODE_PRIVATE);
preferences.edit().putString(Config.SHARED_PREFS_DEVICE_TOKEN, s).apply();
Intent intent = new Intent(this, XmppConnectionService.class);
intent.setAction(XmppConnectionService.ACTION_FCM_TOKEN_REFRESH);
intent.putExtra("token", s);
startService(intent);
pushToServer();
}
public static void getToken() {
Log.i(Config.LOGTAG, "######**** get token for fcm called");
try {
Log.i(Config.LOGTAG, "######**** delete token for fcm called");
FirebaseInstanceId.getInstance().deleteInstanceId();
FirebaseInstanceId.getInstance().getInstanceId();
} catch (IOException e) {
e.printStackTrace();
Log.w(Config.LOGTAG, "######**** delete InstanceId failed", e);
}
FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(task
-> {
if (!task.isSuccessful()) {
Log.w(Config.LOGTAG, "getInstanceId failed", task.getException());
return;
}
Log.i(Config.LOGTAG, "######**** getInstanceId successful");
// Get new Instance ID token
String token = task.getResult().getToken();
Context ctx = ApplicationCustom.getContext();
SharedPreferences preferences = ctx.getSharedPreferences(Config.SHARED_PREFERENCES, Context.MODE_PRIVATE);
preferences.edit().putString(Config.SHARED_PREFS_DEVICE_TOKEN, token).apply();
pushToServer();
});
}
public void pushToServer(){
// Logic to push token to a server reading from preferences
}
}
Observations:
1) onNewToken never gets called for apps that are being updated.
2) new installs get a token
3) after I added a call to FirebaseInstanceId.getInstance().deleteInstanceId()
OnComplete does not get called either.
4) A call to getToken(senderId, "FCM") on real phones (not emulators) invariably results in
java.io.IOException: TOO_MANY_REGISTRATIONS
at com.google.firebase.iid.zzr.zza(Unknown Source:66)
at com.google.firebase.iid.zzr.zza(Unknown Source:79)
at com.google.firebase.iid.zzu.then(Unknown Source:4)
at com.google.android.gms.tasks.zzd.run(Unknown Source:5)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
how do I fix observation 1. Is it because the token has already been delivered to UrbanAirship that onNewToken does not get called?
Fyi getToken is called in a service onCreate() method.
implementation 'com.google.firebase:firebase-messaging:17.3.4'
you can get fcm token by this:-
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (task.isSuccessful()) {
String firebaseToken = task.getResult().getToken();
} else {
getFirebaseToken();
}
}
});
That's okay if your onNewToken() is not called. You can get the latest token already made by firebase for your device. onNewToken() is called on specific occasions.
The registration token may change when:
-The app deletes Instance ID
-The app is restored on a new device
-The user uninstalls/reinstall the app
-The user clears app data.
Do read the firebase documentation :
https://firebase.google.com/docs/cloud-messaging/android/client#retrieve-the-current-registration-token
And for your second query, deleteInstanceId is a blocking call, so you will have to do it in a background thread. like this,
new Thread(new Runnable() {
#Override
public void run() {
try {
FirebaseInstanceId.getInstance().deleteInstanceId();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
Some time onTokenRefresh() method call with some delay and it will generate token when new install happen that how its behave their for we need to implement functionality like below to overcome those issue maintain new user login also
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private String TAG = getClass().getName();
public static final String TOKEN_BROADCAST = "myfcmtokenbroadcast";
#Override
public void onTokenRefresh() {
//For registration of token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//To displaying token on logcat
Log.d("TOKEN: ", refreshedToken);
//calling the method store token and passing token
getApplicationContext().sendBroadcast(new Intent(TOKEN_BROADCAST));
storeToken(refreshedToken);
}
private void storeToken(String token) {
//we will save the token in sharedpreferences later
SharedPrefManager.getInstance(getApplicationContext()).saveDeviceToken(token);
}
}
In your onCreate method in MainActivity class call this methord
private void registerFCMToken(){
registerReceiver(broadcastReceiver, new IntentFilter(MyFirebaseInstanceIDService.TOKEN_BROADCAST));
final boolean isRegisterFcm = preferences.getBoolean("IS_REGISTER_FCM", false);
// FCM token Register when onTokenRefresh method call
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String fcmToken = SharedPrefManager.getInstance(MainActivity.this).getDeviceToken();
if(!isRegisterFcm) {
RegisterFcmTokenRequest request = new RegisterFcmTokenRequest();
request.setFcmtoken(fcmToken);
performRegisterFcmRequest(request);
}
}
};
// FCM token Register when new user Login
if(SharedPrefManager.getInstance(this).getDeviceToken() != null && !isRegisterFcm) {
String fcmToken = SharedPrefManager.getInstance(MainActivity.this).getDeviceToken();
RegisterFcmTokenRequest request = new RegisterFcmTokenRequest();
request.setFcmtoken(fcmToken);
performRegisterFcmRequest(request);
}
}
In the onDestroy method
unregisterReceiver(broadcastReceiver);
This class maintains the Shredpreferance for FCM token
public class SharedPrefManager {
private static final String SHARED_PREF_NAME = "FCMSharedPref";
private static final String TAG_TOKEN = "tagtoken";
private static SharedPrefManager mInstance;
private static Context mCtx;
private SharedPrefManager(Context context) {
mCtx = context;
}
public static synchronized SharedPrefManager getInstance(Context context) {
if (mInstance == null) {
mInstance = new SharedPrefManager(context);
}
return mInstance;
}
//this method will save the device token to shared preferences
public boolean saveDeviceToken(String token){
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(TAG_TOKEN, token);
editor.apply();
return true;
}
//this method will fetch the device token from shared preferences
public String getDeviceToken(){
SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
return sharedPreferences.getString(TAG_TOKEN, null);
}
}
I want to send push notifications to my android app.The problem is that when i run the app at my phone i can't get the reg id.But when i run it on my emulator runs perfectly and gets the regid.Any ideas?In case needed here is the code
MyFirebaseInstanceID.java
#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.apply();
}
As according to Firebase FirebaseInstanceIdService is deprecated now.
You should try this to get Token !
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener( MyActivity.this, new OnSuccessListener<InstanceIdResult>() {
#Override
public void onSuccess(InstanceIdResult instanceIdResult) {
String newToken = instanceIdResult.getToken();
}
});
I'm able to receive a GCM registration id (for push notifications) thanks to this google guide and store the reg.id in a database and without authentication everything works fine.
I use web api 2, oauth 2 authentication and account manager.
1) User sign in to application, App creates an account for the user.
- Or if an account exists auto sign the user in.
2) App gets auth token, if expired retrieves it via Volley string request
3) App checks UserData of Account Manager if reg. id received before. If not App requests an reg. id from GCM and posts it to the server via Volley(AuthToken is required here) and App sets a userdata in account that reg. id has received.
With the above flow of my app which is exists only in my mind at the moment, I've some questions.
First, how can I get auth token first and move to the step 3 which is IntentService according to the Guide.
Second, let's say we managed to do first question. What happens if user login to his account from a different device? Should I update his reg. id for his new device. But what if this device was temporary and he returns to use his permanent device? Notifications will be sent to tempopary device because it was the last device he signed in!
I'm really confused and will be apreciated for anyone who lights my way. Thanks.
Edit
Instead of following Google's guide (instead of using IntentService) is it possible getting both Authorization Token and Registration Id(Token) in a AsyncTask?
Just as answer for 2nd part of question.
Relation between user and his regId should be 1 to n. So 1 user can have multiple devices, and by this multiple regId. And when you would like to send message to this user - you should send multiple messages (1 to every device). Other possible solution is using lately introduced Device Group Messaging, and IMO is preferable way for it.
Thanks for your answers, it only works if I use two async tasks and here is my solution. Any criticism or recommendation will be welcome.
I create a TokenCheckerActivity and put it between login activity and main activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_token_checker);
webApiUri = "url Here";
tokenContext = this;
accountManager = accountManager.get(tokenContext);
PpSharedPreferences ppSharedPreferences = new PpSharedPreferences(tokenContext);
ppAuthenticator = new PpAuthenticator(tokenContext);
account = ppAuthenticator.getCurrentAccount(ppSharedPreferences.getUsername());
new GetAuthorizationToken().execute(ppSharedPreferences.getUsername());
}
Async Tasks
/**
* Gets the authorization token and checks if GCM registration id received.
* Gets reg is if not exists.
*/
private class GetAuthorizationToken extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... params) {
String username = params[0];
String mAuthToken = ppAuthenticator.getPpAuthToken(username);
return mAuthToken;
}
#Override
protected void onPostExecute(String authToken) {
if(!TextUtils.isEmpty(authToken))
{
final String gcmTokenSent = accountManager.getUserData(account, AccountGeneral.GCM_REGISTRATION_ID);
if (gcmTokenSent == null || !gcmTokenSent.equals("true")) {
new GetGcmRegistrationToken().execute(authToken);
} else {
// We have the Gcm Registration Id continue to the main activity
Intent intent = new Intent(tokenContext, MainActivity.class);
startActivity(intent);
finish();
}
}
}
}
private class GetGcmRegistrationToken extends AsyncTask<String,Void,PpTokens>{
#Override
protected PpTokens doInBackground(String... params) {
PpTokens tokens = new PpTokens();
tokens.setAuthToken(params[0]);
try {
if (checkPlayServices()) {
InstanceID instanceID = InstanceID.getInstance(tokenContext);
String regToken = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
tokens.setRegToken(regToken);
}
} catch (IOException e) {
e.printStackTrace();
}
return tokens;
}
#Override
protected void onPostExecute(PpTokens tokens) {
if (!TextUtils.isEmpty(tokens.getRegToken()))
{
sendRegistrationToServer(tokens.getRegToken(),tokens.getAuthToken());
}
}
}
private class PpTokens
{
private String authToken;
private String regToken;
public String getAuthToken() {
return authToken;
}
public void setAuthToken(String authToken) {
this.authToken = authToken;
}
public String getRegToken() {
return regToken;
}
public void setRegToken(String regToken) {
this.regToken = regToken;
}
}
Send reg id to server
private void sendRegistrationToServer(String regToken, final String authToken) {
final String tag_json_obj = "json_obj_req";
String url = webApiUri + "?gcmRegistrationToken=" + regToken;
JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.POST, url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d("Name for Reg Token:", response.getString("Name"));
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
accountManager.setUserData(account, AccountGeneral.GCM_REGISTRATION_ID, "true");
Intent intent = new Intent(tokenContext, MainActivity.class);
startActivity(intent);
finish();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
String errorMessage = JsonErrorMessageHandler.onErrorResponse(error);
accountManager.setUserData(acc, AccountGeneral.GCM_REGISTRATION_ID, "false");
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", "Bearer " + authToken);
return headers;
}
};
int socketTimeout = 5000;
int maxRetries = 3;
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, maxRetries, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
objectRequest.setRetryPolicy(policy);
// Adding request to request queue
AppController.getInstance().addToRequestQueue(objectRequest, tag_json_obj);
}
I have an activity that call an Otto Event called LoadAuthenticateEvent this event then goes to my ClientManager.java where the following code is:
#Subscribe
public void onLoadAuthenticateEvent(LoadAuthenticateEvent loadAuthenticateEvent) {
// GCM cannot register on the main thread
String deviceID = "";
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
String differentId = GCMRegistrationUtil.registerDevice(mContext);
Log.d(TAG, "Device Id: " + differentId);
}
});
thread.start();
String email = loadAuthenticateEvent.getEmail();
String password = loadAuthenticateEvent.getPassword();
Callback<User> callback = new Callback<User>() {
#Override
public void success(User user, Response response) {
sClient.setOrganization(user.getRole().getOrganization().getSubdomain());
mBus.post(new LoadedMeEvent(user));
}
#Override
public void failure(RetrofitError retrofitError) {
mBus.post(new LoadedErrorEvent(retrofitError));
}
};
sClient.authenticate(email, password, deviceID, PLATFORM, callback);
}
The problem is that the server needs the deviceID, but GCM requires that a call be asynchronous and not on the main thread, how should I go about implementing this where I can properly get the deviceID and then pass it to sClient? Since it is possible that deviceID might be empty.
The best way is to contact GCM is through services.
Creates a IntentService to catch the intent released from the
activity
onHandleIntent(Intent intent)
Device sends service request GCM and receives the tokenID.
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Implement this method to send any registration to your app's servers.
sendRegistrationToserver(token)
Notify UI that registrationComplete
Intent registrationComplete = new Intent(GcmUtils.REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
(Optional) Subscribe to topic channels
private void subscribeTopics(String token, ArrayList topics_gcm)throws IOException {
for (String topic : topics_gcm) {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
pubSub.subscribe(token, topic, null);
}
}
Full IntentService:
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
public RegistrationIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
ArrayList<String> topics_gcm = intent.getStringArrayListExtra("topics_gcm");
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
// In the (unlikely) event that multiple refresh operations occur simultaneously,
// ensure that they are processed sequentially.
synchronized (TAG) {
// Initially this call goes out to the network to retrieve the token, subsequent calls
// are local.
// [START get_token]
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// [END get_token]
Log.i(TAG, "GCM Registration Token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
//sendRegistrationToServer(token);
// TODO: Subscribe to topic channels
//subscribeTopics(token, topics_gcm);
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
sharedPreferences.edit().putBoolean(GcmUtils.SENT_TOKEN_TO_SERVER, true).apply();
// [END register_for_gcm]
}
} catch (Exception 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(GcmUtils.SENT_TOKEN_TO_SERVER, false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(GcmUtils.REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
/**
* Persist registration to third-party servers.
*
* Modify this method to associate the user's GCM registration token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
/**
* Subscribe to any GCM topics of interest, as defined by the TOPICS constant.
*
* #param token GCM token
* #throws IOException if unable to reach the GCM PubSub service
*/
// [START subscribe_topics]
private void subscribeTopics(String token, ArrayList<String> topics_gcm) throws IOException {
for (String topic : topics_gcm) {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
pubSub.subscribe(token, topic, null);
}
}
// [END subscribe_topics]
}
Start IntentService from any context: activity, service....
Intent intent = new Intent(getContext(), egistrationIntentService.class);
intent.putCharSequenceArrayListExtra("topics_gcm", topcics_gcm);
getContext().startService(intent);
If you want to make the sClient call on the UI thread (not sure if that is a good solution for you), use a Handler to call it once your GCM registration ID is returned by GCM.
The accepted answer here has sample code to help you out.
I ended up using an AsyncTask for this specific thing like so:
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String regId = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(mContext);
}
regId = gcm.register(GCMConfig.getSenderId());
storeRegistrationId(mContext, regId);
} catch (IOException e) {
Log.e(TAG, "Error: ", e);
e.printStackTrace();
}
Log.d(TAG, "GCM AsyncTask completed");
return regId;
}
#Override
protected void onPostExecute(String result) {
// Get the message
Log.d(TAG, "Registered with GCM Result: " + result);
}
}.execute(null, null, null);
}
This worked really well inside the GCMRegistration class
I am using the sameple code from developer website but get error in compiling.
http://developer.android.com/google/gcm/gs.html
copying the code below
private void registerBackground() {
new AsyncTask() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
regid = gcm.register(GCM_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.
// For this demo: we don't need to send it because the device
// will send upstream messages to a server that will echo back
// the message using the 'from' address in the message.
// Save the regid for future use - no need to register again.
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regid);
editor.commit();
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
// Once registration is done, display the registration status
// string in the Activity's UI.
#Override
protected void onPostExecute(String msg) {
mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
}
I get the error in compiling stating "Asynctask is a raw type. Reference to generic type should be paramterised.
You have not declared generic type parameters.
change
new AsyncTask() {
to
new AsyncTask<Void,Void,String>() {
and Also,
execute(null, null, null);
can be changed to
execute();