Creating a blank location object
-
29-09-2019 - |
문제
A couple of other people and me are working on an app for android. It requires locating the device in latitude and longitude. We've been able to create a location object, but the object is always blank. We even tried recreating the code in a completely empty project, but that also failed. Here's our root activity:
package com.app.Locationtest;
import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
public class locationtest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LocationManager locman =(LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location loc = locman.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (loc==null)
{
finish();
}
}
}
Here's the Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.Locationtest"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".locationtest"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="8" />
</manifest>
How do we fix this problem?
해결책
Sometimes the device needs too much time to retrieve the location, this is the flow for retrieving locations listed on the android site:
- Start application.
- Sometime later, start listening for updates from desired location providers.
- Maintain a "current best estimate" of location by filtering out new, but less accurate fixes.
- Stop listening for location updates.
- Take advantage of the last best location estimate.
I use a custom location listener and start listening for location updates, since my app is initialized, even if I'm not showing the map:
locationManager = (LocationManager) this.getSystemService(LOCATION_SERVICE);
locationListener = new CustomLocationListener();
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
I have a thread that is listening the locations, so when a user taps and calls my mapview, if the location is null, we send a msg to the user, to wait while we are retrieving his location.
You might want to develop a method to choose the better location, because the last location maybe is not the best location, try with this:
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
*/
protected 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 boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
This code is provided on the same page I linked.
Hope this helps!
다른 팁
getLastKnownLocation() javadoc says: ".. If the provider is currently disabled, null is returned."
So it relies on GPS but it does not turn it on. It is used to piggyback on other applications using GPS.