ACRA( arca.ch )を使用して自動エラーレポートを生成しています。
Google Maps Android API v2。を使用して、アプリの新しいバージョンをリリースしました。なぜこれが起こるのか知っていますか?
Acraによって報告される関連コードとLogcatは次のとおりです。
この行を呼び出している間:
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.
あなたが提供できる助けを事前に感謝します。
更新
この問題はまだグーグルによって解決されていません。何か質問があれば、この質問を更新します(GoogleバグレポートのリンクについてはCommonsWareの回答をご覧ください)。当面の間、この問題に遭遇し、アプリをクラッシュさせたくない場合は、当面の間、次のことを行います。
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();
}
Google suggests ( docs でも)結果コードがSERVICE_MISSING
、SERVICE_VERSION_UPDATE_REQUIRED
またはSERVICE_DISABLED
の場合、getErrorDialog()
を呼び出します。そのため、最後に発生した可能性のあるステータスコード(SERVICE_INVALID
)が問題の原因である可能性があります。
私は次のコードを使用していますが、これまでのところうまくいくようです(エミュレータ、プラットフォーム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();
}
ダイアログを表示する前にisUserRecoverableError
で確認する必要があるようです。
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();
}
}
Rahimのコードに基づいて、ユーザーが(戻るボタンを押すことで)Google Play Servicesダイアログを閉じ、Google Play Servicesがインストールされていない状態でアプリの使用を続行できないようにする機能を追加します。
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();
}
}
}
GooglePlayServicesUtil
メソッドの代わりにGoogleApiAvailability
が推奨されているため、 @ Nevermore による回答の更新:
_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();
}
_
GoogleApiAvailability
実装では、getErrorDialog()
の最初の2つのパラメーターの順序が入れ替わっていることに注意してください。