35

我正在使用ACRA(arca.ch)生成自動錯誤報告。GooglePlayServicesUtil.getErrorDialog爲空

我剛剛使用Google Maps Android API v2發佈了我的應用程序的新版本。當試圖顯示GooglePlayServicesUtil.getErrorDialog返回的對話框時,我收到EEEPad和Transformer Pad用戶報告的錯誤。有誰知道爲什麼會發生這種情況?

下面是相關的代碼和logcat中所報告的ACRA:

在呼籲這行:

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. 

預先感謝任何幫助,您可以提供。

更新

的問題還沒有被谷歌尚未解決,一旦我聽到什麼(見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(); 
} 
+0

嗨DiscDev,當我嘗試使用showOkDialogWithText()它拋出的錯誤說,「不能創建處理程序內部線程沒有調用looper.prepare()」爲什麼它試圖在工作線程而不是UI線程上運行? –

回答

37

谷歌suggests(也docs)如果結果調用getErrorDialog()代碼是SERVICE_MISSING,SERVICE_VERSION_UPDATE_REQUIREDSERVICE_DISABLED。所以最後可能的狀態碼(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(); 
} 
+0

我剛剛用'ConnectionResult.SERVICE_INVALID'測試了'getErrorDialog',並在我的Nexus S上得到了'null'。所以我想這個答案是正確的。 –

+1

那麼,你們一起忽略了SERVICE_INVALID?不應該這樣處理? – ComputerEngineer88

+0

應該使用** GoogleApiAvailability **,而不是** GooglePlayServicesUtil **。 –

22

好像你必須試圖顯示之前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(); 
    } 
    } 
+3

+1 - GooglePlayServicesUtil.isUserRecoverableError(status)比列舉所有可能的狀態更優雅。 –

+0

+1 - 我現在正在使用它,但在閱讀完這個問題後,我想我也會檢查null,因爲這是一個簡單的檢查來添加。 – eselk

8

基於拉希姆的代碼,我添加了防止用戶駁回谷歌播放服務對話框(通過點擊返回按鈕),繼續使用該應用,而無需谷歌播放安裝服務的能力:

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(); 
     } 
    } 
} 
+0

+1感謝您分享這個更完整的解決方案。 –

+0

好的額外添加。 –

0

通過@Nevermore答案的更新,因爲GooglePlayServicesUtil方法棄用,取而代之的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(); 
} 

請注意getErrorDialog()中前兩個參數的順序已在GoogleApiAvailability實施中切換。