1 /*
2  * Copyright (C) 2011 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.camera;
18 
19 import android.content.Context;
20 import android.location.Location;
21 import android.location.LocationProvider;
22 import android.os.Bundle;
23 import android.util.Log;
24 
25 /**
26  * A class that handles everything about location.
27  */
28 public class LocationManager {
29     private static final String TAG = "LocationManager";
30 
31     private Context mContext;
32     private Listener mListener;
33     private android.location.LocationManager mLocationManager;
34     private boolean mRecordLocation;
35 
36     LocationListener [] mLocationListeners = new LocationListener[] {
37             new LocationListener(android.location.LocationManager.GPS_PROVIDER),
38             new LocationListener(android.location.LocationManager.NETWORK_PROVIDER)
39     };
40 
41     public interface Listener {
showGpsOnScreenIndicator(boolean hasSignal)42         public void showGpsOnScreenIndicator(boolean hasSignal);
hideGpsOnScreenIndicator()43         public void hideGpsOnScreenIndicator();
44    }
45 
LocationManager(Context context, Listener listener)46     public LocationManager(Context context, Listener listener) {
47         mContext = context;
48         mListener = listener;
49     }
50 
getCurrentLocation()51     public Location getCurrentLocation() {
52         if (!mRecordLocation) return null;
53 
54         // go in best to worst order
55         for (int i = 0; i < mLocationListeners.length; i++) {
56             Location l = mLocationListeners[i].current();
57             if (l != null) return l;
58         }
59         Log.d(TAG, "No location received yet.");
60         return null;
61     }
62 
recordLocation(boolean recordLocation)63     public void recordLocation(boolean recordLocation) {
64         if (mRecordLocation != recordLocation) {
65             mRecordLocation = recordLocation;
66             if (recordLocation) {
67                 startReceivingLocationUpdates();
68             } else {
69                 stopReceivingLocationUpdates();
70             }
71         }
72     }
73 
startReceivingLocationUpdates()74     private void startReceivingLocationUpdates() {
75         if (mLocationManager == null) {
76             mLocationManager = (android.location.LocationManager)
77                     mContext.getSystemService(Context.LOCATION_SERVICE);
78         }
79         if (mLocationManager != null) {
80             try {
81                 mLocationManager.requestLocationUpdates(
82                         android.location.LocationManager.NETWORK_PROVIDER,
83                         1000,
84                         0F,
85                         mLocationListeners[1]);
86             } catch (SecurityException ex) {
87                 Log.i(TAG, "fail to request location update, ignore", ex);
88             } catch (IllegalArgumentException ex) {
89                 Log.d(TAG, "provider does not exist " + ex.getMessage());
90             }
91             try {
92                 mLocationManager.requestLocationUpdates(
93                         android.location.LocationManager.GPS_PROVIDER,
94                         1000,
95                         0F,
96                         mLocationListeners[0]);
97                 if (mListener != null) mListener.showGpsOnScreenIndicator(false);
98             } catch (SecurityException ex) {
99                 Log.i(TAG, "fail to request location update, ignore", ex);
100             } catch (IllegalArgumentException ex) {
101                 Log.d(TAG, "provider does not exist " + ex.getMessage());
102             }
103             Log.d(TAG, "startReceivingLocationUpdates");
104         }
105     }
106 
stopReceivingLocationUpdates()107     private void stopReceivingLocationUpdates() {
108         if (mLocationManager != null) {
109             for (int i = 0; i < mLocationListeners.length; i++) {
110                 try {
111                     mLocationManager.removeUpdates(mLocationListeners[i]);
112                 } catch (Exception ex) {
113                     Log.i(TAG, "fail to remove location listners, ignore", ex);
114                 }
115             }
116             Log.d(TAG, "stopReceivingLocationUpdates");
117         }
118         if (mListener != null) mListener.hideGpsOnScreenIndicator();
119     }
120 
121     private class LocationListener
122             implements android.location.LocationListener {
123         Location mLastLocation;
124         boolean mValid = false;
125         String mProvider;
126 
LocationListener(String provider)127         public LocationListener(String provider) {
128             mProvider = provider;
129             mLastLocation = new Location(mProvider);
130         }
131 
132         @Override
onLocationChanged(Location newLocation)133         public void onLocationChanged(Location newLocation) {
134             if (newLocation.getLatitude() == 0.0
135                     && newLocation.getLongitude() == 0.0) {
136                 // Hack to filter out 0.0,0.0 locations
137                 return;
138             }
139             // If GPS is available before start camera, we won't get status
140             // update so update GPS indicator when we receive data.
141             if (mListener != null && mRecordLocation &&
142                     android.location.LocationManager.GPS_PROVIDER.equals(mProvider)) {
143                 mListener.showGpsOnScreenIndicator(true);
144             }
145             if (!mValid) {
146                 Log.d(TAG, "Got first location.");
147             }
148             mLastLocation.set(newLocation);
149             mValid = true;
150         }
151 
152         @Override
onProviderEnabled(String provider)153         public void onProviderEnabled(String provider) {
154         }
155 
156         @Override
onProviderDisabled(String provider)157         public void onProviderDisabled(String provider) {
158             mValid = false;
159         }
160 
161         @Override
onStatusChanged( String provider, int status, Bundle extras)162         public void onStatusChanged(
163                 String provider, int status, Bundle extras) {
164             switch(status) {
165                 case LocationProvider.OUT_OF_SERVICE:
166                 case LocationProvider.TEMPORARILY_UNAVAILABLE: {
167                     mValid = false;
168                     if (mListener != null && mRecordLocation &&
169                             android.location.LocationManager.GPS_PROVIDER.equals(provider)) {
170                         mListener.showGpsOnScreenIndicator(false);
171                     }
172                     break;
173                 }
174             }
175         }
176 
current()177         public Location current() {
178             return mValid ? mLastLocation : null;
179         }
180     }
181 }
182