Mogens TrasherDK
Mogens TrasherDK

Reputation: 670

ClassCastException class extends android.location.Location

Here's another bug that I just can't figure out.

I've got this class ExtendedLocation extends Location that throws ClassCastException when instantiated by currentGpsLocation = new ExtendedLocation((ExtendedLocation) location);

Looking at the stack trace tells me absolutely nothing about a possible solution. Maybe someone smarter than me, can chime in.

I'm pretty new at this java/android stuff, so this might be a simple problem to some, just not for me.


The Exception

: java.lang.ClassCastException: android.location.Location
:   at ru.alperez.gpsdub.GpsActivity$1.onLocationChanged(GpsActivity.java:485)
:   at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:227)
:   at android.location.LocationManager$ListenerTransport.access$000(LocationManager.java:160)
:   at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:176)
:   at android.os.Handler.dispatchMessage(Handler.java:99)
:   at android.os.Looper.loop(Looper.java:130)
:   at android.app.ActivityThread.main(ActivityThread.java:3687)
:   at java.lang.reflect.Method.invokeNative(Native Method)
:   at java.lang.reflect.Method.invoke(Method.java:507)
:   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
:   at dalvik.system.NativeStart.main(Native Method)

ExtendedLocation.class

package ru.alperez.model;

import org.json.JSONException;
import org.json.JSONObject;

import android.location.Location;

public class ExtendedLocation extends Location{

    public ExtendedLocation(ExtendedLocation l) {
        super(l);
    }

    public ExtendedLocation(String provider) {
        super(provider);
    }

    public JSONObject toJSON() throws JSONException {
        JSONObject ret = new JSONObject();
        ret.put("accuracy", this.getAccuracy());
        ret.put("altitude", this.getAltitude());
        ret.put("bearing", this.getBearing());
        ret.put("lat", this.getLatitude());
        ret.put("lon", this.getLongitude());
        ret.put("provider", this.getProvider());
        ret.put("speed", this.getSpeed());
        ret.put("time", this.getTime());
        return ret;
    }

    public static ExtendedLocation fromJSON(JSONObject jLocation) {
        ExtendedLocation ret = null;
        try {
            ret = new ExtendedLocation(jLocation.optString("provider"));
            ret.setAccuracy((float) jLocation.optDouble("accuracy"));
            ret.setAltitude(jLocation.optDouble("altitude"));
            ret.setBearing((float) jLocation.optDouble("bearing"));
            ret.setLatitude(jLocation.optDouble("lat"));
            ret.setLongitude(jLocation.optDouble("lon"));
            ret.setSpeed((float) jLocation.optDouble("speed"));
            ret.setTime(jLocation.optLong("time"));
        } catch (Exception e) {
            ret = null;
        }
        return ret;
    }
}

The offending code

    @Override
    public void onLocationChanged(Location location) {
        Log.d(TAG, "LocationListener::onLocationChanged: "+location);
        try
        {
            currentGpsLocation = new ExtendedLocation((ExtendedLocation) location);
            Log.d(TAG, "LocationListener::onLocationChanged:currentGpsLocation "+currentGpsLocation);
        }
        catch (ClassCastException e)
        {
            Log.d(TAG,"ExtendedLocation failed.",e);
            return;
        }
        if (!USE_NMEA) {
            populateCurrentGpsData(currentGpsLocation, lastFixState, referenceGpsPoint);
        }
    }

Upvotes: 1

Views: 855

Answers (5)

Daniel S.
Daniel S.

Reputation: 6640

You are trying to cast a Location to an ExtendedLocation:

currentGpsLocation = new ExtendedLocation((ExtendedLocation) location);
                                          ^^^^^^^^^^^ here ^^^^^^^^^^

This is not allowed. An ExtendedLocation is a Location. This is not true for the other way around: A Location is not an ExtendedLocation. Thus, a Location can not be casted to an ExtendedLocation.

However, you don't need this. You have to change two spots:

Change the above line to

currentGpsLocation = new ExtendedLocation(location);

and change the constructor of the class ExtendedLocation to take a Location instead of an ExtendedLocation:

public ExtendedLocation(Location l) {
    super(l);
}

Upvotes: 0

Sushil
Sushil

Reputation: 8478

Base classes shouldn't know anything about classes derived from them, otherwise the problems highlighted above will arise. Downcasting is a 'code smell', and downcasting in the base class to a derived class is particularly 'smelly'. Such designs can lead to difficult to resolve circular dependencies too.

If you want a base class to make use of derived class implementations use the Template method pattern i.e add a virtual or abstract method in your base class and override and implement it in the derived class. You can then safely call this from the base class.

Follow the link below for methods to cast:

Java; casting base class to derived class

Upvotes: 0

Pawel Cala
Pawel Cala

Reputation: 685

Your ExtendedLocation should take a Location class object as parameter in consutructor. You also can't cast location object to ExtendLocation.

Upvotes: 0

gunar
gunar

Reputation: 14710

onLocationChanged is called by LocationManager. The object is passed by that manager, it's not an object of your class. Instead of having a constructor like you have there:

public ExtendedLocation(ExtendedLocation l) {
    super(l);
}

try to replace it with:

public ExtendedLocation(Location l) {
    super(l);
}

and this line from onLocationChanged

  currentGpsLocation = new ExtendedLocation((ExtendedLocation) location);

becomes:

  currentGpsLocation = new ExtendedLocation(location);

Upvotes: 1

esentsov
esentsov

Reputation: 6522

Change parameter of the constructor of ExtendedLocation to Location and remove class casting from calling this: currentGpsLocation = new ExtendedLocation(location);

Upvotes: 0

Related Questions