I'm developing an application that uses google maps and I encountered a weird problem when trying to launch my app on emulator - it (obviously) doesn't work and shows an error message "MyApp having trouble with Google Play services. Please try again".
To solve this problem, I decided to check the availability of Google Play Services (as recommended in this guide by Google https://developers.google.com/android/guides/setup). And.. it doesn't work as intended.
So, here's the code I use to check the availability of Google Play Services and the result code for the emulator is always SUCCESS, even though it doesn't have the desired version installed.
private fun checkPlayServices(): Boolean {
val apiAvailability = GoogleApiAvailability.getInstance()
val resultCode = apiAvailability.isGooglePlayServicesAvailable(activity)
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this.activity, resultCode, 9000)
.show()
} else {
Timber.tag("tag").e("This device is not supported.")
}
return false
}
return true
}
In logs I can clearly see the message
W/GooglePlayServicesUtil: Google Play services out of date. Requires 13400000 but found 13280022
And I cannot comprehend why Google says that there are google play services installed on a version without google play service
I expected this function to return some kind of error and show the correct dialog, but it just returns success for the emulator.
Though, if I run it on a version WITHOUT google API, it shows the error correctly about not having google play services completely.
So, my question is - is it a problem with emulator or API and will it misbehave like this on normal phones or this is just an emulator bug (feature)?
Related
I'm developing an android project and until today it was fine. It gets user data and creates a connection via websocket to server. I started the project to check something and it worked normally and 2 minutes later I started t again it stopped getting user location and it said there is a problem with google play sevices
W/GoogleApiManager: The service for com.google.android.gms.common.internal.service.zap is not available: ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null}
W/GooglePlayServicesUtil: com.example.airboxproject requires the Google Play Store, but it is missing.
W/GoogleApiManager: The service for com.google.android.gms.common.internal.service.zap is not available: ConnectionResult{statusCode=SERVICE_INVALID, resolution=null, message=null}
I wouldn't get this messages before but now it keeps producing these error and I don't know what to do. I deleted the emulator and uploaded a new one and now there is difference in it GUI. I have to submit this project in less than 48 hours and I'm having problems with it.
Edit: It shows some parts of the GUI as Android 2 even though it is Android 11
Create a new emulator from Android Studio and verify it has Google Play Installed. Tools > Device Manager > Create Device. Select a device which has the Google Play logo under the Play Store column.
And/or verify the correct emulator is selected next to the run button at the top of Android studio.
It is also best practice to check if the device supports Google Play Services.
Uncomment if (googleAPI.isUserResolvableError(result)) conditional for an automatic dialog to the user explaining the error
public static boolean isPlayServicesInstalled(Context context) {
GoogleApiAvailabilityLight googleAPI = GoogleApiAvailabilityLight.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(context);
//This call shows a dialog not controlled by the app (dialog text controlled by Firebase package)
// so do not show this as if self handled
// if(googleAPI.isUserResolvableError(result)) {
// Log.v(LOG_TAG, "Google Play Services are not installed");
// GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
// Objects.requireNonNull(googleApiAvailability.getErrorDialog(frag, result, 6)).show();
// }
return result == ConnectionResult.SUCCESS;
}
https://developers.google.com/android/reference/com/google/android/gms/common/GoogleApiAvailability
NOTE: I am not trying to update google play services in the emulator. I do not care that it is out of date. I mentioned it only to show that somehow logcat is reporting the actual build number, which I wish to access in the app.
Similar, but not the same as, How can I determine the version of Google Play services?
An app I'm developing using Android Studio 1.2.2 is experiencing a problem if the latest Google Play Services is not installed on the device, yet GoogleApiAvailability is not reporting a problem and so the code instructing the user to update is never called. If I manually tell the users to update play services in the play store with a manual link to https://play.google.com/store/apps/details?id=com.google.android.gms&hl=en, there is an update available, and the app functions correctly after they install it.
However I am unable to find a way to determine that the user needs to update via application code or the gradle build file.
In the gradle file I've specified: compile 'com.google.android.gms:play-services:7.5.0' and this is the latest version as far as I know. Android Studio does not indicate that I should update this line to a newer version.
The SDK manager reports the play services I have installed is "rev 25", and no update is available.
When I test in an emulator, the code works correctly, and in logcat I see the message: "W/GooglePlayServicesUtil: Google Play services out of date. Requires 7571000 but found 6774470". This is normal for the emulator since they haven't released new images yet, but it provides an interesting clue.
Is there a way to get this build number reported in item 3 above, programatically? If so, I could compare against that rather than using the isgooglePlayServicesAvailable method of GoogleApiAvailability -- which I'm already using, but is reporting success on devices that need an update.
I've managed to do a little digging and answer my own question. The following code will do what I (and perhaps others) want.
PackageInfo pi = getPackageManager().getPackageInfo("com.google.android.gms", 0);
if (pi.versionCode < VERSION_YOU_WANT)
{
// instruct user to update
}
What I've done is wrap this in the required exception handler and run it if the API check reports SUCCESS. If the version is too low I call the getErrorDialog just like when the API check fails, with ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED instead of the returned SUCCESS value.
Doing this may require you to update your minimum SDK target. For example both my phone(5.0.1) and tablet(4.2.2) report success from the API check, and going to the play store does not show an update for either one; However, the installed build on the table is 7895032 while on the phone it's 7895438.
This function will tell the user to update the GooglePlaServices if an update is available. You can start the registration process, if this function returns true
private boolean checkPlayServices()
{
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS)
{
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode))
GooglePlayServicesUtil.getErrorDialog(resultCode, this, 9000).show();
else
{
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
I'm trying to implement Google Play Services Library to my Android app. But there is an issue about isGooglePlayServicesAvailable function.
Although my play services is up to date, it returns 2 which means SERVICE_VERSION_UPDATE_REQUIRED according to documentation.
My code is below:
#Override
protected void onResume() {
super.onResume();
int statusCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(LoginSigninActivity.this);
if( statusCode != ConnectionResult.SUCCESS)
{
Log.e("statuscode",statusCode+"");
if(GooglePlayServicesUtil.isUserRecoverableError(statusCode))
{
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
statusCode,
LoginSigninActivity.this,
REQUEST_CODE_RECOVER_PLAY_SERVICES);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
errorDialog.show();
}
}
else
{
Toast.makeText(this, getString(R.string.toast_google_play_services_not_found),Toast.LENGTH_LONG).show();
}
}
}
Thanks in advance.
P.S. Error dialog is always shown.
No it should not.
Device with android 4.4.4 has play service version 5.0.89 where as devices with android L preview has play service version 5.2.08. This is reason why android studio ask you to update your play service version to 5.2.08. So, for now use
compile 'com.google.android.gms:play-services:5.0.89'
If you are using android L emulator, i think you should use 5.2.08.
And if you want to update your play service to 5.2 see this.
I also faced same problem. I used latest play services version: 5.+ to develop may app. But my device which has Kitkat uses play services version: 4.4.52. It always said SERVICE_VERSION_UPDATE_REQUIRED because i build an app which uses upper version of play service but device has lower version.
My suggestion is use lower play services version to develop your app or use device which uses upper version of play service.
I am trying to implement the google play services sign-in to my app.
I added libraries (Google-play-services lib, basegameutils lib).I have added the sign in button. The app is not crashing. Everything that I have done seems to be ok.
I signed the app with the keytool and export it, then install it to my phone. I added the SHA1 code to my test app on developers console. And added My app Id to my app.
But when I tap on the sign in button it say with a pop-up "this app won\'t work unless you update google play services". When tap on the "update" it seems the service is up to date.
Is this a problem with my device? Or else What can I try to solve that?
My device is Samsung Galaxy S3.
Update
I added this code :
private boolean checkIfMapsIsOk() {
int checkGooglePlayServices = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (checkGooglePlayServices != ConnectionResult.SUCCESS) {
GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, this, 1122).show();
Toast.makeText(getApplicationContext(), "err"+checkGooglePlayServices, Toast.LENGTH_SHORT).show();
return false;
} else {
Toast.makeText(getApplicationContext(), "ok", Toast.LENGTH_SHORT).show();
return true;
}
}
and the toast result is "err2". And I looked up for the error numbers from http://developer.android.com/reference/com/google/android/gms/common/ConnectionResult.html
It says on that site "public static final int SERVICE_VERSION_UPDATE_REQUIRED"
"The installed version of Google Play services is out of date. The calling activity should pass this error code to getErrorDialog(int, Activity, int) to get a localized error dialog that will resolve the error when shown.
Constant Value: 2 (0x00000002)"
So from this I think the reason for error is my device. But my device sees no updates. It is up to date. This is so strange.
I have an app that uses Google Maps. Since, with the new Api in Android, the map wont work if the user don't have the Google Maps app up to date, is there any way that my app can know the version that the user have installed? And... can my app know wich version is the last in Google Play?
the map wont work if the user don't have the Google Maps app up to date, is there any way that my app can know the version that the user have installed?
Your app does not care about the version of Google Maps. Your app cares about having the Play Services Framework installed.
My sample apps, such as this one, use an AbstractMapActivity that wraps up the details of checking for the Play Services Framework, in a call to readyToGo():
protected boolean readyToGo() {
int status=
GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (status == ConnectionResult.SUCCESS) {
return(true);
}
else if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
ErrorDialogFragment.newInstance(status)
.show(getSupportFragmentManager(),
TAG_ERROR_DIALOG_FRAGMENT);
}
else {
Toast.makeText(this, R.string.no_maps, Toast.LENGTH_LONG).show();
finish();
}
return(false);
}
This will return true if isGooglePlayServicesAvailable() itself returns true. Otherwise, if possible, it will display a dialog (there's an ErrorDialogFragment inner class) that will lead the user to install the Play Services Framework. Or, it will display a Toast for an unrecoverable problem (though production code should use something else, like a crouton).
GooglePlayServicesUtil has its own set of JavaDocs.