My Android app requires Google Play services to display Google Maps. I've included a function call that checks for the availability of Google Play services and proceed if it exists. If it doesn't exist or has an outdated version, an error dialog is shown that redirects user to Play Store. I wanted to ask, how can I check if a user has actually installed (or updated) Google Play services when they land back to my app? I'm using Fragment and checking for the availability of Google Play services in onResume().
The function is as follow:
private boolean isPlayServicesConfigured() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity().getApplicationContext());
if(status == ConnectionResult.SUCCESS)
return true;
else {
Log.d("STATUS", "Error connecting with Google Play services. Code: " + String.valueOf(status));
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, getActivity(), status);
dialog.show();
return false;
}
}
Moreover, even if I get the status of Google Play Services back in my app, how do I reload the fragment? Can I call onCreateView() programatically?
Related
I can easily detect that my device's google play services app needs to be updated, and present the getErrorDialogFragment() to prompt the user to update it with:
GoogleApiAvailability googleApi = GoogleApiAvailability.getInstance();
mServiceAvailabilityCode = googleApi.isGooglePlayServicesAvailable(this);
if (mServiceAvailabilityCode == ConnectionResult.SUCCESS) {
...
else {
if (googleApi.isUserResolvableError(mServiceAvailabilityCode)) {
switch (mServiceAvailabilityCode) {
....
case SERVICE_VERSION_UPDATE_REQUIRED:
googleApi.showErrorDialogFragment(SplashActivity.this, mServiceAvailabilityCode, PLAY_SERVICES_RESOLUTION_REQUEST);
break;
....
}
However, if Google play services is disabled AND out of date, then, the user is presented with a dialog with an "Update" button, once the user presses it, the app returns immediately to the onActivityResult, which I then catch the response and request code in OnActivityResult like this:
#Override
protected void onActivityResult(int requestCode, int mServiceAvailabilityCode, Intent data) {
super.onActivityResult(requestCode, mServiceAvailabilityCode, data);
switch (requestCode) {
case PLAY_SERVICES_RESOLUTION_REQUEST:
finish();
// do i need to launch app manager-> app info for google play services ?
So, by the user pressing the "Update" button on the dialog did not launch Android's Playstore and load the "Playstor services" app for the user to update, which I had expected it to do. Pressing "Update" just goes straight back to onActivityResult. This is where I'm confused. Shouldn't Android have launched this for me ? Or do I have to do it myself in OnActivityResult ?
The problem is caused by a specific condition when you have 2 issues with Google Play Services (GPS). Because GPS is also disabled Google Play Store (GPT), will not run on the device.
If your Google Play Services is out of date, then calling showErrorDialogFragment using an error code of ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED, (error code 2), which works fine.
But if your GPS is both disabled AND out-of-date, then there is an issue with the way googleApiAvailability api works.If you call isGooglePlayServicesAvailable() it will return the first error it finds, but it's not necessarily the error you want to resolve first. The problem is knowing that you have another error you need to address first. isGooglePlayServicesAvailable() does not help in this regard.
In my case play services is both disabled, AND out of date. So, the approach is to first call showErrorDialogFragment and you'll get a response error code for SERVICE_VERSION_UPDATE_REQUIRED.
Android will attempt to resolve it by sending a pendingIntent to launch Google Play Store (GPT) to update GPS, but this will fail, as GPT depends on an ENABLED version of GPS. Because you're calling showErrorDialogFragment it will call onActivityResult after it fails to launch GPT.
The next step is codig the onActivityResult. I needed to test for isGooglePlayServicesAvailable() again. If you still get the same error code (SERVICE_VERSION_UPDATE_REQUIRED), then you need to call showErrorDialogFragment again in onActivityResult, but this time pass it a different error code, ConnectionResult.SERVICE_DISABLED (error code 3). This will take the user to the app manager to ENABLE google play services first. Then when returning to the app, you need to test for isGooglePlayServicesAvailable and it should then detect google services is still out of date. If you successfully update the app, onActivityResult should allow you to determine that isGooglePlayServicesAvailable is succcessful and you can continue. Note that you will may need to add a flag that so that you know to test again for google play services compatibility rather than continue executing a startup process.
(So, really what googleApiAvailability should do is return the disabled error first (ie ConnectionResult.SERVICE_DISABLED aka error code 3), so you can resolve that first before attempting to update GPS.)
This is working for me
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if(result != ConnectionResult.SUCCESS) {
if(googleAPI.isUserResolvableError(result)) {
//prompt the dialog to update google play
googleAPI.getErrorDialog(this,result,PLAY_SERVICES_RESOLUTION_REQUEST).show();
}
}
else{
//google play up to date
}
Not sure in which version Google has it fixed, but with the latest 11.6.0 you can get the correct statusCode and the dialog that leads to Settings to enable the Google Play Services.
Logcat:
11-24 05:48:07.266 V/FA: Activity resumed, time: 2070779368
11-24 05:48:07.320 W/FA: Service connection failed: ConnectionResult{statusCode=SERVICE_DISABLED, resolution=null, message=null}
Dialog:
Google Play Services are available on Play Store to download and update. You can simply open Play Store.
Here is link to the services.
What you can do is start activity with ACTION_VIEW intent like below
String LINK_TO_GOOGLE_PLAY_SERVICES = "play.google.com/store/apps/details?id=com.google.android.gms&hl=en";
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://" + LINK_TO_GOOGLE_PLAY_SERVICES)));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://" + LINK_TO_GOOGLE_PLAY_SERVICES)));
}
There is also this code:
https://gist.github.com/kristopherjohnson/7554793
Which require:
implementation "com.google.android.gms:play-services-auth:$playServiceAuthVersion"
According to the documentation GooglePlayServicesUtil.isGooglePlayServicesAvailable returns SERVICE_VERSION_UPDATE_REQUIRED when "The installed version of Google Play services is out of date".
Does this mean that there is a new version of google play services in the play store?
Does this mean that the app needs a newer version than the one that is currently installed in the device?
How is this check done?
this means that the version of google play service you included in your app is higher than the one currently installed on the users device. the user needs to update their google play services in-order for your app to work correctly.
if the result comes back with that error you can simply call this method to alert the user they need to update and it will take them there.
GooglePlayServicesUtil.getErrorDialog(result, this, GOOGLE_PLAY_SERVICE_UPDATE_CODE).show();
result is the result of the isGooglePlayServicesAvailable method
Here are the docs for GooglePlayServicesUtil: http://developer.android.com/reference/com/google/android/gms/common/GooglePlayServicesUtil.html.
Here is where they talking about "ensuring" the user has it installed: https://developer.android.com/google/play-services/setup.html#ensure
This is taken from the Official Iosched 2014 source code here:
https://github.com/google/iosched/blob/0a90bf8e6b90e9226f8c15b34eb7b1e4bf6d632e/android/src/main/java/com/google/samples/apps/iosched/util/PlayServicesUtils.java
public class PlayServicesUtils {
public static boolean checkGooglePlaySevices(final Activity activity) {
final int googlePlayServicesCheck = GooglePlayServicesUtil.isGooglePlayServicesAvailable(activity);
switch (googlePlayServicesCheck) {
case ConnectionResult.SUCCESS:
return true;
case ConnectionResult.SERVICE_DISABLED:
case ConnectionResult.SERVICE_INVALID:
case ConnectionResult.SERVICE_MISSING:
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(googlePlayServicesCheck, activity, 0);
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialogInterface) {
activity.finish();
}
});
dialog.show();
}
return false;
}
}
Here is how to use it in an Activity: https://github.com/google/iosched/blob/cf1f30b4c752f275518384a9b71404ee501fc473/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
#Override
protected void onResume() {
super.onResume();
// Verifies the proper version of Google Play Services exists on the device.
PlayServicesUtils.checkGooglePlaySevices(this);
}
Does this mean that there is a new version of google play services in the play store?
From the site latest update was on December 2014
Does this mean that the app needs a newer version than the one that is currently installed in the device?
You can check if the device has the higher version ofGoogle Play Service than the one on your app like so:
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable( getApplicationContext() );
if(status == ConnectionResult.SUCCESS) {
//OK
}else if(status == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED){
Toast.makeText(context,"please udpate your google play service",Toast.LENGTH_SHORT).show
}
Documentation was updated, now it is clear:
Verifies 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.
Note that all of the current answers reference GooglePlayServicesUtil which is now deprecated. See GooglePlayServicesUtil vs GoogleApiAvailability for details on how to perform the Google Play Services version compatibility check.
I resolved this problem by updating the last version of Youtube library available in : https://developers.google.com/youtube/android/player/downloads
In the gradle :
implementation files('libs/YouTubeAndroidPlayerApi.jar')
I am integrating google plus into my app and it works fine with the google_play_service library.But since this library doesn't work in amazon devices my app always crash when I share something from the Amazon devices.So it is only possible to avoid sharing in google plus when using Amazon devices or is there a workaround.
Thanks in advance.
Whenever you use the Google Play Services lib, it is important to check whether the device supports the use of Google Play Services. This is done as follows:
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDisplay = (TextView) findViewById(R.id.display);
context = getApplicationContext();
// Check device for Play Services APK.
if (checkPlayServices()) {
// If this check succeeds, proceed with normal processing.
// Otherwise, prompt user to get valid Play Services APK.
...
}
}
// You need to do the Play Services APK check here too.
#Override
protected void onResume() {
super.onResume();
checkPlayServices();
}
/**
* Check the device to make sure it has the Google Play Services APK. If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings.
*/
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
The above code is usually added to your app's starting activity, and will prevent your application from crashing (throwing an exception) if that device does not support the use of Google Play Services (which is the case with Amazon's Android-based devices). So the answer to your second question, whether we can get access to Google Plus on Amazon devices, is NO.
References:
1. Ensure Devices Have the Google Play services APK.
2. Check for Google Play Services APK.
Yey! soon we cant even use Google Analytics on Amazon android devices! we're already limited in Google Drive support, Chrome cast, Locations API. Developing for "Android" and not only"Google" is becoming harder and harder. Amazon, Google and ebay everyone has its own api for its services.
OR try this.
http://androidcowboy.com/2013/10/add-google-account-kindle-fire-hdx/
My app crashes if a device does not have "Google Play Services" installed in it or if "Google Play Services" in not updated.
I want to direct a user to the download page of "Google play Services" if he does not have Play Services installed in his device.
I have applied an exception but what should I put in the catch block?
I mean how to direct user to the download page of Play Services?
Call GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) to get a status. If the status is not ConnectionResult.SUCCESS, call GooglePlayServicesUtil.isUserRecoverableError(status) -- if that returns true, you should be able to use GooglePlayServicesUtil.getErrorDialog() to display a dialog that will lead the user to download the Play Services Framework.
I think it is too late to answer this, but it could help other people.
Implement this method which check the device to make sure it has the Google Play Services APK, If it doesn't, display a dialog that allows users to download the APK from the Google Play Store or enable it in the device's system settings.
public static boolean checkPlayServices(Activity activity) {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(activity);
if (resultCode != ConnectionResult.SUCCESS) {
Log.e("GooglePlayServices", "Google play services not working.");
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(activity, resultCode, 9000)
.show();
} else {
Log.e("GooglePlayServices", "GCM - This device is not supported.");
}
return false;
}
return true;
}
Hope it helps someone :)
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.