/*
* Copyright 2015. Appsi Mobile
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.appsimobile.appsii;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresPermission;
import android.support.v4.util.CircularArray;
import android.util.Log;
import com.appsimobile.appsii.dagger.AppInjector;
import com.appsimobile.appsii.module.weather.loader.CantGetWeatherException;
import com.appsimobile.appsii.module.weather.loader.YahooWeatherApiClient;
import java.lang.ref.WeakReference;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
/**
* Utility helper to load location info
* Created by nick on 18/06/15.
*/
public class LocationLoader {
final LocationReceiver mLocationReceiver;
LocationManager mLocationManager;
AsyncTask<Location, Void, YahooWeatherApiClient.LocationInfo> mTask;
/**
* True when the loader has been destroyed
*/
boolean mDestroyed;
private LocationListenerImpl mLocationListener;
public LocationLoader(LocationReceiver locationReceiver) {
mLocationReceiver = locationReceiver;
mLocationManager = AppInjector.provideLocationManager();
}
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public boolean requestLocationUpdate(Context context) throws SecurityException {
if (!mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
return false;
}
Location lastKnown =
mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (lastKnown != null) {
onLocationChanged(lastKnown);
}
mLocationListener = new LocationListenerImpl(this);
mLocationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER,
mLocationListener, null);
return true;
}
public void onLocationChanged(final Location location) {
if (mDestroyed) return;
if (mTask != null) {
mTask.cancel(true);
}
mTask = new AsyncTask<Location, Void, YahooWeatherApiClient.LocationInfo>() {
@Override
protected YahooWeatherApiClient.LocationInfo doInBackground(
Location... locations) {
Location location = locations[0];
try {
return YahooWeatherApiClient.getLocationInfo(location);
} catch (CantGetWeatherException e) {
Log.w("WeatherFragment", "Error getting locationInfo", e);
return null;
}
}
@Override
protected void onPostExecute(
YahooWeatherApiClient.LocationInfo locationInfo) {
onLocationInfoLoaded(locationInfo);
}
};
mTask.execute(location);
}
void onLocationInfoLoaded(@Nullable YahooWeatherApiClient.LocationInfo locationInfo) {
CircularArray<String> woeids = locationInfo == null ?
null : locationInfo.woeids;
String town = locationInfo == null ? null : locationInfo.town;
String country = locationInfo == null ? null : locationInfo.country;
String timezone = locationInfo == null ? null : locationInfo.timezone;
Log.i("WeatherFragment",
"town: " + town + " country: " + country + " woeids: " + woeids);
if (woeids != null && town != null) {
String woeid = woeids.get(0);
mLocationReceiver.onCurrentLocationInfoReady(woeid, country, town, timezone);
} else {
mLocationReceiver.onCurrentLocationInfoReady(null, null, null, null);
}
}
public void destroy() {
mDestroyed = true;
if (mLocationListener != null) {
mLocationListener.destroy();
}
if (mTask != null) {
mTask.cancel(true);
}
}
private static class LocationListenerImpl implements LocationListener {
WeakReference<LocationLoader> mLocationLoaderRef;
public LocationListenerImpl(LocationLoader locationLoader) {
mLocationLoaderRef = new WeakReference<>(locationLoader);
}
@Override
public void onLocationChanged(Location location) {
LocationLoader locationLoader = mLocationLoaderRef.get();
if (locationLoader != null) {
locationLoader.onLocationChanged(location);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
public void destroy() {
mLocationLoaderRef.clear();
}
}
}