GooglePlayServicesUtil.getErrorDialog es nulo


Estoy usando ACRA ( arca.ch ) para generar informes de errores automáticos.

Acabo de lanzar una nueva versión de mi aplicación utilizando Google Maps Android API v2. Estoy recibiendo un error reportado por los usuarios de EeePad y Transformer Pad al intentar mostrar el diálogo devuelto por GooglePlayServicesUtil.getErrorDialog. ¿Alguien sabe por qué podría pasar esto?

Aquí está el código relevante y el Logcat según lo informado por acra:

Mientras llama a esto línea:

int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resultCode != ConnectionResult.SUCCESS)
{
        //The dialog that comes back is null (probably due to the logcat message)
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, 69);
        //So when I call the next line, the app crashes with a NullPointerException
        dialog.show();
}
...

Logcat:

12-18 04:21:04.531 W/GooglePlayServicesUtil( 3977): Google Play Store signature invalid.
12-18 04:21:04.551 E/GooglePlayServicesUtil( 3977): Google Play services is invalid. Cannot recover.

Gracias de antemano por cualquier ayuda que pueda proporcionar.

Actualización

El problema no ha sido resuelto por Google todavía y voy a actualizar esta pregunta una vez que escuche algo (ver respuesta de CommonsWare para el enlace de informe de error de Google). Mientras tanto, si te encuentras con este problema y no quieres que tu aplicación se bloquee, esto es lo que estoy haciendo por el momento:

public void checkGooglePlayServicesAvailability()
{
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if(resultCode != ConnectionResult.SUCCESS)
    {
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, 69);
        if(dialog != null)
        {
            dialog.show();                
        }
        else
        {
            showOkDialogWithText(this, "Something went wrong. Please make sure that you have the Play Store installed and that you are connected to the internet. Contact developer with details if this persists.");
        }
    }

    Log.d("GooglePlayServicesUtil Check", "Result is: " + resultCode);
}

public static void showOkDialogWithText(Context context, String messageText)
{
    Builder builder = new AlertDialog.Builder(context);
    builder.setMessage(messageText);
    builder.setCancelable(true);
    builder.setPositiveButton("OK", null);
    AlertDialog dialog = builder.create();
    dialog.show();
}
Author: DiscDev, 2012-12-18

4 answers

Google sugiere (también en docs) llamar a getErrorDialog() si el código de resultado es SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED o SERVICE_DISABLED. Así que puede ser que el último código de estado posible (SERVICE_INVALID) es lo que está causando problemas.

Estoy usando el siguiente código y hasta ahora parece funcionar bien (probando en emulador, plataforma 2.3.3):

int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(activity.getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS) {
    activity.selectMap();
} else if (resultCode == ConnectionResult.SERVICE_MISSING ||
           resultCode == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED ||
           resultCode == ConnectionResult.SERVICE_DISABLED) {
    Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, activity, 1);
    dialog.show();
}
 37
Author: Nevermore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-31 12:57:19

Parece que tienes que comprobar con isUserRecoverableError antes de intentar mostrar el diálogo.

  int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
  if (status != ConnectionResult.SUCCESS) {
    if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
      GooglePlayServicesUtil.getErrorDialog(status, this, 
      REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
    } else {
      Toast.makeText(this, "This device is not supported.", 
          Toast.LENGTH_LONG).show();
      finish();
    }
  }
 22
Author: Rahim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-04 08:40:30

Basado en el código de Rahim, agrego la capacidad de evitar que el usuario desestime el diálogo de Google Play Services (presionando el botón atrás) y continúe usando la aplicación sin Google Play Services instalado:

private void checkGooglePlayServicesAvailable() {
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (status != ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, 0);
            dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialogInterface) {
                    MainActivity.this.finish();
                }
            });
            dialog.show();
        } else {
            Toast.makeText(this, "This device is not supported.", Toast.LENGTH_LONG).show();
            finish();
        }
    }
}
 8
Author: Daniele B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-26 04:52:06

Una actualización de la respuesta de @Nevermore , ya que GooglePlayServicesUtil los métodos están en desuso a favor de GoogleApiAvailability:

GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(activity.getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS) {
    activity.selectMap();
} else if (resultCode == ConnectionResult.SERVICE_MISSING ||
           resultCode == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED ||
           resultCode == ConnectionResult.SERVICE_DISABLED) {
    Dialog dialog = googleApiAvailability.getErrorDialog(activity, resultCode, 1);
    dialog.show();
}

Tenga en cuenta que el orden de los dos primeros parámetros en getErrorDialog() se ha cambiado en la implementación GoogleApiAvailability.

 0
Author: DaveAlden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:16:54