Разработка Android - GPS не работает - приложение зависает при отправке координат

Предыстория проблемы:

Я несколько новичок в разработке Android. Все, что я пытаюсь сделать на данный момент, это получить GPS-координаты с GPS-устройства телефона и отобразить их на Google Maps или просто в TextView или где-то еще. Основная задача – их получить.

Я прочитал несколько руководств. Я использую
- Android 2.3.3
- уровень API 10
- Eclipse 3.6.1
- Windows 7


Описание проблемы :

Я написал класс GeoUpdateHandler, который реализует LocationListener и реализует его методы onLocationChange() и т. д. А в MyMapsActivity я использую обычный requestLocationUpdates из LocationManager для получения периодических обновлений.

Когда я запускаю приложение, я отправляю GPS-координаты из элемента управления эмулятором Eclipse (Окно --> Показать представление --> Другое --> Android --> Управление эмулятором) для отправки долготы и широты. Как только эмулируемое устройство получает координаты, приложение зависает. Ничего не происходит, и курсор меняется на синий кружок (что означает раздумья/зависание), и ничего не происходит. Если я использую locationManager.getLastKnownLocation(String provider), он становится нулевым. Очевидно, потому что нет последнего известного местоположения. Он застревает, прежде чем узнать один!

Я также пытался отправить координаты через telnet. (cmd --> telnet localhost 5554 --> geo fix . Но происходит то же самое.

Я попытался запустить устройство независимо от приложения, отправить координаты, а затем запустить приложение. Но то же самое происходит, когда я запускаю приложение: оно зависает.

Следующий код HelloItemizedOverlay взят из учебника Android MapView и отлично работает с заданными вручную координатами. Проблема возникает при попытке получить местоположение GPS.

public class MyMapsActivity extends MapActivity 
{
private MapController mapController;
private MapView mapView;
private LocationManager locationManager;
LinearLayout linLayout;
MapView mView;
List<Overlay> mapOverlays;
Drawable drawable;
HelloItemizedOverlay itemizedOverlay;
GeoUpdateHandler handler;
Location location;
public void onCreate(Bundle bundle)
{
    super.onCreate(bundle);
    setContentView(R.layout.main); // bind the layout to the activity

    mView = (MapView) findViewById(R.id.mapview);
    mView.setBuiltInZoomControls(true);
    mapOverlays = mView.getOverlays();
    drawable = this.getResources().getDrawable(R.drawable.icon);
    itemizedOverlay = new HelloItemizedOverlay(drawable);

    mapController = mView.getController();
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    handler = new GeoUpdateHandler();
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, handler);

    location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

    GeoPoint point = new GeoPoint((int)location.getLongitude(),(int)location.getLatitude());
    OverlayItem overlayitem = new OverlayItem(point, "", "");

    mView.setBuiltInZoomControls(true);
    itemizedOverlay.addOverlay(overlayitem);

    mapOverlays.add(itemizedOverlay);

    mapController.setZoom(8);
    mapController.animateTo(point);
}

@Override
protected boolean isRouteDisplayed() 
{
    return false;
}

public class GeoUpdateHandler implements LocationListener 
{
    @Override
    public void onLocationChanged(Location location) 
    {
        int lat = (int) (location.getLatitude());
        int lng = (int) (location.getLongitude());
        GeoPoint point = new GeoPoint(lat, lng);
        mapController.animateTo(point); //  mapController.setCenter(point);
    }

    @Override
    public void onProviderDisabled(String provider) 
    {

    }

    @Override
    public void onProviderEnabled(String provider) 
    {

    }

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

    }
}

@Override
protected void onResume()
{
    handler = new GeoUpdateHandler();
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, handler);
    super.onResume();
}
}

person Abubakar Mehmood    schedule 18.02.2011    source источник


Ответы (1)


Согласно этому, конструктор Geopoint принимает (широта * 1e6, долгота * 1e6) в качестве параметров; тогда как вы указали (долгота, широта) при вызове getLastKnownLocation и забыли масштабный коэффициент в другом вызове (в onLocationChanged). Широта и логарифм не масштабируются в объектах Location. .

В любом случае, эта ошибка должна приводить только к отображению синей карты ((0,0) находится в Атлантическом океане), поэтому могут быть другие проблемы.


Редактировать:

1/ при воспроизведении вашего комментария, если вы перепутаете долготу и широту, вы можете получить несуществующую точку (широта всегда остается в пределах [-90°,90°], тогда как долгота может варьироваться в пределах [-180°,180°])

2/ есть ошибка в SDK 2.3 (уровень API 9), которая приводит к сбою эмулятора при отправке фиктивных местоположений. Не знаю, верно ли это для 2.3.3 (10 ур.), но для проверки использовал 2.1u1 (7 ур.).

3/Для меня работает следующий код:

package test.testmap;

import java.util.List;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.LinearLayout;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class MyMapsActivity extends MapActivity 
{
    private MapController mapController;
    private LocationManager locationManager;
    LinearLayout linLayout;
    MapView mView;
    List<Overlay> mapOverlays;
    Drawable drawable;
    HelloItemizedOverlay itemizedOverlay;
    GeoUpdateHandler handler;
    Location location;
    public void onCreate(Bundle bundle)
    {
        super.onCreate(bundle);
        setContentView(R.layout.main); // bind the layout to the activity

        drawable = this.getResources().getDrawable(R.drawable.icon);
        itemizedOverlay = new HelloItemizedOverlay(drawable);

        mView = (MapView) findViewById(R.id.mapview);
        mView.setBuiltInZoomControls(true);

        mapOverlays = mView.getOverlays();
        mapOverlays.add(itemizedOverlay);

        mapController = mView.getController();
    }

    @Override
    protected boolean isRouteDisplayed() 
    {
        return false;
    }

    public class GeoUpdateHandler implements LocationListener 
    {
        @Override
        public void onLocationChanged(Location location) 
        {
            Log.d(this.getClass().getName(),"onLocationChanged : lat = "+location.getLatitude()+" lon = "+location.getLongitude());
            int lat = (int) Math.round(location.getLatitude()*1.0e6);
            int lng = (int) Math.round(location.getLongitude()*1.0e6);
            GeoPoint point = new GeoPoint(lat, lng);
            itemizedOverlay.addOverlay(new OverlayItem(point, "", ""));
            mapController.animateTo(point);
            mapController.setZoom(8);
        }

        @Override
        public void onProviderDisabled(String provider) 
        {
            Log.d(this.getClass().getName(),"onProviderDisabled");
        }

        @Override
        public void onProviderEnabled(String provider) 
        {
            Log.d(this.getClass().getName(),"onProviderEnabled");
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) 
        {
            Log.d(this.getClass().getName(),"onStatusChanged");
        }
    }

    @Override
    protected void onResume()
    {
        handler = new GeoUpdateHandler();
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, handler);
        super.onResume();
    }
}
person Stéphane    schedule 18.02.2011
comment
Большое спасибо, Стефан! Но предоставление (долгота, широта) вместо (широта, долгота) должно просто стать другим местоположением, отличным от того, которое я хочу. И да, масштабирование имеет значение. Но не знаю, почему, когда я вручную создаю геоточку, задавая образцы значений широты и долготы, она отображается на карте. Но все равно спасибо. :) Должна быть более серьезная проблема. Либо в моем коде, который я сейчас вряд ли найду, либо в эмуляторе, либо еще в чем-то. - person Abubakar Mehmood; 20.02.2011
comment
Можете ли вы зарегистрировать значения широты и долготы, которые вы получаете (прямо из объекта Location)? Ну, у меня сейчас не так много времени, но, надеюсь, я посмотрю поближе сегодня (часовой пояс GMT+1)... - person Stéphane; 20.02.2011