11package com .mapbox .services .android .testapp .geocoding ;
22
3+ import android .content .Context ;
34import android .content .Intent ;
45import android .location .Location ;
56import android .os .Bundle ;
1314import android .widget .Toast ;
1415
1516import com .mapbox .services .android .geocoder .AndroidGeocoder ;
17+ import com .mapbox .services .android .telemetry .location .AndroidLocationEngine ;
18+ import com .mapbox .services .android .telemetry .location .LocationEngine ;
19+ import com .mapbox .services .android .telemetry .location .LocationEngineListener ;
1620import com .mapbox .services .android .testapp .R ;
1721import com .mapbox .services .android .testapp .geocoding .service .Constants ;
1822import com .mapbox .services .android .testapp .geocoding .service .FetchAddressIntentService ;
19- import com . mapzen . android . lost . api . LocationServices ;
20- import com . mapzen . android . lost . api . LostApiClient ;
23+
24+ import java . lang . ref . WeakReference ;
2125
2226/**
2327 * This activity is inspired by the stock Android Geocoder sample code in
2428 * https://github.com/googlesamples/android-play-location/tree/master/LocationAddress
2529 * <p>
26- * In this sample, we show how to use Mapbox' Geocoder simply replacing the
30+ * In this sample, we show how to use Mapbox's Geocoder simply replacing the
2731 * android.location.Geocoder object with com.mapbox.services.android.geocoder.AndroidGeocoder.
28- * To simplify the code, we've replaced Google Play Services with LOST .
32+ * To simplify the code, we've replaced Google Play Services with Android .
2933 */
30- public class GeocodingServiceActivity extends AppCompatActivity {
34+ public class GeocodingServiceActivity extends AppCompatActivity implements LocationEngineListener {
3135
32- protected static final String ADDRESS_REQUESTED_KEY = "address-request-pending" ;
33- protected static final String LOCATION_ADDRESS_KEY = "location-address" ;
36+ private static final String ADDRESS_REQUESTED_KEY = "address-request-pending" ;
37+ private static final String LOCATION_ADDRESS_KEY = "location-address" ;
3438
3539 /**
36- * Provides the entry point to LOST services.
40+ * Provides the entry point to location services.
3741 */
38- protected LostApiClient lostApiClient ;
42+ private LocationEngine locationEngine ;
3943
4044 /**
4145 * Represents a geographical location.
4246 */
43- protected Location lastLocation ;
47+ private Location lastLocation ;
4448
4549 /**
4650 * Tracks whether the user has requested an address. Becomes true when the user requests an
4751 * address and false when the address (or an error message) is delivered.
4852 * The user requests an address by pressing the Fetch Address button. This may happen
49- * before LostApiClient connects. This activity uses this boolean to keep track of the
53+ * before location engine connects. This activity uses this boolean to keep track of the
5054 * user's intent. If the value is true, the activity tries to fetch the address as soon as
51- * LostApiClient connects.
55+ * location engine connects.
5256 */
53- protected boolean addressRequested ;
57+ private static boolean addressRequested ;
5458
5559 /**
5660 * The formatted location address.
5761 */
58- protected String addressOutput ;
62+ private static String addressOutput ;
5963
6064 /**
6165 * Receiver registered with this activity to get the response from FetchAddressIntentService.
@@ -65,36 +69,37 @@ public class GeocodingServiceActivity extends AppCompatActivity {
6569 /**
6670 * Displays the location address.
6771 */
68- protected TextView locationAddressTextView ;
72+ private TextView locationAddressTextView ;
6973
7074 /**
7175 * Visible while the address is being fetched.
7276 */
73- ProgressBar progressBar ;
77+ private ProgressBar progressBar ;
7478
7579 /**
7680 * Kicks off the request to fetch an address when pressed.
7781 */
78- Button fetchAddressButton ;
82+ private Button fetchAddressButton ;
7983
8084 @ Override
8185 public void onCreate (Bundle savedInstanceState ) {
8286 super .onCreate (savedInstanceState );
8387 setContentView (R .layout .activity_geocoding_service );
8488
85- resultReceiver = new AddressResultReceiver (new Handler ());
86-
8789 locationAddressTextView = (TextView ) findViewById (R .id .location_address_view );
8890 progressBar = (ProgressBar ) findViewById (R .id .progress_bar );
8991 fetchAddressButton = (Button ) findViewById (R .id .fetch_address_button );
9092
93+ resultReceiver = new AddressResultReceiver (new Handler (), this , locationAddressTextView , progressBar ,
94+ fetchAddressButton );
95+
9196 // Set defaults, then update using values stored in the Bundle.
9297 addressRequested = false ;
9398 addressOutput = "" ;
9499 updateValuesFromBundle (savedInstanceState );
95100
96- updateUiWidgets ();
97- buildLostApiClient ();
101+ updateUiWidgets (addressRequested , progressBar , fetchAddressButton );
102+ buildAndroidLocationEngine ();
98103 }
99104
100105 /**
@@ -111,48 +116,51 @@ private void updateValuesFromBundle(Bundle savedInstanceState) {
111116 // and stored in the Bundle. If it was found, display the address string in the UI.
112117 if (savedInstanceState .keySet ().contains (LOCATION_ADDRESS_KEY )) {
113118 addressOutput = savedInstanceState .getString (LOCATION_ADDRESS_KEY );
114- displayAddressOutput ();
119+ displayAddressOutput (locationAddressTextView );
115120 }
116121 }
117122 }
118123
119124 /**
120- * Builds a LostApiClient.
125+ * Builds Android location engine
121126 */
122- protected synchronized void buildLostApiClient () {
123- lostApiClient = new LostApiClient .Builder (this ).build ();
127+ private synchronized void buildAndroidLocationEngine () {
128+ locationEngine = AndroidLocationEngine .getLocationEngine (this );
129+ locationEngine .addLocationEngineListener (this );
130+ locationEngine .activate ();
124131 }
125132
126133 /**
127134 * Runs when user clicks the Fetch Address button. Starts the service to fetch the address if
128- * LostApiClient is connected.
135+ * location engine is connected.
129136 */
130137 public void fetchAddressButtonHandler (View view ) {
131- // We only start the service to fetch the address if LostApiClient is connected.
132- if (lostApiClient .isConnected () && lastLocation != null ) {
138+ // We only start the service to fetch the address if location engine is connected.
139+ if (locationEngine .isConnected () && lastLocation != null ) {
133140 startIntentService ();
134141 }
135142
136- // If LostApiClient isn't connected, we process the user's request by setting
137- // addressRequested to true. Later, when LostApiClient connects, we launch the service to
143+ // If location engine isn't connected, we process the user's request by setting
144+ // addressRequested to true. Later, when location engine connects, we launch the service to
138145 // fetch the address. As far as the user is concerned, pressing the Fetch Address button
139146 // immediately kicks off the process of getting the address.
140147 addressRequested = true ;
141- updateUiWidgets ();
148+ updateUiWidgets (addressRequested , progressBar , fetchAddressButton );
142149 }
143150
144151 @ Override
145- protected void onStart () {
146- super .onStart ();
147- lostApiClient .connect ();
148- getLastLocation ();
152+ protected void onResume () {
153+ super .onResume ();
154+ if (locationEngine != null && locationEngine .isConnected ()) {
155+ obtainLastAddress ();
156+ }
149157 }
150158
151- private void getLastLocation () {
159+ private void obtainLastAddress () {
152160 // Gets the best and most recent location currently available, which may be null
153161 // in rare cases when a location is not available.
154- //noinspection MissingPermission
155- lastLocation = LocationServices . FusedLocationApi . getLastLocation (lostApiClient );
162+
163+ lastLocation = locationEngine . getLastLocation ();
156164 if (lastLocation != null ) {
157165 // Determine whether a Geocoder is available.
158166 if (!AndroidGeocoder .isPresent ()) {
@@ -161,29 +169,40 @@ private void getLastLocation() {
161169 }
162170
163171 // It is possible that the user presses the button to get the address before the
164- // LostApiClient object successfully connects. In such a case, addressRequested
172+ // location engine object successfully connects. In such a case, addressRequested
165173 // is set to true, but no attempt is made to fetch the address (see
166174 // fetchAddressButtonHandler()) . Instead, we start the intent service here if the
167- // user has requested an address, since we now have a connection to LostApiClient .
175+ // user has requested an address, since we now have a connection to location engine .
168176 if (addressRequested ) {
169177 startIntentService ();
170178 }
171179 }
172180 }
173181
174182 @ Override
175- protected void onStop () {
176- super .onStop ();
177- if (lostApiClient .isConnected ()) {
178- lostApiClient .disconnect ();
183+ public void onConnected () {
184+ obtainLastAddress ();
185+ }
186+
187+ @ Override
188+ public void onLocationChanged (Location location ) {
189+ // Unused on purpose
190+ }
191+
192+ @ Override
193+ protected void onPause () {
194+ super .onPause ();
195+ if (locationEngine != null ) {
196+ locationEngine .removeLocationEngineListener (this );
197+ locationEngine .deactivate ();
179198 }
180199 }
181200
182201 /**
183202 * Creates an intent, adds location data to it as an extra, and starts the intent service for
184203 * fetching an address.
185204 */
186- protected void startIntentService () {
205+ private void startIntentService () {
187206 // Create an intent for passing to the intent service responsible for fetching the address.
188207 Intent intent = new Intent (this , FetchAddressIntentService .class );
189208
@@ -202,28 +221,28 @@ protected void startIntentService() {
202221 /**
203222 * Updates the address in the UI.
204223 */
205- protected void displayAddressOutput () {
206- locationAddressTextView .setText (addressOutput );
224+ private static void displayAddressOutput (TextView view ) {
225+ view .setText (addressOutput );
207226 }
208227
209228 /**
210229 * Toggles the visibility of the progress bar. Enables or disables the Fetch Address button.
211230 */
212- private void updateUiWidgets () {
231+ private static void updateUiWidgets (boolean addressRequested , ProgressBar progressBar , Button button ) {
213232 if (addressRequested ) {
214233 progressBar .setVisibility (ProgressBar .VISIBLE );
215- fetchAddressButton .setEnabled (false );
234+ button .setEnabled (false );
216235 } else {
217236 progressBar .setVisibility (ProgressBar .GONE );
218- fetchAddressButton .setEnabled (true );
237+ button .setEnabled (true );
219238 }
220239 }
221240
222241 /**
223- * Shows a toast with the given text .
242+ * Shows a toast with the given message .
224243 */
225- protected void showToast (String text ) {
226- Toast .makeText (this , text , Toast .LENGTH_SHORT ).show ();
244+ private static void showToast (Context context , String message ) {
245+ Toast .makeText (context , message , Toast .LENGTH_SHORT ).show ();
227246 }
228247
229248 @ Override
@@ -239,9 +258,19 @@ public void onSaveInstanceState(Bundle savedInstanceState) {
239258 /**
240259 * Receiver for data sent from FetchAddressIntentService.
241260 */
242- class AddressResultReceiver extends ResultReceiver {
243- public AddressResultReceiver (Handler handler ) {
261+ private static class AddressResultReceiver extends ResultReceiver {
262+ private final WeakReference <Context > contextReference ;
263+ private final WeakReference <TextView > textViewReference ;
264+ private final WeakReference <ProgressBar > progressBarReference ;
265+ private final WeakReference <Button > fetchAddressButtonReference ;
266+
267+ public AddressResultReceiver (Handler handler , Context context , TextView resultTextView , ProgressBar progressBar ,
268+ Button fetchAddressButton ) {
244269 super (handler );
270+ this .contextReference = new WeakReference <>(context );
271+ this .textViewReference = new WeakReference <>(resultTextView );
272+ this .progressBarReference = new WeakReference <>(progressBar );
273+ this .fetchAddressButtonReference = new WeakReference <>(fetchAddressButton );
245274 }
246275
247276 /**
@@ -251,16 +280,28 @@ public AddressResultReceiver(Handler handler) {
251280 protected void onReceiveResult (int resultCode , Bundle resultData ) {
252281 // Display the address string or an error message sent from the intent service.
253282 addressOutput = resultData .getString (Constants .RESULT_DATA_KEY );
254- displayAddressOutput ();
283+ TextView view = textViewReference .get ();
284+ if (view != null ) {
285+ displayAddressOutput (view );
286+ }
255287
256288 // Show a toast message if an address was found.
257289 if (resultCode == Constants .SUCCESS_RESULT ) {
258- showToast (getString (R .string .address_found ));
290+ Context context = contextReference .get ();
291+ if (context != null ) {
292+ String message = context .getString (R .string .address_found );
293+ showToast (context , message );
294+ }
259295 }
260296
261297 // Reset. Enable the Fetch Address button and stop showing the progress bar.
262298 addressRequested = false ;
263- updateUiWidgets ();
299+
300+ ProgressBar progressBar = progressBarReference .get ();
301+ Button fetchAddressButton = fetchAddressButtonReference .get ();
302+ if (progressBar != null && fetchAddressButton != null ) {
303+ updateUiWidgets (addressRequested , progressBar , fetchAddressButton );
304+ }
264305 }
265306 }
266307
0 commit comments