Unable to get location co-ordinates and display them on screen - android

My requirement is very simple.
I want to get the user's location and display the same on screen.
The emulator shows Currently reported location correctly. But I am unable to extract the same to my TextView. Not quite sure what is wrong here.
Please find my code below. Help appreciated.
MainActivity.java
package com.varun.weatherbee;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import java.util.List;
public class MainActivity extends AppCompatActivity implements LocationListener {
private final static String TAG = MainActivity.class.getSimpleName();
TextView mLongitudeText;
TextView mLatitudeText;
LocationManager locationManager;
Location location;
double latitude;
double longitutde;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLatitudeText = (TextView) findViewById(R.id.mLatitudeText);
mLongitudeText = (TextView) findViewById(R.id.mLongitudeText);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
List<String> providers = locationManager.getAllProviders();
for (int i = 0; i < providers.size(); i++) {
Log.i(TAG, providers.get(i));
}
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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.
Log.i(TAG, "Permission Granted");
return;
}
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
mLatitudeText.setText("Latitude: " + location.getLatitude());
mLongitudeText.setText("Longitude: " + location.getLongitude());
}
}
#Override
protected void onStart() {
super.onStart();
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 1000, this);
}
#Override
protected void onStop() {
super.onStop();
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.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;
}
locationManager.removeUpdates(this);
}
#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) {
}
}

try this code:
1.your runtime permission check is wrong
2.Also getLastKnownLocation(LocationManager.GPS_PROVIDER) can return null See here
3.You can change textview with updated location in onLocationChanged() method
here is a simple example:
public class MainActivity extends AppCompatActivity implements LocationListener {
private final static String TAG = MainActivity.class.getSimpleName();
TextView mLongitudeText;
TextView mLatitudeText;
LocationManager locationManager;
Location location;
double latitude;
double longitutde;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLatitudeText = (TextView) findViewById(R.id.mLatitudeText);
mLongitudeText = (TextView) findViewById(R.id.mLongitudeText);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
List<String> providers = locationManager.getAllProviders();
for (int i = 0; i < providers.size(); i++) {
Log.i(TAG, providers.get(i));
}
//location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (isLocationPermissionGranted()) {
location = getLastKnownLocation();
if (location != null) {
mLatitudeText.setText("Latitude: " + location.getLatitude());
mLongitudeText.setText("Longitude: " + location.getLongitude());
}
}
}
private Location getLastKnownLocation() {
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
List<String> providers = locationManager.getProviders(true);
Location bestLocation = null;
for (String provider : providers) {
Location l = locationManager.getLastKnownLocation(provider);
if (l == null) {
continue;
}
if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
// Found best last known location: %s", l);
bestLocation = l;
}
}
return bestLocation;
}
#Override
protected void onStart() {
super.onStart();
if (isLocationPermissionGranted())
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 1000, this);
}
#Override
protected void onStop() {
super.onStop();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
mLatitudeText.setText("Latitude: " + location.getLatitude());
mLongitudeText.setText("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) {
}
public boolean isLocationPermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission is granted");
return true;
} else {
Log.v(TAG, "Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
return false;
}
} else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG, "Permission is granted");
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission: " + permissions[0] + "was " + grantResults[0]);
//resume tasks needing this permission
}
}
}

Related

Android background location service stops at some time

I want to get current location in background every 15 mins. I have created a background service with Timer. But it stops at some point of time.
Please correct me, how to run this all time in background without stopping?
public class BackgroundService extends Service implements LocationListener {
public static String str_receiver = "app.BackgroundService.Locationreceiver";
boolean isGPSEnable = false;
boolean isNetworkEnable = false;
double latitude, longitude;
LocationManager locationManager;
Location location;
long notify_interval = 600000;
Intent intent;
private Handler mHandler = new Handler();
private Timer mTimer = null;
public BackgroundService() {
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(BackgroundService.this, "Getting Location", Toast.LENGTH_SHORT).show();
mTimer = new Timer();
mTimer.schedule(new TimerTaskToGetLocation(), 60000, notify_interval);
intent = new Intent(str_receiver);
}
#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) {
}
private void fn_getlocation() {
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnable && !isNetworkEnable) {
Toast.makeText(BackgroundService.this, "GPS disabled", Toast.LENGTH_LONG).show();
} else {
if (isNetworkEnable) {
location = null;
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;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000000, 20, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
Log.e("latitude", location.getLatitude() + "");
Log.e("longitude >>", location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
}
if (isGPSEnable) {
location = null;
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;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000000, 20, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
Log.e("latitude>>", location.getLatitude() + "");
Log.e("longitude", location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
}
}
}
private void fn_update(Location location) {
intent.putExtra("latutide", location.getLatitude() + "");
intent.putExtra("longitude", location.getLongitude() + "");
sendBroadcast(intent);
}
private class TimerTaskToGetLocation extends TimerTask {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
fn_getlocation();
}
});
}
}
In Manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
The thing is location services are expensive for android. Thus, android os stops heavy background services when the apps go in the background. That is why you do not get the location or in some cases, you might get the Old location itself.
Please take a look at this, Background Execution Limit in android for having idea about the problem.
https://medium.com/exploring-android/exploring-background-execution-limits-on-android-oreo-ab384762a66c
So, you should use ForegroundService which generates a Notification while the service is running.
Its onCreate() is somewhat like
override fun onCreate() {
super.onCreate()
log("The service has been created".toUpperCase())
var notification = createNotification()
startForeground(1, notification)
}
And it should be started as
context.startForegroundService(it)
Here, is an article regarding its detailed implementation.
This should help you I hope.

fused location provider give wrong location

i am using Fusedlocationprovider get my current location, Some times I get the current location currently ,but some times give wrong location ,but near the current location. what is the reason, I am new to android , help me to solve this problem.thank you.
This is the my code :
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private FusedLocationProviderApi locationProvider = LocationServices.FusedLocationApi;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private double myLatitude;
private double myLongitude;
private static final int MY_PERMISSION_REQUEST_FINE_LOCATION = 101;
private static final int MY_PERMISSION_REQUEST_COARSE_LOCATION = 102;
private boolean permissionIsGranted = false;
String phonenumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = getIntent().getExtras();
if (extras != null) {
phonenumber = extras.getString("key11");
getIntent().removeExtra("key11");
}
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
locationRequest = new LocationRequest();
locationRequest.setInterval(10 * 1000);
locationRequest.setFastestInterval(15 * 1000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onConnected(Bundle bundle) {
requestLocationUpdates();
}
private void requestLocationUpdates() {
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.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_REQUEST_FINE_LOCATION);
} else {
permissionIsGranted = true;
}
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
myLatitude = location.getLatitude();
myLongitude = location.getLongitude();
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phonenumber, null, "*-"+String.valueOf(myLatitude)+"#"+String.valueOf(myLongitude)+"#", null, null);
System.exit(0);
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.connect();
}
#Override
protected void onResume() {
super.onResume();
if (permissionIsGranted) {
if (googleApiClient.isConnected()) {
requestLocationUpdates();
}
}
}
#Override
protected void onPause() {
super.onPause();
if (permissionIsGranted)
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
#Override
protected void onStop() {
super.onStop();
if (permissionIsGranted)
googleApiClient.disconnect();
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case MY_PERMISSION_REQUEST_FINE_LOCATION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission granted
permissionIsGranted = true;
} else {
//permission denied
permissionIsGranted = false;
Toast.makeText(getApplicationContext(), "This app requires location permission to be granted", Toast.LENGTH_SHORT).show();
}
break;
case MY_PERMISSION_REQUEST_COARSE_LOCATION:
// do something for coarse location
break;
}
}
}
Please help me Android Pro Developers Solve my error!

my Lat Long always display 0.0

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends AppCompatActivity implements com.google.android.gms.location.LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private final FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private double currentLattitude;
private double currentLongitude;
Button button;
TextView textView;
#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) findViewById(R.id.btn_start);
textView = (TextView) findViewById(R.id.txt_route);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textView.setText(String.valueOf(currentLattitude + currentLongitude));
}
});
}
#Override
protected void onResume() {
super.onResume();
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle arg0) {
final LocationRequest locationRequest = LocationRequest.create();
locationRequest
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
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;
}
fusedLocationProviderApi.requestLocationUpdates(mGoogleApiClient,
locationRequest, this);
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
//
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
fusedLocationProviderApi.requestLocationUpdates(mGoogleApiClient,
locationRequest, this);
// currentLattitude = location.getLatitude();
// currentLongitude = location.getLongitude();
Log.e("Lat" , "" +currentLattitude);
Log.e("Long" , "" +currentLongitude);
} else {
currentLattitude = location.getLatitude();
currentLongitude = location.getLongitude();
Log.e("Lat" , "" +currentLattitude);
Log.e("Long" , "" +currentLongitude);
}
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
// the location is no more than 10 min old, and with reasonable
// accurarcy (50m), done
if (System.currentTimeMillis() < location.getTime() + 10 * 60 * 1000
&& location.getAccuracy() < 50) {
mGoogleApiClient.disconnect();
mGoogleApiClient = null;
}
}
}
In my app i get the lat long of user without enabling the GPSLocation of Mobile . I tried with this code a lot but this code always throws the LAT LONG 0.0 . Please help me with this issue . Tell me what will be the issue with this code.?
So basically ,
Manifest.permission.ACCESS_FINE_LOCATION - this will work with GPS
Manifest.permission.ACCESS_COARSE_LOCATION - this will work with Network
So change your && with || will work for you , currently you are asking that both should be Permitted.
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;
}
You should get coordinates in the 'onLocationChanged' callback, by getting latitude and longitude from the Location object passed in the function.
Also check if your manifest has this:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Add this code in "OnCreate":
// CHECK LOCATION SERVICES IS ON
LocationManagerControl locationManagerControl = new LocationManagerControl(this);
try {
if (locationManagerControl.isLocationServiceAvailable()) {
try {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
} catch (Exception e) {
e.printStackTrace();
}
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
// #Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
// #Override
public void onLocationChanged(Location location) {
user_lat = location.getLatitude();
user_lng = location.getLongitude();
}
};
} else {
locationManagerControl.createLocationServiceError(MainActivity.this);
}
}catch (Exception e){
e.printStackTrace();
}
And you want to call it wherever you want:
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
And don't forget to add:
LocationManager locationManager;
LocationListener locationListener;
And add the following permissions to your application in your AndroidManifest.xml file
INTERNET
ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
I hope this helps..

How can I get continuous location updates in Android like in Google Maps?

I'm building a friend tracking android app. While my friend activated the app and goes away along with his GPS and cellular data on, I need to track him on my device. That's the concept.
I've implemented LocationListener class and now I can get the last updated location either from Gps or Network but is not updated unless I launch Google Maps and return to my application. After googling, I learned that location cache is updated only by GMaps.!
Is there an alternate way to continuously update location?
What if when I need to get continues location after the device locked without making use of Wakelock?
This is my location listener class:
package com.amazinginside;
/** AMAZING LOCATION SUPPORT CLASS, Devoloped By SANGEETH NANDAKUMAR */
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
public class AmazingLocation extends Service implements LocationListener
{
private final Context mContext;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
boolean canGetLocation = false;
Location location;
double latitude=0.0;
double longitude=0.0;
//MINIMUM DISTANCE FOR UPDATE (meters)
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 0 Meters
//MINIMUM TIME BETWEEN UPDATES
private static final long MIN_TIME_BW_UPDATES = 1000 * 0; // 0 Seconds
//LOCATION MANAGER
protected LocationManager locationManager;
//CONSTRUCTOR
public AmazingLocation(Context context)
{
this.mContext = context;
getLocation();
}
//LOCATION PROVISION
public Location getLocation()
{
try
{
//GET LOCATION MANAGER
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
//CHECK GPS STATE
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
//CHECK NETWORK STATE
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled)
{
//NO LOCATION PROVIDERS
}
else
{
this.canGetLocation = true;
/** GET LOCATION FROM NETWORK */
//FIRST GET LOCATION FROM NETWORK
if (isNetworkEnabled)
{
//REQUEST LOCATION
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null)
{
//START WITH LAST KNOWN LOCATION
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//EXTRACT LOCATION
if (location != null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
/** GET LOCATION FROM GPS SENSOR */
//THEN GET LOCATION FROM GPS
if (isGPSEnabled)
{
if (location == null)
{
//REQUEST GPS LOCATION
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null)
{
//EXTRACT LAST KNOWN LOCATION
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//RETURN LOCATION
if (location != null)
{
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return location;
}
//STOP GPS SENSOR
public void stopUsingGPS()
{
if(locationManager != null)
{
locationManager.removeUpdates(AmazingLocation.this);
}
}
//EXTRACT LATTITUDE
public double getLatitude()
{
if(location != null)
{
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
//EXTACT LONGITUDE
public double getLongitude()
{
if(location != null)
{
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
//CAN I GET THE LOCATION.?
public AmazingStatus canGetLocation()
{
AmazingStatus status=new AmazingStatus();
if(this.canGetLocation)
{
status.setStatus(true);
status.setErrorcode(0);
status.setErrormsg("Task completed");
}
else
{
status.setStatus(false);
status.setErrorcode(145);
status.setErrormsg("Please turn on GPS access manually");
}
return status;
}
//SHOW LOCATION SETTINGS
public AmazingStatus showSettingsAlert()
{
final AmazingStatus status=new AmazingStatus();
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
alertDialog.setTitle("REQUIRES LOCATION ACCESS");
alertDialog.setMessage("Please allow GPS access to this app");
//POSSITIVE REPLY
alertDialog.setPositiveButton("Allow", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,int which)
{
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
status.setStatus(true);
status.setErrorcode(0);
status.setErrormsg("Task completed");
}
});
//NEGATIVE REPLY
alertDialog.setNegativeButton("Deny", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
status.setStatus(false);
status.setErrorcode(408);
status.setErrormsg("User denied permission");
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
return status;
}
//UNUSED OVERRIDE METHORDS...
#Override
public void onLocationChanged(Location location)
{
getLocation();
}
#Override
public void onProviderDisabled(String provider)
{
}
#Override
public void onProviderEnabled(String provider)
{
getLocation();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
getLocation();
}
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
}
This my onCreate() method:
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//CREATE A BUTTON HANDLER
Button start_btn=(Button)findViewById(R.id.start_location_streaming);
//ON BUTTON CLICK EVENT
start_btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//REPEAT A METHORD AT SPECIFIC INTERVALS
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask()
{
#Override
public void run()
{
TimerMethod();
}
}, 0, 8000);
}
}); }
These are other methods:
private void TimerMethod()
{
//START METHORD
this.runOnUiThread(Timer_Tick);
}
//LOCATION REPORTING METHORD
private Runnable Timer_Tick = new Runnable()
{
public void run()
{
Toast.makeText(MainActivity.this, "Current latitude : "+Double.toString(getLocation().latitude), Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this, "Current longitude : "+Double.toString(getLocation().longitude), Toast.LENGTH_SHORT).show();
}
};
private LatLng getLocation()
{
//CREATE A LOCATION CLASS INSTANCE
AmazingLocation gps = new AmazingLocation(this);
//RETRIVE LOCATION
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
//RETURN LOCATION
LatLng loc=new LatLng(latitude,longitude);
return loc;
}
Now the problem is, the toast just shows previously known the location and not updating unless I opened Google Maps and returned.
Any help will be great for me.
Use Fused location provider in Android set your interval in that:
For an example create your activity like this:
public class LocationActivity extends Activity implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "LocationActivity";
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
Button btnFusedLocation;
TextView tvLocation;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
String mLastUpdateTime;
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate ...............................");
//show error dialog if GoolglePlayServices not available
if (!isGooglePlayServicesAvailable()) {
finish();
}
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
setContentView(R.layout.activity_main);
tvLocation = (TextView) findViewById(R.id.tvLocation);
btnFusedLocation = (Button) findViewById(R.id.btnShowLocation);
btnFusedLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
updateUI();
}
});
}
#Override
public void onStart() {
super.onStart();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
#Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop fired ..............");
mGoogleApiClient.disconnect();
Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
protected void startLocationUpdates() {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed: " + connectionResult.toString());
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Firing onLocationChanged..............................................");
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
private void updateUI() {
Log.d(TAG, "UI update initiated .............");
if (null != mCurrentLocation) {
String lat = String.valueOf(mCurrentLocation.getLatitude());
String lng = String.valueOf(mCurrentLocation.getLongitude());
tvLocation.setText("At Time: " + mLastUpdateTime + "\n" +
"Latitude: " + lat + "\n" +
"Longitude: " + lng + "\n" +
"Accuracy: " + mCurrentLocation.getAccuracy() + "\n" +
"Provider: " + mCurrentLocation.getProvider());
} else {
Log.d(TAG, "location is null ...............");
}
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
Log.d(TAG, "Location update stopped .......................");
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
}
Google play services required:
To get continiuos location update, you can refer to the above provided answers .
But You can also make use of LocationServices which is faster than other approaches and much easy and efficient to get location.
This approach is quit long but kindly follow all the provided steps
So let me provide a brief working :
Add these two dependencies in your gradle app file
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.android.gms:play-services-location:17.0.0'
Add these permissions in the manifest file outside applicationtag
Declare variable outside onCreate
private FusedLocationProviderClient fusedLocationClient;
private LocationRequest mLocationRequest;
private LocationCallback mlocationCallback;
private LocationSettingsRequest.Builder builder;
private static final int REQUEST_CHECK_SETTINGS = 102;
Now inside onCreate :
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
fetchLastLocation();
mlocationCallback = new LocationCallback() {
#Override
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
return;
}
for (Location location : locationResult.getLocations()) {
// Update UI with location data
// ...
Log.e("CONTINIOUSLOC: ", location.toString());
}
};
};
mLocationRequest = createLocationRequest();
builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
checkLocationSetting(builder);
No define fetchLastLocation method
private void fetchLastLocation() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#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 Activity#requestPermissions for more details.
// Toast.makeText(MainActivity.this, "Permission not granted, Kindly allow permission", Toast.LENGTH_LONG).show();
showPermissionAlert();
return;
}
}
fusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations this can be null.
if (location != null) {
// Logic to handle location object
Log.e("LAST LOCATION: ", location.toString()); // You will get your last location here
}
}
});
}
Now define other two method for permission request
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 123: {
// If request is cancelled, the result arrays are empty.
if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
// permission was denied, show alert to explain permission
showPermissionAlert();
}else{
//permission is granted now start a background service
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fetchLastLocation();
}
}
}
}
}
private void showPermissionAlert(){
if (ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainHomeActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 123);
}
}
now define createLocationRequest method and checkLocationSetting method :
protected LocationRequest createLocationRequest() {
LocationRequest mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(30000);
mLocationRequest.setFastestInterval(10000);
mLocationRequest.setSmallestDisplacement(30);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return mLocationRequest;
}
private void checkLocationSetting(LocationSettingsRequest.Builder builder) {
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
#Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
// All location settings are satisfied. The client can initialize
// location requests here.
// ...
startLocationUpdates();
return;
}
});
task.addOnFailureListener(this, new OnFailureListener() {
#Override
public void onFailure(#NonNull final Exception e) {
if (e instanceof ResolvableApiException) {
// Location settings are not satisfied, but this can be fixed
AlertDialog.Builder builder1 = new AlertDialog.Builder(mContext);
builder1.setTitle("Continious Location Request");
builder1.setMessage("This request is essential to get location update continiously");
builder1.create();
builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ResolvableApiException resolvable = (ResolvableApiException) e;
try {
resolvable.startResolutionForResult(MainHomeActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e1) {
e1.printStackTrace();
}
}
});
builder1.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(mContext, "Location update permission not granted", Toast.LENGTH_LONG).show();
}
});
builder1.show();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if (requestCode == REQUEST_CHECK_SETTINGS) {
if (resultCode == RESULT_OK) {
// All location settings are satisfied. The client can initialize
// location requests here.
startLocationUpdates();
}
else {
checkLocationSetting(builder);
}
}
}
now atlast define startLocationUpdates and stopLocationUpdates method :
public void startLocationUpdates() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// Activity#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 Activity#requestPermissions for more details.
return;
}
}
fusedLocationClient.requestLocationUpdates(mLocationRequest,
mlocationCallback,
null /* Looper */);
}
private void stopLocationUpdates() {
fusedLocationClient.removeLocationUpdates(mlocationCallback);
}
Note : Replace context with your class context and call stopLocationUpdates() inside onDestroy method of your class
Note : For any futher information or doubt you can refer to :
https://developer.android.com/training/location/retrieve-current
https://developer.android.com/training/location/change-location-settings
https://developer.android.com/training/location/receive-location-updates
You will get your location in Logcat.
Hope this will hope you or somebody else !
I believe rather than reinventing the wheel, you can use one of the third party libraries that are easy to implement and in this case, battery efficient. One of the library I found is SmartLocation. You can add the following dependency in your build.gradle (app) to start using the library.
compile 'io.nlopez.smartlocation:library:3.2.9'
After adding the dependency, you should rebuild the project to get the references.
As an example you can try the following code in your Activity.
Button start_btn=(Button)findViewById(R.id.start_location_streaming);
Context context = start_btn.getContext();
Handler handler = new Handler();
start_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SmartLocation.with(context).location().start(locationListener);
}
});
OnLocationUpdatedListener locationListener = new OnLocationUpdatedListener({
#Override
public void onLocationUpdated(Location location) {
double lat = location.getLatitude();
double lng = location.getLongitude();
handler.postDelayed(locationRunnable,8000);
}
});
Runnable locationRunnable = new Runnable({
#Override
public void run() {
SmartLocation.with(context).location().start(locationListener);
}
});
You can stop location tracking in onStop() method
#Override
public void onStop() {
SmartLocation.with(context).location().stop();
super.onStop();
}
SmartLocation library will give you more than what is expected, just try that once.
Note: Make sure your application does have ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION (both) to have accurate results. Don't forget to ask for permissions at runtime for Android 6.0 and above.
You should use android services, rather than the app itself. This way you will achieve to run code continuously in the background and you will receive the location even if the app closes.
https://www.tutorialspoint.com/android/android_services.htm

Adding location permissions on marshmallow

I am writing a code to get lastknownlocation from location manager and this prompted me to add runtime permissions.
Here is my code:
public class MainActivity extends AppCompatActivity implements LocationListener {
LocationManager locationManager;
String provider;
private final int MY_PERMISSIONS_REQUEST_CODE=1;
Location location;
Boolean isPermissionGranted=false;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
provider = locationManager.getBestProvider(new Criteria(), false);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},MY_PERMISSIONS_REQUEST_CODE);
}
// return;
}
}
public void getlastknownposition()
{
}
#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
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == MY_PERMISSIONS_REQUEST_CODE)
{
if(grantResults[0]==PackageManager.PERMISSION_GRANTED && grantResults[1]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this," granted "+grantResults[0]+"granted2"+grantResults[1], Toast.LENGTH_SHORT).show();
location = locationManager.getLastKnownLocation(provider);}
}
}
}
I am still getting an error "Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with checkPermission) or explicitly handle a potential SecurityException
in onRequestPermissionsResult on line location = locationManager.getLastKnownLocation(provider);
Put some braces around the second if in onPermissionsResult =)
if(requestCode == MY_PERMISSIONS_REQUEST_CODE){
if(grantResults[0]==PackageManager.PERMISSION_GRANTED && grantResults[1]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this," granted "+grantResults[0]+"granted2"+grantResults[1], Toast.LENGTH_SHORT).show();
location = locationManager.getLastKnownLocation(provider);
} else {
//TODO handle user saying NO! :)
}
}
Tip: if you request FINE_LOCATION you don't need COARSE, it already includes it.
Replace the line
location = locationManager.getLastKnownLocation(provider);
with
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
location = locationManager.getLastKnownLocation(provider);
}

Categories

Resources