1

以下のコードを使用して、エミュレーターで最初にテストしようとしています。これは、正常に動作していることを確認してから、実際のデバイスでテストを開始できます。

以下のコードはGoogle Map、Android画面の上半分と下半分にを作成しTextViewます。私の知る限り、Googleマップを使用してアプリケーションを起動するときは常に、DDMSの観点から緯度と経度の座標を渡す必要があります。

しかし、私の場合、私は位置座標を渡していないので、以下のプログラムはNULL POINTER EXCEPTIONこの行にスローされます-

mScreenPoints = mapView.getProjection().toPixels(pointToDraw, mScreenPoints);

なぜそれが起こっているのかわかりません。私が知る限り、Google Map最初にロードしてから、DDMSの観点から位置座標を渡すのを待つ必要がありますが、アプリケーションを起動するとすぐforce closedNPE

なぜそれが起こっているのか考えはありますか?

以下は完全なコードです-

private MapView mapView;
private ListView listView;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mapView = (MapView) findViewById(R.id.mapView);
    listView = (ListView) findViewById(R.id.mylist);

    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);    

    locationListener = new GPSLocationListener(mapView);

    locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER, 
            35000, 
            0, 
            locationListener);


    mapView.setStreetView(true);
    mapView.setBuiltInZoomControls(true);
    mapController = mapView.getController();
    mapController.setZoom(15);
}

場所更新クラス-

    private class GPSLocationListener implements LocationListener {

    MapOverlay mapOverlay;

    public GPSLocationListener(MapView mapView) {
        mapOverlay = new MapOverlay(this,android.R.drawable.star_on);
        List<Overlay> listOfOverlays = mapView.getOverlays();
        listOfOverlays.add(mapOverlay);
    }

    @Override
    public void onLocationChanged(Location location) {
        if (location != null) {
            GeoPoint point = new GeoPoint(
                    (int) (location.getLatitude() * 1E6), 
                    (int) (location.getLongitude() * 1E6));

            mapController.animateTo(point);
            mapController.setZoom(15);

            mapOverlay.setPointToDraw(point);
            mapView.invalidate();
        }
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

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

以下は、現在の場所で地図上に円を描くクラスと、このクラスでのみ発生するNPEです-

    class MapOverlay extends Overlay {
    private GeoPoint pointToDraw;
    int[] imageNames=new int[6];
    private Point mScreenPoints;
    private Bitmap mBitmap;
    private Paint mCirclePaint;


    public MapOverlay(GPSLocationListener gpsLocationListener, int currentUser) {
        imageNames[0]=currentUser;
        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCirclePaint.setColor(0x30000000);
        mCirclePaint.setStyle(Style.FILL_AND_STROKE);
        mBitmap = BitmapFactory.decodeResource(getResources(),imageNames[0]);
        mScreenPoints = new Point();
    }

    public void setPointToDraw(GeoPoint point) {
        pointToDraw = point;
    }

    public GeoPoint getPointToDraw() {
        return pointToDraw;
    }

    public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
        super.draw(canvas, mapView, shadow);

                   // NPE happening here
        mScreenPoints = mapView.getProjection().toPixels(pointToDraw, mScreenPoints);

        int totalCircle=4;
        int radius=40;
        int centerimagesize=35;

        for (int i = 1; i <= totalCircle; i ++) { 
            canvas.drawCircle(mScreenPoints.x,mScreenPoints.y, i*radius, mCirclePaint); 
        } 

        canvas.drawBitmap(mBitmap, (mScreenPoints.x-(centerimagesize/2)),(mScreenPoints.y-(centerimagesize/2)), null);
        super.draw(canvas,mapView,shadow);

        return true;
    }
}

アップデート:-

問題を見つけました。オーバーレイをリストに追加すると、常にすぐに描画が開始されると思います。場所を取得するかどうかは関係ありません。設定する場所ができるまでオーバーレイを追加しないように、を安全かつ効率的に追加するにはどうすればよいですか?

4

3 に答える 3

1
mapView = (MapView) findViewById(R.id.mapView);

マップ ビューが作成され、マップの読み込みが開始されます。

locationManager.requestLocationUpdates

あなたは位置情報をリクエストしていますが、それは後で到着します。

public void onLocationChanged(Location location) {
        if (location != null) {
            GeoPoint point = new GeoPoint(
                    (int) (location.getLatitude() * 1E6), 
                    (int) (location.getLongitude() * 1E6));

            mapController.animateTo(point);
            mapController.setZoom(15);

            mapOverlay.setPointToDraw(point);
            mapView.invalidate();
        }
    }

ここでのみポイントを設定し、その場所に到着したとき

mapOverlay.setPointToDraw(point);

しかし、マップはすでに表示されており、draw() が呼び出されています。

于 2012-09-17T03:40:08.513 に答える
1

安全な方法:

public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
    if(pointToDraw == null){ // it isn't found the location yet.
         return super.draw(canvas, mapView, shadow); // do the default
    }        

   // else:
    super.draw(canvas, mapView, shadow);

                   // NPE happening here
        mScreenPoints = mapView.getProjection().toPixels(pointToDraw, mScreenPoints);

        int totalCircle=4;
        int radius=40;
        int centerimagesize=35;

        for (int i = 1; i <= totalCircle; i ++) { 
            canvas.drawCircle(mScreenPoints.x,mScreenPoints.y, i*radius, mCirclePaint); 
        } 

        canvas.drawBitmap(mBitmap, (mScreenPoints.x-(centerimagesize/2)),(mScreenPoints.y-(centerimagesize/2)), null);
        super.draw(canvas,mapView,shadow);

        return true;
    }
于 2012-09-17T08:45:56.830 に答える
0
if(mapView != null){
    Projection projection = mapView.getProjection();
    if(projection != null){
          mScreenPoints = projection.toPixels(pointToDraw, mScreenPoints);
    }
    else{
      // log it projection is null
    }
}
else{
   //log it mapView is null
}

nulllpointerはどこにありますか?

于 2012-09-17T03:23:17.020 に答える