When updated code containing a deprecated Android API call, it's relatively straightforward to code for each Android version. e.g.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mTonePlayer = new SoundPool.Builder().build();
} else {
mTonePlayer = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
}
But what if something is deprecated in the Google Play Services API? For example LocationServices.GeofencingAPI was recently deprecated and should be replaced by GeofencingClient.
This will depend on the target device running Google Play services version 11.0.0 and isn't necessarily dependent on the Android SDK. So how can I code for both?
e.g.
if (Google Play Services is below version 11.0.0) {
LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient etc
} else {
GeofencingClient gc = LocationServices.getGeofencingClient();
gc.removeGeofences(); etc
}
You can use the checkApiAvailability() method.
Pay attention since the method returns a task that asynchronously checks if specified APIs are available. If one or more aren't available, the task fails with an AvailabilityException.
Otherwise you can isGooglePlayServicesAvailable to verify that Google Play services is installed and enabled on this device, and that the version installed on this device is no older than the one required by this client.
Related
A trivial but annoying issue has come up in the last few days.
Previously my menu option which popped up a dialog to show the legal text for using Google Services was very full (if a little slow to load), but now it is null with no change to the code..
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode == ConnectionResult.SUCCESS) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("About");
builder.setMessage(apiAvailability.getOpenSourceSoftwareLicenseInfo(this));
builder.setPositiveButton("OK", null);
builder.show();
}
Is this a problem common to others, i.e. a new bug introduced by a Google update or some other possibility?
according to https://code.google.com/p/gmaps-api-issues/issues/detail?id=9813
It appears that google changed the file name it was looking for from oss_notice to third_party_licenses. They basically broke getting the license info for any play services implementation below 9.0.0.
you will need to update the version to 9.0.0 to get the license info back for device with later versions of play services.
EDIT (June 6, 2016): Google is looking into the issue now.
Project Member #3 l...#google.com
Thanks for the reports. We've filed
this internally and will look into it.
Status: Accepted Labels:
Internal-29143355
Yes, upgrading Google Play Services to last version (9.0.0 at time of writing this answer) solves the issue.
I had the same problem and after upgrading Google Play Services I started getting the licenses properly.
If you're maintaining an old app and can't reasonably update from a very old version of Google Play Services without breaking a whole lot of ancient features, there's a viable workaround:
Decompile the getOpenSourceSoftwareLicenseInfo() method with Android Studio, copy the method into your project, and change the line to point from "oss_notice" to "third_party_licenses".
Uri var1 = (new android.net.Uri.Builder()).scheme("android.resource").authority("com.google.android.gms").appendPath("raw").appendPath("oss_notice").build();
to
Uri var1 = (new android.net.Uri.Builder()).scheme("android.resource").authority("com.google.android.gms").appendPath("raw").appendPath("third_party_licenses").build();
This method has been deprecated and is no longer necessary:
https://developers.google.com/android/reference/com/google/android/gms/common/GooglePlayServicesUtil.html#getOpenSourceSoftwareLicenseInfo(android.content.Context)
This license information is displayed in Settings > Google > Open Source on any device running Google Play services. Applications do not need to display this license text, and this method will be removed in a future version of Google Play services.
👍
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 had been successfully using the following code to launch the Google Leaderboards display from my game:
startActivityForResult(Games.Leaderboards.getLeaderboardIntent(googleApiClient,getString(R.string.leaderboard)),LEADERBOARD_REQUEST_CODE);
However, recently after updating including Google Play Services (and probably other google libraries), the leaderboard display no longer launches and instead I get the return code GamesActivityResultCodes.RESULT_RECONNECT_REQUIRED in onActivityResult(), and in the logcat I see:
E/ClientUiFragAct(26401): Not signed in. To launch Client UI activities, you must be connected to the games service AND signed in.
even though when I attempt to launch the GUI, I check I am signed in by doing googleAPIClient.isConnected() which returns true.
So, on 2 separate devices, this functionality has stopped working on the same version of my app when the only relevant change I can think of has been updates to Google libraries (Google Play Services 7.5.71 1955121-036).
I have a third device on which it still works, with an older version of Google Play Services 6.7.76 (1745988-034).
I build using API level 22.
Curiously, a couple of other games (not mine) still have Google Leaderboard display working with version 7.5.71 installed.
I may be barking up the wrong tree with the Google Play Services version hypothesis.
Anyone else experienced this?
We solved the issue by removing the "setAccountName" call in the configuration of the GoogleApiClient.Builder.
Old code:
GoogleApiClient.Builder builder = new GoogleApiClient.Builder( this );
builder.addApi( Games.API );
builder.addScope( Games.SCOPE_GAMES );
builder.addConnectionCallbacks( this );
builder.addOnConnectionFailedListener( this );
builder.setAccountName( "some.account#gmail.com" );
builder.build();
New code:
GoogleApiClient.Builder builder = new GoogleApiClient.Builder( this );
builder.addApi( Games.API );
builder.addScope( Games.SCOPE_GAMES );
builder.addConnectionCallbacks( this );
builder.addOnConnectionFailedListener( this );
builder.build();
This has the drawback that the account chooser will be shown when signing in which is okay in our use case and maybe yours as well. At least the achievements screen can be opened again.
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.
Announcing the Android Advertising ID as "forced" replacement for Android ID, Google did not mention the compatibility concerns.
With iOS, the new advertising identifier was introduced from ~6.0, not downward compatible.
How is this managed with Android now? Do we need a fallback for former Android ID or does each api version support the new identifier? The manual does not cover these concerns.
Requirements
The advertising ID APIs are supported in Google Play services 4.0+
Support for the advertising ID on specific devices is based on their installed versions of Google
Play services
From the example provided,
public void getIdThread() {
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
} catch (IOException e) {
// Unrecoverable error connecting to Google Play services (e.g.,
// the old version of the service doesn't support getting AdvertisingId).
}
}
You need to handle the exception if the user's device is not updated to the required version.