0

これは少し複雑な問題なので、注意深く読んでください。

私はその地図を実現しようとしました

-私の現在の位置を示し、

-マップ内のポイントをクリックすると、アプリは緯度と経度を取得するカスタム geoPoint を配置して、これらをアクティビティに渡して新しい Pub オブジェクトを作成する必要があります

-開始時のマップには、以前に保存されたパブの位置が表示されている必要があります

このチュートリアルに従って、これらのクラスを作成しました

クラス MyMap :

public class MyMap extends MapActivity implements LocationListener {
    private MapView mapView;
     private LocationManager locManager;
     private MapLocationOverlay itemizedOverlay;
     GeoPoint point ;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Inflate our UI from its XML layout description.
        setContentView(R.layout.mymap);

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

        // invalidate the map in order to show changes
        mapView.invalidate();

        MapController controller = mapView.getController();


        // Use the location manager through GPS
        locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
                0, this);

        //get the current location (last known location) from the location manager
        Location location = locManager
                .getLastKnownLocation(LocationManager.GPS_PROVIDER);



            //if location found display as a toast the current latitude and longitude
        if (location != null) {
            point = new GeoPoint((int)(location.getLatitude()*1E6),(int)(location.getLongitude() *1E6));
            Toast.makeText(
                    this,
                    "Current location:\nLatitude: " + location.getLatitude()
                            + "\n" + "Longitude: " + location.getLongitude(),
                    Toast.LENGTH_LONG).show();


            controller.animateTo(point);
            controller.setZoom(13);

        } else {

            Toast.makeText(this, "Cannot fetch current location!",
                    Toast.LENGTH_LONG).show();
        }


        // fetch the drawable - the pin that will be displayed on the map
        Drawable drawable = this.getResources().getDrawable(R.drawable.pin_custom);

        // create and add an OverlayItem to the MyItemizedOverlay list
        OverlayItem overlayItem = new OverlayItem(point, "", "");
        itemizedOverlay = new MapLocationOverlay(drawable,this);
        itemizedOverlay.addOverlay(overlayItem);

        // add the overlays to the map
        mapView.getOverlays().add(itemizedOverlay);
        mapView.invalidate();

        GestureDetector gd=new GestureDetector(this, new MyGestureDetector ());
        itemizedOverlay.setGestureDetector(gd);

        //when the current location is found – stop listening for updates (preserves battery)
        locManager.removeUpdates(this);
    }





    protected boolean isRouteDisplayed() {
        return false;

    }

    /* When the activity starts up, request updates */

    protected void onResume() {
        super.onResume();
        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,
                0, this);
    }


    protected void onPause() {
        super.onPause();
        locManager.removeUpdates(this); //activity pauses => stop listening for updates
    }

    public void onLocationChanged(Location location) {

    }



    public void onProviderDisabled(String provider) {

    }


    public void onProviderEnabled(String provider) {

    }


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

    }

    public class MyGestureDetector  extends SimpleOnGestureListener {


        public boolean onSingleTapConfirmed(MotionEvent event) {

            // fetch the correspondent point from the map
            GeoPoint p = mapView.getProjection().fromPixels((int) event.getX(),(int) event.getY());

            // create an overlay item and clear all others
            OverlayItem o = new OverlayItem(p, null, null);
            itemizedOverlay.clear();
            itemizedOverlay.addOverlay(o);

            // add the overlay item
            mapView.getOverlays().clear();
            mapView.getOverlays().add(itemizedOverlay);
            mapView.invalidate();

            Geocoder geoCoder = new Geocoder(getBaseContext(),
                    Locale.getDefault());

            // get the address based on the coordinates
            try {
                List<Address> addresses = geoCoder.getFromLocation(p.getLatitudeE6() / 1E6, p.getLongitudeE6() / 1E6, 1);

                String addressString = "";
                if (addresses.size() > 0) {
                    for (int i = 0; i < addresses.get(0)
                            .getMaxAddressLineIndex(); i++)
                        addressString += addresses.get(0).getAddressLine(i)
                                + " - ";
                }

                Toast.makeText(getBaseContext(), addressString,
                        Toast.LENGTH_SHORT).show();

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

            return true;
        }

        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            return super.onFling(e1, e2, velocityX, velocityY);
        }

        public boolean onDown(MotionEvent e) {
            return false;
        }
    }


}

クラスMapLocationOverlay :

public class MapLocationOverlay extends ItemizedOverlay<OverlayItem> {

       private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
       private GestureDetector gestureDetector;

       private List<Pub> pubList;
       private Context context;



       public MapLocationOverlay(Context context, List<Pub> pubList, Drawable marker) {
          super(boundCenterBottom(marker));
          try{
              this.context = context;
              this.pubList = pubList;
              if (pubList == null) {
                  pubList = new ArrayList<Pub>();
              }
              populate();
          }
          catch(RuntimeException e){

          }

       }

       public MapLocationOverlay(Drawable defaultMarker, Context ctx) {
            super(boundCenterBottom(defaultMarker));

        }

       @Override
       protected OverlayItem createItem(int i) {
           try{
           Pub c=pubList.get(i);
              GeoPoint point =
                       new GeoPoint((int) (c.getLatitude() * 1e6), (int) (c.getLongitude() * 1e6));
              return new OverlayItem(point, c.getName(), null);
          }
          catch(RuntimeException e){

          }
          return mOverlays.get(i);
       }

       public void addOverlay(OverlayItem overlay) {
            mOverlays.add(overlay);
            populate();
        }

       public void clear() {

            mOverlays.clear();
            populate();
        }

       @Override
       public boolean onTap(final int index) {
           Pub c=pubList.get(index);
           final String name=c.getName();
           final String description=c.getDescription();
           final String street=c.getStreet();
         // BrewLocation brewLocation = brewLocations.get(index);
          AlertDialog.Builder builder = new AlertDialog.Builder(context);
          builder.setTitle("Visualizzare la nota "+name+"?")
                   .setPositiveButton("Si", new DialogInterface.OnClickListener() {
                      public void onClick(DialogInterface dialog, int id) {
                         Intent pubDetails = new Intent(context, InfoPub.class);
                         pubDetails.putExtra("name", name);
                         pubDetails.putExtra("description", description);
                         pubDetails.putExtra("street", street);
                         context.startActivity(pubDetails);
                      }
                   }).setNegativeButton("No", new DialogInterface.OnClickListener() {
                      public void onClick(DialogInterface dialog, int id) {
                         dialog.cancel();
                      }
                   });
          AlertDialog alert = builder.create();
          alert.show();

          return true; // we'll handle the event here (true) not pass to another overlay (false)
       }


        /**
         * Override this method to handle a "tap" on a balloon. By default, does nothing 
         * and returns false.
         * 
         * @param index - The index of the item whose balloon is tapped.
         * @return true if you handled the tap, otherwise false.
         */
        protected boolean onBalloonTap(int index) {
            return false;
        }

          @Override
            public boolean onTouchEvent(MotionEvent event, MapView mapView) {

                // when the user lifts its finger
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }

                return false;
                }

            public GestureDetector getGestureDetector() {
                    return gestureDetector;
                }

            public void setGestureDetector(GestureDetector gestureDetector) {
                this.gestureDetector = gestureDetector;
            }

       @Override
       public int size() {
           //return pubList.size();
           return mOverlays.size();
       }



    }

完全には完了していませんが、チュートリアルに従って実行する必要があります。残念ながら、アクティビティを起動しようとすると、致命的なエラーでアプリがクラッシュします。

これはエラー スタックです。

10-13 17:25:56.109: E/AndroidRuntime(28215): FATAL EXCEPTION: main
10-13 17:25:56.109: E/AndroidRuntime(28215): java.lang.RuntimeException: Unable to start activity ComponentInfo{it.myapp.mymapapp/it.myapp.mymapapp.MyMap}: java.lang.NullPointerException
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.os.Handler.dispatchMessage(Handler.java:99)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.os.Looper.loop(Looper.java:130)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.app.ActivityThread.main(ActivityThread.java:3687)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at java.lang.reflect.Method.invokeNative(Native Method)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at java.lang.reflect.Method.invoke(Method.java:507)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at dalvik.system.NativeStart.main(Native Method)
10-13 17:25:56.109: E/AndroidRuntime(28215): Caused by: java.lang.NullPointerException
10-13 17:25:56.109: E/AndroidRuntime(28215):    at com.google.android.maps.ItemizedOverlay.populate(ItemizedOverlay.java:312)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at it.myapp.mymapapp.utility.MapLocationOverlay.addOverlay(MapLocationOverlay.java:72)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at it.myapp.mymapapp.MyMap.onCreate(MyMap.java:89)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-13 17:25:56.109: E/AndroidRuntime(28215):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
10-13 17:25:56.109: E/AndroidRuntime(28215):    ... 11 more

どうすればこれを修正できますか? 何が欠けていますか?

4

2 に答える 2

1

有効な を取得する場合を除き、 で初期化pointしていません。onCreate()lastKnownLocation()

この初期化pointされていないものは、ItemizedOverlay に追加される OverlayItem に追加されます。

Mapview がマーカーを描画するために Geopoint を取得しようとすると、おかしなことにnullなります!!

置き換えるだけです:

GeoPoint point;

に:

GeoPoint point = new Geopoint(0,0); 

もうクラッシュしません。

于 2012-10-13T22:10:55.013 に答える
0

あなたのcreateItem()実装はかなり奇妙です:

  1. あなたは a を捕まえてRuntimeException、それで何もしません。特にコードに問題がある場合は、例外をログに記録する必要があります。

  2. size()メソッドは of に基づいていますが、 in を使用していませmOverlaysん(誤った処理が発生しない限り)。一貫して使用するか、完全に削除してください。mOverlayscreateItem()RuntimeExceptionmOverlays

それを超えて、そうではItemizedOverlayないことを期待するものnullは確かにnull. 1 つの可能性は、「スニペット」(OverlayItemコンストラクターの 3 番目のパラメーター) で、これを に設定しnullます。もう 1 つの可能性は、それc.getName()が を返していることnullであり、おそらくItemizedOverlay名前を非にする必要がありますnull

他に何もない場合は、そのブログ投稿の元のコードに戻り、それが機能するようにしてから、必要な機能を持つようにゆっくりと変更し、テストを続けます。

于 2012-10-13T18:24:09.217 に答える