how to serialize for android.location class?

后端 未结 3 1755
青春惊慌失措
青春惊慌失措 2021-01-18 10:34

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.         


        
相关标签:
3条回答
  • 2021-01-18 11:04

    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;
        }
    }
    
    0 讨论(0)
  • 2021-01-18 11:10

    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.

    0 讨论(0)
  • 2021-01-18 11:10

    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.

    0 讨论(0)
提交回复
热议问题