Cannot seem to get user location - java

I've been trying to get the longitude and latitude of a users location with Android. I've been trying to use the LocationManger however it does not seem to activate and give me an update. Here is the code, any ideas what I'm doing wrong?
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) { // Called when a new location is found by the network location provider.
System.out.println(location.getLatitude());
System.out.println(location.getLongitude());
locationplace = location.getProvider();
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {} };// Register the listener with the Location Manager to receive location updates
//locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
System.out.println(locationplace);

Related

How can I get location in background every 10 minutes even if the app is not running?

I'm working on a small app that displays the history of my geolocation over the year. To achieve this, I'm getting the geolocation every 10 minutes in the background, even if the app is not running. For this, I've tried to make an AlarmManager that calls a Service (which gets the location using LocationManager) every 600000ms (10m). It didn't work at all so I've made my AlarmManager calls a BroadcastReceiver which then calls the Service. But this didn't work as well.
I'm new at Services, BroadcastReceivers and sheduled tasks... I've searched on Google how to make this work properly, how to make sheduled tasks, how to correctly setup an AlarmManager, how to get location every X minutes in background, etc. but I didn't find any useful tutorial or answers on StackOverflow.
So here I am. How could I achieve this?
Here's the code I currently use in my project:
MainActivity.java:
private void startAlarmTimerTask() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alm = new Intent(this, LocationBroadcast.class);
PendingIntent pendInt = PendingIntent.getBroadcast(this, 0, alm, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 600000, pendInt);
}
//Call startAlarmTimerTask(); in onCreate()
LocationBroadcast.java:
public class LocationBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Fetching location...", Toast.LENGTH_LONG);
Intent serviceIntent = new Intent(context, LocationService.class);
context.startService(serviceIntent);
}
}
LocationService.java:
public class LocationService extends Service implements LocationListener {
private SharedPreferences dataly;
private LocationManager geolocation;
#Override
public void onCreate() {
geolocation = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
geolocation.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, this);
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onLocationChanged(Location location) {
final double latitude = location.getLatitude();
final double longitude = location.getLongitude();
//Save latitude and longitude in SharedPreferences
//Stop location updates
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}

LocationListner no longer listen for gps status change after upgrade to Android 7

After updated my app to support Android 7 the GPS listner no longer is invoked when the GPS on/off is triggerd. If I refresh my activity it works as expected on Android 6, but not in Android 7. Does anyone have any idea. I have added both my listner, and code releated to gps change in my activity.
I have if its difficult a theory to override the backpressed or activity resumed to recreate view, but havn't suceeded with that either .
GPSListner.java
public abstract class GPSListener implements LocationListener {
private Context context;
public GPSListener(Context context) {
this.context = context;
}
#Override
public void onProviderEnabled(String provider) {
onGPSOn();
}
#Override
public void onProviderDisabled(String provider) {
onGPSOff();
}
public abstract void onGPSOff();
public abstract void onGPSOn();
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
My class
gpsListener = new GPSListener(this) {
#Override
public void onGPSOff() {
gpsImg.setImageResource(R.drawable.notok);
}
#Override
public void onGPSOn() {
gpsImg.setImageResource(R.drawable.ok);
}
};
final LocationManager manager;
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
final ImageView gpsImg = (ImageView) findViewById(R.id.gpsstatus);
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
gpsImg.setImageResource(R.drawable.ok);
} else {
gpsImg.setImageResource(R.drawable.notok); //not ok
}
This last method opens the gps settings.
public View.OnClickListener onButtongpsClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(gpsOptionsIntent);
}
};
Obtaining location is a bit tricky itself. Only GPS can have line-of-sight issues and would vary depending on device too, not just Android version. Over the years Android location services have matured and using up-to-date standard practices does result in higher consistency with respect to results.
By the way, LocationClient is deprecated. FusedLocationProviderApi does not use it anymore.
It works through a GoogleApiClient and this part makes the GooglePlayServices mandatory. You have options if this does not suit your app.
Making your app location aware suggests:
The Google Play services location APIs are preferred over the Android
framework location APIs (android.location) as a way of adding location
awareness to your app. If you are currently using the Android
framework location APIs, you are strongly encouraged to switch to the
Google Play services location APIs as soon as possible.
You can break it into parts to understand it better, like;
Building the GoogleApiClient
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this) //this = activity
.addApi(LocationServices.API)
.addConnectionCallbacks(this) //interfaces implemented
.addOnConnectionFailedListener(this)
.build();
}
Requesting location,
// Create the location request
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
// Request location updates
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
Try the last known location, if that requirement works for you,
#Override
public void onConnected(Bundle bundle) {
Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
...}
onConnected() is the callback from GoogleApiClient...
So there is more to location than initialising a client and implementing the listener. I recommend you go through a few questions or android docs to ensure you implement what suits your requirement.
Also,
instead of
Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); ,
use SettingsApi
can refer to Enabling location mode...
Some useful Q&As:
Comprehensive answer for obtaining location
Good to go through LocationRequest part here if you want to avoid reading in detail
final LocationManager manager;
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Do i even have to comment on this one? Read it again and you will understand what is wrong with it.
Hint. Try:
final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
You can used fused location api to get the location
Fused Location Api :
Fused Location Provider automatically decides best location from the available options for that it uses GPS and Network Provider, So if the device GPS is off we can still get the location from Network provider vice versa.
Why Fused Location Api ?
Consumption of power while fetching location.
It will give accurate
location based on user priority.
Piggyback which means you can get
location every time when other application hits for location for you
advantage is user not blame you for that you just getting those
location which other application request.
We don’t have to pick the
provider(GPS or network provider)
please refer code for following for getting location.
LocationService : We required these for getting continues location and these register as pending intent so whenever device got new location these service invoke.
public class LocationService extends IntentService {
private String TAG = this.getClass().getSimpleName();
public LocationService() {
super("Fused Location");
}
public LocationService(String name) {
super("Fused Location");
}
#Override
protected void onHandleIntent(Intent intent) {
Location location = intent.getParcelableExtra(LocationClient.KEY_LOCATION_CHANGED);
if(location !=null){
Log.i(TAG, "onHandleIntent " + location.getLatitude() + "," + location.getLongitude());
// write your code here.
}
}
}
MainActivity : which register callbacks for it which tell us whether we are connected or disconnected with api.
public class MainActivity extends Activity implements GooglePlayServicesClient.ConnectionCallbacks,GooglePlayServicesClient.OnConnectionFailedListener,LocationListener {
private String TAG = this.getClass().getSimpleName();
private LocationClient locationclient;
private LocationRequest locationrequest;
private Intent mIntentService;
private PendingIntent mPendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIntentService = new Intent(this,LocationService.class);
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, 0);
int resp =GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if(resp == ConnectionResult.SUCCESS){
locationclient = new LocationClient(this,this,this);
locationclient.connect();
}
else{
Toast.makeText(this, "Google Play Service Error " + resp, Toast.LENGTH_LONG).show();
}
}
public void buttonClicked(View v){
if(v.getId() == R.id.btnLastLoc){
if(locationclient!=null && locationclient.isConnected()){
Location loc =locationclient.getLastLocation();
Log.i(TAG, "Last Known Location :" + loc.getLatitude() + "," + loc.getLongitude());
txtLastKnownLoc.setText(loc.getLatitude() + "," + loc.getLongitude());
}
}
if(v.getId() == R.id.btnStartRequest){
if(locationclient!=null && locationclient.isConnected()){
if(((Button)v).getText().equals("Start")){
locationrequest = LocationRequest.create();
locationrequest.setInterval(Long.parseLong(etLocationInterval.getText().toString()));
locationclient.requestLocationUpdates(locationrequest, this);
((Button) v).setText("Stop");
}
else{
locationclient.removeLocationUpdates(this);
((Button) v).setText("Start");
}
}
}
if(v.getId() == R.id.btnRequestLocationIntent){
if(((Button)v).getText().equals("Start")){
locationrequest = LocationRequest.create();
locationrequest.setInterval(100);
locationclient.requestLocationUpdates(locationrequest, mPendingIntent);
((Button) v).setText("Stop");
}
else{
locationclient.removeLocationUpdates(mPendingIntent);
((Button) v).setText("Start");
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(locationclient!=null)
locationclient.disconnect();
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "onConnected");
txtConnectionStatus.setText("Connection Status : Connected");
}
#Override
public void onDisconnected() {
Log.i(TAG, "onDisconnected");
txtConnectionStatus.setText("Connection Status : Disconnected");
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "onConnectionFailed");
txtConnectionStatus.setText("Connection Status : Fail");
}
#Override
public void onLocationChanged(Location location) {
if(location!=null){
Log.i(TAG, "Location Request :" + location.getLatitude() + "," + location.getLongitude());
}
}
}
For more reference refer below link
https://github.com/riteshreddyr/fused-location-provider
https://github.com/kpbird/fused-location-provider-example
Hope these help you.

How to obtain the current location data as a sharable link (Android App Development)?

I am working on an app that obtains the current location of the device as a link, and sends it as SMS to a specified number. The link which when clicked, must open google maps with the current location of the device marked on it.
I checked developer docs and could find fused location provider.
But that doesn't seem to be relevant here.
Instead of fused location provider, I used the LocationManager() and LocationListener().
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
textView.append("\nLatitude: " + location.getLatitude() + " Longitude: " + location.getLongitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
locationManager.requestSingleUpdate("gps", locationListener, null);

Getting location android?

I want to receive location updates every second for a small period of time, so I wrote this code:
public void registerListener() {
if (ActivityCompat.checkSelfPermission(c, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(c, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
} else {
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 10, locationListener);
}
}
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();
Log.v(TAG, ""+longitude + " " +latitude);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
#Override
public void onProviderEnabled(String provider) {}
#Override
public void onProviderDisabled(String provider) {}
};
I call registerListener() from somewhere else. The problem is, my location update is only called once, and I only get that log once. Also, the log only comes about 5-10 seconds after calling registerListener.
What is the reason of the slowness, and why isn't the location being updated?
Thanks,
Ruchir
You're requesting GPS location. It will take a few seconds to get a satellite lock for the first time. It may never happen if you can't receive a signal lock (indoors in some buildings, too far underground, physical damage to the phone like a loose antenna (common in early gen Samsungs)).
As for not receiving it again- you won't receive it again unless you move at least 10 meters. Change that to 0 and see it come every second.

How can I check if GPS is enabled before I try to use it

I have the following code and it's not good because sometimes GPS takes very long
How can I do the following:
Check if GPS is enabled
Use GPS if it is enabled otherwise use the network provider.
If GPS takes more than 30 seconds, use network.
I can do this with my own logic using a time or Thread.sleep but I think there might be a more stabndard way
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
locationCallback(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
There's no standard way to do this, you have to do it on your own with the help of:
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//Do what you need if enabled...
} else {
//Do what you need if not enabled...
}
And this permission in manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
As recommendation if GPS is not enabled, usually the standard specifies to popup the Location Settings Activity so the user can specifically enable it...
Hope this helps.
Regards!
Just using this code, you can check GPS availability:
LocationManager mlocManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);;
boolean enabled = mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Think you could use the code in my answer to: Location servise GPS Force closed
It gives you a callback method for GPS first fix and location changes that can be very convenient. This also makes it easy to change the implementation of GPSTracker to switch to network if GPS takes too long to get a first fix.

Categories