• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.location;
18 
19 import android.annotation.NonNull;
20 import android.compat.annotation.UnsupportedAppUsage;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.os.SystemClock;
24 import android.util.TimeUtils;
25 
26 import com.android.internal.util.Preconditions;
27 
28 import java.util.Objects;
29 
30 /**
31  * Represents a geographical boundary, also known as a geofence.
32  *
33  * <p>Currently only circular geofences are supported and they do not support altitude changes.
34  *
35  * @hide
36  */
37 public final class Geofence implements Parcelable {
38 
39     private final double mLatitude;
40     private final double mLongitude;
41     private final float mRadius;
42     private long mExpirationRealtimeMs;
43 
44     /**
45      * Create a circular geofence (on a flat, horizontal plane).
46      *
47      * @param latitude latitude in degrees, between -90 and +90 inclusive
48      * @param longitude longitude in degrees, between -180 and +180 inclusive
49      * @param radius radius in meters
50      * @return a new geofence
51      * @throws IllegalArgumentException if any parameters are out of range
52      */
createCircle(double latitude, double longitude, float radius, long expirationRealtimeMs)53     public static Geofence createCircle(double latitude, double longitude, float radius,
54             long expirationRealtimeMs) {
55         return new Geofence(latitude, longitude, radius, expirationRealtimeMs);
56     }
57 
Geofence(double latitude, double longitude, float radius, long expirationRealtimeMs)58     Geofence(double latitude, double longitude, float radius, long expirationRealtimeMs) {
59         Preconditions.checkArgumentInRange(latitude, -90.0, 90.0, "latitude");
60         Preconditions.checkArgumentInRange(longitude, -180.0, 180.0, "latitude");
61         Preconditions.checkArgument(radius > 0, "invalid radius: %f", radius);
62 
63         mLatitude = latitude;
64         mLongitude = longitude;
65         mRadius = radius;
66         mExpirationRealtimeMs = expirationRealtimeMs;
67     }
68 
getLatitude()69     public double getLatitude() {
70         return mLatitude;
71     }
72 
getLongitude()73     public double getLongitude() {
74         return mLongitude;
75     }
76 
getRadius()77     public float getRadius() {
78         return mRadius;
79     }
80 
isExpired()81     public boolean isExpired() {
82         return isExpired(SystemClock.elapsedRealtime());
83     }
84 
85     /**
86      * Returns true if this geofence is expired with reference to the given realtime.
87      */
isExpired(long referenceRealtimeMs)88     public boolean isExpired(long referenceRealtimeMs) {
89         return referenceRealtimeMs >= mExpirationRealtimeMs;
90     }
91 
92     @UnsupportedAppUsage
93     public static final @NonNull Parcelable.Creator<Geofence> CREATOR =
94             new Parcelable.Creator<Geofence>() {
95                 @Override
96                 public Geofence createFromParcel(Parcel in) {
97                     return new Geofence(
98                             in.readDouble(),
99                             in.readDouble(),
100                             in.readFloat(),
101                             in.readLong());
102                 }
103 
104                 @Override
105                 public Geofence[] newArray(int size) {
106                     return new Geofence[size];
107                 }
108             };
109 
110     @Override
describeContents()111     public int describeContents() {
112         return 0;
113     }
114 
115     @Override
writeToParcel(Parcel parcel, int flags)116     public void writeToParcel(Parcel parcel, int flags) {
117         parcel.writeDouble(mLatitude);
118         parcel.writeDouble(mLongitude);
119         parcel.writeFloat(mRadius);
120         parcel.writeLong(mExpirationRealtimeMs);
121     }
122 
123     @Override
equals(Object o)124     public boolean equals(Object o) {
125         if (this == o) {
126             return true;
127         }
128         if (!(o instanceof Geofence)) {
129             return false;
130         }
131         Geofence geofence = (Geofence) o;
132         return Double.compare(geofence.mLatitude, mLatitude) == 0
133                 && Double.compare(geofence.mLongitude, mLongitude) == 0
134                 && Float.compare(geofence.mRadius, mRadius) == 0
135                 && mExpirationRealtimeMs == geofence.mExpirationRealtimeMs;
136     }
137 
138     @Override
hashCode()139     public int hashCode() {
140         return Objects.hash(mLatitude, mLongitude, mRadius);
141     }
142 
143     @Override
toString()144     public String toString() {
145         StringBuilder builder = new StringBuilder();
146         builder.append("Geofence[(").append(mLatitude).append(", ").append(mLongitude).append(")");
147         builder.append(" ").append(mRadius).append("m");
148         if (mExpirationRealtimeMs < Long.MAX_VALUE) {
149             if (isExpired()) {
150                 builder.append(" expired");
151             } else {
152                 builder.append(" expires=");
153                 TimeUtils.formatDuration(mExpirationRealtimeMs, builder);
154             }
155         }
156         builder.append("]");
157         return builder.toString();
158     }
159 }
160