1package com.android.contacts.common.location;
2
3import android.app.IntentService;
4import android.content.Context;
5import android.content.Intent;
6import android.content.SharedPreferences;
7import android.content.SharedPreferences.Editor;
8import android.location.Address;
9import android.location.Geocoder;
10import android.location.Location;
11import android.preference.PreferenceManager;
12import android.util.Log;
13
14import java.io.IOException;
15import java.util.List;
16
17/**
18 * Service used to perform asynchronous geocoding from within a broadcast receiver. Given a
19 * {@link Location}, convert it into a country code, and save it in shared preferences.
20 */
21public class UpdateCountryService extends IntentService {
22    private static final String TAG = UpdateCountryService.class.getSimpleName();
23
24    private static final String ACTION_UPDATE_COUNTRY = "saveCountry";
25
26    private static final String KEY_INTENT_LOCATION = "location";
27
28    public UpdateCountryService() {
29        super(TAG);
30    }
31
32    public static void updateCountry(Context context, Location location) {
33        final Intent serviceIntent = new Intent(context, UpdateCountryService.class);
34        serviceIntent.setAction(ACTION_UPDATE_COUNTRY);
35        serviceIntent.putExtra(UpdateCountryService.KEY_INTENT_LOCATION, location);
36        context.startService(serviceIntent);
37    }
38
39    @Override
40    protected void onHandleIntent(Intent intent) {
41        if (intent == null) {
42            Log.d(TAG, "onHandleIntent: could not handle null intent");
43            return;
44        }
45        if (ACTION_UPDATE_COUNTRY.equals(intent.getAction())) {
46            final Location location = (Location) intent.getParcelableExtra(KEY_INTENT_LOCATION);
47            final String country = getCountryFromLocation(getApplicationContext(), location);
48
49            if (country == null) {
50                return;
51            }
52
53            final SharedPreferences prefs =
54                    PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
55
56            final Editor editor = prefs.edit();
57            editor.putLong(CountryDetector.KEY_PREFERENCE_TIME_UPDATED,
58                    System.currentTimeMillis());
59            editor.putString(CountryDetector.KEY_PREFERENCE_CURRENT_COUNTRY, country);
60            editor.commit();
61        }
62    }
63
64    /**
65     * Given a {@link Location}, return a country code.
66     *
67     * @return the ISO 3166-1 two letter country code
68     */
69    private String getCountryFromLocation(Context context, Location location) {
70        final Geocoder geocoder = new Geocoder(context);
71        String country = null;
72        try {
73            final List<Address> addresses = geocoder.getFromLocation(
74                    location.getLatitude(), location.getLongitude(), 1);
75            if (addresses != null && addresses.size() > 0) {
76                country = addresses.get(0).getCountryCode();
77            }
78        } catch (IOException e) {
79            Log.w(TAG, "Exception occurred when getting geocoded country from location");
80        }
81        return country;
82    }
83}
84