/* * Copyright 2011 Matthew Precious * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.mattprecious.locnotifier; import java.io.IOException; import java.util.List; import android.content.Context; import android.location.Address; import android.location.Geocoder; import android.location.Location; import com.google.android.maps.GeoPoint; /** * * @author Google * */ public class LocationHelper { private static final int TWO_MINUTES = 1000 * 60 * 2; /** * Determines whether one Location reading is better than the current * Location fix * * @param location * The new Location that you want to evaluate * @param currentBestLocation * The current Location fix, to which you want to compare the new * one */ public static boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, use the new location // because the user has likely moved if (isSignificantlyNewer) { return true; // If the new location is more than two minutes older, it must be // worse } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return true; } return false; } /** Checks whether two providers are the same */ private static boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2); } public static GeoPoint getFirstPointFromSearch(Context context, String address) { List<Address> addressList = stringToAddresses(context, address); if (addressList == null) { return null; } return addressToPoint(addressList.get(0)); } public static List<Address> stringToAddresses(Context context, String address) { try { Geocoder coder = new Geocoder(context); List<Address> result = coder.getFromLocationName(address, 10); return result; } catch (IOException e) { return null; } } public static GeoPoint addressToPoint(Address address) { if (address == null) { return null; } int latitude = (int) (address.getLatitude() * 1E6); int longitude = (int) (address.getLongitude() * 1E6); return new GeoPoint(latitude, longitude); } public static String addressToString(Address address) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < address.getMaxAddressLineIndex(); i++) { if (i > 0) { builder.append(", "); } builder.append(address.getAddressLine(i)); } return builder.toString(); } }