我正在Android中开发一个应用程序,其中捕获用户的当前位置,而不是保存在服务器上我的应用程序正常运行,
在我告诉你问题之前让我解释一下我如何捕捉位置
要捕获位置,我创建了服务,每当用户使用 GPS 和网络
登录并捕获位置时,该服务就会运行>LocationService.java
public class LocationService extends Service implements LocationListener,
Runnable {
private static final int PERIOD_SECONDS = 30;
private LocationManager mgr = null;
private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
private boolean isScheduled = false;
private boolean ishaveNet = false;
//String isFrom = "";
@Override
public void onCreate() {
super.onCreate();
//Utils.printLoge(5, locService + "-->", "LocationService");
if (Utils.checkDataBase(getApplicationContext())) {
PackageManager pm = getPackageManager();
Constant.hasGps = pm.hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS);
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
mgr = (LocationManager) getSystemService(LOCATION_SERVICE);
} else {
stopSelf();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
ishaveNet = CommonFunction.getConnectivityStatusString(getApplicationContext());
//isFrom = "extra null";
setBeforeDelay15();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
if (mgr != null)
mgr.removeUpdates(this);
/*if (executor != null)
executor.shutdown();*/
if (executor != null)
executor.shutdownNow();
//Utils.printLoge(5, "location service", "SET FALSE FLAG");
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
return (null);
}
@Override
public void onLocationChanged(Location location) {
if (!isScheduled) {
isScheduled = true;
if (executor != null)
executor.scheduleAtFixedRate(this, 0, PERIOD_SECONDS,
TimeUnit.SECONDS);
}
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void run() {
Location loc = getBestLocation();
SharedPreferences sp = getApplicationContext().getSharedPreferences("ECP", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (loc == null) {
//Utils.printLoge(5, locService + "error 1--->", "Got null for getBestLocation()");
editor.putBoolean(Constant.LOCATION_SAVE_LOC, false);
Utils.printLoge(5, "location service", "lOC NOT FOUND");
editor.apply();
} else {
String locService = "ECP_LOC";
Utils.printLoge(5, locService + " LOCATION_PROVIDER_LOC", "" + loc.getProvider());
editor.putBoolean(Constant.LOCATION_SAVE_LOC, true);
editor.putString(Constant.LOCATION_LAT_LOC, "" + loc.getLatitude());
editor.putString(Constant.LOCATION_LON_LOC, "" + loc.getLongitude());
String P = "";
try {
if (loc.getProvider().equalsIgnoreCase("network")) {
P = "N";
} else if (loc.getProvider().equalsIgnoreCase("gps")) {
P = "G";
}
} catch (Exception e) {
Log.e("error get provider", "error get provider");
e.printStackTrace();
}
editor.putString(Constant.LOCATION_PROVIDER_LOC, "" + P);
editor.putLong(Constant.LOCATION_SAVE_TIME_LOC, System.currentTimeMillis());
editor.apply();
}
}
private void startWork() {
if (Constant.hasGps) {
//Utils.printLoge(5, "location service", "start work");
try {
//Utils.printLoge(5, locService + " isFrom", "-->" + isFrom);
boolean isStarted = false;
if (mgr != null) {
if (Constant.hasGps) {
isStarted = true;
mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
if (ishaveNet) {
isStarted = true;
mgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
}
}
if (!isStarted) {
try {
//Utils.printLoge(5, "location service", "insert module error log");
clsModules_Error_Log objclsError_CRMErrorLog = new clsModules_Error_Log(
"Location Services", "", "com.vcs.ecp.locservice", "get location in services", "not able to start location services because device have not GPS and not network at this time",
MyFunction.GetCurrentDate(Constant.ENTRY_DATE), "");
DBAdapter db = new DBAdapter(getApplicationContext());
db.open();
db.InsertModules_Error_Log(objclsError_CRMErrorLog);
db.close();
/***
* stop service start agian if internet is working
* */
stopSelf();
} catch (Exception e) {
e.printStackTrace();
//Utils.printLoge(5, "erro location service 2", "-->" + e.getMessage().toString());
stopSelf();
}
} else {
setDelay15();
}
} catch (Exception e) {
e.printStackTrace();
//Utils.printLoge(5, "erro location service 1", "-->" + e.getMessage().toString());
stopSelf();
}
} else {
stopSelf();
}
}
private void manageLoc() {
//Utils.printLoge(5, "location service", "manageLoc");
Intent i = new Intent(getApplicationContext(), LocationManageService.class);
getApplicationContext().startService(i);
stopSelf();
}
private Location getBestLocation() {
Location gps = mgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location network = mgr
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// start off by handling cases where we only have one
if (gps == null) {
return (network);
}
if (network == null) {
return (gps);
}
Location older = (gps.getTime() < network.getTime() ? gps : network);
Location newer = (gps == older ? network : gps);
if (isBetterLocation(newer, older)) {
return (newer);
} else {
// older and less accurate fixes suck
if (older.getAccuracy() <= newer.getAccuracy()) {
return (newer);
}
// if older is within error radius of newer, assume
// not moving and go with older (since has better
// accuracy, else would have been caught by previous
// condition)
// ideally, this would really be "if the odds of
// the older being within the error radius of the
// newer are higher than 50%", taking into account
// the older one's accuracy as well -- the
// implementation
// of this is left as an exercise for the reader
if (newer.distanceTo(older) < newer.getAccuracy()) {
return (older);
}
// if all else fails, choose the newer one -- the device
// is probably moving, and so we are better off with the
// newer fix, even if less accurate
return (newer);
}
}
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
*/
private 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);
}
/*public void saveFlagStop(boolean isStartManage) {
Utils.printLoge(5, "location service", "STOP lOC");
if (isStartManage == true) {
manageLoc();
}
stopSelf();
}*/
}
现在的问题是,有时它给我错误的位置,就像用户使用我的应用程序在印度但GPS给了我IRAN的位置。同样,用户使用我的应用程序是在印度的一个像TELANGANA这样的州,但GPS给了我BIHAR的位置。
我试图找出这个问题并且我知道它依赖于服务器来源,如GPS,WIFI,手机数据和设备H / W
中进行了解释但我仍然想要正确的解决方案这个问题,还是这个错误?