wangzhibo
4 天以前 ae6f40460dcd56af6c5f60ba52c883854c3bac55
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package nodomain.freeyourgadget.gadgetbridge.womp;
 
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
 
import androidx.core.content.ContextCompat;
 
import org.json.JSONObject;
 
/**
 * 取一次当前位置,优先用最近缓存,必要时单次刷新。
 */
public final class WompLocation {
    public interface Callback {
        void onResult(boolean ok, String json);
    }
 
    private static volatile Location lastFix;
 
    private WompLocation() {}
 
    public static void remember(Location location) {
        if (location != null) {
            lastFix = location;
        }
    }
 
    public static Location peek() {
        return lastFix;
    }
 
    public static String toJson(Location location) {
        try {
            JSONObject obj = new JSONObject();
            obj.put("longitude", location.getLongitude());
            obj.put("latitude", location.getLatitude());
            return obj.toString();
        } catch (Exception e) {
            return "{}";
        }
    }
 
    public static void fetch(Context context, Callback callback) {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            callback.onResult(false, "{\"message\":\"请先开启定位权限\"}");
            return;
        }
        Context app = context.getApplicationContext();
        LocationManager lm = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE);
        Location fresh = newest(readLast(lm), lastFix);
        if (fresh != null && System.currentTimeMillis() - fresh.getTime() < 120_000) {
            lastFix = fresh;
            callback.onResult(true, toJson(fresh));
            return;
        }
        Handler handler = new Handler(Looper.getMainLooper());
        final boolean[] done = {false};
        LocationListener listener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                finish(lm, this, handler, done, callback, location, true);
            }
 
            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {}
 
            @Override
            public void onProviderEnabled(String provider) {}
 
            @Override
            public void onProviderDisabled(String provider) {}
        };
        try {
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener, Looper.getMainLooper());
        } catch (Exception ignored) {
        }
        try {
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener, Looper.getMainLooper());
        } catch (Exception ignored) {
        }
        handler.postDelayed(() -> {
            Location fallback = newest(readLast(lm), lastFix, fresh);
            if (fallback != null) {
                finish(lm, listener, handler, done, callback, fallback, true);
            } else {
                finish(lm, listener, handler, done, callback, null, false);
            }
        }, 8000);
    }
 
    private static void finish(LocationManager lm, LocationListener listener, Handler handler,
                               boolean[] done, Callback callback, Location location, boolean ok) {
        if (done[0]) {
            return;
        }
        done[0] = true;
        handler.removeCallbacksAndMessages(null);
        try {
            lm.removeUpdates(listener);
        } catch (Exception ignored) {
        }
        if (ok && location != null) {
            lastFix = location;
            callback.onResult(true, toJson(location));
        } else {
            callback.onResult(false, "{\"message\":\"无法获取定位,请开启GPS后重试\"}");
        }
    }
 
    private static Location readLast(LocationManager lm) {
        Location best = null;
        try {
            best = newest(best, lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER));
        } catch (Exception ignored) {
        }
        try {
            best = newest(best, lm.getLastKnownLocation(LocationManager.GPS_PROVIDER));
        } catch (Exception ignored) {
        }
        return best;
    }
 
    private static Location newest(Location... items) {
        Location best = null;
        for (Location item : items) {
            if (item == null) {
                continue;
            }
            if (best == null || item.getTime() > best.getTime()) {
                best = item;
            }
        }
        return best;
    }
}