Ask location permissions inside service - java

I am getting the location data using a service, this service is started when my app runs on a activity, and i need that activity to ask for the permissions.
So basicly this is my service (it works fine)
public class GoogleLocation extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private static final String TAG = "BOOMBOOMTESTGPS";
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 0;
private LocationManager mLocationManager = null;
private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 0f;
private int updatePriority;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private final IBinder mBinder = new LocalBinder();
private Intent intent;
private String provider;
Context context;
Location mLastLocation;
public class LocalBinder extends Binder {
public GoogleLocation getServerInstance() {
return GoogleLocation.this;
}
}
public Location getLocation() {
Log.d("IMHERE", "HELLO");
return mLastLocation;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
context = getApplicationContext();
super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onCreate() {
Log.e(TAG, "onCreate");
initializeLocationManager();
if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
this.updatePriority = LocationRequest.PRIORITY_HIGH_ACCURACY;
} else if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
this.updatePriority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;
} else {
this.updatePriority = LocationRequest.PRIORITY_HIGH_ACCURACY;
}
this.buildGoogleApiClient();
this.createLocationRequest();
this.googleApiClient.connect();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
// Request location updates
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(this.googleApiClient, this.locationRequest,this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
Log.d("localizacao",mLastLocation.toString());
}
#Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
this.googleApiClient.unregisterConnectionCallbacks(this);
this.googleApiClient.unregisterConnectionFailedListener(this);
this.googleApiClient.disconnect();
this.mLastLocation = null;
}
private void initializeLocationManager() {
Log.e(TAG, "initializeLocationManager");
mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private synchronized void buildGoogleApiClient() {
this.googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
private void createLocationRequest() {
this.locationRequest = new LocationRequest();
this.locationRequest.setInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
this.locationRequest.setPriority(updatePriority);
}
here is where i start it
package com.example.afcosta.inesctec.pt.android;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.example.afcosta.inesctec.pt.android.services.GoogleLocation;
public class LocationPermission extends AppCompatActivity {
public static final int REQ_PERMISSION = 99;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
askPermission();
Intent i = new Intent(this,Login.class);
startActivity(i);
}
// PEDIDO DE PERMISSÃO
private void askPermission() {
checkLocationPermission();
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission. ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission. ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle("Partilhar localização")
.setMessage("Permitir a partilha de dados sobre a sua localização?")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(LocationPermission.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission. ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
startService(new Intent(this, GoogleLocation.class));
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission. ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
startService(new Intent(this, GoogleLocation.class));
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
}
the thing is, i need to ask for permissions when he runs the app for the first time, or he has the location disabled. And that never happens.
I should just start the service when the user has give the permission.
Any help with this?
Thanks

you can ask for any permission in runtime in this way:
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, RC_ACCESS_FINE_LOCATION);
}
}
and you can get it's result in:
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case RC_ACCESS_FINE_LOCATION: {
}
}
}

#Override
protected Boolean processInBackground(Void... params) {
PermissionResponse response = PermissionEverywhere.getPermission(getApplicationContext(),
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQ_CODE,
"Notification title",
"This app need external permisison",
R.launcher)
.call();
boolean isGranted = response.isGranted();
if(isGrante){
// here do your stuff
}
}

Related

App Crashes instantly after asking for location permission

I have looked for question similar to this and all of them did not include the catlog so nobody could really help them. I have made sure to include it here so I hope you can help! Basically as soon as I Open the app it prompts me with a location permission saying will I allow it. As soon as i hit yes, the app crashes!
package com.worden.jason.sample;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity implements LocationListener {
LocationManager locationManager;
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
String provider;
public void Analysis(View view) {
Intent intent = new Intent(MainActivity.this,Analysis.class);
startActivity(intent);
finish();
}
public void Tips(View view) {
Intent intent = new Intent(MainActivity.this,Tips.class);
startActivity(intent);
finish();
}
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle(R.string.TileLocation)
.setMessage(R.string.TextLocation)
.setPositiveButton(R.string.Positive, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
} else {
// permission denied, boo! Disable the
}
return;
}
}
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
protected void onResume() {
super.onResume();
if (checkLocationPermission()) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Request location updates:
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
}
}
}
log for crash
EDIT
public class MainActivity extends AppCompatActivity implements LocationListener {
LocationManager locationManager;
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
**String GPS_PROVIDER;**
public void Analysis(View view) {
Intent intent = new Intent(MainActivity.this,Analysis.class);
startActivity(intent);
finish();
}
public void Tips(View view) {
Intent intent = new Intent(MainActivity.this,Tips.class);
startActivity(intent);
finish();
}
**#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);**
}
public boolean checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle(R.string.TileLocation)
.setMessage(R.string.TextLocation)
.setPositiveButton(R.string.Positive, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
})
.create()
.show();
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// location-related task you need to do.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(GPS_PROVIDER, 400, 1, this);
}
} else {
// permission denied, boo! Disable the
}
return;
}
}
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
protected void onResume() {
super.onResume();
if (checkLocationPermission()) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Request location updates:
locationManager.requestLocationUpdates(GPS_PROVIDER, 400, 1, this);
}
}
}
}
Two problems here:
You do not initialize the locationManager field. Your call to locationManager.requestLocationUpdates results in a NullPointerException.
You do not initialize the provider field. Your call to locationManager.requestLocationUpdates does not like this.
To fix the first problem, add this override:
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
To fix the second problem, throw out your provider field and use LocationManager.GPS_PROVIDER (or one of the other providers defined in LocationManager) instead. Or initialize the provider field.
Setting breakpoints and running the program under a debugger is a good way to find such problems. Another approach is to look at logs – I'll bet there's a relevant stack trace in there somewhere.
Also ensure that your manifest mentions the requisite permission:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Can't get GPS coordinates in android application

I use this code to get the current location's coordinates. When I start this activity, nothing happens. When I use this exact code in another application it worked. The only difference that I use this location-getter in a different class, not in MainActivity. When I open that app a service comes up and starts searching the coordinates. In this case (GetLocationPS) nothing happens.
What could be the problem?
build.gradle:
compile 'com.google.android.gms:play-services:11.0.2'
GetLocationPS.java:
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class GetLocationPS extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private static final String TAG = "MainActivity";
private TextView mLatitudeTextView;
private TextView mLongitudeTextView;
private GoogleApiClient mGoogleApiClient;
private Location mLocation;
private LocationManager mLocationManager;
private LocationRequest mLocationRequest;
private com.google.android.gms.location.LocationListener listener;
private long UPDATE_INTERVAL = 2 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
private LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_location_ps);
mLatitudeTextView = (TextView) findViewById((R.id.latitude_textview));
mLongitudeTextView = (TextView) findViewById((R.id.longitude_textview));
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
checkLocation(); //check whether location service is enable or not in your phone
}
#Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
startLocationUpdates();
mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if(mLocation == null){
startLocationUpdates();
}
if (mLocation != null) {
// mLatitudeTextView.setText(String.valueOf(mLocation.getLatitude()));
//mLongitudeTextView.setText(String.valueOf(mLocation.getLongitude()));
} else {
Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection Suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode());
}
#Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
protected void startLocationUpdates() {
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
Log.d("reque", "--->>>>");
}
#Override
public void onLocationChanged(Location location) {
String msg = "Updated Location: " +
Double.toString(location.getLatitude()) + "," +
Double.toString(location.getLongitude());
mLatitudeTextView.setText(String.valueOf(location.getLatitude()));
mLongitudeTextView.setText(String.valueOf(location.getLongitude() ));
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
// You can now create a LatLng Object for use with maps
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}
private boolean checkLocation() {
if(!isLocationEnabled())
showAlert();
return isLocationEnabled();
}
private void showAlert() {
final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Enable Location")
.setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
"use this app")
.setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.show();
}
private boolean isLocationEnabled() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
}
Hope this might help
Edit:
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final int PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 100;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private TextView mLatitudeTextView;
private TextView mLongitudeTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLatitudeTextView = (TextView) findViewById((R.id.latitude_textview));
mLongitudeTextView = (TextView) findViewById((R.id.longitude_textview));
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
if (!checkPermissions()) requestPermissions();
}
#Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
public void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
#Override
protected void onPause() {
super.onPause();
if(checkPermissions()) stopLocationUpdates();
}
#Override
public void onResume() {
super.onResume();
if(checkPermissions() && mGoogleApiClient.isConnected()) startLocationUpdates();
}
private void startLocationUpdates() {
//noinspection MissingPermission
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
private void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
private boolean checkPermissions() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
private void requestPermissions() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_ACCESS_FINE_LOCATION);
}
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if(checkPermissions() && mGoogleApiClient.isConnected()) startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
mLatitudeTextView.setText(String.valueOf(location.getLatitude()));
mLongitudeTextView.setText(String.valueOf(location.getLongitude()));
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_ACCESS_FINE_LOCATION: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startLocationUpdates();
} else {
}
}
}
}
}
In onLocationChanged() you get location which you can use to get latitude and longitude. Also, this code does not give continuous location updates. For that you have to set UPDATE INTERVAL & FASTEST UPDATE INTERVAL in method createLocationRequest().

Access Application context data through activities

This question can be a little complex, but I try to explain it as best I can.
Basically I am trying to get last location (lat, long) with my application, so I did something like this:
public class GoogleLocation extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
GoogleApiClient mGoogleApiClient = null;
Location mLastLocation = null;
LocationManager lm;
Double latitude;
Double longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
connectLocation();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
lm = (LocationManager) getSystemService(LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION},
30);
}
}
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null){
longitude = location.getLongitude();
latitude = location.getLatitude();
}
Log.d("IMHERE","IMHERE");
Log.d("latitude",String.valueOf(latitude));
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
//Log.d("latitudee",String.valueOf(latitude));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
}
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
public void connectLocation(){
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.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(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:
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(
GoogleLocation.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 onLocationChanged(Location location) {
mLastLocation = location;
Log.d("mLastLocation",String.valueOf(location.getLatitude()));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
It just works if it pass trough the onLocationChanged, so the first time it enters it takes some seconds to get the location, the second time I try that, my application already got a last location and it takes more 10 seconds to reach the new location.
At this point everything fine.
Now what I want to do is run this in background, thats why I changed the extends to activity, and try in background with that onLocationChanged to updated my location.
Something like in this example.
Every time my application detects a new location, I want to updated(do a setLocation or whatever in my class).
As I said I want to do this every time I start my application and this should run that in background, every time I access this class it should retrieve me the last location, and I want to access this class from different locations.
My full code:
public class GoogleLocation extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
GoogleApiClient mGoogleApiClient = null;
Location mLastLocation = null;
LocationManager lm;
Double latitude;
Double longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
connectLocation();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
lm = (LocationManager) getSystemService(LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION},
30);
}
}
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(location != null){
longitude = location.getLongitude();
latitude = location.getLatitude();
}
Log.d("IMHERE","IMHERE");
Log.d("latitude",String.valueOf(latitude));
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
//Log.d("latitudee",String.valueOf(latitude));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 10, locationListener);
}
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
public void connectLocation(){
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.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(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:
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(
GoogleLocation.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 onLocationChanged(Location location) {
mLastLocation = location;
Log.d("mLastLocation",String.valueOf(location.getLatitude()));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
How can I do that?
FULL CODE:
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.location.Criteria;
import android.location.Location;
import com.google.android.gms.location.LocationListener;
import android.location.LocationManager;
import android.media.Image;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.support.v7.widget.SearchView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import static android.location.Criteria.POWER_HIGH;
public class MainActivity extends Activity implements GoogleApiClient.OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks, ResultCallback<LocationSettingsResult> ,LocationListener {
Double lat, lng;
GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent k = getIntent();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
} else {
mGoogleApiClient.connect();
}
}
protected LocationRequest createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return mLocationRequest;
}
#Override
public void onConnected(Bundle bundle) {
Log.e("Connection", "GOOGLE API Connected");
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(createLocationRequest());
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient,
builder.build());
result.setResultCallback(this);
}
protected void getPhoneLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
Log.e("Connection","GOOGLE API Suspended");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e("Connection","GOOGLE API Failed : " + connectionResult.toString() );
}
#Override
protected void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
if (!(ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
222);
}
else
{
getPhoneLocation();
}
// All location settings are satisfied. The client can
// initialize location requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// 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().
status.startResolutionForResult(
MainActivity.this,
111);
} 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
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.e("Activity","Result");
if(requestCode != 333) {
if (!(ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
222);
} else {
getPhoneLocation();
}
}
else
{
if(resultCode == RESULT_OK) {
finish();
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == 222) {
if (grantResults.length != 0) {
getPhoneLocation();
}
}
}
#Override
public void onLocationChanged(Location location) {
lat = location.getLatitude();
lng = location.getLongitude();
}
} `
This code gets you location between 10 - 5 second intervals and they pass through onLocationChanged ... the GetLastKnowLocation gets you the last known location to the device... so sometimes it could return null...
CODE EXPLANATION
This code block in the OnCreate connects to the Google API Client with callbacks pointing back to the activity.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
} else {
mGoogleApiClient.connect();
}
THIS IS IMPORTANT
public class MainActivity extends Activity implements GoogleApiClient.OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks, ResultCallback<LocationSettingsResult> ,LocationListener {
Creates A location request like yours with intervals
protected LocationRequest createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return mLocationRequest;
}
WHEN GOOGLE API CONNECTS CHECK SETTINGS AND PERMISSIONS
#Override
public void onConnected(Bundle bundle) {
Log.e("Connection", "GOOGLE API Connected");
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(createLocationRequest());
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient,
builder.build());
result.setResultCallback(this);
}
THE SETTINGS CALLBACK RETURNS TO ACTIVITY HERE
In this block we check the status of the settings and see if they return success we check for permission ... if we have permission to access the location ... then we getPhoneLocation() OPTION A ... if we dont have permission we ask for permission and the callback goes to OPTION B
`#Override`
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
if (!(ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
222);
}
else
{
getPhoneLocation();
}
// All location settings are satisfied. The client can
// initialize location requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// 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().
status.startResolutionForResult(
MainActivity.this,
111);
} 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;
}
}
OPTION B
In this block we get the Return from checking the user permission ... if he accepted the request for location we go on to get the PhoneLocation ... if no we close the activity.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.e("Activity","Result");
if(requestCode != 333) {
if (!(ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
222);
} else {
getPhoneLocation();
}
}
else
{
if(resultCode == RESULT_OK) {
finish();
}
}
}
ADD THE LOCATION REQUESTS (OPTION A)
protected void getPhoneLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
NOW YOU HAVE LOCATION
Now you have the location in the given interval as long as the Activity is open.
#Override
public void onLocationChanged(Location location) {
lat = location.getLatitude();
lng = location.getLongitude();
}

GPS Location always remains active in notification tray after exit MapView

Original Title:
"Location set by GPS" still remains active after
LocationServices.FusedLocationApi.removeLocationUpdates()
Edited Title:
GPS Location always remains active in notification tray after exit MapView
I want to disable remove the "Location set by GPS" and the location icon in top notification tray right after exit my map activity but it doesn't.
I'm using someone's code in stackoverflow which using following variable only:
GoogleMap mGoogleMap;
MapView mapView;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
MapLocationListener mapLocationListener;
What I've tried:
#Override
public void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mapLocationListener);
if(mGoogleApiClient != null){
mGoogleApiClient = null;
}
if(mapView != null){
mapView = null;
}
if(mGoogleMap != null){
mGoogleMap = null;
}
if(mLocationRequest != null){
mLocationRequest = null;
}
if(mLastLocation != null){
mLastLocation = null;
}
if(mCurrLocationMarker != null){
mCurrLocationMarker = null;
}
if(mapLocationListener != null){
mapLocationListener = null;
}
}
activity.finish();
}
I understand that assigning null to my references should not be the solution because the location process is running in system background not using my app references.And Yes, the location listener is no longer update but it just not disable the location icon on top like other apps did.
What I want:disable the "Location set by GPS" and the location icon in top notification tray immediately after exit my map activity. I don't want to make my user thinks I'm doing "location hacking"What I've found:All the solution I found is using LocationManager.removeUpdate which I don't have it. How can I declare it in my activity? Is this can really solve my problem?
EDIT: Attacthed Code:Using Daniel Nugent's answer...
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.location.LocationManager.GPS_PROVIDER;
import static android.location.LocationManager.NETWORK_PROVIDER;
/**
* Created by elliotching on 11-Apr-17.
*/
public class ActivityMaps_ extends MyCustomActivity {
GoogleMap mGoogleMap;
MapView mapView;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
MapLocationListener mapLocationListener;
LocationManager locManager;
Button buttonSaveLocation;
double[] markerLocation;
private final static int mapZoomLevel = 18;
Context context = this;
AppCompatActivity activity = (AppCompatActivity) context;
private class GoogleApiClientConnection implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
#Override
public void onConnected(Bundle bundle) {
Log.d("onConnected", "onConnected.");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(50);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(context,
ACCESS_FINE_LOCATION)
== PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mapLocationListener);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
private class MapLocationListener implements com.google.android.gms.location.LocationListener {
#Override
public void onLocationChanged(Location location) {
// DO MY LOCATION UPDATE...
}
}
private class OnMapReady implements OnMapReadyCallback {
#Override
public void onMapReady(GoogleMap googleMap) {
Log.d("onMapReady", "onMapReady.");
mGoogleMap = googleMap;
mGoogleMap.setOnMapClickListener(new OnMapTouched());
//if device OS SDK >= 23 (Marshmallow)
if (Build.VERSION.SDK_INT >= 23) {
//IF Location Permission already granted
if (ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PERMISSION_GRANTED) {
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
} else {
// Request Location Permission
checkLocationPermission();
}
}
//if device OS is version 5 Lollipop and below ( <= SDK_22 )
else {
if (checkLocationPermission_v22()) {
buildGoogleApiClient();
mGoogleMap.setMyLocationEnabled(true);
} else {
// AlertDialog TO EXIT MAP...
}
}
}
}
private class OnMapTouched implements GoogleMap.OnMapClickListener {
#Override
public void onMapClick(LatLng latLng) {
// CHANGE MY MARKER...
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// createMyView = setContentView(...)
createMyView(R.layout.activity_maps, R.id.toolbar);
mapLocationListener = new MapLocationListener();
buttonSaveLocation = (Button) findViewById(R.id.button_save_location);
buttonSaveLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
saveLocation();
}
});
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReady());
mapView.onResume();
}
private void saveLocation() {
Intent i = new Intent();
i.putExtra("savedlocation", markerLocation);
setResult(RESULT_OK, i);
this.onPause();
}
#Override
public void onPause() {
super.onPause();
if (mGoogleApiClient != null && mapLocationListener != null) {
Log.d("FusedLocationApi", "run!");
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mapLocationListener);
}
activity.finish();
}
protected synchronized void buildGoogleApiClient() {
Log.d("buildGoogleApiClient", "buildGoogleApiClient.");
GoogleApiClientConnection g = new GoogleApiClientConnection();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(g)
.addOnConnectionFailedListener(g)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
private boolean checkLocationPermission_v22() {
locManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
if (locManager.isProviderEnabled(GPS_PROVIDER) ||
locManager.isProviderEnabled(NETWORK_PROVIDER)) {
return true;
} else {
return false;
}
}
public static final int FR_PERMISSIONS_REQUEST_CODE_LOCATION = 99;
private void checkLocationPermission() {
if (ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) != PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{ACCESS_FINE_LOCATION}, FR_PERMISSIONS_REQUEST_CODE_LOCATION);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case FR_PERMISSIONS_REQUEST_CODE_LOCATION: {
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PERMISSION_GRANTED) {
if (mGoogleApiClient == null) {
buildGoogleApiClient();
}
mGoogleMap.setMyLocationEnabled(true);
}
} else {
// AlertDialog to EXIT MAP...
}
return;
}
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (Build.VERSION.SDK_INT > 5
&& keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) {
this.onPause();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
this.onPause();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Use this class for location tracking .
public class FusedLocationTracker implements LocationListener, GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
Context context;
protected GoogleApiClient mGoogleApiClient;
GoogleMap googleMap;
LocationRequest mLocationRequest;
Location mCurrentLocation = null;
private static final long INTERVAL = 1000 * 5;
private static final long FASTEST_INTERVAL = 1000 * 1;
String TAG = "LocationTracker";
boolean isGPSEnabled, wifiStatus;
WifiManager wifiManager;
FusedLocationDataInterface fusedLocationDataInterface;
public FusedLocationTracker(Context context){
this.context = context;
wifiManager = (WifiManager)this.context.getSystemService(Context.WIFI_SERVICE);
wifiStatus = wifiManager.isWifiEnabled();
if (!wifiStatus){
wifiManager.setWifiEnabled(true);
wifiManager.startScan();
}
createLocationRequest();
buildGoogleApiClient();
}
public void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
Log.d(TAG, "createLocationRequest");
}
protected synchronized void buildGoogleApiClient() {
Log.d(TAG, "buildGoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG, "onConnected");
startLocationUpdates();
}
public void startLocationUpdates() {
Log.d(TAG, "startLocationUpdates");
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "onConnectionSuspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionSuspended");
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged");
if (location != null) {
fusedLocationDataInterface = (FusedLocationDataInterface) context;
fusedLocationDataInterface.getFusedLocationData(location);
}
}
public void stopLocationUpdates() {
Log.d(TAG, "stopLocationUpdates");
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
if (!wifiStatus){
wifiManager.setWifiEnabled(false);
}
}
}
}
create interface for writing location
public interface FusedLocationDataInterface {
public void getFusedLocationData(Location location);
}
In main activity in onCreate() method create object of class FusedLocationTracker.class and implement interface in the activity.
override this method
#Override
public void getFusedLocationData(Location location) {
LatLng locate = new LatLng(location.getLatitude(), location.getLongitude());
mMap.addMarker(new MarkerOptions().title("My Location").position(locate));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(locate, 16.0f));
}
if you want to stop the locations service call the stopLocationUpdates().
Solved.It's my fault with not getting well known understand MapView well. Just call MapView.onPause() inside my overriden onPause() solve the problem.

App enters in loop while during localization

I think my app enters loop because once it starts in device, it doesn't respond to any commands including lisener the button. I believe that the problem is the methods for permits in RunTime. I'm sorry for my English.
My code is:
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final int REQUEST_RESOLVE_ERROR = 3;
private GoogleApiClient mGoogleApiClient;
private volatile Location mCurrentLocation;
private static final int REQUEST_PERMISSION_LOCATE = 2;
private static final int LOCATION_DURATE_TIME = 5000;
private boolean mResolvingError = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Toast.makeText(MainActivity.this, "ciao", Toast.LENGTH_LONG).show();
}
});
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
Toast.makeText(MainActivity.this, "connesso", Toast.LENGTH_LONG).show();
}
#Override
protected void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
manageLocationPermission();
}
#Override
public void onConnectionSuspended(int i) {
}
//gestione dell'errore
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult)
{
if (mResolvingError) {
// If we're already managing an error we skip the invocation of this method
return;
} else if (connectionResult.hasResolution()) {
// Here we check if the ConnectionResult has already the solution. If it has
// we start the resolution process
try {
// Starting resolution
mResolvingError = true;
// We launch the Intent using a request id
connectionResult.startResolutionForResult(MainActivity.this, REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
// If we have an error during resolution we can start again.
mGoogleApiClient.connect();
}
} else {
// The ConnectionResult in the worse case has the error code we have to manage
// into a Dialog
// Starting resolution
mResolvingError = true;
}
}
//location update
private void updateLocation()
{
LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setNumUpdates(1)
.setExpirationDuration(LOCATION_DURATE_TIME);
LocationServices.FusedLocationApi
.requestLocationUpdates(mGoogleApiClient, locationRequest, new LocationListener() {
#Override
public void onLocationChanged(Location location)
{
mCurrentLocation = location;
}
});
}
private void startLocationListener()
{
updateLocation();
}
//permessi in RunTime
private void manageLocationPermission()
{
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
{
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
{
new AlertDialog.Builder(this)
.setTitle("Permesso di geolocalizzazione")
.setMessage("Devi dare il permesso alla geolocalizzazione")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSION_LOCATE);
}
})
.create()
.show();
}
else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSION_LOCATE);
}
}else
{
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
manageLocationPermission();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == REQUEST_PERMISSION_LOCATE)
{
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
//se mi hanno accettato i permessi
startLocationListener();
}
else{
new AlertDialog.Builder(this)
.setTitle("Permesso di geolocalizzazione")
.setMessage("Devi dare il permesso alla geolocalizzazione")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.create()
.show();
}
}
}
}
If manageLocationPermission() is called with the permissions already granted, your code enters the following else clause
} else {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
manageLocationPermission();
}
Here you're calling the same function again, and since the permissions are granted, you will enter the same else clause, and again the same thing... You see where this is going? Just remove manageLocationPermission() from this else clause

Categories

Resources