SupportLifecycleFragmentImpl automatically add fragment when enable location using google dialog - android

SupportLifecycleFragmentImpl automatically add fragment when enable
location using google dialog.
When calling location on and when it shows dialog for turning on location it automatically adds fragment. When calling getFragmentManager().getFragments() it shows a new fragment it added automatically with tag SupportLifecycleFragmentImpl. which creates issue in backstack.
this tag add
java code
public void enableLoc() {
activity.setFinishOnTouchOutside(true);
final int REQUEST_LOCATION = 199;
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(activity)
.addApi(LocationServices.API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.e("location", "Connect");
}
#Override
public void onConnectionSuspended(int i) {
Log.e("location", "fail");
//googleApiClient.connect();
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("location", "Location error " + connectionResult.getErrorCode());
}
}).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
SettingsClient client = LocationServices.getSettingsClient(activity);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnSuccessListener(activity, new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
Log.d("location_enable", "enable");
}
});
task.addOnFailureListener(activity, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (e instanceof ResolvableApiException) {
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(activity,
REQUEST_LOCATION);
} catch (IntentSender.SendIntentException sendEx) {
// Ignore the error.
}
}
}
});
}

I just faced a similar issue - I tried initing a GeofencingClient object from Location services. when I used the activity:
geofencingClient = LocationServices.getGeofencingClient(activity);
the very same SupportLifecycleFragmentImpl was added to the fragments back stack (although it was not visible at any time since I manage permissions requests myself).
The problem was solved when I switched to initing the client using the application context:
geofencingClient = LocationServices.getGeofencingClient(getApplicationContext());

Related

Location Settings Dialog caused the current activity to go back in android?

I am using Location Setting Dialog in my Application. I am using the below code:
private void enableLoc() {
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
googleApiClient.connect();
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("Location error","Location error " + connectionResult.getErrorCode());
}
}).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(AboutUsActivity.this, REQUEST_LOCATION);
finish();
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
}
}
});
}
}
When I call this method the dialog appears if my location setting is off.
Now as soon as the dialog appears my activity goes to the back and the previous activity is showing.
Why this is happening? How to ask user for location setting updating?

how to get activity in service using startResolutionForResult

I want to start a service which opens GPS dialogue if it is off on device boot process. I have a broadcast receiver on boot then I trigger this service to open dialogue without opening the main application.I am using service, in service I need to call GPS location dialogue box to turn on if disable.
public class GPSTestService extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener ,VolleyResultCallBack {
private boolean ContinueConnection = true;
LocationRequest mLocationRequest;
public static GoogleApiClient mGoogleApiClient;
PendingResult<LocationSettingsResult> result;
final static int REQUEST_LOCATION = 199;
Context contex;
#Override
public void onVolleyErrorListener(VolleyError error) {
}
#Override
public void onVolleyResultListener(Context mContext, JSONArray response) {
}
#Override
public void onCreate() {
super.onCreate();
contex=getApplicationContext();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(30 * 1000);
mLocationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
//final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
//...
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
Toast.makeText(getApplicationContext(), "GPSTestService", Toast.LENGTH_SHORT).show();
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult((Activity) contex, REQUEST_LOCATION);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
//...
break;
}
}
});
}
#Override
public void onConnectionSuspended(int i) {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Utils.getInstance().syncData(this,this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
return Service.START_NOT_STICKY;
}
}
I have an issue with status.startResolutionForResult((Activity) context, REQUEST_LOCATION); how to deal it in service? as we can not pass activity here.
in service I need to call GPS location dialogue box to turn on if disable
That is not possible, sorry. Do that work in your activity before starting the service. If the service detects that the user disabled location access while the service is running, the service can raise a Notification which leads the user to an activity where you can request GPS access.

Requesting for Location Services Android

I am using this code to for user to activate the location services. I want to show user dialog to accept to enable location services then redirect them to the LOCATION_SETTINGS Page. But Without the user accepting it from user it redirects to location settings.
if(lm==null)
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
try{
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
}catch(Exception ex){}
try{
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}catch(Exception ex){}
if(!gps_enabled && !network_enabled){
dialog = new AlertDialog.Builder(this);
dialog.setMessage(this.getResources().getString(R.string.gps_network_not_enabled));
dialog.setPositiveButton(this.getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
//get gps
}
});
dialog.setNegativeButton(this.getString(R.string.Cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
finish();
}
});
dialog.show();
}
As far as I understand you try to enable the location.
You can show a dialog to enable the location instead of redirect them to LOCATION_SETTING page.
Step by step process.
First you need to set a GoogleApiClient and implements GoogleApiClient CallBackMethods.
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
mGoogleApiClient.connect();
}
CallBack Methods
#Override
public void onConnected(Bundle bundle) {
Log.d("OnConnected", "Connection successful");
settingsrequest();
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
}
As soon as the googleapiclient connects, onconnected method will invoke and settingsRequest method will call.
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
LocationRequest locationRequest;
public void settingsrequest() {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setNumUpdates(1);
locationRequest.setExpirationDuration(20000);
locationRequest.setFastestInterval(500);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
builder.setAlwaysShow(true); //this is the key ingredient
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS: {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this);
}
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(MainTab.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
status.startResolutionForResult(MainTab.this, REQUEST_CHECK_SETTINGS) will show a dialog requesting location.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this);
break;
case Activity.RESULT_CANCELED:
break;
}
break;
}
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this) will set a listener for the location cahnged.
As the location changed onLocationChanged method will invoke.
#Override
public void onLocationChanged(Location location) {
prevLocation = location;
//Do you work
}
Hope this will helps you.

getLastLocation() always null after reinstall

I seem to have a problem that I just can't figure out.
I am creating an application that requires Location Services with Android. The application needs to constantly poll for location.
This code had been working for months, and then when I uninstalled it from my phone and reinstalled it, the location is suddenly returning null.
Here is the LocationProvider class, which grabs the location using a Google API client:
public class LocationProvider implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
public abstract interface LocationCallback {
public void handleNewLocation(Location location);
}
public static final String TAG = LocationProvider.class.getSimpleName();
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationCallback mLocationCallback;
private Context mContext;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
public LocationProvider(Context context, LocationCallback callback) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationCallback = callback;
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(3 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
mContext = context;
}
public void connect() {
mGoogleApiClient.connect();
}
public void disconnect() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Location services connected.");
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
//----------------
//----------------
Log.i(TAG, "couldnt get location");
noLocationEnabledDialog();
/*LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLocationCallback.handleNewLocation(location); */
}
else {
/* Log.i(TAG, "couldnt get location");
noLocationEnabledDialog(); */
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLocationCallback.handleNewLocation(location);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution() && mContext instanceof Activity) {
try {
Activity activity = (Activity)mContext;
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(activity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
public void noLocationEnabledDialog(){
AlertDialog.Builder setLocationDialog = new AlertDialog.Builder(mContext);
setLocationDialog.setTitle(R.string.location_message_title);
setLocationDialog.setMessage(R.string.location_message);
/*Button takes user to settings*/
setLocationDialog.setPositiveButton(R.string.affirmative, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(settingsIntent);
}
});
/*If no location, close the activity*/
setLocationDialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//do nothing....yet
}
});
setLocationDialog.show();
}
#Override
public void onLocationChanged(Location location) {
mLocationCallback.handleNewLocation(location);
Log.i(TAG, "New location received ");
} }
I have also tried turning on Google Maps to grab a location on the device, hoping that it would use the location grabbed from Maps. Curiously, the location icon showed up in the top bar before reinstalling and it no longer shows. Does anyone know why reinstalling the application would cause this error? I am running this on a Samsung Galaxy s6 running Android 6.0.1
Thank you very much!
Well, it appears I have answered my own question. I am a serious derp.
Marshmallow requires that individual apps ask for permission for location and such. Since the previous installation had a different target API, it didnt need that and the manifest sufficed.
I brought the target API down to 22 and that was it. In the future, I will need to ask for permission. This question answers it quite well:
Permission issues for location in android Marshmallow applicaton

Location Settings Dialog shown twice OR how to detect that dialog is shown\closed

I want to show Location Settings Dialog every time when activity in foreground and Location turned off, in onResume().
The issue: every time will be created new Settings Dialog without destroying previous one and I have stack from dialogues. By back button or by cancel button will be shown another Settings Dialog that was shown before.
Another issue if that when location is enabled from notification bar dialog still shown and I can't close it.
public class CheckLocationActivity extends FloatingActionsMenuActivity implements ConnectionCallbacks, OnConnectionFailedListener {
private GoogleApiClient googleApiClient;
#Override
public void onResume() {
super.onResume();
showDialog();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
private void showDialog() {
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
googleApiClient.connect();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
//**************************
// builder.setAlwaysShow(true); //this is the key ingredient
//**************************
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
CheckLocationActivity.this, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}nSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(CheckLocationActivity.this, 1000);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
Use a boolean to check if the dialog as being already shown. Remember to persist in the boolean in your bundle outstate and load in onCreate so that it doesn't get lost upon rotation change.

Categories

Resources