• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * 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, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package android.location;
18 
19 import java.util.HashMap;
20 
21 import android.os.Handler;
22 import android.os.Looper;
23 import android.os.RemoteException;
24 import android.util.Log;
25 
26 /**
27  * This class provides access to the system country detector service. This
28  * service allows applications to obtain the country that the user is in.
29  * <p>
30  * The country will be detected in order of reliability, like
31  * <ul>
32  * <li>Mobile network</li>
33  * <li>Location</li>
34  * <li>SIM's country</li>
35  * <li>Phone's locale</li>
36  * </ul>
37  * <p>
38  * Call the {@link #detectCountry()} to get the available country immediately.
39  * <p>
40  * To be notified of the future country change, use the
41  * {@link #addCountryListener}
42  * <p>
43  * <p>
44  * You do not instantiate this class directly; instead, retrieve it through
45  * {@link android.content.Context#getSystemService
46  * Context.getSystemService(Context.COUNTRY_DETECTOR)}.
47  *
48  * @hide
49  */
50 public class CountryDetector {
51 
52     /**
53      * The class to wrap the ICountryListener.Stub and CountryListener objects
54      * together. The CountryListener will be notified through the specific
55      * looper once the country changed and detected.
56      */
57     private final static class ListenerTransport extends ICountryListener.Stub {
58 
59         private final CountryListener mListener;
60 
61         private final Handler mHandler;
62 
ListenerTransport(CountryListener listener, Looper looper)63         public ListenerTransport(CountryListener listener, Looper looper) {
64             mListener = listener;
65             if (looper != null) {
66                 mHandler = new Handler(looper);
67             } else {
68                 mHandler = new Handler();
69             }
70         }
71 
onCountryDetected(final Country country)72         public void onCountryDetected(final Country country) {
73             mHandler.post(new Runnable() {
74                 public void run() {
75                     mListener.onCountryDetected(country);
76                 }
77             });
78         }
79     }
80 
81     private final static String TAG = "CountryDetector";
82     private final ICountryDetector mService;
83     private final HashMap<CountryListener, ListenerTransport> mListeners;
84 
85     /**
86      * @hide - hide this constructor because it has a parameter of type
87      *       ICountryDetector, which is a system private class. The right way to
88      *       create an instance of this class is using the factory
89      *       Context.getSystemService.
90      */
CountryDetector(ICountryDetector service)91     public CountryDetector(ICountryDetector service) {
92         mService = service;
93         mListeners = new HashMap<CountryListener, ListenerTransport>();
94     }
95 
96     /**
97      * Start detecting the country that the user is in.
98      *
99      * @return the country if it is available immediately, otherwise null will
100      *         be returned.
101      */
detectCountry()102     public Country detectCountry() {
103         try {
104             return mService.detectCountry();
105         } catch (RemoteException e) {
106             Log.e(TAG, "detectCountry: RemoteException", e);
107             return null;
108         }
109     }
110 
111     /**
112      * Add a listener to receive the notification when the country is detected
113      * or changed.
114      *
115      * @param listener will be called when the country is detected or changed.
116      * @param looper a Looper object whose message queue will be used to
117      *        implement the callback mechanism. If looper is null then the
118      *        callbacks will be called on the main thread.
119      */
addCountryListener(CountryListener listener, Looper looper)120     public void addCountryListener(CountryListener listener, Looper looper) {
121         synchronized (mListeners) {
122             if (!mListeners.containsKey(listener)) {
123                 ListenerTransport transport = new ListenerTransport(listener, looper);
124                 try {
125                     mService.addCountryListener(transport);
126                     mListeners.put(listener, transport);
127                 } catch (RemoteException e) {
128                     Log.e(TAG, "addCountryListener: RemoteException", e);
129                 }
130             }
131         }
132     }
133 
134     /**
135      * Remove the listener
136      */
removeCountryListener(CountryListener listener)137     public void removeCountryListener(CountryListener listener) {
138         synchronized (mListeners) {
139             ListenerTransport transport = mListeners.get(listener);
140             if (transport != null) {
141                 try {
142                     mListeners.remove(listener);
143                     mService.removeCountryListener(transport);
144                 } catch (RemoteException e) {
145                     Log.e(TAG, "removeCountryListener: RemoteException", e);
146                 }
147             }
148         }
149     }
150 }
151