com.appsimobile.appsii.LocationLoader.java Source code

Java tutorial

Introduction

Here is the source code for com.appsimobile.appsii.LocationLoader.java

Source

/*
 * 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();
        }
    }
}