Android的GPS上查询不正确的位置数据 [英] Android GPS incorrect location data on query

查看:198
本文介绍了Android的GPS上查询不正确的位置数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不使用模拟地点为这个......其实在code是工作的罚款上周。

我有一个应用程序,它收集GPS数据,并吐出了一个谷歌地图链接用X,Y由应用程序本身产生的坐标。我不是100%肯定为什么它不工作就应该是这样,但是当我要求的应用程序,使基于手机提供的GPS定位谷歌地图的链接它告诉我,我是5 - 6个街区从我的角度原产地(如果我其实是在当时)不完全是我想要它做的

Knowns:

  • 我有适当的权限设置
  • 所有的code,上周只是正常工作

下面是code收集的GPS信息:

  Toast.makeText(背景下,收集GPS数据......,Toast.LENGTH_SHORT).show();
    GPS =新gpsTracker(Settings.this);
    如果(gps.canGetLocation()){
        尝试{
            gps.getLocation();
            LON = gps.getLongitude();
            纬度= gps.getLatitude();
            Toast.makeText(getApplicationContext(),您现在的位置是 -  \新工人艺术团:+纬度+\ nlon:+ LON,Toast.LENGTH_LONG).show();
        }
        赶上(例外五){}
    }
    其他{
        gps.showSettingsAlert();
    }
 

以上所有是拉动类的:

 进口android.app.AlertDialog;
进口android.app.Service;
进口android.content.Context;
进口android.content.DialogInterface;
进口android.content.Intent;
进口android.location.Location;
进口android.location.LocationListener;
进口android.location.LocationManager;
进口android.os.Bundle;
进口android.os.IBinder;
进口android.provider.Settings;
进口android.util.Log;

公共类gpsTracker扩展服务实现LocationListener的{

私人最终语境mContext;

//标志GPS状态
布尔isGPSEnabled = FALSE;

//标志网络状态
布尔isNetworkEnabled = FALSE;

//标志GPS状态
布尔canGetLocation = FALSE;

地点位置; // 位置
双纬度; // 纬度
双经度; // 经度

//最小距离改变以米为单位更新
私有静态最后长MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; //10米

//毫秒更新之间的最短时间
私有静态最后长MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1分钟

//声明一个位置管理
保护LocationManager locationManager;

公共gpsTracker(上下文的背景下){
    this.mContext =背景;
    的getLocation();
}

公共场所的getLocation(){
    尝试 {
        locationManager =(LocationManager)mContext
                .getSystemService(LOCATION_SERVICE);

        //获取GPS状态
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        //获取网络状态
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        如果(isGPSEnabled&安培;!&安培;!isNetworkEnabled){
            //没有网络提供商启用
        } 其他 {
            this.canGetLocation = TRUE;
            //首先从网络提供商处获取位置
            如果(isNetworkEnabled){
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES,这一点);
                Log.d(网络,网络);
                如果(locationManager!= NULL){
                    位置= locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    如果(位置!= NULL){
                        纬度= location.getLatitude();
                        经度= location.getLongitude();
                    }
                }
            }
            //如果GPS功能的获得纬度/经度使用GPS服务
            如果(isGPSEnabled){
                如果(位置== NULL){
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES,这一点);
                    Log.d(GPS功能的,GPS功能的);
                    如果(locationManager!= NULL){
                        位置= locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        如果(位置!= NULL){
                            纬度= location.getLatitude();
                            经度= location.getLongitude();
                        }
                    }
                }
            }
        }

    }赶上(例外五){
        e.printStackTrace();
    }

    返回的位置;
}

/ **
 *停止使用GPS监听器
 *调用此函数将停止使用GPS在你的应用程序
 * * /
公共无效stopUsingGPS(){
    如果(locationManager!= NULL){
        locationManager.removeUpdates(gpsTracker.this);
    }
}

/ **
 *功能得到纬度
 * * /
公共双getLatitude(){
    如果(位置!= NULL){
        纬度= location.getLatitude();
    }

    //返回纬度
    返回纬度;
}

/ **
 *功能得到经度
 * * /
公共双getLongitude(){
    如果(位置!= NULL){
        经度= location.getLongitude();
    }

    //返回经度
    返回经度;
}

/ **
 *功能检查GPS / WiFi功能
 * @返回布尔
 * * /
公共布尔canGetLocation(){
    返回this.canGetLocation;
}

/ **
 *功能,以显示设置警告对话框
 *在pressing设置按钮将劳克设置选项
 * * /
公共无效showSettingsAlert(){
    AlertDialog.Builder alertDialog =新AlertDialog.Builder(mContext);

    //设置对话框标题
    alertDialog.setTitle(全球定位系统设置);

    //设置对话框消息
    alertDialog.setMessage(GPS未启用你想进入设置菜单。?);

    //在pressing设置按钮
    alertDialog.setPositiveButton(设置,新DialogInterface.OnClickListener(){
        公共无效的onClick(DialogInterface对话,诠释它){
            意向意图=新的意图(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(意向);
        }
    });

    //在pressing取消按钮
    alertDialog.setNegativeButton(取消,新DialogInterface.OnClickListener(){
        公共无效的onClick(DialogInterface对话,诠释它){
            dialog.cancel();
        }
    });

    //显示警报信息
    alertDialog.show();
}

@覆盖
公共无效onLocationChanged(位置定位){
}

@覆盖
公共无效onProviderDisabled(字符串提供商){
}

@覆盖
公共无效onProviderEnabled(字符串提供商){
}

@覆盖
公共无效onStatusChanged(字符串商,INT地位,捆绑演员){
}

@覆盖
公众的IBinder onBind(意向为arg0){
    返回null;
}
 

解决方案

这是什么规定[4-5块差别],您可以在位置从获得 networkProvider 只。

通过这种 gpsTracker code中提到的问题,
有需要进行一些修改,而不是使用code,因为它是:

1 有2 如果环,其验证的源位置已启用或没有,没有其他

 如果(isNetworkEnabled){
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES,这一点);
                Log.d(网络,网络);
                如果(locationManager!= NULL){
                    位置= locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    如果(位置!= NULL){
                        纬度= location.getLatitude();
                        经度= location.getLongitude();
                    }
                }
            }
            //如果GPS功能的获得纬度/经度使用GPS服务
            如果(isGPSEnabled){
                如果(位置== NULL){
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES,这一点);
                    Log.d(GPS功能的,GPS功能的);
                    如果(locationManager!= NULL){
                        位置= locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        如果(位置!= NULL){
                            纬度= location.getLatitude();
                            经度= location.getLongitude();
                        }
                    }
                }
            }
 

这意味着应用程序会做这项工作的两倍时,你可以得到位置这两个来源。此外,位置总是获得的来源仍然不明确。

这是很好的时候,你只需要近似位置这不应该是空majorly。

如果您只想使用这个类来获得位置,尝试构建了的if-else 根据需要并确保其不会,如果获得位置重复。
例如:如果 GPS 是一个更高的preference,适用于你的情况,移如果上面,并把网络状况与其他这样的:

 如果(isGPSEnabled){
                如果(位置== NULL){
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES,这一点);
                    Log.d(GPS功能的,GPS功能的);
                    如果(locationManager!= NULL){
                        位置= locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        如果(位置!= NULL){
                            纬度= location.getLatitude();
                            经度= location.getLongitude();
                        }
                    }
                }
            }否则,如果(isNetworkEnabled){
            locationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER,
                    MIN_TIME_BW_UPDATES,
                    MIN_DISTANCE_CHANGE_FOR_UPDATES,这一点);
            Log.d(网络,网络);
            如果(locationManager!= NULL){
                位置= locationManager
                        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                如果(位置!= NULL){
                    纬度= location.getLatitude();
                    经度= location.getLongitude();
                }
            }
        }
 

有关您的要求,我建议去掉网络提供商的一部分,获得位置仅从GPS,ESP,如果视线不是问题。

当您的code是工作的罚款,必须获取来自GPS的位置和对象设置它。但由于这两个如果,并没有其他,you'l永远不知道是否位置获得来自网络或GPS - 你可以检查的 location.getProvider() canGetLocation(

里面

2 此外,您还可以登录信息或提示一个特定的源代码一些行动......这样的:
在这一部分:

 如果(isGPSEnabled&安培;!&安培;!isNetworkEnabled){
            //没有网络提供商启用
        }
 

只是把它分割成两个不同的如果(S)和code相应。截至目前,没有发生在这里,所以你不会知道,除非你在外部检查都是禁用的。

建议:试着它使用 LocationClient GooglePlayServices 了解检索当前位置。我发现它更可靠,更有效。勾选此融合位置提供者例如,设置的 LocationRequest根据您的要求对象是关键。

另一个更新:刚刚碰到:<一href="http://stackoverflow.com/questions/6181704/good-way-of-getting-the-users-location-in-android?rq=1">useful疑问句的堆栈溢出 - 良好的获取用户的位置方式


更新有人查找这个问题/答案
关于LocationClient的建议;
LocationClient根据 com.google.android.gms.location ,请参考:
<一href="http://stackoverflow.com/questions/27372638/android-play-services-6-5-locationclient-is-missing">Android发挥服务6.5:LocationClient缺少

I am not using mock locations for this... In fact the code was working fine just last week.

I have an app that gathers GPS data and spits out a google maps link using X,Y coordinates generated by the application itself. I am not 100% sure why its not working the way it should be but when I request the app to make a google maps link based on the GPS location provided by the phone it tells me I am 5 - 6 blocks away from my point of origin (Where I actually am at the time) Not quite what I want it to do

Knowns:

  • I have the proper permissions set up
  • All of the code worked last week just fine

Here is the code to gather the GPS info:

        Toast.makeText(context, "Gathering GPS Data...", Toast.LENGTH_SHORT).show();
    gps = new gpsTracker(Settings.this);
    if(gps.canGetLocation()){
        try{
            gps.getLocation();
            lon = gps.getLongitude();
            lat = gps.getLatitude();
            Toast.makeText(getApplicationContext(), "Your location is - \nlat: " + lat + "\nlon: " + lon, Toast.LENGTH_LONG).show();
        }
        catch(Exception  e){}
    }
    else{
        gps.showSettingsAlert();
    }

The class all of the above is pulling from:

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

public class gpsTracker extends Service implements LocationListener {

private final Context mContext;

// flag for GPS status
boolean isGPSEnabled = false;

// flag for network status
boolean isNetworkEnabled = false;

// flag for GPS status
boolean canGetLocation = false;

Location location; // location
double latitude; // latitude
double longitude; // longitude

// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

// Declaring a Location Manager
protected LocationManager locationManager;

public gpsTracker(Context context) {
    this.mContext = context;
    getLocation();
}

public Location getLocation() {
    try {
        locationManager = (LocationManager) mContext
                .getSystemService(LOCATION_SERVICE);

        // getting GPS status
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled && !isNetworkEnabled) {
            // no network provider is enabled
        } else {
            this.canGetLocation = true;
            // First get location from Network Provider
            if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d("Network", "Network");
                if (locationManager != null) {
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    }
                }
            }
            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

    return location;
}

/**
 * Stop using GPS listener
 * Calling this function will stop using GPS in your app
 * */
public void stopUsingGPS(){
    if(locationManager != null){
        locationManager.removeUpdates(gpsTracker.this);
    }
}

/**
 * Function to get latitude
 * */
public double getLatitude(){
    if(location != null){
        latitude = location.getLatitude();
    }

    // return latitude
    return latitude;
}

/**
 * Function to get longitude
 * */
public double getLongitude(){
    if(location != null){
        longitude = location.getLongitude();
    }

    // return longitude
    return longitude;
}

/**
 * Function to check GPS/wifi enabled
 * @return boolean
 * */
public boolean canGetLocation() {
    return this.canGetLocation;
}

/**
 * Function to show settings alert dialog
 * On pressing Settings button will lauch Settings Options
 * */
public void showSettingsAlert(){
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

    // Setting Dialog Title
    alertDialog.setTitle("GPS is settings");

    // Setting Dialog Message
    alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

    // On pressing Settings button
    alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog,int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
        }
    });

    // on pressing cancel button
    alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
        }
    });

    // Showing Alert Message
    alertDialog.show();
}

@Override
public void onLocationChanged(Location location) {
}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

解决方案

From what is specified[difference of 4-5 blocks], you may be obtaining the location from networkProvider only.

With this gpsTracker code mentioned in the question,
there are a few modifications required, instead of using the code as it is:

1. There are 2 if loops which verify the source of location is enabled or not and No 'else':

 if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                Log.d("Network", "Network");
                if (locationManager != null) {
                    location = locationManager
                            .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                    }
                }
            }
            // if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
            }  

This means the application is going to do twice the work when you can obtain the location from both sources. Further, the source of location obtained always remains ambiguous.

This is good when you just need approximate location which should not be null majorly.

If you want to use only this class to obtain location, try structuring the if-else according to requirement and ensuring that its not going to repeat if the location is obtained.
Eg. if GPS is on a higher preference, applies in your case, shift that if above and put the network condition with an else like:

if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
            } else if (isNetworkEnabled) {
            locationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER,
                    MIN_TIME_BW_UPDATES,
                    MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
            Log.d("Network", "Network");
            if (locationManager != null) {
                location = locationManager
                        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (location != null) {
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                }
            }
        }

For your requirement, i suggest removing the network provider part and obtaining the location only from GPS, esp if line of sight is not a problem.

When your code was working fine, it must be fetching the location from GPS and setting it in the object. But because of the two "if" and no "else", you'l never know whether location obtained is from Network or GPS - you can check location.getProvider() inside the condition of canGetLocation()

2. Also, you can log the message or prompt some action for one particular source...like:
In this part:

 if (!isGPSEnabled && !isNetworkEnabled) {
            // no network provider is enabled
        }    

just separate it into two different if(s) and code accordingly. As of now, nothing happens here so you wouldn't know if both are disabled unless you check it externally.

Suggestion: Try the LocationClient which uses GooglePlayServices for Retrieving Current Location . I have found it more reliable and useful. Check this Fused Location Provider example, setting LocationRequest object according to your requirement is the key.

Another update: just came across: useful ques on stack overflow - Good way of getting the users location


Update for anybody looking up this question/answer
Regarding the suggestion of LocationClient;
LocationClient is no longer found under com.google.android.gms.location, refer:
Android play services 6.5: LocationClient is missing

这篇关于Android的GPS上查询不正确的位置数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆