This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Closed 8 years ago.
I have integrated Google Maps in ViewPager and afterward, when I close my app by pressing back button, I get "Unfortunately app has closed" message. If anyone have gone through issue and get solved, please let me know how to solve it.
Code
public class NearestBathroomMapView extends Fragment {
//Declare all necessary objects
public static View view;
public static GoogleMap gMap;
public static Double latitude,longitude;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(container==null){
return null;
}
//Inflate the view
view= inflater.inflate(R.layout.bathroomsmapview,
container, false);
latitude=27.706750;//declare latitude and logitude
longitude=85.314513;
setUpIfMapNeeded();
//call this function to obtain SupportMapFragment
return view;
}
//Get the map from SupportMapFragment
public void setUpIfMapNeeded(){
// Try to obtain the SupportMapFragment if map does not equal null.
if (gMap == null) {
gMap = ((SupportMapFragment) BathroomInformation.fragmentManager
.findFragmentById(R.id.location_map)).getMap();
//call this function to display map
if (gMap != null){
setUpMap();
}
}
}
private void setUpMap() {
gMap.setMyLocationEnabled(true);
//add marker in map
gMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title("My Home").snippet("Home Address"))
//setup map position and animate it
gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,
longitude), 12.0f));
}
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//view created to display map
if (gMap != null)
setUpMap();
//get SupportMapFragment if map is equal to null
if (gMap == null) {
gMap = ((SupportMapFragment) BathroomInformation.fragmentManager
.findFragmentById(R.id.location_map)).getMap();
//set up map if map is not null
if (gMap != null)
setUpMap();
}
}
//should I need to call this below function onBackPressed method ??
public void onDestroyView() {
super.onDestroyView();
//map fragment get remove from FragmentManager
if (gMap != null) {
BathroomInformation.fragmentManager.beginTransaction()
.remove(BathroomInformation.fragmentManager
.findFragmentById(R.id.location_map)).commit();
gMap = null;
}
}
}
I think you should eliminate your
public void onDestroyView()
function. I don't see correct to remove a fragment that is destroyed.
Hope it helps.
Related
I'm using Google maps to show my Office location inside Fragment. When I compile and run the application, It shows the maps but doesn't mark my location.
and on fragment java file, map.setMyLocationEnabled(true);
is been underlined by red color and I don't know how to solve it.
Below is my code from Fragment maps.
public class maps extends Fragment implements OnMapReadyCallback {
private Context mContext;
private SupportMapFragment supportMapFragment;
private GoogleMap map;
private MarkerOptions currentPositionMarker = null;
private Marker currentLocationMarker;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mContext = getActivity();
return inflater.inflate(R.layout.fragment_maps, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContext = getActivity();
FragmentManager fm = getActivity().getSupportFragmentManager();/// getChildFragmentManager();
supportMapFragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (supportMapFragment == null) {
supportMapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, supportMapFragment).commit();
}
supportMapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
if (ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
map.setMyLocationEnabled(true);
map.animateCamera(CameraUpdateFactory.zoomTo(15));
/*map.setOnMapLongClickListener(MapyFragment.this);
map.setOnMapClickListener(MapFragment.this);*/
}
public void updateCurrentLocationMarker(Location currentLatLng){
if(map != null){
LatLng latLng = new LatLng(currentLatLng.getLatitude(),currentLatLng.getLongitude());
if(currentPositionMarker == null){
currentPositionMarker = new MarkerOptions();
currentPositionMarker.position(latLng)
.title("My Location").
icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_facebook_3));
currentLocationMarker = map.addMarker(currentPositionMarker);
}
if(currentLocationMarker != null)
currentLocationMarker.setPosition(latLng);
///currentPositionMarker.position(latLng);
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
}
}
Thanks in advance.
For the current location, you find the best solution with the proper example you find below google official document. Try it your self it will explore you.
https://developers.google.com/maps/documentation/android-api/current-places-tutorial?hl=pt-br
this is my activity
public class FindPeopleFragment extends Fragment implements OnMapReadyCallback {
private GoogleMap googleMap;
MapFragment fragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_find_people, container, false);
initilizeMap();
return rootView;
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private void initilizeMap() {
MapFragment fragment = (MapFragment) getChildFragmentManager().findFragmentById(R.id.map1);
if (fragment != null) {
fragment.getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
LatLng marker = new LatLng(44.797283, 20.460663);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(44.797283, 20.460663), 12));
googleMap.addMarker(new MarkerOptions()
.position(new LatLng(44.797283, 20.460663))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
googleMap.setMyLocationEnabled(true);
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public void onPause() {
final FragmentManager fragManager = this.getFragmentManager();
final Fragment fragment = fragManager.findFragmentById(R.id.map1);
if (fragment != null) {
fragManager.beginTransaction().remove(fragment).commit();
super.onPause();
}
}
#Override
public void onDestroy() {
super.onDestroy();
final FragmentManager fragManager = this.getFragmentManager();
final Fragment fragment = fragManager.findFragmentById(R.id.map1);
if (fragment != null) {
fragManager.beginTransaction().remove(fragment).commit();
}
}
}
I am using navigation drawer to show the map. my map is working but the marker on it does not show. I have used all permission and created the xml file well. I don't know what is the problem, I can't find a solution for this anywhere. I think I am having problem as I am using fragment, but I need it as I am using navigation drawer. please anybody? give me a solution, I'm stuck at this
You should implement onMapReadyCallback, you should set marker when map is ready. Once an instance of this interface is set on a MapFragment or MapView object, the onMapReady(GoogleMap) method is triggered when the map is ready to be used and provides a non null instance of GoogleMap.
The onMapReady() and method might not being called. Try to implement SupportMapFragment object that you retrieved from the XML layout. Then, call getMapAsync().
supportMapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(final GoogleMap googleMap) {
// ...
}
});
I've got an app which is quite intensive in terms of memory and i'm trying to get all I can. I've noticed something which I can't work out, Google maps is keeping its allocation of memory even after (I think) i'm getting rid of it.
Before Google Maps is called:
After Google Maps is called:
Returned from Google Maps with back button:
Returned from Google Maps with on info window press button:
(the slightly higher number is just due to the fact I included a couple of methods more to include a marker to return)
As you can see, it's retaining a lot of the memory. So i'll show you how this is working:
Google Maps is not actually called, but a container for Google Maps is, and it's below:
public class GoogleMapsAndBookmarksContainer extends ActionBarActivity {
private FragmentTabHost mTabHost;
public ArrayList frameListContainer;
public HashMap<String, HashMap> bookmarkInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google_maps_and_bookmarks_container);
frameListContainer = (ArrayList) getIntent().getSerializableExtra("arrayListWithFrameAttributes");
bookmarkInfo = (HashMap) getIntent().getSerializableExtra("hashmapWithBookmarks");
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
// The first tab is the google maps fragment which i'll include below
mTabHost.addTab(
mTabHost.newTabSpec("tab1").setIndicator("Google Maps", null),
GoogleMapsFragment.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab2").setIndicator("Bookmarks", null),
BookmarksFragment.class, null);
}
#Override
protected void onDestroy() {
super.onDestroy();
/// **** THIS WAS JUST ADDED A LOSS FOR WHAT IT COULD BE RETAINING ****
mTabHost = null;
frameListContainer = null;
bookmarkInfo = null;
}
// access for fragments
public HashMap getBookmarkInfo(){
return bookmarkInfo;
}
public ArrayList getFrameAttributesArrayList(){
return frameListContainer;
}
}
I managed to remove everything from my class but this and still the problem remain:
public class GoogleMapsFragment extends Fragment {
private GoogleMap map;
private SupportMapFragment mapFragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_google_maps, container, false);
FragmentManager fm = getChildFragmentManager();
mapFragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
mapFragment.getMapAsync(new OnMapReadyCallback() {
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
initMap();
}
});
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// frameListContainer = ((GoogleMapsAndBookmarksContainer) this.getActivity()).getFrameAttributesArrayList();
// bookmarkInfo = ((GoogleMapsAndBookmarksContainer) this.getActivity()).getBookmarkInfo();
// markerToFrameAndRoute = new HashMap<Marker, String[]>();
}
#Override
public void onDestroy() {
super.onDestroy();
mapFragment = null;
System.gc();
map = null; // I did add this in an edit, but it was mistakenly taken away when I was cutting it up, sorry
}
}
So, is this solvable? I can't work out what it is that it's retaining. I did notice if I keep going back on Google Maps and off it, it is garbage collecting it, so it's not a memory leak.
edit: have tried map.clear(); still keeps the memory
Just clear map
#Override
public void onDestroy() {
super.onDestroy();
map.clear();
}
One probable solution to this problem may be to use a retained fragment using setRetainInstance(boolean retain). In this process the map fragment wont destroy and recreate itself dumping a lot of memory, instead it will just retain the memory when it is needed, when you switch map fragment back and forth (by pressing back button).
public class RetainMapActivity extends FragmentActivity {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.basic_demo);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
if (savedInstanceState == null) {
// First incarnation of this activity.
mapFragment.setRetainInstance(true);
} else {
// Reincarnated activity. The obtained map is the same map instance in the previous
// activity life cycle. There is no need to reinitialize it.
mMap = mapFragment.getMap();
}
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
Another solution to this may be to use a Otto event bus which is designed to decouple different parts of your application while still allowing them to communicate efficiently.
Hope this Helps!!
public class OutdoorFragment extends Fragment {
private GoogleMap googleMap;
double latitude = 1.31039;
double longitude = 103.7784;
public OutdoorFragment() {
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_outdoor, container,
false);
try {
// Loading map
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
googleMap.getUiSettings().setZoomGesturesEnabled(true);
googleMap.getUiSettings().setRotateGesturesEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.setMyLocationEnabled(true);
// create marker
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude)).title("Koh Chi Hao ");
// adding marker
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_VIOLET));
googleMap.addMarker(marker);
return rootView;
}
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getActivity().getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
}
#Override
public void onResume() {
super.onResume();
initilizeMap();
}
}
Hi there, inside my initializeMap() , googleMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); keeps on saying that Cannot cast from Fragment to SupportMapFragment . I am not sure what is happening .
Thanks in advance
Change;
googleMap = ((SupportMapFragment) getFragmentManager().
findFragmentById(R.id.map)).getMap();
with this;
googleMap = ((SupportMapFragment) getSupportFragmentManager().
findFragmentById(R.id.map)).getMap();
Note that getSupportFragmentManager is from android.support.v4.app.FragmentActivity.
Good luck.
You need to use android.support.v7.app.Fragment;
And need to use getSupportFragmentManager
Basically you need v7 library
Check your activity layout. The fragment with map must have the following attribute name="com.google.android.gms.maps.SupportMapFragment" to indicate which fragment class you use.
I have two FrameLayout in an activity, I just replace fragments inside those FrameLayout.
It works great with everyfragment BUT the one containing the MapFragment for the GoogleMap.
When I first launch the app it works and I see the map (everything works) but when I replace the fragment and replace it back I just get a blank space like nothing is loaded.
public class MapFragment extends CustomFragment {
private GoogleMap mMap;
private Marker currentMarker;
private OnFragmentInteractionListener mListener;
public static final String ID = "MAP_FRAGMENT";
private static View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = null;
try {
view = inflater.inflate(R.layout.fragment_map, container, false);
} catch (InflateException e) {
Log.d("","");
}finally{
setUpMapIfNeeded();
if(view!=null)this.view=view;
return this.view;
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
Fragment f = getFragmentManager().findFragmentById(R.id.map);
if (f != null)getActivity().getFragmentManager().beginTransaction().remove(f).commit();
mMap=null;
currentMarker=null;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
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 = ((com.google.android.gms.maps.MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void update(FragmentMessage message) {
if(mMap!=null) {
Location loc = (Location) message.getMessages()[0];
if (currentMarker != null)
currentMarker.remove();
currentMarker = mMap.addMarker(new MarkerOptions().position(new LatLng(loc.getLatitude(), loc.getLongitude())).title("Marker"));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(loc.getLatitude(), loc.getLongitude())) // Sets the center of the map to Mountain View
.zoom(15) // Sets the zoom
.build(); // Creates a CameraPosition from the builder
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
}
The mMap is never null, so the MapFragment is working I guess but I don't get anything on the screen (see screenshots below).
Does anyone have an idea ? I really don't know what is wrong.