calling maps activity from fragment error support manager [duplicate] - java

I have a problem with Google Maps, i.e. getSupportFragmentManager().findFragmentById returns always null. Do you have an idea how to solve this?
Here is the code:
fragment_map.xml:
<FrameLayout 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.myapp.something.MapFragment">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</FrameLayout>
MapsFragment.java:
public class MapFragment extends Fragment implements OnMapReadyCallback, android.location.LocationListener
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
SupportMapFragment mapFragment = (SupportMapFragment) this.getActivity().getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
...
I have Google Maps in Activity and it works with code:
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
I am trying to reuse this in fragment, becouse I need maps in fragment, not in activity, but it doesn't work.
I tried:
calling this code in "onCreateView" function
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
GoogleMap mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap(); is deprecated, and application crashes
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
and similar variations, but in all cases I get null for mapFragment.
Do you know how could I solve this problem?

The problem is that you're trying to use the Activity's FragmentManager, and you should be using the Fragment's child FragmentManager.
Remove the onCreate() override in the Fragment, and add an onCreateView() Override where you inflate the layout and call getMapAsync():
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
return rootView;
}

Related

Android Studio's navigation problem throws error java.lang.IllegalArgumentException

So i have been trying to get a button to work and navigate through to another fragment but only accessible from that button, which i want separate from my bottom nav bar, that one works
the main issue i find is that when trying to add these actions just like i would with the bottom navigation it throws an java.lang.IllegalArgumentException: ID does not reference a View inside this Activity
can anyone point me in the right direction and tell me what I'm doing wrong?
I think its to do with confusion with the navhost fragments? MAybe they think it's the same and overwriting eachother? Idk, ive been going in circles, and disabling my bottom navigation bar doesnt fix it either.
Heres my Main Activity Code, along with the java fragment with the button i want to have this action.
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration appBarConfiguration;
ActivityMainBinding binding;
BottomNavigationView bottomNavigationView; //initializing the bottom nav bar from activity_main again
#Override
protected void onCreate(Bundle savedInstanceState) {//changing content which is based on the activity_main class, think of activity_main as the main driver class, where everything is activated at
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
//FROM HERE
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
//TO HERE THESE PARTS THROW THE EXCEPTIONS
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp();
}
}
Along with the code for my navigation graph, the other actions in there, are for my bottom navigation, which is why one fragment has 2 actions, 1 foor that button, shared with the same nav _graph,
<navigation 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/my_nav"
app:startDestination="#id/fl1">
<fragment
android:id="#+id/fl1"
android:name="com.example.appnav.FirstFragment"
android:label="fragment_first"
tools:layout="#layout/fragment_first" >
<action
android:id="#+id/action_firstFragment_to_secondFragment"
app:destination="#id/fl2" />
<!--These fragments (pages) are all linked by the action button with where they end up on click -->
</fragment>
<fragment
android:id="#+id/fl2"
android:name="com.example.appnav.SecondFragment"
android:label="fragment_second"
tools:layout="#layout/fragment_second" >
<action
android:id="#+id/action_secondFragment_to_frag3"
app:destination="#id/fl3" />
<action
android:id="#+id/action_fl2_to_flp"
app:destination="#id/flp" />
</fragment>
<fragment
android:id="#+id/fl3"
android:name="com.example.appnav.frag3"
android:label="fragment_frag3"
tools:layout="#layout/fragment_frag3" >
<action
android:id="#+id/action_fl3_to_fl4"
app:destination="#id/fl4" />
</fragment>
<fragment
android:id="#+id/fl4"
android:name="com.example.appnav.frag4"
android:label="fragment_frag4"
tools:layout="#layout/fragment_frag4" >
<action
android:id="#+id/action_fl4_to_fl5"
app:destination="#id/fl5" />
</fragment>
<fragment
android:id="#+id/fl5"
android:name="com.example.appnav.fragt"
android:label="fragment_fragt"
tools:layout="#layout/fragment_temp"/>
<fragment
android:id="#+id/flp"
android:name="com.example.appnav.pay_frag"
android:label="pay_frag"
tools:layout="#layout/pay_frag" >
<action
android:id="#+id/action_flp_to_fl_pdone"
app:destination="#id/fl_pdone" />
</fragment>
<fragment
android:id="#+id/fl_pdone"
android:name="com.example.appnav.fl_pdone"
android:label="fragment_fl_pdone"
tools:layout="#layout/fragment_fl_pdone" />
</navigation>
This is the fragment with the button involved
basically trying to use the action from the nav_graph, and take u to the next fragment, in this case a fragment which is not on the bottom navigation
public class SecondFragment extends Fragment {
private FragmentSecondBinding binding;
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentSecondBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_fl2_to_flp);
}
});
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
NavController wants view not context. Just change your context to view as below.
binding.buttonSecond.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(view)
.navigate(R.id.action_fl2_to_flp);
}
});
If not solved, let me know.

How to fix 'Incovertible types' in android studio?

Inconvertible types; cannot cast 'android.support.v4.app.Fragment' to 'com.google.android.gms.maps.SupportMapFragment'
package com.dhami.ajay.nearby;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
This line is giving me incompatible type issues:
_SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)_
The error you are getting means that the fragment with the id "map" is defined as a regular fragment. It could be that your fragment is missing android:name="com.google.android.gms.maps.SupportMapFragment" in the layout. Check to make sure that your XML layout contains something like this:
<fragment 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"
android:id="#+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment" />
Side Note:
It looks like you are using the Tutorial for the Maps SDK for Android provided by Google. By default, the res/layout/activity_maps.xml should have that exact fragment block in it, so you shouldn't have any issues unless you modified the layout or implemented your own.

android google map issues

I am currently building an android app. I understand the basics and I did a number of apps but now my project is bigger. My app include a number of screens with NavigationDrawer included which forces me to use an extension of Fragment class on every class I want to be displayed on my application.
Here is my problem -some time ago I create an app a simple one page google maps screen and it works just fine. I want to do the same thing on the app I am currently working on but all it gives me when I go to the page is the google log at the bottom left screen and the rest is grey like view (no map is displayed).I searched for solution in a lot of places including this site and I could get as an answer was that it might have to do with my API key given to me by google.I ckecked that and I am pretty sure it is not from the key because I applied it on my one page google map app and it worked perfect.I also have all the permissions needed I checked that like 6 times.So my conclusion is there is something in the code that is preventing the map to be displayed.
Here is my code:
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class guide extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflat and return the layout
View v = inflater.inflate(R.layout.test, container,
false);
return v;
}
class HoldFragmentPlace extends FragmentActivity{
private GoogleMap mMap;
public HoldFragmentPlace(){
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflat and return the layout
View v = inflater.inflate(R.layout.test, container,
false);
return v;
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
}
I need that Fragment extension for my NavigationDrawer to work so I create an inner class and applied the code for the map there.
Here is what I have in my manifest:
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="#string/google_maps_key" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
And here is my xml for the map:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_marginTop="-470dp" />
</LinearLayout>
I also tried a few other variations of the java code some of them does not include inner class and the result is still the same.I am either missing something very fundamental or I am misunderstanding some conception about Android.If you have read all that thank you for the spared time!
Check the APK signing. You have to assign a debug API key in testing and a Release API key when releasing APK. Insert the correct API key, clean and rebuild your project.
I've been there a year a go and I can assure that this was the problem. Double check your key and if it's a debug or release key.
Another thing to check is the package name of your app...
Let me know if you did and still get the grey view instead of the
UPDATE:
I was trying to include everything when I realized that your problem is only in the signing phase.
You only need to get the SHA-1 fingerprint of the debug keystore and put it in your API Key dialog. And trust me there's nothing I can write that can be more clear and informative than the Google documentation.
Follow the steps in this link to get the debug certificate and the SHA-1 fingerprint.
UPDATE 2:
In order to get the SHA-1 of the keystore you might check this thread .
I suspect some part missing :
(1) Declare permission to use MAPS_RECEIVE :
<permission android:name="com.example.yourpackage.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<!-- after declare use this -->
<uses-permission android:name="com.example.yourpackage.permission.MAPS_RECEIVE"/>
(2) Missing Declare gms version variable :
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
(3) The API_KEY may have some problem with generation :
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="your_key" />
Please check with above 3 suspects first : then if still error is there you can re-confirm steps to enable Google Maps from here
Check things related to API_KEY carefully
You can use SupportMapFragment to display map in your fragment.
The xml should be changed to
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/mapView"
android:layout_marginTop="-470dp"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
and your class would be like below
public class guide extends Fragment {
private GoogleMap mMap;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflat and return the layout
View v = inflater.inflate(R.layout.test, container, false);
((SupportMapFragment) getFragmentManager()
.findFragmentById(R.id.mapView)).getMapAsync (new OnMapReadyCallback(){
#Override
public void onMapReady(final GoogleMap map) {
this.mMap = map;
mMap.setMyLocationEnabled(true);
setUpMap();
}
});
return v;
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
Note: Please update your google play services if you dont find the getMapAsync method for your SupportMapFragment.

Set GoogleMaps inside Fragment

I have a FragmentActivity with a lateral bar (like a menu bar), and a container to put fragments there.
From this FragmentActivity I call to other fragments using onClickListener of each button (from the lateral bar).
So for example, FragmentActivity is called MenuViewActivity. This calls Navigation fragment and sets it's layout on the container.
In Navigation Fragment, I have a button that starts GoogleMaps (or that is what I need to get)
[MenuViewActivity(FragmentActivity)] >> [NavigationFragment(Fragment)] >> [GoogleMapsFragment(Fragment)]
The idea is to fit the GoogleMaps windows in the same container that I set the other Fragments (like navigationFragment)
This is the code of NavigationFragment.java:
public class NavigationFragment extends Fragment implements OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/**Inflate the layout for this fragment*/
View mainView = inflater.inflate(R.layout.navegacion, container, false);
mapBtn = (ImageView) mainView.findViewById(R.id.mapsButton);
navBtn = (ImageView) mainView.findViewById(R.id.navigatorButton);
mapBtn.setOnClickListener(this);
navBtn.setOnClickListener(this);
return mainView;
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.mapsButton:
GoogleMapsFragment fragment_maps = new GoogleMapsFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, fragment_maps).commit();
break;
}
}
This is the code of GoogleMapsFragment.java:
public class GoogleMapsFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/**Inflate the layout for this fragment*/
View mainView = inflater.inflate(R.layout.google_maps, container, false);
SupportMapFragment fm = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
mMap = fm.getMap();
return mainView;
}
And the code of the google_maps.xml:
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.MapFragment"
map:cameraTilt="45"
map:cameraZoom="14"
class="com.google.android.gms.maps.SupportMapFragment" />
I think that I'm not calling right the GoogleMapsFragment on the onClick, or that I cannot call maybe to the *fragment_container* from other fragment like I do in NavigationFragment because this id belongs to the layout of MenuViewActivity.
The logCat output's this:
android.view.InflateException: Binary XML file line #3: Error inflating class fragment
at com.example.GoogleMapsFragment.onCreateView(GoogleMapsFragment.java:47)
Caused by: java.lang.IllegalStateException: A required meta-data tag in your app's
AndroidManifest.xml does not exist. You must have the following declaration within the <application> element:
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
The Exception is telling you exactly what the problem is. Since the last update of the google-play-services_lib you need to add the following to the AndroidManifest.xml within the application tag:
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
Also, you have:
android:name="com.google.android.gms.maps.MapFragment"
class="com.google.android.gms.maps.SupportMapFragment"
You should only have one of this attributes. Here you have two and they are pointing to two different classes. If you want backwards compatibility you should use com.google.android.gms.maps.SupportMapFragment.
One suggestion. If you only need to display a map why not extends SupportMapFragment or MapFragment instead of Fragment?

in google maps V2 ... fragment.getMap() returns null

I can't get the map ! all I can get is null.
here is the code.
public class MainActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SupportMapFragment fragment = new SupportMapFragment();
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, fragment).commit();
GoogleMap map;
map = fragment.getMap();
//here i cant access this snippet because map = null
if(map!=null){
UiSettings mm = map.getUiSettings();
map.setMyLocationEnabled(true);
} }
}
The manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.anywhere_reminder"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<permission
android:name="com.example.anywhere_reminder.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.anywhere_reminder.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity android:name="com.google.android.gms.BuildConfig" />
<activity
android:name="com.example.anywhere_reminder.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value=" my key "/>
</application>
</manifest>
here is the 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=".MainActivity" >
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/hello_world" />
</RelativeLayout>
I tried to solve it like this solution Google Maps Android API v2 throws GooglePlayServicesNotAvailableException, out of date, SupportMapFragment.getMap() returns null
.. but still did not work
UPDATE:
I got my map working now .. here is the edited working version
public class MainActivity extends FragmentActivity {
private GoogleMap myMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
android.support.v4.app.FragmentManager myFragmentManager = getSupportFragmentManager();
SupportMapFragment mySupportMapFragment
= (SupportMapFragment)myFragmentManager.findFragmentById(R.id.map);
myMap = mySupportMapFragment.getMap();
if(myMap!=null)
myMap.setMyLocationEnabled(true);
}
You are creating a dynamic fragment, via a FragmentTransaction. When you call commit(), the fragment has not yet been added to the screen, because the FragmentTransaction has only been scheduled to occur -- it has not occurred yet. Hence, the SupportMapFragment has not been called with onCreateView() yet, so there is no GoogleMap.
Either switch to static fragments (<fragment> tag in a layout), or delay your use of the GoogleMap until after the transaction has been processed.
executePendingTransactions() in FragmentManager class was designed to fix this delay.
From documantstion : After a FragmentTransaction is committed with FragmentTransaction.commit(), it is scheduled to be executed asynchronously on the process's main thread. If you want to immediately executing any such pending operations, you can call this function (only from the main thread) to do so. Note that all callbacks and other related behavior will be done from within this call, so be careful about where this is called from.
I have extended the MapFragment class and added a listener.
The doc about getMap() say:
... Null if the view of the fragment is not yet ready. This can happen if the fragment lifecyle have not gone through onCreateView(LayoutInflater, ViewGroup, Bundle) yet....
Then I call the listener after onCreateView. I add the class
public class MySupportMapFragment extends SupportMapFragment{
private MySupportMapFragmentListener listener;
public interface MySupportMapFragmentListener{
public void onMapCreated(GoogleMap googleMap);
}
// value taken from source code
private static final String MAP_OPTIONS = "MapOptions";
public static MySupportMapFragment newInstance() {
MySupportMapFragment f = new MySupportMapFragment();
return f;
}
public static MySupportMapFragment newInstance(GoogleMapOptions options) {
MySupportMapFragment f = new MySupportMapFragment();
Bundle args = new Bundle();
args.putParcelable(MAP_OPTIONS, options);
f.setArguments(args);
return f;
}
// other newInstance methods ...
/* (non-Javadoc)
* #see android.support.v4.app.Fragment#onViewCreated(android.view.View, android.os.Bundle)
*/
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(view, savedInstanceState);
// here, as doc say, the map can be initialized, or the service is not available
if(listener!=null){
listener.onMapCreated(getMap());
}
}
/**
* #return the listener
*/
public MySupportMapFragmentListener getListener() {
return listener;
}
/**
* #param listener the listener to set
*/
public void setListener(MySupportMapFragmentListener listener) {
this.listener = listener;
}
}
After in the calling activity or fragment ...
mapFragment = MySupportMapFragment.newInstance();
mapFragment.setListener(new MySupportMapFragmentListener() {
#Override
public void onMapCreated(GoogleMap googleMap) {
// TODO Auto-generated method stub
if(googleMap!=null){
// service is unaviable
}
}
Move the code snippet:
GoogleMap map;
map = fragment.getMap();
//here map is not null
if(map!=null){
UiSettings mm = map.getUiSettings();
map.setMyLocationEnabled(true);
}
to onResume() method, this will solve your issue.
Another way to solve it. Implemet an interface in the MapFragment to communicate to the activity when it is ready for GoogleMap creation.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
listener.onGoogleMapCreattion();
}
Then you just need to implement the listener in the activtiy:
#Override
public void onGoogleMapCreation() {
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
mMap = mMapFragment.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
// The Map is verified. It is now safe to manipulate the map.
setUpMap();
}
}
}

Categories

Resources