Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to serialize for android.location class?

I'm trying to serialize my location class (using android.location class)

but, it gives me an error!

11-21 21:25:37.337: W/System.err(3152): java.io.NotSerializableException: android.location

So, I tried to extend the android.location.Location class.

private class NewLocation extends Location implements Serializable {
        private String Provider;
        private double Latitude, Longitude, Altitude;

private float bear;
        public NewLocation(Location l) {
            super(l);
            Provider = l.getProvider();
            Latitude = l.getLatitude();
            Longitude = l.getLongitude();
            Altitude = l.getAltitude();
            bear = l.getBearing();
        }
    }

After that, i tried to serialize the extended class, but the same error.

Here is the serialization code

 public static byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ObjectOutput oos = new ObjectOutputStream(bao);
        byte[] data = null;
        oos.writeObject(obj);
        oos.flush();
        oos.close();
        data = bao.toByteArray();
        return data;
    }

why this error?

like image 531
user3017494 Avatar asked Nov 21 '13 12:11

user3017494


People also ask

Can class be serialized?

Static fields in a class cannot be serialized. If the serialversionuid is different in the read class it will throw a InvalidClassException exception. If a class implements serializable then all its sub classes will also be serializable.

How do you serialize class?

For serializing the object, we call the writeObject() method of ObjectOutputStream class, and for deserialization we call the readObject() method of ObjectInputStream class. We must have to implement the Serializable interface for serializing the object.

What is serializable class in Android?

Serializable is a markable interface or we can call as an empty interface. It doesn't have any pre-implemented methods. Serializable is going to convert an object to byte stream. So the user can pass the data between one activity to another activity.

How is location determined in Android?

An Android device uses two different location providers to estimate its current geographic coordinates: gps on the one hand and network on the other, the latter based either on the calculated distance to multiple cell towers or on the known location of the Wi-Fi network provider to which we are connected.


3 Answers

Android's Location class already implements Parcelable. So you are better off with it rather than implementing your own Serialization.

Simply use the following to get bytes out from Location:

Parcel p = Parcel.obtain();
objLocation.writeToParcel(p, 0);
final byte[] b = p.marshall();      //now you've got bytes
p.recycle();

However, you should not save bytes (in persistent storage) from Parecelable object for later use because it is designed for high-performance IPC transport, and is not a general-purpose serialization mechanism.

like image 71
waqaslam Avatar answered Oct 16 '22 20:10

waqaslam


You can not make a non-serializable class serializable just implementing the Serializable interface. A serializable class must inherit from a serializable class (if an inherited class) and have all its attributes serializable themselves.

All subtypes of a serializable class are themselves serializable. http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html

However, if you want to serialize a Parcelable class it is still possible, but surely it would not be a good practice.

like image 36
Massimo Avatar answered Oct 16 '22 22:10

Massimo


I needed to serialize Location with most of it's members as well, not just latitude and longitude. I ended up writing my own Serializable class. The source code is bellow. The usage would be:

SerializableLocation serializable = new SerializableLocation(fromLocation);
Location toLocation = serializable.toLocation();

Few notes:

  1. Location's extras (Bundle) are not serialized
  2. Information is original Location coming from mock provider or not is lost. Location.setIsFromMockProvider can be called only by the system.

Here is the source code:

import android.location.Location;
import android.os.Build;

import androidx.annotation.NonNull;

import java.io.Serializable;

public class SerializableLocation implements Serializable {

    private static final long serialVersionUID = 1L;

    private static final int HAS_ALTITUDE_MASK                      = 1;
    private static final int HAS_SPEED_MASK                         = 2;
    private static final int HAS_BEARING_MASK                       = 4;
    private static final int HAS_HORIZONTAL_ACCURACY_MASK           = 8;
    private static final int HAS_MOCK_PROVIDER_MASK                 = 16;
    private static final int HAS_VERTICAL_ACCURACY_MASK             = 32;
    private static final int HAS_SPEED_ACCURACY_MASK                = 64;
    private static final int HAS_BEARING_ACCURACY_MASK              = 128;
    private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK  = 256;

    private String provider;
    private long   time                             = 0;
    private long   elapsedRealtimeNanos             = 0;
    private double elapsedRealtimeUncertaintyNanos  = 0.0f;
    private double latitude                         = 0.0;
    private double longitude                        = 0.0;
    private double altitude                         = 0.0f;
    private float  speed                            = 0.0f;
    private float  bearing                          = 0.0f;
    private float  horizontalAccuracyMeters         = 0.0f;
    private float  verticalAccuracyMeters           = 0.0f;
    private float  speedAccuracyMetersPerSecond     = 0.0f;
    private float  bearingAccuracyDegrees           = 0.0f;
    private int    fieldsMask                       = 0;
//  private Bundle extras = null;

    private boolean hasElapsedRealtimeUncertaintyNanos() {
        return (fieldsMask & HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK) != 0;
    }

    private boolean hasAltitude() {
        return (fieldsMask & HAS_ALTITUDE_MASK) != 0;
    }

    private boolean hasSpeed() {
        return (fieldsMask & HAS_SPEED_MASK) != 0;
    }

    private boolean hasBearing() {
        return (fieldsMask & HAS_BEARING_MASK) != 0;
    }

    private boolean hasAccuracy() {
        return (fieldsMask & HAS_HORIZONTAL_ACCURACY_MASK) != 0;
    }

    private boolean hasVerticalAccuracy() {
        return (fieldsMask & HAS_VERTICAL_ACCURACY_MASK) != 0;
    }

    private boolean hasSpeedAccuracy() {
        return (fieldsMask & HAS_SPEED_ACCURACY_MASK) != 0;
    }

    private boolean hasBearingAccuracy() {
        return (fieldsMask & HAS_BEARING_ACCURACY_MASK) != 0;
    }

    private boolean isFromMockProvider() {
        return (fieldsMask & HAS_MOCK_PROVIDER_MASK) != 0;
    }

    public SerializableLocation(@NonNull Location l) {

        provider             = l.getProvider();
        time                 = l.getTime();
        elapsedRealtimeNanos = l.getElapsedRealtimeNanos();
        latitude             = l.getLatitude();
        longitude            = l.getLongitude();

        if (l.hasAltitude()) {
            altitude = l.getAltitude();
            fieldsMask |= HAS_ALTITUDE_MASK;
        }
        if (l.hasSpeed()) {
            speed = l.getSpeed();
            fieldsMask |= HAS_SPEED_MASK;
        }
        if (l.hasBearing()) {
            bearing = l.getBearing();
            fieldsMask |= HAS_BEARING_MASK;
        }
        if (l.hasAccuracy()) {
            horizontalAccuracyMeters = l.getAccuracy();
            fieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            if (l.hasVerticalAccuracy()) {
                verticalAccuracyMeters = l.getVerticalAccuracyMeters();
                fieldsMask |= HAS_VERTICAL_ACCURACY_MASK;
            }
            if (l.hasSpeedAccuracy()) {
                speedAccuracyMetersPerSecond =
                    l.getSpeedAccuracyMetersPerSecond();
                fieldsMask |= HAS_SPEED_ACCURACY_MASK;
            }
            if (l.hasBearingAccuracy()) {
                bearingAccuracyDegrees = l.getBearingAccuracyDegrees();
                fieldsMask |= HAS_BEARING_ACCURACY_MASK;
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

            if (l.hasElapsedRealtimeUncertaintyNanos()) {
                elapsedRealtimeUncertaintyNanos =
                    l.getElapsedRealtimeUncertaintyNanos();
                fieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
            }
        }

        if (l.isFromMockProvider()) {
            fieldsMask |= HAS_MOCK_PROVIDER_MASK;
        }
    }

    public Location toLocation() {

        Location l = new Location(provider);

        l.setTime(time);
        l.setElapsedRealtimeNanos(elapsedRealtimeNanos);
        l.setLatitude(latitude);
        l.setLongitude(longitude);

        if (hasAltitude()) {
            l.setAltitude(altitude);
        }
        if (hasSpeed()) {
            l.setSpeed(speed);
        }
        if (hasBearing()) {
            l.setBearing(bearing);
        }
        if (hasAccuracy()) {
            l.setAccuracy(horizontalAccuracyMeters);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            if (hasVerticalAccuracy()) {
                l.setVerticalAccuracyMeters(verticalAccuracyMeters);
            }
            if (hasSpeedAccuracy()) {
                l.setSpeedAccuracyMetersPerSecond(speedAccuracyMetersPerSecond);
            }
            if (hasBearingAccuracy()) {
                l.setBearingAccuracyDegrees(bearingAccuracyDegrees);
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

            if (hasElapsedRealtimeUncertaintyNanos()) {
                l.setElapsedRealtimeUncertaintyNanos(
                    elapsedRealtimeUncertaintyNanos
                );
            }
        }

//        l.setIsFromMockProvider(isFromMockProvider());

        return l;
    }
}
like image 38
Viktor Brešan Avatar answered Oct 16 '22 21:10

Viktor Brešan