Unregister a device from GCM using registration Id

2019-01-17 16:43发布

问题:

I have a list of GCM registered users and their corresponding registration Ids in a database table, and I actually want to unregister a user whenever he/she is deleted from the table. I found a lot of examples here in Stackoverflow, but most of them are based on the old GCMRegistrar API which is now deprecated. I'm using GoogleCloudMessaging API and registering a user by following method:

private void registerUser(){
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(getBaseContext());
        String regId = "";
        try {
            regId = gcm.register(getString(R.string.project_number));
            Log.i("registrationId", regId);
        } 
        catch (IOException e) {
            Log.i("Registration Error", e.getMessage());
        }
}

I have an administrator app, which acts as a 3rd-party application server, since it pushes notifications to all users. I want to unregister a specific user from this administrator app with following method:

private void unRegister(String regId) {

        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(getBaseContext());
        try {
            gcm.unregister();
        } 
        catch (IOException e) {     
        System.out.println("Error Message: " + e.getMessage());
        }

   }

But it confuses me that unregister() method does not take registration Id as an argument, which makes it impossible to unregister a specific device. Is there any way to unregister a specific device from GCM by registration Id ?.

回答1:

This method does the trick:

gcm.unregister();

However, gcm.unregister() is now deprecated, hence, you must use one of these:

InstanceID.deleteToken() or InstanceID.deleteInstanceID().

These methods take the following parameters:

public void deleteToken (String authorizedEntity, String scope)

Being authorized entity the entity that you want to remove...

// THE FOLLOWING EXPLANATION IS ONLY FOR "UNREGISTER"

So, based on your comment:

But it confuses me that unregister() method does not take registration Id as an argument, which makes it impossible to unregister a specific device.

That's because you are expecting it to work in a way that it doesn't. It seems like you want to be able to make an http request passing a parameter to uregister(e.g. "http://www.gcmserver.com?unregisterid=xxxx"), and that's not the way it works, this is the way it works based on Google's Documentation:

How unregistration works

An application can be automatically unregistered after it is uninstalled from the device. However, this process does not happens right away, as Android does not provide an uninstall callback. What happens in this scenario is as follows:

The end user uninstalls the application.

The 3rd-party server sends a message to GCM server.

The GCM server sends the message to the device.

The GCM client receives the message and queries Package Manager about whether there are broadcast receivers configured to receive it, which returns false.

The GCM client informs the GCM server that the application was uninstalled.

The GCM server marks the registration ID for deletion.

The 3rd-party server sends a message to GCM.

The GCM returns a NotRegistered error message to the 3rd-party server.

The 3rd-party deletes the registration ID.

So, based on that, what the method gcm.unregister() actually does is marking that device for deletion(think of it as forcing the first steps of the process without actually uninstalling the app), letting the server know that it no longer needs to get notifications, also by not taking an "Id" as a parameter it means that it is referencing to that specific device.

Regards!



回答2:

unregister() is now deprecated:

https://developers.google.com/android/reference/com/google/android/gms/gcm/GoogleCloudMessaging.html#unregister()

Quoting the docs you should call:

Instead use InstanceID.deleteToken() or InstanceID.deleteInstanceID().