そのため、マップフラグメントを含む空のフラグメントがあります。マップを含むフラグメントをアクティブにしようとすると、アプリがクラッシュし、次の行でnullポインターエラーが返されます。
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
完全なエラーメッセージ:
Java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.Android.gms.maps.GoogleMap com.google.Android.gms.maps.MapFragment.getMap()' on a null object reference
at com.collusion.serviceassistant.ReturnVisitDetails.onViewCreated(ReturnVisitDetails.Java:39)
at Android.app.FragmentManagerImpl.moveToState(FragmentManager.Java:904)
at Android.app.FragmentManagerImpl.moveToState(FragmentManager.Java:1062)
at Android.app.BackStackRecord.run(BackStackRecord.Java:684)
at Android.app.FragmentManagerImpl.execPendingActions(FragmentManager.Java:1447)
at Android.app.FragmentManagerImpl$1.run(FragmentManager.Java:443)
at Android.os.Handler.handleCallback(Handler.Java:733)
at Android.os.Handler.dispatchMessage(Handler.Java:95)
at Android.os.Looper.loop(Looper.Java:136)
at Android.app.ActivityThread.main(ActivityThread.Java:5001)
at Java.lang.reflect.Method.invoke(Native Method)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:785)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:601)
これが私のフラグメントコードです。
import Android.app.Activity;
import Android.app.Dialog;
import Android.net.Uri;
import Android.os.Bundle;
import Android.app.Fragment;
import Android.util.Log;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import com.google.Android.gms.common.ConnectionResult;
import com.google.Android.gms.common.GooglePlayServicesUtil;
import com.google.Android.gms.maps.CameraUpdateFactory;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.MapFragment;
import com.google.Android.gms.maps.MapView;
import com.google.Android.gms.maps.model.BitmapDescriptorFactory;
import com.google.Android.gms.maps.model.LatLng;
import com.google.Android.gms.maps.model.Marker;
import com.google.Android.gms.maps.model.MarkerOptions;
public class ReturnVisitDetails extends Fragment {
static final LatLng HAMBURG = new LatLng(53.558, 9.927);
static final LatLng KIEL = new LatLng(53.551, 9.993);
private GoogleMap map;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_return_visit_add, container, false);
return rootView;
}
public void onViewCreated(View view, Bundle savedInstanceState)
{
// Get a handle to the Map Fragment
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
.title("Hamburg"));
Marker kiel = map.addMarker(new MarkerOptions()
.position(KIEL)
.title("Kiel")
.snippet("Kiel is cool")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.ic_launcher)));
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
}
}
そして、私の親フラグメントXMLレイアウト:
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context="com.collusion.serviceassistant.ReturnVisitDetails"
Android:background="#009688">
<fragment
Android:id="@+id/map"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
class="com.google.Android.gms.maps.MapFragment" />
</RelativeLayout>
マップフラグメントがnullを返している理由は誰にも分かりますか?
編集:だから今、私はマップを初期化するためにこのコードを持っています:
MapFragment mapFragment = new MapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.rl_map_container, mapFragment).commit();
map = mapFragment.getMap();
Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
.title("Hamburg"));
Marker kiel = map.addMarker(new MarkerOptions()
.position(KIEL)
.title("Kiel")
.snippet("Kiel is cool")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.ic_launcher)));
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
そして、それはまだnullポインタ値を返します
EclipseプロジェクトをAndroid Studioプロジェクトに移植しようとしたときにこの問題が発生しました。
Java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.Android.gms.maps.GoogleMap com.google.Android.gms.maps.SupportMapFragment.getMap()' on a null object reference
このようなフラグメントアクティビティで使用しました。
((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.mapToday)).getMap();
しかし、問題は以前、特定のバージョンのGoogle Play Services(4.3.23)を使用していたことでした。
ただし、Gradleビルドでは最新バージョン(compile 'com.google.Android.gms:play-services:+')
(6.1.71)のような他の特定のバージョンを試しました。しかし、それでもヌルポイント例外が発生しました。
以前使用したのと同じ古いバージョンを使用しましたが、機能しました。
compile 'com.google.Android.gms:play-services:4.3.23'
これは私にとって一時的な解決策として機能します。ただし、新しいプレイサービスライブラリに更新する必要がある場合、これは問題になります。
私がこのようにしようとすると、Gradleビルドに利用できるこのバージョンの特定のマップライブラリはないようです:
compile 'com.google.Android.gms:play-services-maps:4.3.23'
私は問題を解決しました。ビューページャーがある場合、この行:
mMap = ((SupportMapFragment) MainActivity.fragmentManager
.findFragmentById(R.id.mapView)).getMap();
これに変更する必要があります:
mMap = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.mapView)).getMap();
クラスはFragment
から拡張され、レイアウトで宣言されたFragment
を使用していますが、ネストされたフラグメントは動的に追加された場合にのみ機能します。
したがって、2つのオプションがあります。
1)FragmentAcivity
の代わりにFragment
から拡張し、適切なメソッドを適用します。
2)次のように、Fragment
を動的に追加します。
// ReturnVisitDetails
MapFragment mapFragment = new MapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.rl_map_container, mapFragment).commit();
//レイアウト
<FrameLayout
Android:id="@+id/rl_map_container"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
-UPDATED-
Fragment
内でGoogleマップを使用する完全な例:
// TestFragmentActivity
public class TestFragmentActivity extends Android.support.v4.app.FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_fragment_activity);
}
}
// TestFragment
public class TestFragment extends Android.support.v4.app.Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.test_fragment, container, false);
CustomMapFragment mapFragment = new CustomMapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.map_container, mapFragment).commit();
return rootView;
}
}
// CustomMapFragment
public class CustomMapFragment extends com.google.Android.gms.maps.SupportMapFragment {
private final LatLng HAMBURG = new LatLng(53.558, 9.927);
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
GoogleMap googleMap = getMap();
googleMap.addMarker(new MarkerOptions().position(HAMBURG).title("Hamburg"));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
}
}
//test_fragment_activity.xml
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<fragment
Android:id="@+id/map"
class="your_package.TestFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</RelativeLayout>
//test_fragment.xml
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<FrameLayout
Android:id="@+id/map_container"
Android:layout_width="match_parent"
Android:layout_height="match_parent"/>
</RelativeLayout>
古いGoogle Playサービスで同じ問題を抱えていたので、これに関する多くのスレッドを検索しました。ビクターがクラスはフラグメントから拡張し、レイアウトで定義された別のフラグメントを使用する必要があると言ったので、最善のアプローチはgetChildFragmentManager()
の代わりにgetSupportFragmentManager()
を使用することです。
また、Googleドキュメントに記載されているgetMap() method is deprecated
になりました。詳細についてはこちらを参照してください: https://developers.google.com/Android/reference/com/google/Android/gms/maps/MapFragment.html#getMap()
以下は、古いプレイサービスのさまざまなデバイスでテストした作業コードです。これは、古いGoogle Playサービスを備えたデバイスの場合、およびGoogleMap
のオブジェクトがnullを返す場合にデフォルトメッセージを生成します。
class MyFragment extends Fragment
{
SupportMapFragment myMapFragment;
GoogleMap myMap;
View convertView;
FragmentManager fm;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
convertView=inflater.inflate(R.layout.mymap,null);
fm=getChildFragmentManager();
myMapFragment=(SupportMapFragment) fm.findFragmentById(R.id.myMapId);
// here instead of using getMap(), we are using getMapAsync() which returns a callback and shows map only when it gets ready.
//it automatically checks for null pointer or older play services version, getMap() is deprecated as mentioned in google docs.
myMapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googlemap) {
// TODO Auto-generated method stub
myMap=googlemap;
startMap();
}
});
return convertView;
}
}
詳細については、このスレッドを参照してください。
これは21のターゲットSDKバージョンへの移行の問題ですか?その場合、次の解決策が興味を引く可能性があります。
この問題は、targetSdkVersion
がAndroidサポートライブラリが使用されているバージョンよりも高いバージョンであるという事実に関連している可能性があります。
私が取り組んでいたプロジェクトの1つでは、targetSdkVersion
は21でしたが、サポートライブラリのバージョンは19.0.0でした。 targetSdkVersion
を19に変更すると問題が修正されました。
私は同じ問題に直面することができますが、最終的に私はそのエラーを解決することができます。現在マップは正しく表示されています...
=> onCreateView()メソッド内でFragmentのinitilizeMap()メソッドを呼び出す...
=>のようなグローバル変数を宣言します
private GoogleMap googleMap;
private void initilizeMap() {
try {
// Changing marker icon
// marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.my_marker_icon)));
// adding marker
if (googleMap == null) {
googleMap = ((MapFragment)getActivity().getFragmentManager()
.findFragmentById(R.id.map)).getMap();
// create marker
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude)).title(
"YourCare");
// Changing marker icon
MarkerOptions icon = marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
// adding marker
LatLng latLng = new LatLng(latitude, longitude);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
latLng, 15);
googleMap.animateCamera(cameraUpdate);
// locationManager.removeUpdates(this);
googleMap.addMarker(marker);
googleMap.setMyLocationEnabled(true);
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getActivity(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
} catch (Exception e) {
System.out.print("Error :" + e.getMessage());
}
}
MapFragmentの代わりにSupportMapFragmentを使用してみてください。このコードはフラグメントのために私のために機能します、ちょうど試してみました:
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import com.google.Android.gms.maps.CameraUpdateFactory;
import com.google.Android.gms.maps.GoogleMap;
import com.google.Android.gms.maps.SupportMapFragment;
import com.google.Android.gms.maps.model.BitmapDescriptorFactory;
import com.google.Android.gms.maps.model.LatLng;
import com.google.Android.gms.maps.model.Marker;
import com.google.Android.gms.maps.model.MarkerOptions;
public class MapFragment extends Fragment {
private GoogleMap map;
static final LatLng HAMBURG = new LatLng(53.558, 9.927);
static final LatLng KIEL = new LatLng(53.551, 9.993);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container,
false);
// Get a handle to the Map Fragment
map = ((SupportMapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
.title("Hamburg"));
Marker kiel = map.addMarker(new MarkerOptions()
.position(KIEL)
.title("Kiel")
.snippet("Kiel is cool")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.ic_launcher)));
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
return rootView;
}
}
そしてあなたのレイアウト:
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment
Android:id="@+id/map"
Android:name="com.example.test.MapFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
class="com.google.Android.gms.maps.SupportMapFragment" />
</RelativeLayout>