Android 在碎片上添加带有开放街道地图的标记
我试图使用带有片段的开放街道地图,但当我调用“addMarker”函数时,应用程序关闭。我试图修改函数,但没有成功。我的目标是在地图上添加标记。我认为这是因为这个函数正在获取一个活动的上下文,但我无法让它获取片段的上下文Android 在碎片上添加带有开放街道地图的标记,android,openstreetmap,osmdroid,Android,Openstreetmap,Osmdroid,我试图使用带有片段的开放街道地图,但当我调用“addMarker”函数时,应用程序关闭。我试图修改函数,但没有成功。我的目标是在地图上添加标记。我认为这是因为这个函数正在获取一个活动的上下文,但我无法让它获取片段的上下文 public class MapFragment extends Fragment implements LocationListener { private static MapFragment INSTANCE = null; View view; MapView ma
public class MapFragment extends Fragment implements LocationListener {
private static MapFragment INSTANCE = null;
View view;
MapView map = null;
private MapView osm;
private MapController mc;
private LocationManager locationManager;
private CompassOverlay compassOverlay;
private DirectedLocationOverlay locationOverlay;
private static final int PERMISSAO_REQUERIDA = 1;
public MapFragment() {
// Required empty public constructor
}
public static MapFragment getINSTANCE(){
if(INSTANCE==null)
INSTANCE = new MapFragment();
return INSTANCE;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_map, container, false);
//return view;
if (Build.VERSION.SDK_INT >= M) {
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
String[] permissoes = {Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION};
requestPermissions(permissoes, PERMISSAO_REQUERIDA);
}
}
//onde mostra a imagem do mapa
Context ctx = getActivity().getApplicationContext();
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
MapView osm = view.findViewById(R.id.map);
osm.setTileSource(TileSourceFactory.MAPNIK);
osm.setBuiltInZoomControls(true);
osm.setMultiTouchControls(true);
mc = (MapController) osm.getController();
mc.setZoom(15);
//GeoPoint center = new GeoPoint(-5.1251,-38.3640);
//mc.animateTo(center);
//addMarker(center);
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, this);
/* grade no mapa
LatLonGridlineOverlay2 overlay = new LatLonGridlineOverlay2();
osm.getOverlays().add(overlay);
*/
osm.setMapListener(new MapListener() {
@Override
public boolean onScroll(ScrollEvent event) {
Log.i("Script", "onScroll()");
return false;
}
@Override
public boolean onZoom(ZoomEvent event) {
Log.i("Script", "onZoom()");
return false;
}
});
return view;
}
public void addMarker (GeoPoint center){
Marker marker = new Marker(osm);
marker.setPosition(center);
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
marker.setIcon(getResources().getDrawable(R.drawable.fire));
osm.getOverlays().clear();
osm.getOverlays().add(marker);
osm.invalidate();
marker.setTitle("Sua Localização");
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSAO_REQUERIDA: {
// Se a solicitação de permissão foi cancelada o array vem vazio.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permissão cedida, recria a activity para carregar o mapa, só será executado uma vez
getActivity().recreate();
}
}
}
}
public void onResume() {
super.onResume();
}
public void onPause(){
super.onPause();
}
@Override
public void onLocationChanged(Location location) {
GeoPoint center = new GeoPoint(location.getLatitude(), location.getLongitude());
mc.animateTo(center);
addMarker(center);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onDestroy(){
super.onDestroy();
if (locationManager != null){
locationManager.removeUpdates(this);
}
}
}
返回此错误:
Process: ep.tech.myapp, PID: 15419
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context org.osmdroid.views.MapView.getContext()' on a null object reference
at org.osmdroid.views.overlay.Marker.<init>(Marker.java:93)
at ep.tech.myapp.Fragments.MapFragment.addMarker(MapFragment.java:132)
at ep.tech.myapp.Fragments.MapFragment.onLocationChanged(MapFragment.java:175)
at android.location.LocationManager$ListenerTransport._handleMessage(LocationManager.java:292)
at android.location.LocationManager$ListenerTransport.-wrap0(Unknown Source:0)
at android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:237)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6543)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)
流程:ep.tech.myapp,PID:15419
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“android.content.Context org.osmdroid.views.MapView.getContext()”
位于org.osmdroid.views.overlay.Marker.(Marker.java:93)
位于ep.tech.myapp.Fragments.MapFragment.addMarker(MapFragment.java:132)
在ep.tech.myapp.Fragments.MapFragment.onLocationChanged(MapFragment.java:175)中
位于android.location.LocationManager$ListenerTransport.\u handleMessage(LocationManager.java:292)
位于android.location.LocationManager$ListenerTransport.-wrap0(未知来源:0)
位于android.location.LocationManager$ListenerTransport$1.handleMessage(LocationManager.java:237)
位于android.os.Handler.dispatchMessage(Handler.java:106)
位于android.os.Looper.loop(Looper.java:164)
位于android.app.ActivityThread.main(ActivityThread.java:6543)
位于java.lang.reflect.Method.invoke(本机方法)
位于com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)
在onCreateView()中,您缺少findViewById:
osm= (MapView) view.findViewById(R.id.your_map_id);
在onCreateView()中,缺少findViewById:
osm= (MapView) view.findViewById(R.id.your_map_id);
实际上,我在从XML布局加载固定的OSMDroid映射视图时遇到了问题。它简直崩溃了 下面是片段_test.xml的样子:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/osm_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.osmdroid.views.MapView
android:id="@+id/osmap"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
但它不起作用。我所做的只是一种变通办法。我从XML中删除了静态MapView,并在onCreateView中动态添加了MapView。现在它可以工作了。也许这个解决方案对任何人都有帮助
这就是新fragment_test.xml的样子(只是空容器):
实际上,我在从XML布局加载固定的OSMDroid映射视图时遇到了问题。它简直崩溃了 下面是片段_test.xml的样子:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/osm_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.osmdroid.views.MapView
android:id="@+id/osmap"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
但它不起作用。我所做的只是一种变通办法。我从XML中删除了静态MapView,并在onCreateView中动态添加了MapView。现在它可以工作了。也许这个解决方案对任何人都有帮助
这就是新fragment_test.xml的样子(只是空容器):
请随时告诉我您是否卡住了。请随时告诉我您是否卡住了。您已经得到了正确的答案,但值得指出的是,在
中,尝试在空对象引用上调用虚拟方法“android.content.Context org.osmdroid.views.MapView.getContext()”
中的“空对象”是MapView
。getContext()
是被调用的方法,因此MapView
是空对象。这就是你阅读崩溃日志的方式。你已经得到了正确的答案,但值得指出的是,在中,在空对象引用上尝试调用虚拟方法“android.content.Context org.osmdroid.views.MapView.getContext()”
中,“空对象”是MapView
。getContext()
是被调用的方法,因此MapView
是空对象。这就是你阅读类似崩溃日志的方式。
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Context ctx = getActivity();
View view = inflater.inflate(R.layout.fragment_test, container, false);
Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
mMapView = new MapView(ctx);
((ConstraintLayout) view.findViewById(R.id.osm_fragment)).addView(mMapView);
mMapView.setTileSource(TileSourceFactory.OpenTopo);