I am trying to create a background service that updates the current gps position. I am getting a NullPointerException at line LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
HomeActivity launches a service
startService(new Intent(getApplicationContext(), ForHire.class));
Service (ForHire) creates a TimerTask Updates
public class ForHire extends Service {
...
private Timer getUpdatesNow = new Timer();
private Updates updates = new Updates(getUpdatesNow);
#Override
public void onCreate() {
...
getUpdatesNow.schedule(updates, God.KM20TIME);
Log.v("Taxeeta", "Notification created");
}
private class Updates extends TimerTask implements LocationListener {
private Timer getUpdatesNow;
public Updates(Timer newGetUpdatesNow) {
super();
getUpdatesNow = newGetUpdatesNow;
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
God.KM20TIME, God.KM20DISTANCE, (LocationListener) this);
}
public void run() {
...
//do some cleanup
}
#Override
public void onLocationChanged(Location location) {
Log.v("Taxeeta", "Location changed");
// do a update of the current location.
}
The first issue is that I get that NullPointerException.
Second issue is that onLocationChanged is never called if I comment out LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, God.KM20TIME, God.KM20DISTANCE, (LocationListener) this); these 2 lines.
My Manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<application ...>
...
<uses-library android:name="com.google.android.maps" />
</application>
What am I missing here ?
Edit : Values of KM20TIME = 5000 (5seconds), and KM20DISTANCE = 1 (1meter). Apart from the fix's below, I walked out of my house, got GPS enabled and walked from one corner of my balcony to the other. I noticed that my gps (LSB) changed as I walked from one corner to the other every 5 seconds.
The earliest you can call new Updates(getUpdatesNow); is inside your Service's onCreate() method. The simple reason is that getSystemService() requires a valid Context which doesn't exist before entering onCreate().
Try:
private Timer getUpdatesNow;
private Updates updates;
#Override
public void onCreate() {
...
getUpdatesNow = new Timer();
updates = new Updates(getUpdatesNow);
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
Toast.makeText(getBaseContext(),
"Last Location is found..",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getBaseContext(),
"Last Location is not found..",
Toast.LENGTH_LONG).show();
}
LocationListener locationListener = new LocationListener() {
public void onStatusChanged(String provider,
int status, Bundle extras) {
}
public void onProviderEnabled(String provider) {
Toast.makeText(getApplicationContext(),
"Gps Enabled", Toast.LENGTH_SHORT).show();
}
public void onProviderDisabled(String provider) {
Toast.makeText(getApplicationContext(),
"Gps Disabled", Toast.LENGTH_SHORT).show();
}
#Override
public void onLocationChanged(Location location) {
Log.i("geolocation",
"lat is : " + location.getLatitude()
+ " and " + location.getLongitude()
+ "");
Toast.makeText(getBaseContext(),
"Location is Changed..", Toast.LENGTH_LONG)
.show();
}
};
// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0,
locationListener);
#Override
public void onCreate() {
new Updates(getUpdatesNow);
...
getUpdatesNow.schedule(updates, God.KM20TIME);
Log.v("Taxeeta", "Notification created");
}
Related
I am using below code to periodically check location change after some distance travelled. But onLocationChanged never called.
Android Manifiest File having permission:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(MainActivity1.this,
"Provider enabled: " + provider, Toast.LENGTH_SHORT)
.show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(MainActivity1.this,
"Provider disabled: " + provider, Toast.LENGTH_SHORT)
.show();
}
#Override
public void onLocationChanged(Location location) {
Toast.makeText(MainActivity1.this, "onLocationChanged",
Toast.LENGTH_SHORT).show();
}
};
locationManager = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0,10, locationListener);
Check your current location id null or not. & then call onlocationchanged() if its null in your activity or service.
private Location location;
if (location != null) {
mCurrentLoc.onLocationChanged(location);
}
You just need to change like:-
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
0,10, (android.location.LocationListener) this);
That's it.
I tried to get latitude and longitude for current location.
However, when I use the code below, the location listener is not triggered at all.
I've added the LOCATION permission in manifest file.
anyone can help?
Here is the java code:
package com.example.setlocaction;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends Activity{
double latitude, longitude, radius;
LocationManager mlocManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Acquire a reference to the system Location Manager
mlocManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener()
{
public void onLocationChanged(Location loc)
{
// Called when a new location is found by the network location provider.
Log.i("loc","location changed");
if (loc!=null)
{
loc.getLatitude();
loc.getLongitude();
String Text = "My current location is: " +
"Latitud =" + loc.getLatitude() +
"Longitud = " + loc.getLongitude();
Toast.makeText( getApplicationContext(),Text,Toast.LENGTH_SHORT).show();
}
}
public void onStatusChanged(String provider, int status, Bundle extras)
{}
public void onProviderEnabled(String provider)
{}
public void onProviderDisabled(String provider)
{}
};
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
// 高精度
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = mlocManager.getBestProvider(criteria, true);
mlocManager.requestLocationUpdates(provider, 2000, 0, locationListener);
Location loc=mlocManager.getLastKnownLocation(provider);
if (loc==null)
{
Log.i("loc","loc=null");
}
}
}
mafinest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.setlocaction"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.setlocaction.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
First of all, your current solution utilizes "getLastKnownLocation" which means, that if you actually retrieve the longitude and latitude, you cannot be certain that it will return the current position of the user. It simply returns the location which was last found which can be miles away.
That is nothing wrong in doing so, but it leaves for uncertainty.
Instead, I have personally implemented a location manager for retrieving the current position of the user by utilizing the code provided in the following post which works great:
https://stackoverflow.com/a/17290348/2399772
By using this specific code, you will also be given the advantage that it tries to utilize the WiFi connection first for determining the position which is slightly better. It that doesn't work, it will utilize the GPS instead. Additionally, if GPS services aren't enabled, a dialogue will be shown telling the user to enable those.
Hope this helps.
Additional notes
As I have stated in a previous post, the Geolocation API will does unfortunately not work on all devices. You can hereby consider using the Reverse Geocoding API instead, which is additionally much more reliable:
https://developers.google.com/maps/documentation/geocoding/
It simply requires that you send a HTTP request which should contain latitude and longitude, whereafter it will provide a response in JSON which is easily parsed.
Sometimes it takes a while for the device to deliver the first locations if you haven't used the GPS before. Also, make sure you're in a location where you can gps updates, or try on the emulator using geo fix via telnet.
try this
public class MyLocationActivity extends Activity implements LocationListener {
private LocationManager mgr;
private String best;
public static double myLocationLatitude;
public static double myLocationLongitude;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
dumpProviders();
Criteria criteria = new Criteria();
best = mgr.getBestProvider(criteria, true);
Log.d("best provider", best);
Location location = mgr.getLastKnownLocation(best);
dumpLocation(location);
//may be some intent here
}
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
dumpLocation(location);
}
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
protected void onPause() {
super.onPause();
mgr.removeUpdates(this);
}
#Override
protected void onResume() {
super.onResume();
mgr.requestLocationUpdates(best, 15000, 1, this);
}
private void dumpLocation(Location l) {
if (l == null) {
myLocationLatitude = 0.0;
myLocationLongitude = 0.0;
} else {
myLocationLatitude = l.getLatitude();
myLocationLongitude = l.getLongitude();
}
}
private void dumpProviders() {
List<String> providers = mgr.getAllProviders();
for (String p : providers) {
dumpProviders(p);
}
}
private void dumpProviders(String s) {
LocationProvider info = mgr.getProvider(s);
StringBuilder builder = new StringBuilder();
builder.append("name: ").append(info.getName());
}
}
Add following code to your java file
private void GetLocation()
{
LocationDetail pref_LocationDetail = new LocationDetail(_context);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(objCommon.isOnline(_context))
{
if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER ,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationListener()
);
return ;
}
else if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER ,
MINIMUM_TIME_BETWEEN_UPDATES,
MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
new MyLocationListener()
);
return ;
}
}
}
private class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location location)
{
LocationDetail pref_LocationDetail = new LocationDetail(_context);
double Lattitude = location.getLatitude();
double Longitude = location.getLongitude();
Toast.makeText(_context , location.getProvider().toString() , Toast.LENGTH_LONG).show();
locationManager.removeUpdates(this);
locationManager = null;
}
public void onStatusChanged(String s, int i, Bundle b) {
Toast.makeText(_context , "Provider status changed",
Toast.LENGTH_LONG).show();
}
public void onProviderDisabled(String s) {
Toast.makeText(_context ,
"Provider disabled by the user. GPS turned off",
Toast.LENGTH_LONG).show();
}
public void onProviderEnabled(String s) {
Toast.makeText(_context ,
"Provider enabled by the user. GPS turned on",
Toast.LENGTH_LONG).show();
}
}
just add following code in your manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
I am trying to get the current location (latitude and longitude values) in my application.
I used the below code.
Problem is----------------->
When the Best provider is GPS,Location returned is null.
I learned some SO posts and I added LocationListener to my code,then it worked but when I restart my device and I run the application again,it gives the same NULL values when Provider is GPS. I don't understand why its not working now.
I also learned that Gps provider is slow in getting values,so I have to add LocationListener to solve this issue.So,I added this to my code
LocationListener locationListener = new MyLocationListener();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 35000, 10, locationListener);
complete code here ----------->
public void getCurrentlocation()
{
String providers = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
Log.e("provider"," "+providers);
if(!providers.contains("gps")){
final Intent poke = new Intent();
poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
sendBroadcast(poke);
Log.e("your gps is","enabled");
}
LocationListener locationListener = new MyLocationListener();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 35000, 10, locationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 35000, 10, locationListener);
// Define the criteria how to select the locatioin provider -> use
// default
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria,true);
Log.e("location provider",""+provider);
Location location = locationManager.getLastKnownLocation(provider);
// Initialize the location fields
if (location != null)
{
System.out.println("Provider " + provider + " has been selected.");
strLatitude=String.valueOf(location.getLatitude());
strLongitude=String.valueOf(location.getLongitude());
Log.e("lattitude",strLatitude);
Log.e("logntitude",strLongitude);
latituteField.setText( strLatitude);
longitudeField.setText(strLongitude);
}
else
{
strLatitude=String.valueOf(0);
strLongitude=String.valueOf(0);
Log.e("lattitude",strLatitude);
Log.e("logntitude",strLongitude);
latituteField.setText( strLatitude);
longitudeField.setText(strLongitude);
}
}
private class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location location)
{
// mLattitude = location.getLatitude();
// mLongitude = location.getLongitude();
//
// Log.w("value : ",
// String.valueOf(location.getLatitude()) + String.valueOf(location.getLongitude())
// +
//
//
// context.sendBroadcast(new Intent(Constants.BRDCAST_LOCATION_UPDATED));
}
#Override
public void onProviderDisabled(String provider)
{
// Log.w("provider", provider);
}
#Override
public void onProviderEnabled(String provider)
{
// Log.w("provider", provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
// Log.w("status", String.valueOf(status));
}
}
please help
Thanks in advance
Well I tried the following code and it fetched the latitude and longitude:
public class MainActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Use the LocationManager class to obtain GPS locations */
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> providers = lm.getProviders(true);
/* Loop over the array backwards, and if you get an accurate location, then break out the loop*/
Location location = null;
for (int i=providers.size()-1; i>=0; i--) {
location = lm.getLastKnownLocation(providers.get(i));
if (location != null) break;
}
String Text = "My current location is: " +
"Latitud = " + location.getLatitude() +
"Longitud = " + location.getLongitude();
Toast.makeText( getApplicationContext(), Text, Toast.LENGTH_SHORT).show();
}
AndroidManifest.xml:
See that the following permissions are set:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
I want to start a service which will run in the background, and will show latitude and longitude every 30 to 45 seconds.
Below is my code which I'm using:
public class LocalService extends Service implements LocationListener {
private final static String TAG = "LocalService";
LocationManager lm;
public LocalService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
subscribeToLocationUpdates();
}
public void onLocationChanged(Location loc) {
Log.d(TAG, loc.toString());
Toast.makeText(getApplicationContext(), loc.getLatitude() + " - " + loc.getLongitude(), Toast.LENGTH_LONG).show();
Log.i("Location", loc.getLatitude() + " - " + loc.getLongitude());
}
public void onProviderEnabled(String s) {
}
public void onProviderDisabled(String s) {
}
public void onStatusChanged(String s, int i, Bundle b) {
}
public void subscribeToLocationUpdates() {
this.lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
this.lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30, 0, this);
}
}
I'm calling my service like this:
startService(new Intent(TimerServiceActivity.this,
LocalService.class));
This is my manifest code for service:
<service android:name="LocalService" >
Whenever I am running this code it gives me an error message that unfortunately, TimerService has stopped.
Do you have the permissions added in your manifest?
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
I instead highly recommend using this library optimized for battery usage and is rather simple to use:
http://code.google.com/p/little-fluffy-location-library/
Based on the concepts in, and some code adapted from,
android-protips-location by Reto Meier, from his blog post A Deep Dive
Into Location.
You need to subscribe to a provider first. To do this, add this in the beginning of your onCreate() method:
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Define the criteria how to select the locatioin provider -> use
// default
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
Log.v(TAG, "Init");
// Initialize the location fields
if (location != null) {
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
}
I am using following code to get current latitude and longitude. But none of the toasts are displayed.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* Use the LocationManager class to obtain GPS locations */
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
}
/* Class My Location Listener */
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
Log.i("","loccccccccccc");
loc.getLatitude();
loc.getLongitude();
String Text = "My current location is: " + "Latitud = " + loc.getLatitude() + "Longitud = " + loc.getLongitude();
Toast.makeText( getApplicationContext(), Text, Toast.LENGTH_LONG).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
} }
}
used all the permissions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.CONTROL_LOCATION_UPDATES" />
<uses-permission android:name="android.permission.INTERNET" />
Thanks for the help in advance
Sneha
GPS doesn't work in indoor mode..depending upon the place..It works perfectly on outdoor mode..So check it out outside..
GPS_PROVIDER is slow when compared to The NETWORK_PROVIDER.And in room it may not work.Switch on the GPS if you want to use GPS_PROVIDER. or else use NETWORK_PROVIDER.
Go through this
Note:Network_provider is not so accurate compared to the GPS_Provider.. But it is fast..
See this link also
#Sneha --
1) is this line printed Log.i("","loccccccccccc");
2) Check this
3) try to use criteria
4) Test this on mobile (Device) & also test it outside as GPS doesn't work inside.