I'm creating an app, and I just got it to show the map on the screen. Now I was wondering how can I have it find the user and track where he/she goes. I did the setMyLocationEnabled(true), but all that does is show a button, and when you click it nothing happens. I've never used google maps api before so I don't know much about it.
There you have got this trouble good explained - http://wptrafficanalyzer.in/blog/showing-current-location-in-google-maps-using-api-v2-with-supportmapfragment/.
You have to implement getting user's location out of Google Maps API. You need to use those permissions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
There is class example which shows that, what you want. Got this from page I wrote above:
public class MainActivity extends FragmentActivity implements LocationListener {
GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
// Showing status
if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
dialog.show();
}else { // Google Play Services are available
// Getting reference to the SupportMapFragment of activity_main.xml
SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
// Getting GoogleMap object from the fragment
googleMap = fm.getMap();
// Enabling MyLocation Layer of Google Map
googleMap.setMyLocationEnabled(true);
// Getting LocationManager object from System Service LOCATION_SERVICE
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location
Location location = locationManager.getLastKnownLocation(provider);
if(location!=null){
onLocationChanged(location);
}
locationManager.requestLocationUpdates(provider, 20000, 0, this);
}
}
#Override
public void onLocationChanged(Location location) {
TextView tvLocation = (TextView) findViewById(R.id.tv_location);
// Getting latitude of the current location
double latitude = location.getLatitude();
// Getting longitude of the current location
double longitude = location.getLongitude();
// Creating a LatLng object for the current location
LatLng latLng = new LatLng(latitude, longitude);
// Showing the current location in Google Map
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// Zoom in the Google Map
googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
// Setting latitude and longitude in the TextView tv_location
tvLocation.setText("Latitude:" + latitude + ", Longitude:"+ longitude );
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Related
Hi guys im very new with app development ,any ideas how im i able to store my Latitude and Longitude of my users positions with its names and plot in my google maps?
I used this code below and it is working fine it plot the multiple marker as expected , my problem is ,i have my datas from firebase data base please see images
2 users with positions :
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private GoogleMap googleMap;
private MarkerOptions options = new MarkerOptions();
private ArrayList<LatLng> latlngs = new ArrayList<>();
private ArrayList<String> Names = new ArrayList<>();
#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);
latlngs.add(new LatLng(12.334343, 33.43434)); //some latitude and logitude value
latlngs.add(new LatLng(10.334343, 32.43434)); //some latitude and logitude value
Names.add("Name 1"); //some latitude and logitude value
Names.add("Name 2"); //some latitude and logitude value
}
/**
* 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 sydney = new LatLng(-34, 151);
// mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
// mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
for (LatLng point : latlngs) {
options.position(point);
options.title(String.valueOf(Names));
options.snippet("someDesc");
googleMap.addMarker(options);
}
}
}
The code below is used to fetch data from firebease:
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Positions");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot chidSnap : dataSnapshot.getChildren()) {
System.out.println("id",""+ chidSnap.getKey()); //displays the key for the node
System.out.println("Latit",""+ chidSnap.child("Latitude").getValue());
System.out.println.v("Longitude",""+ chidSnap.child("Longitude").getValue()); //gives the value for given keyname
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
you get data from firbase database and store it in list you want to publish marker on map
you can use this Method
public ArrayList<MarkerOptions> publishMarker(GoogleMap googleMap, int recourceMarker) {
ArrayList<MarkerOptions> markerOption = new ArrayList<>();
for (LatLng point : latlngs) {
MarkerOptions markerOptions = new MarkerOptions().position(point);
markerOptions.icon(BitmapDescriptorFactory.fromResource(recourceMarker));
markerOption.add(markerOptions);
googleMap.addMarker(markerOptions).setTag(point);
googleMap.addMarker(markerOptions);
}
return markerOption;
}
then call method in on mapReady Method
ArrayList<MarkerOptions> markerOptions=publishMarker(mMap, R.drawable.map_marker);
if (markerOptions!=null&&markerOptions.size() > 0)this.mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(markerOptions.get(0).getPosition(), 15));
I am trying to create an interactive infoWindow based on one of the answers from Stack Overflow.
However, I am getting an error with getMap() used in the code. Although I've tried with getMapAsync(), I'm unable to resolve the problem. Please help me. If any new code is available for an interactive infowindow with a button, then please share the code.
public class MainActivity extends AppCompatActivity {
private ViewGroup infoWindow;
private TextView infoTitle;
private TextView infoSnippet;
private Button infoButton1, infoButton2;
private OnInfoWindowElemTouchListener infoButtonListener;
static final LatLng latlng1 = new LatLng(28.5355, 77.3910);
static final LatLng latlng2 = new LatLng(28.6208768, 77.3726377);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout)findViewById(R.id.map_relative_layout);
final GoogleMap googleMap = mapFragment.getMap();
// MapWrapperLayout initialization
// 39 - default marker height
// 20 - offset between the default InfoWindow bottom edge and it's content bottom edge
mapWrapperLayout.init(googleMap, getPixelsFromDp(this, 39 + 20));
// We want to reuse the info window for all the markers,
// so let's create only one class member instance
this.infoWindow = (ViewGroup)getLayoutInflater().inflate(R.layout.custom_infowindow, null);
this.infoTitle = (TextView)infoWindow.findViewById(R.id.nameTxt);
this.infoSnippet = (TextView)infoWindow.findViewById(R.id.addressTxt);
this.infoButton1 = (Button)infoWindow.findViewById(R.id.btnOne);
this.infoButton2 = (Button)infoWindow.findViewById(R.id.btnTwo);
// Setting custom OnTouchListener which deals with the pressed state
// so it shows up
this.infoButtonListener = new OnInfoWindowElemTouchListener(infoButton1, getResources().getDrawable(R.drawable.btn_bg), getResources().getDrawable(R.drawable.btn_bg)){
#Override
protected void onClickConfirmed(View v, Marker marker) {
// Here we can perform some action triggered after clicking the button
Toast.makeText(MainActivity.this, "click on button 1", Toast.LENGTH_SHORT).show();
}
};
this.infoButton1.setOnTouchListener(infoButtonListener);
infoButtonListener = new OnInfoWindowElemTouchListener(infoButton2, getResources().getDrawable(R.drawable.btn_bg),getResources().getDrawable(R.drawable.btn_bg)){
#Override
protected void onClickConfirmed(View v, Marker marker) {
Toast.makeText(getApplicationContext(), "click on button 2", Toast.LENGTH_LONG).show();
}
};
infoButton2.setOnTouchListener(infoButtonListener);
/*infoWindow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "click on infowindow", Toast.LENGTH_LONG).show();
}
});*/
googleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
// Setting up the infoWindow with current's marker info
infoSnippet.setText(marker.getTitle());
infoTitle.setText(marker.getSnippet());
infoButtonListener.setMarker(marker);
// We must call this to set the current marker and infoWindow references
// to the MapWrapperLayout
mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
return infoWindow;
}
});
// Let's add a couple of markers
googleMap.addMarker(new MarkerOptions()
.position(latlng1)
.title("Source")
.snippet("Comapny Name")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
googleMap.addMarker(new MarkerOptions()
.position(latlng2)
.title("Destination")
.snippet("AmisunXXXXXX")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
//googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 15));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latlng1, 10));
}
public static int getPixelsFromDp(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dp * scale + 0.5f);
}
}
The error is coming because Google has removed getMap(), but I dont know the alternative solution for this.
UPDATE
Define private GoogleMap gMapand implement OnMapReadyCallback in your main Activity and implement onMapReady method
in onMapReady you should write this line
gMap = googleMap, then you can do what you want in onMapReady
getting current location
custom setting for your map
and ...
now it's time to use this lines in your OnCreate method
SupportMapFragment supportMapFragment = (SupportMapFragment)
getSupportFragmentManager().findFragmentById(R.id.map);
supportMapFragment.getMapAsync(this);
it should solve your problem, hope it helped you
I am trying for interactive infoWindow with one of the answer of stack overflow.
link is given below:
interactive infowindow
but i am getting error with getMap() used in the code. although I tried with getMapAsync but unable to resolve the problem. please help me asap.If any new code available for interactive infowindow with button then please share the code.
public class MainActivity extends Activity {
private ViewGroup infoWindow;
private TextView infoTitle;
private TextView infoSnippet;
private Button infoButton;
private OnInfoWindowElemTouchListener infoButtonListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout)findViewById(R.id.map_relative_layout);
final GoogleMap map = mapFragment.getMap();
// MapWrapperLayout initialization
// 39 - default marker height
// 20 - offset between the default InfoWindow bottom edge and it's content bottom edge
mapWrapperLayout.init(map, getPixelsFromDp(this, 39 + 20));
// We want to reuse the info window for all the markers,
// so let's create only one class member instance
this.infoWindow = (ViewGroup)getLayoutInflater().inflate(R.layout.info_window, null);
this.infoTitle = (TextView)infoWindow.findViewById(R.id.title);
this.infoSnippet = (TextView)infoWindow.findViewById(R.id.snippet);
this.infoButton = (Button)infoWindow.findViewById(R.id.button);
// Setting custom OnTouchListener which deals with the pressed state
// so it shows up
this.infoButtonListener = new OnInfoWindowElemTouchListener(infoButton,
getResources().getDrawable(R.drawable.btn_default_normal_holo_light),
getResources().getDrawable(R.drawable.btn_default_pressed_holo_light))
{
#Override
protected void onClickConfirmed(View v, Marker marker) {
// Here we can perform some action triggered after clicking the button
Toast.makeText(MainActivity.this, marker.getTitle() + "'s button clicked!", Toast.LENGTH_SHORT).show();
}
};
this.infoButton.setOnTouchListener(infoButtonListener);
map.setInfoWindowAdapter(new InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
// Setting up the infoWindow with current's marker info
infoTitle.setText(marker.getTitle());
infoSnippet.setText(marker.getSnippet());
infoButtonListener.setMarker(marker);
// We must call this to set the current marker and infoWindow references
// to the MapWrapperLayout
mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
return infoWindow;
}
});
// Let's add a couple of markers
map.addMarker(new MarkerOptions()
.title("Prague")
.snippet("Czech Republic")
.position(new LatLng(50.08, 14.43)));
map.addMarker(new MarkerOptions()
.title("Paris")
.snippet("France")
.position(new LatLng(48.86,2.33)));
map.addMarker(new MarkerOptions()
.title("London")
.snippet("United Kingdom")
.position(new LatLng(51.51,-0.1)));
}
public static int getPixelsFromDp(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dp * scale + 0.5f);
}
}
error is coming because of google has removed getMap but dont know the alternative solution for this.
Error:(149, 42) error: cannot find symbol method getMap()
Your Existing Code is:
final MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
final GoogleMap map = mapFragment.getMap();
Try this instead of that:
MapFragment mapFragment; // declare in global scope
GoogleMap googleMap; // declare in global scope
Put this code in OnCreate method:
mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap map) {
googleMap = map;
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
googleMap.setMyLocationEnabled(false); // false to disable
googleMap.setOnMarkerClickListener(onMarkerClick);
googleMap.setOnInfoWindowClickListener(onInfoWindowClick);
googleMap.getUiSettings().setZoomControlsEnabled(true);// Display Zoom Controls
googleMap.setMyLocationEnabled(true);// Display My Location Control
}
});
}
for converting pixels into DP use this:
public int getPixelsFromDp(int px){
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
Use getMapAsync in your onCreatView() method
((SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map))
.getMapAsync(this)
Also imeplement the OnMapReadyCallback interface, and override it's method
In method onMapReady() which belongs to onMapReadyCallback interface do all the operations with your map you need. It will look like after your manipulations next
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// some action with our map
mMap.addMarker(new MarkerOptions().position(randomPosition).title("Random Title"));
mMap.addMarker(new MarkerOptions().position(antoherRandomPosition).title("Another RND Title"));
// some processes with db
DataBaseMapFragment database = new DataBaseMapFragment(dbHelper, mMap);
database.createBD();
// permission to check, if gps access is granted
if (ActivityCompat.checkSelfPermission(getActivity().getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity().getApplicationContext(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
//another actions with map
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(camera, 13));
mMap.setBuildingsEnabled(true);
mMap.setOnMapLongClickListener(this);
mMap.setOnMyLocationChangeListener(myLocationChangeListener);
mMap.setOnMarkerClickListener(this);
reffering Google documentation and guide.
Check it to learn more about maps in android and to be clear about
The getMap() function replaced from getMapAsync() more here
https://developers.google.com/android/reference/com/google/android/gms/maps/package-summary
I need that in my Map-application Google map markers title always will be shown without any user click. I want that this title even will not be possible hide.
Of course I searched online, and I found this: marker.showInfoWindow(); but it is not working because I have near to 30 markers and I need that all of them will be shown all the time (I guess marker.showInfoWindow(); working just when there is one marker).
............................................................................
(And I would like to know how to do that when map activity will start it will not show whole world from far, but from specific country. I mean already zoomed to this country.)
public class Map extends Activity {
static LatLng Sapphire = new LatLng(41.085078, 29.006100);
static LatLng Metrocity = new LatLng(41.076138, 29.010518);
static LatLng Istinye = new LatLng(41.114247, 29.058924);
private GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
try {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
}
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.setMyLocationEnabled(true);
googleMap.setTrafficEnabled(true);
googleMap.setIndoorEnabled(true);
googleMap.setBuildingsEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
Marker marker = googleMap.addMarker(new MarkerOptions().position(Sapphire).title("Istanbul Sapphire").snippet("Levent")); marker.showInfoWindow();
Marker marker1 = googleMap.addMarker(new MarkerOptions().position(Metrocity).title("Metrocity").snippet("Levent")); marker1.showInfoWindow();
Marker marker2 = googleMap.addMarker(new MarkerOptions().position(Istinye).title("Istinye Park").snippet("Istinye/ Pınar Mh.")); marker2.showInfoWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When I run the app, I get the world map, where you can see all the countries. But this is not what I want, I want it to show the map of my country or city as an example. Is there a way to do this? This is my code so far. I don't think the xml code should be necassary for this?
public class MainActivity extends Activity {
private GoogleMap gMap;
private LocationManager locationManager;
private Location location, g;
private double lati, longi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
// gMap.setMyLocationEnabled(true);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
System.out.println("Last known location: " + location);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void showUsersPosition(View v) {
gMap.setMyLocationEnabled(true);
if(location != null) {
lati = location.getLatitude();
longi = location.getLongitude();
}
gMap.addMarker(new MarkerOptions().position(new LatLng(lati, longi)).title("You are here"));
}
}
I also have added a button, where I want to show the users location when this button is clicked. This happens in the method "showUsersPosition". But at this point, Location is null, even though I try to set it when the app is beeing started. Can anyone see why it is null? When the gMap.setMyLocation(true) is called, a symbole appears at the right corner, and if I click on this, it will show me my position. But I want it so that it does this when I click the button.
So the questions again are:
1. How to show the map of my country or city, and not the world map?
2. Why is Location null?
3. How do I make it show my exact location when the button is clicked
1)
You can use this on your fragment declaration to set the default latitude and longitude.
map:cameraTargetLat="Your Latitude"
map:cameraTargetLng="Your Longitude"
Do not forget to put xmlns:map="http://schemas.android.com/apk/res-auto" on your fragment if it is not there.
2) From the docs:
If the provider is currently disabled, null is returned.
Is the GPS turned on?. Also, you should use the new Location API.
3) The exactness of your Location will be based on the Provider used to get the Location. One of the advantages of using the new Fused Provider is that the system will try to get the best Location possible for you.