How to handle Google Services API checkings for Firebase Cloud Messaging?
<p>I can't seem to find a way to make the Google Services API checkings work correctly for FCM.</p>

<p>The use case is the following:</p>

<p>The Google Play services app is disabled (<em>In emulator: Settings>apps>Google Play Services>Disabled</em>). The application starts. It runs the check and sees Google Play Services is disabled. As it is a <code>userResovlableError</code>, it calls the <code>getErrorDialog</code> which in turn shows the Google Play Services config screen to enable the services.</p>

<p>If the user <strong>cancels</strong> at any moment, it is fine, the app sends a toast and finishes. If the user <strong>enables</strong> the Google Play Services and hits back from the configuration screen, it is captured by the app in the <code>onActivityResult</code>.</p>

<p><strong><em>Note</strong>: Most postings say that result should be <code>Activity.RESULT_OK</code>. This turned out to be wrong, so instead of checking the result status, I re-query the <code>GoogleApiAvailability</code> instance to see if it is now enabled.</em></p>

<p>After checking that the services are enabled, my assumption was that everything should be fine. But messages sent from the FCM server just don't reach the app.</p>

<p>My impression is that, as the app is executing from <code>onResume</code> after enabling the Google Apps Services, the registration of the device with the FCM server is not happening.</p>

<p>To overcome this, I thought of deleting the <code>FirebaseInstanceId</code> which seems to be something that should reset everything. The <code>deleteInstanceId</code> method has to be called from a different thread than the main one. </p>

<p>I have tried both, calling this method in a Runnable from a separate Thread, and the current approach of starting a ServiceIntent to do the deleting. In both cases, I get an <code>NullPointer</code> exception that crashes the Google Services App.</p>

<p>My code is posted below. Any idea on what could be the problem? Or is there any other working solution to correctly do this checking and error handling?</p>

<pre><code>import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;

import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;



public class MainTestActivity extends AppCompatActivity {

    private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 1972;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main_test);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

    }


    private boolean hasGooglePlayServices() {

        boolean rtn = false;
        GoogleApiAvailability instance = GoogleApiAvailability.getInstance();
        int apiStatus = instance.isGooglePlayServicesAvailable(this);
        if (apiStatus != ConnectionResult.SUCCESS) {
            if (instance.isUserResolvableError(apiStatus)) {
                instance.getErrorDialog(this, apiStatus, PLAY_SERVICES_RESOLUTION_REQUEST, new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        finishNotSupported();
                    }
                }).show();
                rtn = true;
            }else {
                rtn = false;
            }
        }else{
            rtn =  true;
        }
        return rtn;
    }




    @Override
    protected void onResume() {
        super.onResume();
        if (!hasGooglePlayServices()) {
            finishNotSupported();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == PLAY_SERVICES_RESOLUTION_REQUEST){

            int apiStatus = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this);
            if (apiStatus != ConnectionResult.SUCCESS) {
                finishNotSupported();
            }else{
                Intent i = new Intent(this, DeleteTokenService.class);
                this.startService(i);
            }
        }
    }

    private void finishNotSupported(){
        Toast.makeText(this, "Esta app no está soportada por este dispositivo.", Toast.LENGTH_LONG).show();
        finish();
    }
}
</code></pre>

<p>This is the service doing the delete:</p>

<pre><code>public class DeleteTokenService extends IntentService {

    public static final String TAG = DeleteTokenService.class.getSimpleName();


    public DeleteTokenService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        try {
            Thread.sleep(10000);
            FirebaseInstanceId.getInstance().deleteInstanceId();
            FirebaseInstanceId.getInstance().getToken();
        }catch(IOException e){
            Log.e(TAG,"Exceptin resetting token.",e);

        }catch(Exception e){
            Log.e(TAG,"Exceptin resetting token.",e);
        }
    }
}
</code></pre>

<p>There are two exceptions, the first one is the one crashing Google Services App. The second one is just the timeout because it never recieves a new FirebaseInstanceId.</p>

<p>This is the Stacktrace:</p>

<pre><code>12326-12494/? E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
                                                   Process: com.google.android.gms.persistent, PID: 12326
                                                   java.lang.RuntimeException: An error occurred while executing doInBackground()
                                                       at android.os.AsyncTask$3.done(AsyncTask.java:309)
                                                       at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                                                       at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                                                       at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                                                       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                       at java.lang.Thread.run(Thread.java:818)
                                                    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.Messenger.send(android.os.Message)' on a null object reference
                                                       at opu.a(:com.google.android.gms:594)
                                                       at oom.doInBackground(:com.google.android.gms:3481)
                                                       at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                       at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                                                       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                                                       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                                                       at java.lang.Thread.run(Thread.java:818) 
10-06 11:38:05.355 12269-12429/? E/DeleteTokenService: Exceptin resetting token.
                                                       java.io.IOException: TIMEOUT
                                                           at com.google.firebase.iid.zzf.zzb(Unknown Source)
                                                           at com.google.firebase.iid.zzf.zza(Unknown Source)
                                                           at com.google.firebase.iid.zzd.zzb(Unknown Source)
                                                           at com.google.firebase.iid.FirebaseInstanceId.deleteInstanceId(Unknown Source)
                                                           at com.xxxxxxxxxxx.androidtestapp.DeleteTokenService.onHandleIntent(DeleteTokenService.java:28)
                                                           at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                           at android.os.Looper.loop(Looper.java:148)
                                                           at android.os.HandlerThread.run(HandlerThread.java:61)
</code></pre>