1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.contacts.common.location; 18 19 import android.app.IntentService; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.SharedPreferences; 23 import android.content.SharedPreferences.Editor; 24 import android.location.Address; 25 import android.location.Geocoder; 26 import android.location.Location; 27 import android.preference.PreferenceManager; 28 import android.util.Log; 29 import java.io.IOException; 30 import java.util.List; 31 32 /** 33 * Service used to perform asynchronous geocoding from within a broadcast receiver. Given a {@link 34 * Location}, convert it into a country code, and save it in shared preferences. 35 */ 36 public class UpdateCountryService extends IntentService { 37 38 private static final String TAG = UpdateCountryService.class.getSimpleName(); 39 40 private static final String ACTION_UPDATE_COUNTRY = "saveCountry"; 41 42 private static final String KEY_INTENT_LOCATION = "location"; 43 UpdateCountryService()44 public UpdateCountryService() { 45 super(TAG); 46 } 47 updateCountry(Context context, Location location)48 public static void updateCountry(Context context, Location location) { 49 final Intent serviceIntent = new Intent(context, UpdateCountryService.class); 50 serviceIntent.setAction(ACTION_UPDATE_COUNTRY); 51 serviceIntent.putExtra(UpdateCountryService.KEY_INTENT_LOCATION, location); 52 context.startService(serviceIntent); 53 } 54 55 @Override onHandleIntent(Intent intent)56 protected void onHandleIntent(Intent intent) { 57 if (intent == null) { 58 Log.d(TAG, "onHandleIntent: could not handle null intent"); 59 return; 60 } 61 if (ACTION_UPDATE_COUNTRY.equals(intent.getAction())) { 62 final Location location = intent.getParcelableExtra(KEY_INTENT_LOCATION); 63 final String country = getCountryFromLocation(getApplicationContext(), location); 64 65 if (country == null) { 66 return; 67 } 68 69 final SharedPreferences prefs = 70 PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 71 72 final Editor editor = prefs.edit(); 73 editor.putLong(CountryDetector.KEY_PREFERENCE_TIME_UPDATED, System.currentTimeMillis()); 74 editor.putString(CountryDetector.KEY_PREFERENCE_CURRENT_COUNTRY, country); 75 editor.commit(); 76 } 77 } 78 79 /** 80 * Given a {@link Location}, return a country code. 81 * 82 * @return the ISO 3166-1 two letter country code 83 */ getCountryFromLocation(Context context, Location location)84 private String getCountryFromLocation(Context context, Location location) { 85 final Geocoder geocoder = new Geocoder(context); 86 String country = null; 87 try { 88 double latitude = location.getLatitude(); 89 // Latitude has to be between 90 and -90 (latitude of north and south poles wrt equator) 90 if (latitude <= 90 && latitude >= -90) { 91 final List<Address> addresses = 92 geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1); 93 if (addresses != null && addresses.size() > 0) { 94 country = addresses.get(0).getCountryCode(); 95 } 96 } else { 97 Log.w(TAG, "Invalid latitude"); 98 } 99 } catch (IOException e) { 100 Log.w(TAG, "Exception occurred when getting geocoded country from location"); 101 } 102 return country; 103 } 104 } 105