Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Google Maps in Fragment

I'm developing an app with a menu on top with some buttons inside that menu. I'm trying to add google maps to one of the button, but I'm not very successful. I was following this tutorial but instead of implementig google maps directly into MainActivity I added them into a fragment that is launched when button is pressed. All worked fine. When I press the button the maps load and they work as they should. When I press the home button to go back to MainActivity it works perfectly, but when I want to load maps again it gives me debugging error: Class File Editor: Source not found

This is code of GoogleMaps fragment:

public class GoogleMaps extends Fragment{

private GoogleMap googleMap;
double latitude = 46.514249;
double longitude = 15.080183;

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View myFragmentView = inflater.inflate(R.layout.maps_layout, container, false);

        try {
            // Loading map
            initilizeMap();

        } catch (Exception e) {
            Log.e("ERROR", "ERROR IN CODE: " + e.toString());
            e.printStackTrace();
        }

        return myFragmentView;
 }

 private void initilizeMap() {
        if (googleMap == null) {
            googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
            googleMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)));
            CameraPosition cameraPosition = new CameraPosition.Builder().target(
                    new LatLng(latitude, longitude)).zoom(12).build();
            googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
            // check if map is created successfully or not
            if (googleMap == null) {
                Toast.makeText(getActivity(),
                        "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                        .show();
            }
       }
 }
}

Any help will be appreciated.

EDIT: If I wasn't specific enough. It works when I load fragment once (for the first time) but it doesn't work when I try to load it again (second time).

EDIT v2: I actually found solution myself. All I had to do was to add OnDestroyView method:

public void onDestroyView() 
 {
         super.onDestroyView(); 
         Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));  
         FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
         ft.remove(fragment);
         ft.commit();
 }

Thanks anyway.

like image 469
Izak Avatar asked Oct 25 '13 07:10

Izak


Video Answer


2 Answers

public class MapCurrentLoactionFragment extends Fragment {
    public static MapView mapView;

    public static GoogleMap map;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_currentlocation_map,
                container, false);
          try
          {

        // Gets the MapView from the XML layout and creates it
        mapView = (MapView) v.findViewById(R.id.mapview);

        mapView.onCreate(savedInstanceState);
        mapView.onResume();
        // Gets to GoogleMap from the MapView and does initialization stuff
        map = mapView.getMap();
        // Changing map type
        map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        // googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        // googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        // googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
        // googleMap.setMapType(GoogleMap.MAP_TYPE_NONE);

        // Showing / hiding your current location
        map.setMyLocationEnabled(false);

        // Enable / Disable zooming controls
        map.getUiSettings().setZoomControlsEnabled(true);

        // Enable / Disable my location button
        map.getUiSettings().setMyLocationButtonEnabled(true);

        // Enable / Disable Compass icon
        map.getUiSettings().setCompassEnabled(true);

        // Enable / Disable Rotate gesture
        map.getUiSettings().setRotateGesturesEnabled(true);

        // Enable / Disable zooming functionality
        map.getUiSettings().setZoomGesturesEnabled(true);

        MapsInitializer.initialize(this.getActivity());
      }
          catch(Exception e)
          {
              System.out.println(e);
          }
        return v;
    }

XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <com.google.android.gms.maps.MapView
         android:id="@+id/mapview"
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" />

</LinearLayout>
like image 165
Saravanan Avatar answered Oct 22 '22 20:10

Saravanan


Have a look at my implementation that works just fine and also dose some checking on the device before trying to diplay the map like if the Google play Services are installed. Maybe it will help you. I am using a simple FragmentActivity and inflating a layout containing a SupportedMapFragment.

Here's the code:

public class LocationActivity extends FragmentActivity {

    private GoogleMap map;
    private long rec_id;
    private String address;
    private Marker selectedLoc;
    private boolean isSessionClosed;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        BugSenseHandler.initAndStartSession(this, Constants.BugSenseKEY);
        setContentView(R.layout.preview_location);
        RelativeLayout cancel_btn = (RelativeLayout) findViewById(R.id.cancel_btn);
        LinearLayout save_location_btn = (LinearLayout) findViewById(R.id.delete_btn);

        save_location_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                if (address != null) {
                    ReceiptDataSource r = new ReceiptDataSource();
                    r.updateReceiptLocation(rec_id, address);
                    Intent returnIntent = new Intent(getBaseContext(), EditReceiptActivity.class);
                    returnIntent.putExtra("result", address);
                    setResult(RESULT_OK, returnIntent);
                    finish();
                } else {
                    Utils.showToast(getApplicationContext(), getString(R.string.c_unknownLocation), Toast.LENGTH_SHORT);
                }
            }
        });

        cancel_btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        if (map == null) {

            map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

            if (isGoogleMapsInstalled()) {
                if (map != null) {
                    retrieveLocation();
                }
            } else {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage("Install Google Maps");
                builder.setCancelable(false);
                builder.setPositiveButton("Install", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.apps.maps"));
                        startActivity(intent);

                        //Finish the activity so they can't circumvent the check
                        finish();
                    }
                });
                AlertDialog dialog = builder.create();
                dialog.show();
            }
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        if (isSessionClosed) {
            BugSenseHandler.startSession(this);
            isSessionClosed = false;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        BugSenseHandler.closeSession(this);
        isSessionClosed = true;
    }

    @Override
    public void onBackPressed() {
        map.clear();
        super.onBackPressed();
    }

    private void retrieveLocation() {
        Intent intent = getIntent();
        address = intent.getStringExtra("location");
        assert address != null;
        if (address.equalsIgnoreCase("")) {
            address = Utils.getCurrentLocation(LocationActivity.this);
        }
        rec_id = intent.getLongExtra("receipt_to_update_location", 0);
        final Geocoder geocoder = new Geocoder(this, Locale.US);
        double latitude = 0, longitude = 0;
        try {
            List<Address> loc = geocoder.getFromLocationName(address, 5);
            if (loc.size() > 0) {
                latitude = loc.get(0).getLatitude();
                longitude = loc.get(0).getLongitude();
            } else {
                //Toast.makeText(getBaseContext(), getResources().getString(R.string.UnableToFindLocation),Toast.LENGTH_SHORT).show();
                Utils.showToast(LocationActivity.this, getString(R.string.UnableToFindLocation), Toast.LENGTH_SHORT);
            }


            selectedLoc = map.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title(address).draggable(true));
            map.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
                @Override
                public void onMarkerDragStart(Marker marker) {

                }

                @Override
                public void onMarkerDrag(Marker marker) {

                }

                @Override
                public void onMarkerDragEnd(Marker marker) {
                    try {
                        List<Address> addresses = geocoder.getFromLocation(selectedLoc.getPosition().latitude, selectedLoc.getPosition().longitude, 1);
                        StringBuilder sb = new StringBuilder();
                        if (addresses.size() > 0) {
                            Address address = addresses.get(0);

                            if (address.getAddressLine(0) != null)
                                sb.append(address.getAddressLine(0)).append(", ");
                            if (address.getLocality() != null)
                                sb.append(address.getLocality()).append(", ");
                            if (address.getCountryName() != null)
                                sb.append(address.getCountryName());
                        }

                        address = sb.toString();
                    } catch (IOException e) {
                    }

                }
            });

            map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 12));

            // Zoom in, animating the camera.
            map.animateCamera(CameraUpdateFactory.zoomTo(12), 2000, null);

        } catch (IOException e) {
            Log.e("IOException", e.getMessage());
            //Toast.makeText(this, getString(R.string.c_unknownLocation), Toast.LENGTH_LONG).show();
            Utils.showToast(LocationActivity.this, getString(R.string.c_unknownLocation), Toast.LENGTH_LONG);
        }

    }

    public boolean isGoogleMapsInstalled() {
        try {
            ApplicationInfo info = getPackageManager().getApplicationInfo("com.google.android.apps.maps", 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

And the corresponding layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:custom="http://schemas.android.com/apk/res/ro.gebs.captoom"
              android:id="@+id/location_stuff"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@color/greenish"
              android:orientation="vertical">

    <RelativeLayout
            android:id="@+id/location_header"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/greenish">

        <RelativeLayout
                android:id="@+id/cancel_btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:background="@drawable/done_rounded_btn"
                android:gravity="center">

            <ro.gebs.captoom.utils.fonts.CustomFontTextView
                    android:id="@+id/retake_txt"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:layout_marginTop="10dp"
                    android:gravity="center"
                    android:paddingLeft="7dp"
                    android:paddingRight="7dp"
                    android:text="@string/cancel"
                    android:textAllCaps="true"
                    android:textColor="#FFFFFF"
                    android:textSize="14sp"
                    custom:fontName="Bold"/>
        </RelativeLayout>

        <ro.gebs.captoom.utils.fonts.CustomFontTextView
                android:id="@+id/location_txt"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:gravity="center_vertical"
                android:text="@string/location_map"
                android:textAllCaps="true"
                android:textColor="@color/done_color"
                android:textSize="16sp"
                custom:fontName="SemiBold"/>
    </RelativeLayout>

    <fragment
            android:layout_weight="6"
            android:id="@+id/map"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            class="com.google.android.gms.maps.SupportMapFragment"/>


    <RelativeLayout
            android:id="@+id/save_location_layout"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/greenish">

        <LinearLayout
                android:id="@+id/delete_btn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:layout_marginLeft="25dp"
                android:layout_marginRight="25dp"
                android:background="@drawable/done_btn_selector"
                android:orientation="horizontal"
                android:paddingBottom="7dip"
                android:paddingTop="7dip"
                android:weightSum="7">

            <ro.gebs.captoom.utils.fonts.CustomFontTextView
                    android:id="@+id/delete_txt"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="6"
                    android:background="@null"
                    android:paddingLeft="10dp"
                    android:text="@string/save_location"
                    android:textAllCaps="true"
                    android:textColor="@color/white"
                    android:textSize="16sp"
                    custom:fontName="Bold"/>

            <ImageView
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:layout_weight="1"

                    android:paddingLeft="10dp"
                    android:paddingRight="10dp"
                    android:src="@drawable/input_map_white"/>
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>
like image 45
Adrian Olar Avatar answered Oct 22 '22 20:10

Adrian Olar