summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java
blob: c4bdb4a17dee14eb6135605480a00e2755f132e2 (plain)
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
package com.mapbox.mapboxsdk.location;

import android.content.Context;
import android.location.Location;
import android.util.Log;

import com.mapbox.services.android.telemetry.location.LocationEngine;
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
import com.mapzen.android.lost.api.LocationListener;
import com.mapzen.android.lost.api.LocationRequest;
import com.mapzen.android.lost.api.LocationServices;
import com.mapzen.android.lost.api.LostApiClient;

import java.lang.ref.WeakReference;

/**
 * Manages locational updates. Contains methods to register and unregister location listeners.
 * <ul>
 * <li>You can register a LocationEngineListener with LocationSource#addLocationEngineListener(LocationEngineListener)
 * to receive location updates.</li>
 * <li> You can unregister a LocationEngineListener with
 * LocationEngine#removeLocationEngineListener(LocationEngineListener)} to stop receiving location updates.</li>
 * </ul>
 * <p>
 * Note: If registering a listener in your Activity.onStart() implementation, you should unregister it in
 * Activity.onStop(). (You won't receive location updates when paused, and this will cut down on unnecessary system
 * overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back
 * in the history stack.
 * </p>
 */
public class LocationSource extends LocationEngine implements
  LostApiClient.ConnectionCallbacks, LocationListener {

  private static final String LOG_TAG = LocationSource.class.getSimpleName();

  private static LocationEngine instance;

  private WeakReference<Context> context;
  private LostApiClient lostApiClient;

  private LocationSource(Context context) {
    super();
    this.context = new WeakReference<>(context);
    lostApiClient = new LostApiClient.Builder(this.context.get())
      .addConnectionCallbacks(this)
      .build();
  }

  public static synchronized LocationEngine getLocationEngine(Context context) {
    if (instance == null) {
      instance = new LocationSource(context.getApplicationContext());
    }

    return instance;
  }

  @Override
  public void activate() {
    if (lostApiClient != null && !lostApiClient.isConnected()) {
      lostApiClient.connect();
    }
  }

  @Override
  public void deactivate() {
    if (lostApiClient != null && lostApiClient.isConnected()) {
      lostApiClient.disconnect();
    }
  }

  @Override
  public boolean isConnected() {
    return lostApiClient.isConnected();
  }

  @Override
  public void onConnected() {
    for (LocationEngineListener listener : locationListeners) {
      listener.onConnected();
    }
  }

  @Override
  public void onConnectionSuspended() {
    Log.d(LOG_TAG, "Connection suspended.");
  }

  @Override
  public Location getLastLocation() {
    if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) {
      //noinspection MissingPermission
      return LocationServices.FusedLocationApi.getLastLocation(lostApiClient);
    }

    return null;
  }

  @Override
  public void requestLocationUpdates() {
    // Common params
    LocationRequest request = LocationRequest.create()
      .setInterval(1000)
      .setFastestInterval(1000)
      .setSmallestDisplacement(3.0f);

    // Priority matching is straightforward
    if (priority == LocationEnginePriority.NO_POWER) {
      request.setPriority(LocationRequest.PRIORITY_NO_POWER);
    } else if (priority == LocationEnginePriority.LOW_POWER) {
      request.setPriority(LocationRequest.PRIORITY_LOW_POWER);
    } else if (priority == LocationEnginePriority.BALANCED_POWER_ACCURACY) {
      request.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    } else if (priority == LocationEnginePriority.HIGH_ACCURACY) {
      request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) {
      //noinspection MissingPermission
      LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this);
    }
  }

  @Override
  public void removeLocationUpdates() {
    if (lostApiClient.isConnected()) {
      LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this);
    }
  }

  @Override
  public void onLocationChanged(Location location) {
    for (LocationEngineListener listener : locationListeners) {
      listener.onLocationChanged(location);
    }
  }
}