1c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li/* 2c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * Copyright (C) 2011 The Android Open Source Project 3c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * 4c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * Licensed under the Apache License, Version 2.0 (the "License"); 5c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * you may not use this file except in compliance with the License. 6c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * You may obtain a copy of the License at 7c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * 8c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * http://www.apache.org/licenses/LICENSE-2.0 9c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * 10c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * Unless required by applicable law or agreed to in writing, software 11c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * distributed under the License is distributed on an "AS IS" BASIS, 12c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * See the License for the specific language governing permissions and 14c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * limitations under the License. 15c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li */ 16c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 17c343fa06491ee5677b735920032d92e055c16366Wu-cheng Lipackage com.android.camera; 18c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 19c343fa06491ee5677b735920032d92e055c16366Wu-cheng Liimport android.content.Context; 20c343fa06491ee5677b735920032d92e055c16366Wu-cheng Liimport android.location.Location; 21c343fa06491ee5677b735920032d92e055c16366Wu-cheng Liimport android.location.LocationProvider; 22c343fa06491ee5677b735920032d92e055c16366Wu-cheng Liimport android.os.Bundle; 23c343fa06491ee5677b735920032d92e055c16366Wu-cheng Liimport android.util.Log; 24c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 25c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li/** 26c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li * A class that handles everything about location. 27c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li */ 28c343fa06491ee5677b735920032d92e055c16366Wu-cheng Lipublic class LocationManager { 29c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li private static final String TAG = "LocationManager"; 30c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 31c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li private Context mContext; 32c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li private Listener mListener; 33c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li private android.location.LocationManager mLocationManager; 34c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li private boolean mRecordLocation; 35c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 36c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li LocationListener [] mLocationListeners = new LocationListener[] { 37c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li new LocationListener(android.location.LocationManager.GPS_PROVIDER), 38c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li new LocationListener(android.location.LocationManager.NETWORK_PROVIDER) 39c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li }; 40c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 41c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public interface Listener { 42c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public void showGpsOnScreenIndicator(boolean hasSignal); 43c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public void hideGpsOnScreenIndicator(); 44c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 45c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 46c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public LocationManager(Context context, Listener listener) { 47c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mContext = context; 48c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mListener = listener; 49c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 50c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 51a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li public Location getCurrentLocation() { 52a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li if (!mRecordLocation) return null; 53a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li 54a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li // go in best to worst order 55a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li for (int i = 0; i < mLocationListeners.length; i++) { 56a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li Location l = mLocationListeners[i].current(); 57a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li if (l != null) return l; 58a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li } 59a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li Log.d(TAG, "No location received yet."); 60a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li return null; 61a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li } 62a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li 63a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li public void recordLocation(boolean recordLocation) { 64a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li if (mRecordLocation != recordLocation) { 65a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li mRecordLocation = recordLocation; 66a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li if (recordLocation) { 67a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li startReceivingLocationUpdates(); 68a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li } else { 69a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li stopReceivingLocationUpdates(); 70a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li } 71a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li } 72a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li } 73a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li 74a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li private void startReceivingLocationUpdates() { 75c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li if (mLocationManager == null) { 76c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mLocationManager = (android.location.LocationManager) 77c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mContext.getSystemService(Context.LOCATION_SERVICE); 78c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 79c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li if (mLocationManager != null) { 80c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li try { 81c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mLocationManager.requestLocationUpdates( 82c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li android.location.LocationManager.NETWORK_PROVIDER, 83c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 1000, 84c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 0F, 85c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mLocationListeners[1]); 86c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } catch (SecurityException ex) { 87c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Log.i(TAG, "fail to request location update, ignore", ex); 88c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } catch (IllegalArgumentException ex) { 89c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Log.d(TAG, "provider does not exist " + ex.getMessage()); 90c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 91c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li try { 92c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mLocationManager.requestLocationUpdates( 93c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li android.location.LocationManager.GPS_PROVIDER, 94c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 1000, 95c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 0F, 96c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mLocationListeners[0]); 97a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li if (mListener != null) mListener.showGpsOnScreenIndicator(false); 98c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } catch (SecurityException ex) { 99c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Log.i(TAG, "fail to request location update, ignore", ex); 100c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } catch (IllegalArgumentException ex) { 101c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Log.d(TAG, "provider does not exist " + ex.getMessage()); 102c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 103c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Log.d(TAG, "startReceivingLocationUpdates"); 104c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 105c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 106c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 107a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li private void stopReceivingLocationUpdates() { 108c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li if (mLocationManager != null) { 109c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li for (int i = 0; i < mLocationListeners.length; i++) { 110c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li try { 111c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mLocationManager.removeUpdates(mLocationListeners[i]); 112c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } catch (Exception ex) { 113c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Log.i(TAG, "fail to remove location listners, ignore", ex); 114c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 115c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 116c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Log.d(TAG, "stopReceivingLocationUpdates"); 117c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 118a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li if (mListener != null) mListener.hideGpsOnScreenIndicator(); 119c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 120c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 121c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li private class LocationListener 122c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li implements android.location.LocationListener { 123c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Location mLastLocation; 124c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li boolean mValid = false; 125c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li String mProvider; 126c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 127c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public LocationListener(String provider) { 128c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mProvider = provider; 129c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mLastLocation = new Location(mProvider); 130c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 131c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 132c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li @Override 133c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public void onLocationChanged(Location newLocation) { 134c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li if (newLocation.getLatitude() == 0.0 135c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li && newLocation.getLongitude() == 0.0) { 136c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li // Hack to filter out 0.0,0.0 locations 137c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li return; 138c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 139c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li // If GPS is available before start camera, we won't get status 140c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li // update so update GPS indicator when we receive data. 141a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li if (mListener != null && mRecordLocation && 142c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li android.location.LocationManager.GPS_PROVIDER.equals(mProvider)) { 143c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mListener.showGpsOnScreenIndicator(true); 144c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 145c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li if (!mValid) { 146c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li Log.d(TAG, "Got first location."); 147c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 148c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mLastLocation.set(newLocation); 149c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mValid = true; 150c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 151c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 152c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li @Override 153c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public void onProviderEnabled(String provider) { 154c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 155c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 156c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li @Override 157c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public void onProviderDisabled(String provider) { 158c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mValid = false; 159c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 160c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 161c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li @Override 162c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public void onStatusChanged( 163c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li String provider, int status, Bundle extras) { 164c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li switch(status) { 165c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li case LocationProvider.OUT_OF_SERVICE: 166c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li case LocationProvider.TEMPORARILY_UNAVAILABLE: { 167c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mValid = false; 168a93a4d60eacee4e12471b45f8691c14114e113a4Wu-cheng Li if (mListener != null && mRecordLocation && 169c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li android.location.LocationManager.GPS_PROVIDER.equals(provider)) { 170c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li mListener.showGpsOnScreenIndicator(false); 171c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 172c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li break; 173c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 174c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 175c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 176c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li 177c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li public Location current() { 178c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li return mValid ? mLastLocation : null; 179c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 180c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li } 181c343fa06491ee5677b735920032d92e055c16366Wu-cheng Li} 182