I created a class to use the LocationListener but I am getting classCastException when I request for location updates
This is my class code
public class Loc implements
LocationListener, GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
// A request to connect to Location Services
private LocationRequest mLocationRequest;
// Stores the current instantiation of the location client in this object
private LocationClient mLocationClient;
/*
* Note if updates have been turned on. Starts out as "false"; is set to
* "true" in the method handleRequestSuccess of LocationUpdateReceiver.
*/
boolean mUpdatesRequested = false;
// Milliseconds per second
public static final int MILLISECONDS_PER_SECOND = 1000;
// The update interval
public static final int UPDATE_INTERVAL_IN_SECONDS = 10;
// A fast interval ceiling
public static final int FAST_CEILING_IN_SECONDS = 1;
// Update interval in milliseconds
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = MILLISECONDS_PER_SECOND
* UPDATE_INTERVAL_IN_SECONDS;
// A fast ceiling of update intervals, used when the app is visible
public static final long FAST_INTERVAL_CEILING_IN_MILLISECONDS = MILLISECONDS_PER_SECOND
* FAST_CEILING_IN_SECONDS;
Location currentLocation ;
LocationListener locListener;
Context x;
public Loc(Context con) {
// Create a new global location parameters object
this.x=con;
mLocationRequest = LocationRequest.create();
/*
* Set the update interval
*/
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the interval ceiling to one minute
mLocationRequest
.setFastestInterval(FAST_INTERVAL_CEILING_IN_MILLISECONDS);
// Note that location updates are off until the user turns them on
mUpdatesRequested = false;
/*
* Create a new location client, using the enclosing class to handle
* callbacks.
*/
mLocationClient = new LocationClient(con, this, this);
}
public void stop() { // If the client is connected
if (mLocationClient.isConnected()) {
stopPeriodicUpdates();
}
// After disconnect() is called, the client is considered "dead".
mLocationClient.disconnect();
}
public void start() {
mLocationClient.connect();
}
public void startUpdates() {
mUpdatesRequested = true;
startPeriodicUpdates();
}
public Location getLocation() {
// Get the current location
currentLocation = mLocationClient.getLastLocation();
// Display the current location in the UI
Log.e("lat log", "" + currentLocation.getLatitude() + " , "
+ currentLocation.getLongitude());
return currentLocation;
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
currentLocation=location;
Log.e("lat log", "" + currentLocation.getLatitude() + " , "
+ currentLocation.getLongitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
private void stopPeriodicUpdates() {
mLocationClient
.removeLocationUpdates((com.google.android.gms.location.LocationListener) this);
}
private void startPeriodicUpdates() {
mLocationClient.requestLocationUpdates(mLocationRequest,(com.google.android.gms.location.LocationListener) this);
}
}
This is my activity code
public class MainActivity1 extends Activity {
Loc l;
TextView t;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_activity1);
t=(TextView)findViewById(R.id.txt);
l = new Loc(getApplicationContext());
l.start();
}
public void getLoc(View v) {
// l.getLocation();
l.startUpdates();
}
I am getting my lat and long perfectly fine.
But my issue is with for location updates
I get this error
Caused by: java.lang.ClassCastException: com.example.gps.Loc cannot be cast to com.google.android.gms.location.LocationListener
I do get that I cannot pass LocationListener like this
mLocationClient.requestLocationUpdates(mLocationRequest,(com.google.android.gms.location.LocationListener) this);
But how should I exactly pass it??
Only needed to add the interface
com.google.android.gms.location.LocationListener
like this.
public class Loc implements
GooglePlayServicesClient.ConnectionCallbacks
,GooglePlayServicesClient.OnConnectionFailedListener
,com.google.android.gms.location.LocationListener {
//...
}
Related
I have used GoogleApiClient for getting GPS location. i have create one service and every 10 seconds getting data from GPS but the problem is there are so many times onConnectionSuspended() called and i am not geeting any GPS data.
following is my service code that i am getting GPS location
<service
android:name="com.GPSService"
android:enabled="true"
android:exported="false"
android:process=":ServiceProcess"
android:stopWithTask="false" />
Service code
public class GPSService extends Service implements LocationListener, ConnectionCallbacks, OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
protected GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
protected boolean requestingLocationUpdate = true;
private Location mLastLocation;
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FASTEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 5; // 5 meters
private static final String LOCATION = "Location Not Available";
private double latitude;
private double longitude;
private String mLastUpdateTime;
Intent intents;
RequestParams requestParams = null;
private static final String TAG = "GPSService";
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
helper.insertServiceLog("oncreate");
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d("GPSService", "onCreate");
//
mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onDestroy() {
Log.i("MyReceiver", "onTaskRemoved called Oooooooooooooppppssssss!!!!");
mGoogleApiClient.disconnect();
}
#Override
public void onStart(Intent intent, int startid) {
super.onStart(intent, startid);
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d("GPSService", "onStart");
mGoogleApiClient.connect();
if (mGoogleApiClient.isConnected() && requestingLocationUpdate) {
startLocationUpdates();
}
}
#Override
public final int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onLocationChanged(Location loc) {
//String imei = "2";
mLastLocation = loc;
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle arg0) {
if (requestingLocationUpdate) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
//LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);
startLocationUpdates();
Toast.makeText(this, "Started the location update", Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionSuspended(int arg0) {
Log.d("GPSService", "onConnectionSuspended called");
}
/**
* Starting the location updates
*/
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Log.i("MyReceiver", "onTaskRemoved called Oooooooooooooppppssssss!!!!");
super.onTaskRemoved(rootIntent);
}
}
can somebody please help me to figure out this issue.
Is there a particular reason why you're running the service in a different process? I think it might be related that. Try changing the declaration of the service to
<service
android:name="com.GPSService"
android:enabled="true"
android:exported="false" />
I want after open dialog and click on location button, detect user's location and show user's location and then user dismiss dialog, location listener removes and not get location from onLocationChanged, I try used locationManager.removeUpdate(locListener)on override dismiss but not any chance and location after dismiss again shows! why? How can i detect user's location after show dialog and after detect location, location listener remove? Thanks
EDIT:
public class DialogTest extends Dialog implements
android.view.View.OnClickListener {
Context context;
LocationManager locationManager;
LocationListener locationListener;
Location location;
public DialogTest(Context context) {
super(context);
// TODO Auto-generated constructor stub
requestWindowFeature(Window.FEATURE_NO_TITLE);
this.context = context;
setContentView(R.layout.profile_dialog);
getWindow().setBackgroundDrawableResource(R.drawable.background_dialog);
firstAccessLocation=true;
setCancelable(true);
initialize();
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
findAddress();
}
private void findAddress() {
// if (gpsCheckBox.isChecked()) {
locationManager = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSLocationListener();
locationManager.requestLocationUpdates(locationManager.GPS_PROVIDER, 0,
0, locationListener);
locationManager.requestLocationUpdates(
locationManager.NETWORK_PROVIDER, 0, 0, locationListener);
// }
}
private void stopTracking(){
if(locationManager!=null){
locationManager.removeUpdates(locationListener);
}
}
#Override
public void dismiss() {
// TODO Auto-generated method stub
stopTracking();
gpsTurnOff();
super.dismiss();
}
public class GPSLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc) {
// TODO Auto-generated method stub
if(location!=null)
Log.e("location", location.getLatitude()+"");
location = loc;
if (location != null&& firstAccessLocation) {
setAddress(location.getLatitude(), location.getLongitude());
firstAccessLocation=false;
}
Toast.makeText(context, "changed", Toast.LENGTH_LONG).show();
Log.e("location", "changed");
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
}
In new code you should use LocationClient rather then LocationManager. It's more efficient in getting the location with minimal energy(battery drain) with greater accuracy. Look here LocationClient vs LocationManager. With LocationClient established you can call getLastLocation() which provide you last location and doesn't start cyclic location updates.
If you want to stick with LocationManager use requestSingleUpdate (String provider, LocationListener listener, Looper looper) method to get only one newest location from it.
I using the new API for get location: android.https://developer.android.com/training/location/retrieve-current.html
Some times when I get the location, It come out of date. I get out at some place and go to another place, then the application returns the first place location to me. It happens when I out the WiFi. When I use the WiFi it works perfectly. Am I missing some method or something else?
public class NewGPSTracker implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener,
LocationListener, com.google.android.gms.location.LocationListener {
private LocationRequest lr;
private LocationClient lc;
Location location;
double latitude = 0;
double longitude = 0;
Context context;
static Boolean status = false;
public int res = 0;
boolean conectado;
public NewGPSTracker(Context context) {
this.context = context;
lr = LocationRequest.create();
lr.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
lr.setInterval(5000);
lr.setFastestInterval(1000);
lc = new LocationClient(context, this, this);
}
#Override
public void onLocationChanged(Location location) {
if (conectado) {
lc.removeLocationUpdates(this);
lc.requestLocationUpdates(lr, this);
location = lc.getLastLocation();
if(location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
Log.e("NewGPSTracker", ""+arg0);
}
#Override
public void onConnected(Bundle connectionHint) {
conectado = true;
Log.i("NewGPSTracker", "Google Play Services Conectado.");
lc.requestLocationUpdates(lr, this);
location = lc.getLastLocation();
if(location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
public void connect(){
lc.connect();
}
public void disconnect(){
lc.disconnect();
}
#Override
public void onDisconnected() {
}
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
lr.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
I exactly don't know what are you using. But when i use google API for this situation, solved a issue like that.
Now line that at top always uses HIGH_ACCURACY of GPS/WI-FI. And your situation it looks like WI-FI always.. As you know there are two method to find user's location. (GPS/WI-FI) when you change your GPS location and not opening your WI-FI it should keep showing first.
So try to change it as a static variable like GPS, if it's possible.
Sorry for my bad english, complicated situation..
Calculate the difference of the time stamp of the location to the current time.
If it is more than some seconds, it is an old positoin, e.g the last known.
In that case wait for the next position, untill time difference is less than some seconds.
I'm trying to get gps location of the current location using simple android program. I used onLocationChanged() method for this. But it returning the coordinates as 0.0. The users permission part is correct. This is the code of main one.
public class MainActivity extends Activity {
GPSTracker gps;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.button1);
final TextView tv = (TextView) findViewById(R.id.textView1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
gps = new GPSTracker(MainActivity.this);
double lat = gps.latitude;
String mlat = String.valueOf(lat);
tv.setText(mlat);
}
});
}
}
this is the gps location class that im using...
public class GPSTracker extends Service implements LocationListener{
private final Context mContext;
boolean isGPSEnabled = false;
boolean canGetLocation = false;
Location location;
double latitude;
double longtitude;
protected LocationManager locationManager;
public GPSTracker(Context context){
this.mContext = context;
getLocation();
}
public Location getLocation(){
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
return null;
}
protected void onStart() {
}
protected void onPause(){
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
latitude = location.getLatitude();
longtitude = location.getLongitude();
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
**i have used the gps coordinates for calculating the distance using location updates. but problem is that if i am standing at same place the coordinates changes and distance is changing with out moving anywhere. I want to change it only when I have moved min 10 mtrs.
## Activity ##
//Activity
public TextView dist;
public double lati1,lati2,longi1,longi2;
private boolean run1 = false;
private Handler handler1 = new Handler();
private Runnable task1 = new Runnable() {
public void run() {
// TODO Auto-generated method stub
if (run1) {
handler1.postDelayed(this,1000);
if(lati1==0.0&&longi1==0.0)
{
lati1=Service1.lat1;
longi1=Service1.lon1;
}
lati2=Service1.lat1;
longi2=Service1.lon1;
double R=63710;
double dLat=Math.toRadians(lati2-lati1);
double dLon=Math.toRadians(longi2-longi1);
double a=Math.sin(dLat/2)*Math.sin(dLat/2)+
Math.cos(Math.toRadians(lati1))*Math.cos(Math.toRadians(lati2))*
Math.sin(dLon/2)*Math.sin(dLon/2);
double c=2*Math.asin(Math.sqrt(a));
double d=R*c;
d=(double)(Math.round(d*100.00))/1000.00;
distance+=d;
String s=String.format("%.2f", distance);
dist.setText(s);
lati1 = lati2;
longi1 = longi2;
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dist=(TextView)findViewById(R.id.distancetextView);
Intent i = new Intent(context, Service1.class);
startService(i);
}
## Service ##
//Service
private double new_latitude = 0.0;
private double new_longitude = 0.0;
public static double lat1=0.0,lon1=0.0;
LocationManager locationManager = null;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 0.0f, this);
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
locationManager.removeUpdates(this);
super.onDestroy();
}
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
new_latitude=location.getLatitude();
new_longitude=location.getLongitude();
lat1=new_latitude;
lon1=new_longitude;
}
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}****
I should see the code you are writing. But without it I can say that there is a function, that you call, and it give you location update each X milliseconds. Or you can get the latest updated location, again, I should see your code.
UPDATE:
change this line
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 0.0f, this);
to
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L, 10.0f, this);
You'll receive updates after moving 10m.
The second parameter is time in millisecond, the third is minimum distance. But it doesn't mean you'll get update exactly at the requested time or requested distance, but rather about it.
//Public or class variable of previous speed initialised on class.
// float previousSpeed;
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
new_latitude=location.getLatitude();
new_longitude=location.getLongitude();
float speed = location.getSpeed();
//You could also use location.hasSpeed(), which is a boolean, but it almost
//always returns True
if(speed > DESIRED_LIMIT && previousSpeed > DESIRED_LIMIT){
lat1=new_latitude;
lon1=new_longitude;
}
previousSpeed = speed;
}
So something like that. That condition is not very well optimized or designed. But that is how you get GPS speed from location object. You can tweak the speed limit or the whole condition to get the best results. Or add even more history of speed to monitor.
You can use the location spoofer application from the android market and specify the duration of spoofing the location and also the distance