Android onLocationChanged()接收更新,但位置永远不会更改

时间:2015-01-28 23:10:25

标签: android gps nokia

我正在编写一个简单的Android导航应用程序,它最终会显示用户当前位置和另一个点之间的直线距离,但我无法获得GPS定位服务好好工作。我有一个Activity实现LocationListener并更新onLocationChanged()中的UI。但是一旦我在设备上启动应用程序(通过Android Studio),GPS就会获得修复并显示一次位置,然后再也不会更新。决不。即使我外出走动也没有。当我旋转屏幕,导致Activity重新注册为听众时,我有时会看到位置发生变化,但有时我不会。将其他代码放入onLocationChanged()会显示正在调用onLocationChanged(),但实际位置数据根本没有变化。

似乎在一两秒内得到修复,让我觉得它只是吐出缓存的位置。但有时候,在启动应用程序时,我会在停止更新之前看到实际数据的几秒钟实际更新。此外,在将手机插回计算机时,我有时会看到一个更新。这甚至发生在我外出时,清除系统设置菜单中应用程序的缓存数据,然后返回应用程序。将会有一些更新,然后它会在一个位置结算并拒绝进一步更新。

奇怪的是,它在两小时前工作得很好。从那时起,我在代码中添加的唯一内容就是UI元素。

我使用的设备是诺基亚X2,因此无法选择切换到较新的Google Play Services API。在日志中,我看到" D / ContextImpl:BYDSafe:new BYDSafeLocationManager"当我第一次获得LocationManager时。谷歌搜索它绝对没有,所以我认为这是一些诺基亚专有类。如果这个课程是我的问题的原因,那么有什么办法可以强迫Android给我一个Android LocationManager的股票吗?

public class NavScreen extends Activity implements LocationListener {

    private TextView latField;
    private TextView longField;
    private TextView altField;
    private TextView beField;
    private TextView spField;
    private TextView luField;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_nav_screen);

        latField = (TextView)(findViewById(R.id.latitudeField));
        longField = (TextView)(findViewById(R.id.longitudeField));
        altField = (TextView)(findViewById(R.id.altitudeField));
        beField = (TextView)(findViewById(R.id.bearingField));
        spField = (TextView)(findViewById(R.id.speedField));
        luField = (TextView)(findViewById(R.id.lastUpdateField));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.nav_screen, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        LocationManager manager = (LocationManager)(getSystemService(Context.LOCATION_SERVICE));
        if(manager.isProviderEnabled(LocationManager.GPS_PROVIDER))
        {
            manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 0, this);
        }
        else
        {
            Toast.makeText(this, "Please enable GPS", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        LocationManager manager = (LocationManager)(getSystemService(Context.LOCATION_SERVICE));
        manager.removeUpdates(this);
    }

    //Location callbacks

    @Override
    public void onLocationChanged(Location location) {
        String lat = String.format("%f", location.getLatitude());
        String lon = String.format("%f", location.getLongitude());
        String alt = String.format("%f", location.getAltitude());
        String bearing = String.format("%f", location.getBearing());
        String speed = String.format("%f", location.getSpeed());

        latField.setText("Latitude: " + lat);
        longField.setText("Longitude: " + lon);
        altField.setText("Altitude: " + alt + "m");
        beField.setText("Bearing: " + bearing + " degrees");
        spField.setText("Speed: " + speed + " m/s");
        luField.setText("Last update: " + new Date(System.currentTimeMillis()).toString());
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        switch(status)
        {
            case LocationProvider.OUT_OF_SERVICE:
                Log.d("DEBUG", provider + " out of service");
                Toast.makeText(this, provider + " out of service", Toast.LENGTH_SHORT).show();
                break;
            case LocationProvider.TEMPORARILY_UNAVAILABLE:
                Log.d("DEBUG", provider + " temp. unavailable");
                Toast.makeText(this, provider + " temp. unavilable", Toast.LENGTH_SHORT).show();
                break;
            case LocationProvider.AVAILABLE:
                Log.d("DEBUG", provider + " available");
                Toast.makeText(this, provider + " available", Toast.LENGTH_SHORT).show();
                break;
            default:
        }
    }

    @Override
    public void onProviderEnabled(String provider) {
        Toast.makeText(this, provider + " enabled", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProviderDisabled(String provider) {
        Toast.makeText(this, provider + " disabled", Toast.LENGTH_SHORT).show();
    }
}

2 个答案:

答案 0 :(得分:0)

初看,您的代码看起来正确。我建议测试两件事。

  1. 在所有情况下注册监听器,不仅仅是对启用的提供商的检查是肯定的。这使您确信,无论设备发生什么情况,您都会收听更新(例如,用户可以通过后台的任何第三方应用启用提供商)

  2. 尝试将manager.requestLocationUpdates中的时间参数也更改为0。我记得我也有一些问题,最后0,0值最好。

  3. 希望这有帮助

答案 1 :(得分:0)

每当onCreate() extends Activity时,您必须使用TextView方法启动所有必需的组件。

在您的情况下,您已启动除LocationManager以外的所有@Override protected void onCreate(Bundle savedInstanceState) { ... ... LocationManger l = (LocationManager)getSystemService(Context.LOCATION_SERVICE); //time interval needs to be multiplied by 1000 as millisecond is the actual unit. l.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1*1000, 0, this); this.onLocationChanged(null);//It is now initiated whenever app started }

只需在onCreate()方法中添加以下代码即可。

LocationManager

或者,您可以在onCreate()之外宣布TextView onResume,如果您需要将其部署到任何地方(等{{1}}内)。