165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/*
265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Copyright (C) 2016 The Android Open Source Project
365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License");
565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * you may not use this file except in compliance with the License.
665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * You may obtain a copy of the License at
765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *      http://www.apache.org/licenses/LICENSE-2.0
965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko *
1065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * Unless required by applicable law or agreed to in writing, software
1165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS,
1265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * See the License for the specific language governing permissions and
1465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * limitations under the License.
1565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */
1665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
1765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopackage com.android.tv.util;
1865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
196ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.Manifest;
2065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.content.Context;
216ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.content.pm.PackageManager;
2265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.location.Address;
2365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.location.Geocoder;
2465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.location.Location;
2565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.location.LocationListener;
2665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.location.LocationManager;
2765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.os.Bundle;
286ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.support.annotation.NonNull;
296ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport android.text.TextUtils;
3065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport android.util.Log;
3165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
326ebde20b03db4c0d57f67acaac11832b610b966bNick Chalkoimport com.android.tv.tuner.util.PostalCodeUtils;
33d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
3465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.io.IOException;
3565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.util.List;
3665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkoimport java.util.Locale;
3765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
3865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko/**
3965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko * A utility class to get the current location.
4065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko */
4165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalkopublic class LocationUtils {
4265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static final String TAG = "LocationUtils";
4365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static final boolean DEBUG = false;
4465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
4565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static Context sApplicationContext;
4665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static Address sAddress;
476ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    private static String sCountry;
4865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private static IOException sError;
4965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
5065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    /**
5165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     * Checks the current location.
5265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko     */
5365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    public static synchronized Address getCurrentAddress(Context context) throws IOException,
5465fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            SecurityException {
5565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (sAddress != null) {
5665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            return sAddress;
5765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
5865fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (sError != null) {
5965fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            throw sError;
6065fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
6165fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        if (sApplicationContext == null) {
6265fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko            sApplicationContext = context.getApplicationContext();
6365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        }
64d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        LocationUtilsHelper.startLocationUpdates();
6565fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko        return null;
6665fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    }
6765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko
686ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    /** Returns the current country. */
696ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    @NonNull
706ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    public static synchronized String getCurrentCountry(Context context) {
716ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (sCountry != null) {
726ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            return sCountry;
736ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
746ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        if (TextUtils.isEmpty(sCountry)) {
756ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            sCountry = context.getResources().getConfiguration().locale.getCountry();
766ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        }
776ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko        return sCountry;
786ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko    }
796ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko
80d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private static void updateAddress(Location location) {
81d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (DEBUG) Log.d(TAG, "Updating address with " + location);
82d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        if (location == null) {
83d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            return;
84d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
85d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        Geocoder geocoder = new Geocoder(sApplicationContext, Locale.getDefault());
86d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        try {
87d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            List<Address> addresses = geocoder.getFromLocation(
88d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    location.getLatitude(), location.getLongitude(), 1);
896ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko            if (addresses != null && !addresses.isEmpty()) {
90d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                sAddress = addresses.get(0);
91d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                if (DEBUG) Log.d(TAG, "Got " + sAddress);
926ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                try {
936ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    PostalCodeUtils.updatePostalCode(sApplicationContext);
946ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                } catch (Exception e) {
956ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                    // Do nothing
966ebde20b03db4c0d57f67acaac11832b610b966bNick Chalko                }
97d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            } else {
98d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                if (DEBUG) Log.d(TAG, "No address returned");
99d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
100d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            sError = null;
101d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        } catch (IOException e) {
102d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            Log.w(TAG, "Error in updating address", e);
103d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            sError = e;
104d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
105d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    }
106d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
10765fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko    private LocationUtils() { }
108d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
109d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    private static class LocationUtilsHelper {
110d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private static final LocationListener LOCATION_LISTENER = new LocationListener() {
111d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            @Override
112d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            public void onLocationChanged(Location location) {
113d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                updateAddress(location);
114d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
115d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
116d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            @Override
117d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            public void onStatusChanged(String provider, int status, Bundle extras) { }
118d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
119d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            @Override
120d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            public void onProviderEnabled(String provider) { }
121d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
122d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            @Override
123d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            public void onProviderDisabled(String provider) { }
124d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        };
125d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
126d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        private static LocationManager sLocationManager;
127d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko
128d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        public static void startLocationUpdates() {
129d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            if (sLocationManager == null) {
130d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                sLocationManager = (LocationManager) sApplicationContext.getSystemService(
131d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                        Context.LOCATION_SERVICE);
132d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                try {
133d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    sLocationManager.requestLocationUpdates(
134d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                            LocationManager.NETWORK_PROVIDER, 1000, 10, LOCATION_LISTENER, null);
135d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                } catch (SecurityException e) {
136d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    // Enables requesting the location updates again.
137d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    sLocationManager = null;
138d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                    throw e;
139d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko                }
140d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko            }
141d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko        }
142d41f0075a7d2ea826204e81fcec57d0aa57171a9Nick Chalko    }
14365fda1eaa94968bb55d5ded10dcb0b3f37fb05f2Nick Chalko}
144