Is it possible to add a Button to GoogleMaps? - android

I am a bit confused whether or not it is possible to add a button to googlemaps. I tried to create a relative layout where i would put the fragment and a image button in the same layout but for some reason my app keeps on crashing. Here is what my XML looks like:
<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=".MapsActivity" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
<ImageButton
android:id="#+id/theimagebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/car"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
And I get this Error java.lang.RuntimeException: Unable to resume activity 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
import android.content.Context;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdate;
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.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.parse.ParseGeoPoint;
import com.parse.ParseObject;
public class MapsActivity extends FragmentActivity implements RoutingListener {
protected GoogleMap mMap;
protected LatLng start;
protected LatLng end;
/**
* This activity loads a map and then displays the route and pushpins on it.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mMap = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
try {
setUpMapIfNeeded();
} catch (Exception e) {
e.printStackTrace();
}
}
#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();
}
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera. In this case, we
* just add a marker near Africa.
* <p/>
* This should only be called once and when we are sure that {#link #mMap} is not null.
*/
private void setUpMap() {
// Enable MyLocation Layer of Google Map
mMap.setMyLocationEnabled(true);
// Get LocationManager object from System Service LOCATION_SERVICE
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Create a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Get the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Get Current Location
Location myLocation = locationManager.getLastKnownLocation(provider);
// set map type
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Get latitude of the current location
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.getUiSettings().setCompassEnabled(true);
mMap.getUiSettings().setRotateGesturesEnabled(true);
mMap.getUiSettings().setZoomGesturesEnabled(true);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
double longitude = location.getLongitude();
double latitude = location.getLatitude();
// Get longitude of the current location
// Create a LatLng object for the current location
LatLng latLng = new LatLng(latitude, longitude);
ParseObject parkingobject = new ParseObject("Kitchen");
parkingobject.put("username","Mike");
ParseGeoPoint point = new ParseGeoPoint(latitude,longitude); **THINK THE ERROR IS HERE**
parkingobject.put("Location", point);
// Show the current location in Google Map
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// Zoom in the Google Map
//LatLng myCoordinates = new LatLng(latitude, longitude);
//CameraUpdate yourLocation = CameraUpdateFactory.newLatLngZoom(myCoordinates, 20);
//mMap.animateCamera(yourLocation);
// mMap.animateCamera(CameraUpdateFactory.zoomTo(20));
//mMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title("You are here!").snippet("Consider yourself located"));
LatLng fromLatLng = latLng;
start = latLng;
Routing routing = new Routing(Routing.TravelMode.DRIVING);
routing.registerListener(this);
routing.execute(start, end);
}
}
//map = fm.getMap();
#Override
public void onRoutingFailure() {
// The Routing request failed
}
#Override
public void onRoutingStart() {
// The Routing Request starts
}
#Override
public void onRoutingSuccess(PolylineOptions mPolyOptions, Route route) {
PolylineOptions polyOptions = new PolylineOptions();
polyOptions.color(Color.BLUE);
polyOptions.width(10);
polyOptions.addAll(mPolyOptions.getPoints());
mMap.addPolyline(polyOptions);
// Start marker
MarkerOptions options = new MarkerOptions();
options.position(start);
//options.icon(BitmapDescriptorFactory.fromResource(R.drawable.home));
mMap.addMarker(options);
// End marker
options = new MarkerOptions();
options.position(end);
options.icon(BitmapDescriptorFactory.fromResource(R.drawable.cars));
mMap.addMarker(options);
}
}
Can someone guide me in the right direction? Thanks in advance.

The main problem is that you're using getSupportFragmentManager() and you're not using a SupportMapFragment in your xml layout.
Replacing class="com.google.android.gms.maps.MapFragment" with class="com.google.android.gms.maps.SupportMapFragment" made it work for me.
xml layout (Note I just used drawable/common_signin_btn_icon_dark for the button image):
<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=".MapsActivity" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
<ImageButton
android:id="#+id/theimagebutton"
android:text="button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/common_signin_btn_icon_dark"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
Default code generated by Android Studio:
public class MapsActivity extends FragmentActivity {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
}
#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"));
}
}
Result:

As #Evan Bashir pointed out in the comments this issue is not related to your layout.
You should use the onMapReady() callback to get a handle to the GoogleMap object.
First implement the callback to your Activity:
public class MainActivity extends FragmentActivity
implements RoutingListener, OnMapReadyCallback {
Find your MapFragment and set the callback in your onCreate():
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Finally implement onMapReady() in your MainActivity:
#Override
public void onMapReady(GoogleMap map) {
mMap = map;
setUpMap();
}
This callback is triggered when the map is ready to be used, so you won't get null.

Related

Place Autocomplete closes immediately

I am having a problem using the Google Places Autocomplete SDK, I already found some answers, however, that didn't resolve the problen. In particular, related questions and answers were found here and here. The documentation on the Android developers site is here.
I activated the Places SDK for Android (and the Maps SDK for Android) and pasted the created API Key into my strings.xml file. The map is working just fine, however the autocomplete widget is closing immediately after selecting it and in the logcat I get the error:
05-23 06:00:40.376 14951-14951/com.example.tobi.beparty I/LOCATIONACTIVITY: An error occurred: Status{statusCode=ERROR, resolution=null}
Due to the linked answers, I was thinking that something is wrong with the API keys, however, in the Google APIs dashboard, I see every request (with an error rate of 100%), therefore I think this is not the problem. Moreover, I tried to implement the Place Autocomplete version with an intent (as described in the documentation) but faced the same problem which is why I think, the fragment is also not the problem.
Any suggestions? Many thanks in advance!
Manifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.tobi.beparty">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<application
android:name=".ParseApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key"/>
<activity android:name=".LogInActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<activity android:name=".MainActivity" />
<activity
android:name=".LocationActivity"
android:label="#string/title_activity_location">
</activity>
<activity android:name=".SearchActivity"/>
</application>
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.tobi.beparty.LocationActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/relLayoutBotBar">
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/map"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:elevation="10dp"
android:background="#drawable/white_border"
android:id="#+id/relLayout1">
<ImageView
android:layout_width="15dp"
android:layout_height="15dp"
android:id="#+id/ic_magnify"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:src="#drawable/ic_magnify"/>
<fragment
android:id="#+id/place_autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="#id/ic_magnify"
android:layout_marginLeft="5dp"
android:layout_centerVertical="true"
android:textSize="15sp"
android:textColor="#000"
android:background="#null"
android:hint="Enter the party name"
android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"
/>
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="#+id/relLayoutBotBar"
android:layout_alignParentBottom="true">
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/white_grey_border_top"
app:menu="#menu/bottom_navigation_menu">
</android.support.design.widget.BottomNavigationView>
</RelativeLayout>
Java:
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlaceAutocompleteFragment;
import com.google.android.gms.location.places.ui.PlaceSelectionListener;
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;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class LocationActivity extends FragmentActivity implements OnMapReadyCallback {
final private String TAG = "LOCATIONACTIVITY";
private GoogleMap mMap;
LocationManager locationManager;
LocationListener locationListener;
EditText mSearchText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.location_layout);
// 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);
// mSearchText = (EditText) findViewById(R.id.inputSearch);
PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
/* Bottom Navigationbar*/
BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomBar);
BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);
Menu menu = bottomNavigationView.getMenu();
MenuItem menuItem = menu.getItem(3);
menuItem.setChecked(true);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.ic_search:
Intent intentSearch = new Intent(LocationActivity.this, MainActivity.class);
startActivity(intentSearch);
break;
case R.id.ic_favorite:
Intent intentFavorite = new Intent(LocationActivity.this, FavoriteActivity.class);
startActivity(intentFavorite);
break;
case R.id.ic_cake:
Intent intentParties = new Intent(LocationActivity.this, PartiesActivity.class);
startActivity(intentParties);
break;
case R.id.ic_location:
Intent intentLocation = new Intent(LocationActivity.this, LocationActivity.class);
startActivity(intentLocation);
break;
case R.id.ic_person:
Intent intentProfile = new Intent(LocationActivity.this, ProfileActivity.class);
startActivity(intentProfile);
break;
}
return false;
}
});
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
/* LatLng center = new LatLng(-34, 151);
String centerName = "Sydney"; */
LatLng center = new LatLng(13.307, 52.500068);
String centerName = "Adenauerplatz";
mMap.addMarker(new MarkerOptions().position(center).title("Marker in " + centerName));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 10));
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
Log.i(TAG, location.toString());
Toast.makeText(LocationActivity.this, location.toString(), Toast.LENGTH_SHORT).show();
// LatLng center = new LatLng(-34, 151);
LatLng center = new LatLng(location.getLatitude(), location.getLongitude());
String centerName = "current position";
mMap.clear();
mMap.addMarker(new MarkerOptions().position(center).title("Marker in " + centerName));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(center, 10));
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> listAddresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if(listAddresses != null && listAddresses.size() > 0){
Log.i(TAG, listAddresses.get(0).toString());
String address = "";
if(listAddresses.get(0).getSubThoroughfare() != null){
address += listAddresses.get(0).getSubThoroughfare() + "";
}
if(listAddresses.get(0).getThoroughfare() != null){
address += listAddresses.get(0).getThoroughfare() + "";
}
if(listAddresses.get(0).getLocale() != null){
address += listAddresses.get(0).getLocale() + ", ";
}
if(listAddresses.get(0).getPostalCode() != null){
address += listAddresses.get(0).getPostalCode() + ", ";
}
if(listAddresses.get(0).getCountryName() != null){
address += listAddresses.get(0).getCountryName() + "";
}
Toast.makeText(LocationActivity.this, address, Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
if (Build.VERSION.SDK_INT < 23) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
} else {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
String lastKnownLocationName;
LatLng lastKnownLatLng;
if(lastKnownLocation == null){
lastKnownLatLng = new LatLng(52.500068, 13.307);
lastKnownLocationName = "Adenauerplatz";
}else{
lastKnownLatLng = new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
lastKnownLocationName = "Last known location";
}
mMap.addMarker(new MarkerOptions().position(lastKnownLatLng).title(lastKnownLocationName));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(lastKnownLatLng, 10));
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); // ToDo: Die zahlen hier stehen dafür, wieviele Meter bzw. Sekunden gegangen werden müssen, dass ein Update erfolgt. evtl. ändern
}
}
}
}
I had this same issue when following the migration guide to use the Places compatibility library.
The problem is that Google considers the original "Places SDK for Android" and the new "Places API" two different APIs. As a result, you need to go into the Google Cloud Platform and enabled the new "Places API".
If you haven't enabled it yet, it will appear under the "Additional APIs" section - click on it, and then click on "Enable".
After you've enabled it, the new Places API should appear under the "Enabled APIs" section as shown below:
After I did this the autocomplete window stayed open and worked correctly.

Create a menu to switch between different types of map (Google Map API on Android)

I am developing a map app with Google Map V2 on Android Studio 2.3 and I would like to create a menu that allows to switch between different types of map. Below is my MapActivity.java code. Please help.
package net.dada.thm;
import android.database.sqlite.SQLiteOutOfMemoryException;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
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;
import com.google.firebase.appindexing.Action;
import com.google.firebase.appindexing.FirebaseUserActions;
import com.google.firebase.appindexing.builders.Actions;
import static net.dada.thm.R.id.map;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
public 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(map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in LOME
LatLng LOME = new LatLng(6.131944, 1.222778);
mMap.addMarker(new MarkerOptions().position(LOME).title("LOME"));
}
You could try this approach:
Create one activity with:
MAPTYPE_ONE tab
MAPTYPE_TWO tab
Example
mMap.setBuildingsEnabled(true);
final float mCameraZoom = 10.00f;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); //this part;
mMap.setTrafficEnabled(true);
mMap.setIndoorEnabled(true);
so then when you select the first tab, you can see the first type of the map and the second one, you set the map type accordingly;
You really don't need a menu; just a small ViewPager with two items on it!
I hope it helps!
I was able to create Buttons inside LinearLayout with onClick attributes to change map types. However, I lost my app initial state in the layout. I don't know where to insert the following paramters:
map:cameraTargetLat="8.6253268"
map:cameraTargetLng="-1.4193078"
map:cameraTilt="00"
map:cameraZoom="6.5"
map:cameraBearing="00"
map:mapType="normal"
map:uiCompass="true"
map:uiRotateGestures="false"
map:uiScrollGestures="true"
map:uiTiltGestures="false"
map:uiZoomControls="true"
map:uiZoomGestures="true"
Or do I have some scripts in the MapsActiviti.java file that is incompatible to what I want to add to the Activity_maps.xml file? Please help.
Activity_maps.xml file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="horizontal">
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="4"
android:hint="Search Location" />
<Button
android:id="#+id/search_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:onClick="onMapSearch"
android:text="Search" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Type: " />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onNormalMap"
android:text="Normal" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onSatelliteMap"
android:text="Satellite" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onTerrainMap"
android:text="Terrain" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onHybridMap"
android:text="Hybrid" />
</LinearLayout>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.dada.thm.MapsActivity"/>
</LinearLayout>
MapsActivity.java file:
package net.dada.thm;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.EditText;
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;
import java.io.IOException;
import java.util.List;
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);
}
public void onMapSearch(View view) {
EditText locationSearch = (EditText) findViewById(R.id.editText);
String location = locationSearch.getText().toString();
List<Address> addressList = null;
Geocoder geocoder = new Geocoder(this);
try {
addressList = geocoder.getFromLocationName(location, 1);
} catch (IOException e) {
e.printStackTrace();
}
assert addressList != null;
Address address = addressList.get(0);
LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
mMap.addMarker(new MarkerOptions().position(latLng).title("Marker"));
mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
}
public void onNormalMap(View view) {
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
public void onSatelliteMap(View view) {
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
public void onTerrainMap(View view) {
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
}
public void onHybridMap(View view) {
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in TSEVIE
LatLng TSEVIE = new LatLng(6.433333, 1.21666);
mMap.addMarker(new MarkerOptions().position(TSEVIE).title("TSEVIE"));
// mMap.moveCamera(CameraUpdateFactory.newLatLng(TSEVIE ));
// Add a marker in ATAKPAME
LatLng ATAKPAME = new LatLng(7.526944, 1.126669);
mMap.addMarker(new MarkerOptions().position(ATAKPAME).title("ATAKPAME"));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
}
}

How can I pop a listView on top of my map activity?

I've got my new application based on Google Maps activity. I set my onMapLongClickListener to add as many new marker as the user want to. But there is my question: I want to set a ListView on the top of my map in order to allow the user to chose between different marker types. How can I set a ListView that appears when I hold a point on the map and then disappear after the selection of one of its items?
Here is my app code, if it can help you on giving me some solutions!
MapsActivity.java
package com.example.mancu_000.onclickmarkerlistener;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
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.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, OnMapLongClickListener {
private GoogleMap map;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
map.setOnMapLongClickListener(this);
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
Toast.makeText(MapsActivity.this, "OnMarkerListener", Toast.LENGTH_SHORT).show();
return true;
}
});
LatLng home = new LatLng(44.42913, 8.84072);
map.addMarker(new MarkerOptions().position(home).title("Home, bitches!"));
map.moveCamera(CameraUpdateFactory.newLatLng(home));
CameraUpdate center = CameraUpdateFactory.newLatLng(home);
map.moveCamera(center);
CameraUpdate zoom = CameraUpdateFactory.zoomTo(17);
map.animateCamera(zoom);
}
#Override
public void onMapLongClick(LatLng location) {
// Here I'm supposed to implements thee code of the ListView on the top of the map
}
}
activity_maps.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.example.mancu_000.onclickmarkerlistener.MapsActivity" >
<fragment xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
class="com.google.android.gms.maps.SupportMapFragment"/>
</FrameLayout>
Thanks for you support!!
push a dialog to get the list of markers like
#Override
public void onMapLongClick(LatLng location) {
AlertDialog.Builder builderSingle = new AlertDialog.Builder(context);
builderSingle.setIcon(R.drawable.title_icon_resource);
builderSingle.setTitle("Select One Name:-");
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>();//create adapter with your markers list
builderSingle.setNegativeButton();//to exit directly if you want
builderSingle.setAdapter(arrayAdapter,new DialogInterface.OnClickListener());//set your adapter and listener
builderSingle.show();
}
hope this will helps you

Null pointer exception in fragment, using google maps

I received a null pointer exception when getting android google maps in a fragment. The error is at the line findFragmentById.I tried using
if (mMap != null) and it indicates that the map is still null. What can I do to resolve this?
In MapActivity.java,
//Relevant imports
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
enter code here
public class MapView extends Fragment {
GoogleMap mMap;
LatLng mLocation = new LatLng(1.379348, 103.849876);
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.map_view, container, false);
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
//Zoom
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLocation, 17));
Marker mMarker = mMap.addMarker(new MarkerOptions()
.position(mLocation)
.title("School")
.snippet("NTU")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
mMap.setOnMarkerClickListener(new OnMarkerClickListener()
{
public boolean onMarkerClick(Marker marker){
Toast.makeText(getActivity().getApplicationContext(), "Welcome to " + marker.getTitle(), Toast.LENGTH_LONG);
return false;
}
});
mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener(){
#Override
public void onInfoWindowClick(Marker arg0) {
// TODO Auto-generated method stub
}
});
return rootView;
}
}
In map_view.xml,
<RelativeLayout 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" >
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
In order to have a SupportMapFragment nested inside a Fragment, you need to use getChildFragmentManager() instead of getFragmentManager().
So, you would change this:
mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
To this, and also move all of the code referencing mMap to onResume():
mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
If you go this route you will also need to fix your layout xml to use a SupportMapFragment:
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
However, it would be best to not have nested Fragments if you don't need to, since it can lead to other problems.
A better approach is just to make the Fragment extend SupportMapFragment. Doing it this way, you don't even need a layout xml file.
Example:
public class MapView extends SupportMapFragment
implements OnMapReadyCallback {
private GoogleMap mMap;
private Marker marker;
public MapView() {
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
setUpMap();
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setMapToolbarEnabled(false);
}
}
Can you please try this way ?
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Activity or Fragment:
private GoogleMap mMap;
private MapView mapView;
on onCreate():
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map,container, false)
initializaMap(rootView, savedInstanceState);
return rootView;
}
on onResume()
#Override
public void onResume() {
if(mapView!=null){
mapView.onResume();
}
super.onResume();
}
on onDestroy()
#Override
public void onDestroy() {
if(mapView!=null){
mapView.onDestroy();
}
super.onDestroy();
}
on onLowMemory()
#Override
public void onLowMemory() {
if(mapView!=null){
mapView.onLowMemory();
}
super.onLowMemory();
}
Add new method:
private void initializaMap(View rootView, Bundle savedInstanceState){
MapsInitializer.initialize(getActivity());
switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity())) {
case ConnectionResult.SUCCESS:
mapView = (MapView) rootView.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
if (mapView != null) {
mMap = mapView.getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
UiSettings mUiSettings = mMap.getUiSettings();
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory.zoomTo(zoomLevel));
mUiSettings.setCompassEnabled(true);
mUiSettings.setMyLocationButtonEnabled(false);
mMap.setOnMarkerClickListener(this);
}
break;
case ConnectionResult.SERVICE_MISSING:
break;
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
break;
default:
}
}
Hope this will help you.

How to put Google Maps V2 on a Fragment using ViewPager

I am trying to do a tab layout same in Play Store. I got to display the tab layout using a fragments and viewpager from androidhive. However, I can't implement google maps v2 on it. I searched the internet for hours already, but I can't find a tutorial on how to do it. Can some one please show me how?
By using this code we can setup MapView anywhere, inside any ViewPager or Fragment or Activity.
In the latest update of Google for Maps, only MapView is supported for fragments. MapFragment & SupportMapFragment didn't work for me.
Setting up the layout for showing the map in the file location_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
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="match_parent" />
</RelativeLayout>
Now, we setup the Java class for showing the map in the file MapViewFragment.java:
public class MapViewFragment extends Fragment {
MapView mMapView;
private GoogleMap googleMap;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.location_fragment, container, false);
mMapView = (MapView) rootView.findViewById(R.id.mapView);
mMapView.onCreate(savedInstanceState);
mMapView.onResume(); // needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
mMapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap mMap) {
googleMap = mMap;
// For showing a move to my location button
googleMap.setMyLocationEnabled(true);
// For dropping a marker at a point on the Map
LatLng sydney = new LatLng(-34, 151);
googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker Title").snippet("Marker Description"));
// For zooming automatically to the location of the marker
CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
});
return rootView;
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
Finally you need to get the API Key for your app by registering your app at Google Cloud Console. Register your app as Native Android App.
The following approach works for me.
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.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
/**
* A fragment that launches other parts of the demo application.
*/
public class MapFragment extends Fragment {
MapView mMapView;
private GoogleMap googleMap;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflat and return the layout
View v = inflater.inflate(R.layout.fragment_location_info, container,
false);
mMapView = (MapView) v.findViewById(R.id.mapView);
mMapView.onCreate(savedInstanceState);
mMapView.onResume();// needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
googleMap = mMapView.getMap();
// latitude and longitude
double latitude = 17.385044;
double longitude = 78.486671;
// create marker
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude)).title("Hello Maps");
// Changing marker icon
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
// adding marker
googleMap.addMarker(marker);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(17.385044, 78.486671)).zoom(12).build();
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
// Perform any camera updates here
return v;
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
fragment_location_info.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
You can use this line if you want to use GoogleMap in a fragment:
<fragment
android:id="#+id/map"
android:layout_width="wrap_content"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
GoogleMap mGoogleMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
Latest stuff with getMapAsync instead of the deprecated one.
1. check manifest for
<meta-data android:name="com.google.android.geo.API_KEY" android:value="xxxxxxxxxxxxxxxxxxxxxxxxx"/>
You can get the API Key for your app by registering your app at Google Cloud Console. Register your app as Native Android App
2. in your fragment layout .xml add FrameLayout(not fragment):
<FrameLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_weight="2"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/mapwhere" />
or whatever height you want
3. In onCreateView in your fragment
private SupportMapFragment mSupportMapFragment;
mSupportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapwhere);
if (mSupportMapFragment == null) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
mSupportMapFragment = SupportMapFragment.newInstance();
fragmentTransaction.replace(R.id.mapwhere, mSupportMapFragment).commit();
}
if (mSupportMapFragment != null)
{
mSupportMapFragment.getMapAsync(new OnMapReadyCallback() {
#Override public void onMapReady(GoogleMap googleMap) {
if (googleMap != null) {
googleMap.getUiSettings().setAllGesturesEnabled(true);
-> marker_latlng // MAKE THIS WHATEVER YOU WANT
CameraPosition cameraPosition = new CameraPosition.Builder().target(marker_latlng).zoom(15.0f).build();
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
googleMap.moveCamera(cameraUpdate);
}
}
});
here what i did in detail:
From here you can get google map api key
alternative and simple way
first log in to your google account and visit google libraries and select Google Maps Android API
dependency found in android studio default map activity :
compile 'com.google.android.gms:play-services:10.0.1'
put your key into android mainifest file under application like below
in AndroidMainifest.xml make these changes:
// required permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
// google map api key put under/inside <application></application>
// android:value="YOUR API KEY"
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzasdfasdf645asd4f847sad5f45asdf7845" />
Fragment code :
public class MainBranchFragment extends Fragment implements OnMapReadyCallback{
private GoogleMap mMap;
public MainBranchFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_main_branch, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.main_branch_map);
mapFragment.getMapAsync(this);
return view;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng UCA = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(UCA).title("YOUR TITLE")).showInfoWindow();
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(UCA,17));
}
}
in you fragment xml :
<fragment
android:id="#+id/main_branch_map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.googlemap.googlemap.MapsActivity" />
For the issue of getting a NullPointerException when we change the Tabs in a FragmentTabHost you just need to add this code to your class which has the TabHost. I mean the class where you initialize the tabs. This is the code :
/**** Fix for error : Activity has been destroyed, when using Nested tabs
* We are actually detaching this tab fragment from the `ChildFragmentManager`
* so that when this inner tab is viewed back then the fragment is attached again****/
import java.lang.reflect.Field;
#Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public class DemoFragment extends Fragment {
MapView mapView;
GoogleMap map;
LatLng CENTER = null;
public LocationManager locationManager;
double longitudeDouble;
double latitudeDouble;
String snippet;
String title;
Location location;
String myAddress;
String LocationId;
String CityName;
String imageURL;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater
.inflate(R.layout.fragment_layout, container, false);
mapView = (MapView) view.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
setMapView();
}
private void setMapView() {
try {
MapsInitializer.initialize(getActivity());
switch (GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getActivity())) {
case ConnectionResult.SUCCESS:
// Toast.makeText(getActivity(), "SUCCESS", Toast.LENGTH_SHORT)
// .show();
// Gets to GoogleMap from the MapView and does initialization
// stuff
if (mapView != null) {
locationManager = ((LocationManager) getActivity()
.getSystemService(Context.LOCATION_SERVICE));
Boolean localBoolean = Boolean.valueOf(locationManager
.isProviderEnabled("network"));
if (localBoolean.booleanValue()) {
CENTER = new LatLng(latitude, longitude);
} else {
}
map = mapView.getMap();
if (map == null) {
Log.d("", "Map Fragment Not Found or no Map in it!!");
}
map.clear();
try {
map.addMarker(new MarkerOptions().position(CENTER)
.title(CityName).snippet(""));
} catch (Exception e) {
e.printStackTrace();
}
map.setIndoorEnabled(true);
map.setMyLocationEnabled(true);
map.moveCamera(CameraUpdateFactory.zoomTo(5));
if (CENTER != null) {
map.animateCamera(
CameraUpdateFactory.newLatLng(CENTER), 1750,
null);
}
// add circle
CircleOptions circle = new CircleOptions();
circle.center(CENTER).fillColor(Color.BLUE).radius(10);
map.addCircle(circle);
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
break;
case ConnectionResult.SERVICE_MISSING:
break;
case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
break;
default:
}
} catch (Exception e) {
}
}
in fragment_layout
<com.google.android.gms.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="160dp"
android:layout_marginRight="10dp" />
When you add yor map use:
getChildFragmentManager().beginTransaction()
.replace(R.id.menu_map_container, mapFragment, "f" + shabbatIndex).commit();
instead of .add and instead of getFragmentManager.
This is the Kotlin way:
In fragment_map.xml you should have:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
In your MapFragment.kt you should have:
private fun setupMap() {
(childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?)!!.getMapAsync(this)
}
Call setupMap() in onCreateView.
According to https://developer.android.com/about/versions/android-4.2.html#NestedFragments, you can use nested fragments to achieve this by calling getChildFragmentManager() if you still want to use the Google Maps fragment instead of the view inside your own fragment:
SupportMapFragment mapFragment = new SupportMapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.content, mapFragment).commit();
where "content" is the root layout in your fragment (preferably a FrameLayout). The advantage of using a map fragment is that then the map lifecycle is managed automatically by the system.
Although the documentation says "You cannot inflate a layout into a fragment when that layout includes a <fragment>. Nested fragments are only supported when added to a fragment dynamically. ", I have somehow successfully done this and it worked fine. Here is my code:
In the fragment's onCreateView() method:
View view = inflater.inflate(R.layout.layout_maps, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(...);
In the layout:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Hope it helps!
i just create MapActivity and inflate it to fragment .
MapActivity.java:
package com.example.ahmedsamra.mansouratourguideapp;
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_categories);//layout for container
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new MapFragment())
.commit();
// 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);
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng mansoura = new LatLng(31.037933, 31.381523);
mMap.addMarker(new MarkerOptions().position(mansoura).title("Marker in mansoura"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(mansoura));
}
}
activity_map.xml:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ahmedsamra.mansouratourguideapp.MapsActivity" />
MapFragment.java:-
package com.example.ahmedsamra.mansouratourguideapp;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* A simple {#link Fragment} subclass.
*/
public class MapFragment extends Fragment {
public MapFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_maps,container,false);
return rootView;
}
}
I've a workaround for NullPointerException when remove fragment in on DestoryView, Just put your code in onStop() not onDestoryView. It works fine!
#Override
public void onStop() {
super.onStop();
if (mMap != null) {
MainActivity.fragmentManager.beginTransaction()
.remove(MainActivity.fragmentManager.findFragmentById(R.id.location_map)).commit();
mMap = null;
}
}
Dynamically adding map fragment to view Pager:
If you are targeting an application earlier than API level 12 make an instance of SupportedMapFragment and add it to your view page adapter.
SupportMapFragment supportMapFragment=SupportMapFragment.newInstance();
supportMapFragment.getMapAsync(this);
API level 12 or higher support MapFragment objects
MapFragment mMapFragment=MapFragment.newInstance();
mMapFragment.getMapAsync(this);

Categories

Resources