35

Tôi đang sử dụng ACRA (arca.ch) để tạo báo cáo lỗi tự động.GooglePlayServicesUtil.getErrorDialog is null

Tôi vừa phát hành phiên bản mới của ứng dụng của mình bằng API Android của Google Maps phiên bản v2. Tôi nhận được thông báo lỗi do người dùng EEEPad và Transformer Pad báo cáo khi cố gắng hiển thị hộp thoại được trả về bởi GooglePlayServicesUtil.getErrorDialog. Có ai biết tại sao điều này có thể xảy ra?

Đây là mã có liên quan và Logcat theo báo cáo của Acra:

Trong khi gọi dòng này:

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. 

Cảm ơn trước sự giúp đỡ nào bạn có thể cung cấp .

Cập nhật

Vấn đề chưa được giải quyết bằng google chưa và tôi sẽ cập nhật câu hỏi này một lần tôi nghe thấy bất cứ điều gì (xem câu trả lời CommonsWare cho các liên kết báo cáo lỗi của Google). Trong lúc này nếu bạn gặp vấn đề này và không muốn ứng dụng của bạn sụp đổ, đây là những gì tôi đang làm cho thời gian được:

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

Hi DiscDev, Khi tôi cố gắng sử dụng showOkDialogWithText() nó là lỗi khi nói rằng "không thể tạo bộ xử lý bên trong luồng mà không được gọi là looper.prepare()" tại sao nó cố gắng chạy trên chuỗi công nhân thay vì chuỗi giao diện người dùng? –

Trả lời

37

Google suggests (cũng trong docs) gọi getErrorDialog() nếu kết quả mã là SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED hoặc SERVICE_DISABLED. Vì vậy, có thể là mã trạng thái cuối cùng có thể (SERVICE_INVALID) là nguyên nhân gây ra sự cố.

Tôi đang sử dụng đoạn mã sau và cho đến nay nó dường như làm việc ok (thử nghiệm trong giả lập, nền tảng 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

Tôi vừa thử nghiệm 'getErrorDialog' với' ConnectionResult.SERVICE_INVALID' và nhận 'null' trên Nexus S. Vì vậy, tôi cho rằng câu trả lời này là chính xác. –

+1

Vì vậy, bạn đang bỏ qua tất cả SERVICE_INVALID? Điều này có nên được xử lý không? – ComputerEngineer88

+0

Bạn nên sử dụng ** GoogleApiAvailability **, chứ không phải ** GooglePlayServicesUtil **. –

22

Dường như bạn phải kiểm tra với isUserRecoverableError trước khi cố gắng để hiển thị hộp thoại.

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 (trạng thái) thanh lịch hơn là liệt kê tất cả các trạng thái có thể. –

+0

+1 - Tôi đang sử dụng điều này ngay bây giờ, nhưng sau khi đọc câu hỏi này, tôi nghĩ rằng tôi cũng sẽ kiểm tra null, vì nó là một kiểm tra dễ dàng để thêm. – eselk

8

Dựa trên mã Rahim, tôi thêm khả năng ngăn chặn người sử dụng để bỏ qua Google Play thoại Dịch vụ (bằng cách nhấn nút quay lại) và tiếp tục sử dụng các ứng dụng mà không cần Google Play Services được cài đặt:

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 cảm ơn vì đã chia sẻ giải pháp hoàn chỉnh hơn này. –

+0

Ngoài ra bổ sung tốt. –

0

Bản cập nhật của câu trả lời bằng cách @Nevermore, vì GooglePlayServicesUtil phương pháp này phản đối ủng hộ 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(); 
} 

Lưu ý thứ tự của hai tham số đầu tiên trong getErrorDialog() đã được chuyển xung quanh trong việc thực hiện GoogleApiAvailability.

Các vấn đề liên quan