Android でメインのアクティビティを表示しようとすると、問題が発生します。アクティビティが MapView を拡張したときに問題が発生しました (理由はわかりません)。LogCat にはいくつかのエラーが表示されますが、その意味がわかりません。LogCat は次のとおりです。
03-07 05:42:56.859: D/AndroidRuntime(15357): Shutting down VM
03-07 05:42:56.859: W/dalvikvm(15357): threadid=1: thread exiting with uncaught exception (group=0x40018578)
03-07 05:42:56.859: E/AndroidRuntime(15357): FATAL EXCEPTION: main
03-07 05:42:56.859: E/AndroidRuntime(15357): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.geo.location/com.geo.location.GeoLocationActivity}: java.lang.IllegalArgumentException: listener==null
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.os.Handler.dispatchMessage(Handler.java:99)
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.os.Looper.loop(Looper.java:130)
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.app.ActivityThread.main(ActivityThread.java:3687)
03-07 05:42:56.859: E/AndroidRuntime(15357): at java.lang.reflect.Method.invokeNative(Native Method)
03-07 05:42:56.859: E/AndroidRuntime(15357): at java.lang.reflect.Method.invoke(Method.java:507)
03-07 05:42:56.859: E/AndroidRuntime(15357): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
03-07 05:42:56.859: E/AndroidRuntime(15357): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
03-07 05:42:56.859: E/AndroidRuntime(15357): at dalvik.system.NativeStart.main(Native Method)
03-07 05:42:56.859: E/AndroidRuntime(15357): Caused by: java.lang.IllegalArgumentException: listener==null
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.location.LocationManager.requestLocationUpdates(LocationManager.java:444)
03-07 05:42:56.859: E/AndroidRuntime(15357): at com.geo.location.GeoLocationActivity.onCreate(GeoLocationActivity.java:64)
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-07 05:42:56.859: E/AndroidRuntime(15357): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
03-07 05:42:56.859: E/AndroidRuntime(15357): ... 11 more
そして、これがアプリのコードです。
public class GeoLocationActivity extends MapActivity implements LocationListener {
private TextView lblLatitud;
private TextView lblLongitud;
private TextView lblPrecision;
private TextView lblEstado;
private TextView lblVelocidad;
private DecimalFormat df;
private MapView lblMapView;
private MapController mapController;
private LocationManager locManager;
private LocationListener locListener;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
df = new DecimalFormat("#.########");
lblLatitud = (TextView) findViewById(R.id.LblPosLatitud);
lblLongitud = (TextView) findViewById(R.id.LblPosLongitud);
lblPrecision = (TextView) findViewById(R.id.LblPosPrecision);
lblVelocidad = (TextView) findViewById(R.id.LblV);
lblEstado = (TextView) findViewById(R.id.textView8);
lblPrecision = (TextView) findViewById(R.id.LblPosPrecision);
lblMapView = (MapView) findViewById(R.id.mapview);
lblMapView.setBuiltInZoomControls(true);
lblLatitud.setText("");
lblLongitud.setText("");
lblPrecision.setText("");
lblVelocidad.setText("");
lblEstado.setText("");
lblPrecision.setText("");
locManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
//Obtenemos la última posición conocida
Location loc = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//Mostramos la última posición conocida
mostrarPosicion(loc);
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
}
//Rellena los TextView de la Activity con la información básica de la posición
private void mostrarPosicion(Location loc) {
if(loc != null){
lblLatitud.setText(String.valueOf(df.format(loc.getLatitude())));
lblLongitud.setText(String.valueOf(df.format(loc.getLongitude())));
lblPrecision.setText(String.valueOf(loc.getAccuracy())+ " metros");
lblEstado.setText("GPS Ok");
lblVelocidad.setText(String.valueOf(loc.getSpeed()*(3600/1000)) + "km/h <=> " + String.valueOf(loc.getSpeed()) + "m/s");
}else{
lblLatitud.setText("(sin_datos)");
lblLongitud.setText("(sin_datos)");
lblEstado.setText("(GPS no disponible)");
lblPrecision.setText("(sin_datos)");
lblVelocidad.setText("(sin_datos)");
}
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
//Añade un punto al array y muestra la posicion en el mapa
protected void updateLocation(Location location) {
GeoPoint point = new GeoPoint((int)(location.getLatitude() * 1E6), (int)(location.getLongitude() * 1E6));
mapController = lblMapView.getController();
mapController.animateTo(point);
mapController.setZoom(lblMapView.getMaxZoomLevel());
List<Overlay> mapOverlays = lblMapView.getOverlays();
MiOverlay2 marker = new MiOverlay2(point, this);
mapOverlays.add(marker);
lblMapView.invalidate();
}
public void onLocationChanged(Location location) {
lblEstado.setText("Gps Ok");
mostrarPosicion(location);
updateLocation(location);
}
public void onProviderDisabled(String provider){
lblEstado.setText("No connection");
Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
public void onProviderEnabled(String provider){
lblEstado.setText("Gps Ok");
}
public void onStatusChanged(String provider, int status, Bundle extras){
Log.i("", "Provider Status: " + status);
}
}
/***********************************************************************
* CLASS: *
* OVERLAY QUE PINTA LAS FLECHAS EN LUGAR DONDE ESTA SITUADO EL USUARIO *
***********************************************************************/
class MiOverlay extends Overlay {
GeoPoint punto;
Context ctxt;
public MiOverlay (GeoPoint punto, Context ctxt) {
super();
this.punto = punto;
this.ctxt = ctxt;
}
@Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
super.draw(canvas, mapView, shadow);
//se traduce el punto geo localizado a un punto en la pantalla
Point scrnPoint = new Point();
mapView.getProjection().toPixels(punto, scrnPoint);
//se construye un bitmap a partir de la imagen
Bitmap marker = BitmapFactory.decodeResource(ctxt.getResources() , R.drawable.arrow);
//se dibuja la imagen del marker
canvas.drawBitmap(marker,
scrnPoint.x - marker.getWidth() / 2,
scrnPoint.y - marker.getHeight(),
null);
return true;
}
}
ご覧のとおり、非常に単純なプログラムですが、問題がわかりません。