I am using google place API in my app and it's working perfectly when using fragment but, I want to call all the functionality on click on EditText. How to call that?
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
mGoogleApiClient = new GoogleApiClient
.Builder(this)
.addApi(Places.PLACE_DETECTION_API)
.enableAutoManage(this, this)
.build();
try {
startActivityForResult(builder.build(this), PLACE_PICKER_REQUEST);
} catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, null);
result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
#Override
public void onResult(PlaceLikelihoodBuffer likelyPlaces) {
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
}
likelyPlaces.release();
}
});
If I am commenting this code from PlaceAutoCompleteFragment to before try block, yet it's working, so I don't understand from where it's is working and how to correct that:
PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
// Log.i(TAG, "Place: " + place.getName());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
//Log.i(TAG, "An error occurred: " + status);
}
});
try {
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
.build(this);
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
Here I am calling ActivityResult:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
Place place = PlacePicker.getPlace(data, this);
String toastMsg = String.format("Place: %s", place.getName());
Toast.makeText(this, toastMsg, Toast.LENGTH_LONG).show();
}
}
if (requestCode == PLACE_AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(this, data);
//Log.i(TAG, "Place: " + place.getName());
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(this, data);
// TODO: Handle the error.
// Log.i(TAG, status.getStatusMessage());
} else if (resultCode == RESULT_CANCELED) {
// The user canceled the operation.
}
}
}
Related
I have an app in which i have implemented google+ sign in. I have checked all the code and found after dubugging it is always throws an error in onConnectionFailed(ConnectionResult result) where result is shown as follow:
ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{425b8550: android.os.BinderProxy#423ec2e8}, message=null}
code:-
mGoogleApiClient = buildGoogleAPIClient();
gPlusLoginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
processGPlusSignIn();
}
});
private void processGPlusSignIn() {
if (!mGoogleApiClient.isConnecting()) {
Log.e("", "GPLUS area 111");
startExecutingGPlusLoginProcess();
mSignInClicked = true;
}
}
private void startExecutingGPlusLoginProcess() {
if (mConnectionResult != null && mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
Log.i("Registration", "Starting...");
mConnectionResult.startResolutionForResult(this, GPLUS_SIGN_IN_REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
Log.e("Registartion", "Exception***" + e);
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG,"onConnectionFailed called");
if (!connectionResult.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, ERROR_DIALOG_REQUEST_CODE).show();
return;
}
if (!mIntentInProgress) {
mConnectionResult = connectionResult;
Log.e("Registration", "Result?***" + connectionResult);
if (mSignInClicked) {
startExecutingGPlusLoginProcess();
}
}
}
You may try the below code :
first you need to initalize GoogleApi like that:
private void googleInitialization() {
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
mGoogleApiClient.connect();
}
After that you need to call this method like that:-
googleInitialization();
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
and thid handle in OnActivityResult there is a CallBackManager which is very useful to call the login button
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);
}
}
Now, Get result in the below method:
private void handleSignInResult(GoogleSignInResult result) {
Log.d("handleSignInResult", "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Signed in successfully, show authenticated UI.
GoogleSignInAccount acct = result.getSignInAccount();
String personName = acct.getDisplayName();
String email = acct.getEmail();
if (personName.contains(" ")) {
String fname = personName.substring(0, personName.lastIndexOf(" ") + 1);
String lname = personName.substring(personName.lastIndexOf(" ") + 1);
Log.e("First name", fname);
Log.e("Last name", lname);
} else
String fname = personName;
Log.e("Profile Info", "Name: " + personName + ", email: " + email);
}
}
We are using Google PlaceAutocomplete for city picker. We need to get country code for picked city. I am trying to use place.getLocale() but its null. Is there a way I can get Country ISO code from PlaceAutocomplete returned data.
in gradle:
compile 'com.google.android.gms:play-services-places:10.0.1'
code:
private void openCityPicker() {
try {
AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
.setTypeFilter(AutocompleteFilter.TYPE_FILTER_CITIES)
.build();
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
.setFilter(typeFilter)
.build(this);
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
com.google.android.gms.location.places.Place googleApiPlace = PlaceAutocomplete.getPlace(this, data);
Log.d(TAG, "onActivityResult: " + googleApiPlace.getAddress());
Log.d(TAG, " googleApiPlace.getLocale().getCountry(): " + googleApiPlace.getLocale().getCountry());
Log.d(TAG, " googleApiPlace.getLocale().getDisplayCountry(): " + googleApiPlace.getLocale().getDisplayCountry());
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(this, data);
// TODO: Handle the error.
Log.i(TAG, status.getStatusMessage());
} else if (resultCode == RESULT_CANCELED) {
// The user canceled the operation.
}
}
}
late but right answer
you can get country code using this
add Place.Field.ADDRESS_COMPONENTS field into your fields list
List<Place.Field> fields = Arrays.asList(Place.Field.ADDRESS_COMPONENTS);
Intent intent = new Autocomplete.IntentBuilder(
AutocompleteActivityMode.FULLSCREEN, fields)
.setTypeFilter(TypeFilter.CITIES)
.build(mActivity);
startActivityForResult(intent, requestCode);
when you get the result into onActivityResult() you'll get full details of location into that you will find country
if (place.getAddressComponents() != null) {
List<AddressComponent> addressComponents = place.getAddressComponents().asList();
for (int i = 0; i < addressComponents.size(); i++) {
if (addressComponents.get(i).getTypes().get(0).equals("country")) {
countryCode = addressComponents.get(i).getShortName();
break;
}
}
}
I'm designing an app that uses maps and requires users to input destinations.i added the PlaceAutoCompleteFragment in the xml
fragment
android:id="#+id/place_autocomplete_fragment"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_gravity="top" android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"
/>
And this is what is in my java
PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
When I try searching it says:"Can't load search results".What should I do after this?
The autocomplete widget is a search dialog with built-in autocomplete functionality.
Use PlaceAutocomplete.IntentBuilder to create an intent to launch the autocomplete widget as an intent. After setting the optional parameters, call build(Activity) and pass the intent to startActivityForResult(android.content.Intent, int).
int PLACE_AUTOCOMPLETE_REQUEST_CODE = 1;
...
try {
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN).build(this);
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
To receive notification when a user has selected a place, your app should override the activity's onActivityResult(), checking for the request code you have passed for your intent, as shown in the following example.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(this, data);
Log.i(TAG, "Place: " + place.getName());
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(this, data);
// TODO: Handle the error.
Log.i(TAG, status.getStatusMessage());
} else if (resultCode == RESULT_CANCELED) {
// The user canceled the operation.
}
}
}
I have 2 edit text inputs in my app.One is from place and another one to place.For these 2 inputs I have implemented google auto complete activity but problem when user click on any one of these inputs google autocomplete intent after user place selection completed intent call onActivityResult().
In onActivityResult() how to know which input clicked.
here is my code
fromPlaceEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
.setTypeFilter(AutocompleteFilter.TYPE_FILTER_REGIONS).setTypeFilter(AutocompleteFilter.TYPE_FILTER_GEOCODE)
.build();
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY).setFilter(typeFilter)
.build(MainActivity.this);
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
});
toPlaceEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
.setTypeFilter(AutocompleteFilter.TYPE_FILTER_REGIONS).setTypeFilter(AutocompleteFilter.TYPE_FILTER_GEOCODE)
.build();
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY).setFilter(typeFilter)
.build(MainActivity.this);
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(this, data);
String fullName= (String) place.getAddress();
#// here I want to know which input clicked and set fullname in input text#
fromPlaceEdit.setText(fullName);
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(this, data);
// TODO: Handle the error.
Log.i("fdfdf", status.getStatusMessage());
} else if (resultCode == RESULT_CANCELED) {
// The user canceled the operation.
}
}
}
I did it different way.
I have created two global boolean value each for from place and to place.
then when user click on from place or to place change boolean value of same place then on onActivityResult check which boolean value is true and set result place name to same input box.
Code follows:
public boolean fromplaceSlected =false ;
public boolean toplaceSlected =false;
fromPlaceEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
.setTypeFilter(AutocompleteFilter.TYPE_FILTER_REGIONS).setTypeFilter(AutocompleteFilter.TYPE_FILTER_GEOCODE)
.build();
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY).setFilter(typeFilter)
.build(MainActivity.this);
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
});
toPlaceEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
AutocompleteFilter typeFilter = new AutocompleteFilter.Builder()
.setTypeFilter(AutocompleteFilter.TYPE_FILTER_REGIONS).setTypeFilter(AutocompleteFilter.TYPE_FILTER_GEOCODE)
.build();
Intent intent =
new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY).setFilter(typeFilter)
.build(MainActivity.this);
startActivityForResult(intent, PLACE_AUTOCOMPLETE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.e("request", String.valueOf(requestCode));
// Check that the result was from the autocomplete widget.
if (requestCode == REQUEST_CODE_AUTOCOMPLETE) {
if (resultCode == RESULT_OK) {
// Get the user's selected place from the Intent.
Place place = PlaceAutocomplete.getPlace(getContext(), data);
String fullName = (String) place.getAddress();
if(fromplaceSlected){
Log.e("from place",fullName);
fromPlaceEdit.setText(fullName);
fromplaceSlected=false;
toplaceSlected=false;
}
else if(toplaceSlected){
Log.e("toplace" ,fullName);
toPlaceEdit.setText(fullName);
fromplaceSlected=false;
toplaceSlected=false;
}
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(getContext(), data);
Log.e("sdsdsdd", "Error: Status = " + status.toString());
fromplaceSlected=false;
toplaceSlected=false;
} else if (resultCode == RESULT_CANCELED) {
// Indicates that the activity closed before a selection was made. For example if
// the user pressed the back button.
fromplaceSlected=false;
toplaceSlected=false;
}
}
}
Your code may work, but it's a bit hacky. Here is the good way to do it:
public static final int PLACE_AUTOCOMPLETE_FROM_PLACE_REQUEST_CODE=1;
public static final int PLACE_AUTOCOMPLETE_TO_PLACE_REQUEST_CODE=2;
fromPlaceEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
//Do your stuff from place
startActivityForResult(intent, PLACE_AUTOCOMPLETE_FROM_PLACE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
});
toPlaceEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
//Do your stuff to place
startActivityForResult(intent, PLACE_AUTOCOMPLETE_TO_PLACE_REQUEST_CODE);
} catch (GooglePlayServicesRepairableException e) {
// TODO: Handle the error.
} catch (GooglePlayServicesNotAvailableException e) {
// TODO: Handle the error.
}
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_AUTOCOMPLETE_FROM_PLACE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
//Do your ok >from place< stuff here
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
//Handle your error >from place<
} else if (resultCode == RESULT_CANCELED) {
// The user canceled the operation.
}
} else if (requestCode == PLACE_AUTOCOMPLETE_TO_PLACE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
//Do your ok >to place< stuff here
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
//Handle your error >to place<
} else if (resultCode == RESULT_CANCELED) {
// The user canceled the operation.
}
}
}
From documentation:
requestCode int: If >= 0, this code will be returned in onActivityResult() when the activity exits.
So, before android 6 marshmallow release, google + sign in worked perfectly. After release, Im having issues like permissions, onConnectionFailed, etc... Does anybody has a solution how to fix this? Im calling google sign in methods from fragment. Here is the code:
Fragment:
#Override
public void onConnected(Bundle bundle) {
Log.d("GoogleApiClient", "onConnected");
mShouldResolve = false;
new RetrieveTokenTask().execute(Plus.AccountApi.getAccountName(mGoogleApiClient));
}
#Override
public void onConnectionSuspended(int i) {
Log.d("GoogleApiClient", "onConnectionSuspended " + String.valueOf(i));
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("GoogleApiClient", "onConnectionFailed");
Log.d("GoogleApiCLient", connectionResult.toString());
ViewUtils.hideProgressDialog();
if (!mIsResolving && mShouldResolve) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(getActivity(), RC_SIGN_IN);
mIsResolving = true;
} catch (IntentSender.SendIntentException e) {
Log.e("LoginFragment", "Could not resolve ConnectionResult.", e);
mIsResolving = false;
mGoogleApiClient.connect();
}
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i("RequestCode", String.valueOf(requestCode));
Log.i("ResultCode", String.valueOf(resultCode));
try {
Log.i("Intent", data.getAction());
} catch (Exception e) {
}
if (requestCode == RC_SIGN_IN) {
// If the error resolution was not successful we should not resolve further.
ViewUtils.showProgressDialog(getActivity(), getActivity().getResources().getString(R.string.loading_dialog_str));
if (resultCode != getActivity().RESULT_OK) {
mShouldResolve = false;
}
mIsResolving = false;
mGoogleApiClient.connect();
if (mGoogleApiClient.isConnected()) {
new RetrieveTokenTask().execute(Plus.AccountApi.getAccountName(mGoogleApiClient));
}
} else {
//facebook
Log.d("Login", "FaceBook");
mCallbackManagerFacebook.onActivityResult(requestCode, resultCode, data);
}
}
private class RetrieveTokenTask extends AsyncTask<String, Void, String> {
private static final String TAG = "RetrieveAccessToken";
private static final int REQ_SIGN_IN_REQUIRED = 55664;
#Override
protected String doInBackground(String... params) {
String accountName = params[0];
String scopes = "oauth2:profile";
String token = null;
try {
token = GoogleAuthUtil.getToken(getActivity(), accountName, scopes);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), REQ_SIGN_IN_REQUIRED);
} catch (GoogleAuthException e) {
Log.e(TAG, e.getMessage());
}
return token;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("Token", "Token Value: " + s);
if (s == null) {
ViewUtils.hideProgressDialog();
ViewUtils.showToastMessage(getActivity(), getActivity().getResources().getString(R.string.login_error));
} else {
loginGoogleUser(s);
}
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
}
}
}
and activities on result:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
LoginFragment loginFragment = (LoginFragment) getSupportFragmentManager().findFragmentByTag("MyProfileFragment");
if (loginFragment != null) {
loginFragment.onActivityResult(requestCode, resultCode, data);
}
}
Ok, so, first of all, you need to change all of your dependencies of google play services to 8.1.0, also, build.gradle to the newest version, targeted sdk 23, comiled version 23, etc. So, basicaly, check your gradle. After that, you need to change your mGoogleApiClient to :
mGoogleApiClient = new GoogleApiClient.Builder(getActivity()).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addScope(new Scope(Scopes.PROFILE))
.addScope(new Scope(Scopes.EMAIL))
.addScope(new Scope(Scopes.PLUS_LOGIN))
.addScope(new Scope(Scopes.PLUS_ME))
.build();
mGoogleApiClient.connect();
And finally, you need to include permissions you need for sdk>= 23. To do that, create
private static String ACCOUNT_PERMISSIONS[] = new String[]{
Manifest.permission.GET_ACCOUNTS
};
Here is a good tutorial on how to get permissions for sdk >= 23:
https://github.com/googlesamples/android-RuntimePermissions