Hello I am new in android development and i want to get current location in mapview using fragment class. when i am adding setMyLocationEnabled method it is asking for permissions and i have added all the permissions in manifest. Please help me .
Gmaps.java (fragment)
public class Gmaps extends Fragment implements OnMapReadyCallback {
private GoogleMap googleMap;
private MapView mapView;
private boolean mapsSupported = true;
private GoogleApiClient mGoogleApiClient;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MapsInitializer.initialize(getActivity());
if (mapView != null) {
mapView.onCreate(savedInstanceState);
}
initializeMap();
}
private void initializeMap() {
if (googleMap == null && mapsSupported) {
mapView = (MapView) getActivity().findViewById(R.id.map);
googleMap = mapView.getMap();
double latitude = 0.00;
double longitude = 0.00;
MarkerOptions marker = new MarkerOptions().position(new LatLng(latitude, longitude)).title("Marker");
googleMap.addMarker(marker);
CameraPosition cameraPosition = new CameraPosition.Builder().target(
new LatLng(0, 0)).zoom(12).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
googleMap.getUiSettings().setZoomControlsEnabled(true); // true to enable
googleMap.getUiSettings().setZoomGesturesEnabled(true);
googleMap.getUiSettings().setCompassEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setRotateGesturesEnabled(true);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout p = (FrameLayout) inflater.inflate(R.layout.fragment_gmaps, container, false);
mapView = (MapView) p.findViewById(R.id.map);
return p;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
#Override
public void onResume() {
super.onResume();
mapView.onResume();
initializeMap();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
public void onMapReady(GoogleMap googleMap) {
}
In Manifest, I have added all these permissions used for google map services
According to the documentation:
If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.
That's the reason why althought you have declared the permissions in your manifest file you still need to ask for them at runtime.
As a workaround you can set a minSdkVersion < 23, but also as the documentation says:
Note: Beginning with Android 6.0 (API level 23), users can revoke permissions from any app at any time, even if the app targets a lower API level. You should test your app to verify that it behaves properly when it's missing a needed permission, regardless of what API level your app targets.
Also, according to the Permissions Best Practices you should test against both permission models to provide a better user experience.
Try this:
public void showMap() {
mapFragment = (SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map);
if (map == null) {
map = mapFragment.getMap();
}
// Enable Zoom
map.getUiSettings().setZoomGesturesEnabled(true);
//set Map TYPE
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//enable Current location Button
map.setMyLocationEnabled(true);
LocationManager locationManager = (LocationManager)getActivity().getSystemService(getActivity().LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, true);
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), 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;
}
Location location = locationManager.getLastKnownLocation(bestProvider);
if (location != null) {
onLocationChanged(location);
}
locationManager.requestLocationUpdates(bestProvider, 2000, 0, this);
}
#Override
public void onLocationChanged(Location location) {
latitude= location.getLatitude();
longitude=location.getLongitude();
LatLng loc = new LatLng(latitude, longitude);
if (marker!=null){
marker.remove();
}
marker= map.addMarker(new MarkerOptions().position(loc).title("Sparx IT Solutions"));
map.moveCamera(CameraUpdateFactory.newLatLng(loc));
map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
Toast.makeText(getActivity().getBaseContext(), "Gps is turned off!!",
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(getActivity().getBaseContext(), "Gps is turned on!! ",
Toast.LENGTH_SHORT).show();
}
add these uses-permissions in Manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Related
I want to show my current location using Google maps v2 from a fragment however the Google maps is not initializing on start up. When i run the application, it is nor crashing but the map is not showing my current location neither is it displaying anything. I have used this code on my activity and it is fully functional.
Below is my java code:
public class MapFragment extends Fragment implements LocationListener,GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,OnMapReadyCallback {
SupportMapFragment mSupportMapFragment;
MapView mMapView;
Location mLastLocation;
Marker mCurrLocationMarker;
private MarkerOptions markerOptions;
protected GoogleApiClient mGoogleApiClient;
private LatLng latLng;
public GoogleMap mMap;
private Marker marker;
LocationRequest mLocationRequest;
private GoogleMap googleMap;
private TextView lastTrip, lastDeliveryText, lastDelivery, lastAmountText, lastAmount, kes,
todayTotal, totalDeliveryText, totalDelivery, totalAmount, totalAmountText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
buildGoogleApiClient();
// inflat and return the layout
View v = inflater.inflate(R.layout.map_fragment, container,
false);
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(this);
}
return v;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
Log.d("one","one");
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//mMap.getUiSettings().setZoomControlsEnabled(true);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
Log.d("two","two");
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
Log.d("three","three");
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
Log.d("four","four");
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
Log.d("five","five");
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//mMap.getUiSettings().setZoomControlsEnabled(true);
final Double lat = location.getLatitude();
final Double lng = location.getLongitude();
Log.d("LATLANGz", lat + "|" + lng);
latLng = new LatLng(lat, lng);
markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Positionn");
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), 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;
}
mMap.setMyLocationEnabled(false);
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.user_location));
marker = mMap.addMarker(markerOptions);
//move map camera_main
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}
#Override
public void onResume() {
super.onResume();
Log.d("hey2","hey2");
// mMapView.onResume();
mSupportMapFragment.onResume();
}
#Override
public void onPause() {
super.onPause();
Log.d("hey1","hey1");
// mMapView.onPause();
mSupportMapFragment.onPause();
}
/* #Override
public void onDestroy() {
super.onDestroy();
// mMapView.onDestroy();
mSupportMapFragment.onDestroy();
}*/
#Override
public void onLowMemory() {
super.onLowMemory();
// mMapView.onLowMemory();
mSupportMapFragment.onLowMemory();
}
#Override
public void onDetach() {
Log.d("detach", "detach");
super.onDetach();
mSupportMapFragment.onDetach();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d("six","six");
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (mGoogleApiClient.isConnected()){
Log.d("seven","six");
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
first of all Chaeck permission in manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
then check method for current location
private GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());
marker = map.addMarker(new MarkerOptions().position(loc));
if(map != null){
map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
}
}
};
then use
mMap.setOnMyLocationChangeListener(myLocationChangeListener);
and be patience map take laoding time depend on you network speed
comment if any query
First check your permissions and your google api key in your manifest
Your xml layout must be something like this without any thing else:
. <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.isg_biz.isg_tracking.MainActivity" />
You have to implement OnMapReadyCallback, then
your code should be something like this in onCreate() :
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Do not to copy and past the same xml code literally you have to change (tools : .....) to same that exist in your xml
for documentation, java code & more Please read :
https://developers.google.com/maps/documentation/android-api/map-with-marker
I wrote code in Android studio to display my location in a Google Map fragment but it is not doing so. The map is being displayed but the coordinates I want is not getting marked. The code is the following:
public class SEMapTab extends Fragment implements OnMapReadyCallback {
private View rootView;
private MapFragment mMapFrag;
private GoogleMap mMap;
private LocationManager locationManager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (rootView != null) {
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null)
parent.removeView(rootView);
}
try {
rootView = inflater.inflate(R.layout.single_entity_map, container, false);
} catch (InflateException e) {
}
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
if (mMapFrag == null) {
super.onViewCreated(view, savedInstanceState);
FragmentManager fragment = getActivity().getFragmentManager();
mMapFrag = (MapFragment) fragment.findFragmentById(R.id.map);
mMapFrag.getMapAsync(this);
}
locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), 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;
}
//if network provider is enabled
if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))
{
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
double Latitude= location.getLatitude(); //Get latitude
double Longitude = location.getLongitude(); //Get longitude
LatLng latLng= new LatLng(Latitude, Longitude);
//Map latitude and longitude
mMap.addCircle(new CircleOptions().center(latLng).fillColor(Color.BLUE).radius(10));
//Zoom in to current location
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,18));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
});
}
//else if gps provider is enabled
else if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
double Latitude= location.getLatitude(); //Get latitude
double Longitude = location.getLongitude(); //Get longitude
LatLng latLng= new LatLng(Latitude, Longitude);
//Map latitude and longitude
mMap.addCircle(new CircleOptions().center(latLng).fillColor(Color.BLUE).radius(10));
//Zoom in to current location
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,18));
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
});
}
}
#Override
public void onMapReady(GoogleMap googleMap)
{
}
}
I have also included the necessary permissions in AndroidManifest.xml file
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
The Map fragment is opening but there is no circle getting marked at my current location. Alternatively, if I hard code a GPS location in OnMapReady function, then that is gettig marked and is working fine. I request you to help me resolve this issue.
At onMapReady add googleMap.setMyLocationEnabled(true). No need to handle "manually" the location manager and these providers. Just be sure that user has given the permission to the app to access his location before call this, otherwise the app will crash.
I'm trying to get my current location with the location button on Google Maps but I have some problems. With the new runtime permissions (API level 23), I don't know if i am doing well or not.
With that code below, when I use a virtual device API 23, the location button doesn't appear and with a virtual device API 22, it appears but don't do anything. So what can be the problem ?
public class MapsActivity extends FragmentActivity implements
OnMapReadyCallback{
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap map) {
mMap = map;
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
// Show rationale and request permission.
}
}
}
In the Manifest file :
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Thanks in advance..
In api level 23, you need check permissions programmatically. You are checking the location permission and if it's granted, setting the location enabled. You can ask for permission if it is not granted.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
} else {
ActivityCompat.requestPermissions(MapActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_CODE);
}
Then you can handle the result by overriding this method.
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//do something
} else {
finish();
}
break;
}
}
}
Also you can give permission from the emulator's settings for your application.
Let me know after trying. Good luck.
EDIT:
You need to implement a clicklistener to mylocation button.
final GoogleMap mMap = map;
map.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
#Override
public boolean onMyLocationButtonClick() {
LatLng loc = new LatLng(mMap.getMyLocation().getLatitude(),mMap.getMyLocation().getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLng(loc));
return true;
}
});
I have made an app which gives you current latitude and longitude using GPS service.
Now i plan to show location on MAP based on this co-ordinates
I want to create 2 activities. 1st already created in which i am showing latitude and longitude in TextView. in 2nd activity i want to display map in which location will be displayed. to go from one activity to another i will use a button in 1st activity.
here is my code (Not Full)
protected LocationManager locMan;
protected LocationListener locLis;
protected Context contex;
TextView txtview;
String lat,provider;
protected String latitude,longtitude;
protected boolean gps_enable,network_enable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar bar = getActionBar();
bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#F44336")));
txtview = (TextView)findViewById(R.id.locView);
locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
#Override
public void onLocationChanged(Location loc){
txtview = (TextView)findViewById(R.id.locView);
txtview.setText("Latitude = "+loc.getLatitude()+", Longitude = "+ loc.getLongitude());
}
Note :- I have refer javapapers website for my current app
Regards
Create Map Activity and pass the location via bundle or save it in sharedpreference
public class MapActivity extends ActionBarActivity{
private GoogleMap googleMap;
FragmentManager fm;
private Location mLocation;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fm = getSupportFragmentManager();
// get location from bundle or sharedprefs
// mLocation = ...
try {
if (googleMap == null) {
googleMap = ((SupportMapFragment) fm.findFragmentById(R.id.map)).getMap();
googleMap.getUiSettings().setZoomGesturesEnabled(true);
}
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
MarkerOptions TP = new MarkerOptions().title("title").position(new LatLng(mLocation.getLatitude(), mLocation.getLongitude())).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_map_marker));
googleMap.addMarker(TP);
}}
xml layout for this activity is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
You need to use MapView and MyLocationOverLay to the map, as Android will handle displaying the user's location for you.
map=(MapView)findViewById(R.id.whatever_your_mapview_id_is);
map.getOverlays().add(new MyLocationOverlay(this, map));
Refer : display google maps using coordinates obtained using gps
You can pass the location to the Maps Activity using a LatLng Object since it's parcelable, see this answer.
Then, you could create a Marker in your MapsActivity, and use the CameraPosition class to move the map view to the specified location.
First, make sure that you have double values with the current location in your existing Activity:
//instance variables:
double lat;
double lon;
Set lat/lon in your onLocationChanged() callback:
#Override
public void onLocationChanged(Location loc){
lat = loc.getLatitude(); //added
lon = loc.getLongitude(); //added
txtview = (TextView)findViewById(R.id.locView);
txtview.setText("Latitude = "+loc.getLatitude()+", Longitude = "+ loc.getLongitude());
}
Create a Button in your layout in your existing Activity, and in the click listener you would create a LatLng object and send it in the Intent to the Maps Activity:
Button b = (Button) findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LatLng fromPostion = new LatLng(lat, lon );
Bundle args = new Bundle();
args.putParcelable("location", fromPostion);
Intent i = new Intent(this, MapsActivity.class);
i.putExtras(args);
startActivity(i);
}
});
Then, in your Maps Activity, you would get the LatLng object in onCreate() from the Bundle:
LatLng latlng; //Create as instance variable
In onCreate():
Bundle b = getIntent().getExtras();
if (b != null){
latlng = (LatLng) b.getParcelable("location");
}
Then, add the Marker at that location and set the camera position and zoom:
private void setUpMap() {
mMap.getUiSettings().setMapToolbarEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.setMyLocationEnabled(true);
MarkerOptions marker = new MarkerOptions().position(latlng).title("My Location");
// Changing marker icon
marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
Marker m = mMap.addMarker(marker);
//move camera position and zoom to specified location
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latlng).zoom(8).build();
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
Your full Maps Activity might look something like this:
public class MapsActivity extends ActionBarActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, OnMapReadyCallback {
private GoogleMap mMap;
LatLng latlng;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
LocationManager manager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
Bundle b = getIntent().getExtras();
if (b != null){
latlng = b.getParcelable("location");
}
manager =(LocationManager) getSystemService(Context.LOCATION_SERVICE);
setUpMapIfNeeded();
buildGoogleApiClient();
mGoogleApiClient.connect();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setTitle("Location is disabled")
.setMessage("Please enable your location")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), 100);
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
Log.v("Connection Status", String.valueOf(mGoogleApiClient.isConnected()));
mGoogleApiClient.connect();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == 100) {
Toast.makeText(this, "location enabled", Toast.LENGTH_LONG).show();
if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
Toast.makeText(this, "location enabled", Toast.LENGTH_LONG).show();
//At least one provider enabled, connect GoogleApiClient
mGoogleApiClient.connect();
}
}
}
#Override
protected void onPause(){
super.onPause();
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
protected synchronized void buildGoogleApiClient() {
Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnected(Bundle bundle) {
Toast.makeText(this,"onConnected", Toast.LENGTH_SHORT).show();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10);
mLocationRequest.setFastestInterval(10);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setSmallestDisplacement(0.1F);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
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.getUiSettings().setMapToolbarEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.setMyLocationEnabled(true);
MarkerOptions marker = new MarkerOptions().position(latlng).title("My Location");
// Changing marker icon
marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
Marker m = mMap.addMarker(marker);
//move camera position and zoom to specified location
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latlng).zoom(8).build();
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
#Override
public void onConnectionSuspended(int i) {
Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
}
#Override
public void onLocationChanged(Location location) {
Log.d("locationtesting", "lat: " + location.getLatitude() + " lon: " + location.getLongitude());
}
}
layout xml for MapsActivity:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:id="#+id/map" tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment" />
Note that you will also need to enable Google Maps in the Google Developer Console, and include Google Play Services in your build.gradle file (update version with the version that you are using):
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.google.android.gms:play-services:7.3.0'
}
The last thing is to set up your AndroidManifest.xml for the Google Maps API v2:
permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but are recommended.
-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
meta-data tags, make sure they are inside the application tag:
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="Your-API-Key" />
First of all, I´ve been searching for an answer for this the whole evening. I have read many of the questions -probably all- asking why OnloCationChanged is not called... nothing helped me.
I have a Fragment that displays a map. I can add markers to it and it also shows the current location of the user correctly. Everything seems to be ok but, I want to zoom in the user´s location and that´s why I need the method "OnLocationChanged" to be called.
Also, locationManager.getLastKnownLocation(provider) returns always null.
I have tested this in a real device.
Here is my configuration, I hope somebody can point me in the right direction.
Thanks
Fragment Class
public class MapMainFragment extends BaseFragment implements LocationListener{
private SupportMapFragment fragment;
private GoogleMap map;
private LocationManager locationManager;
private static final long MIN_TIME = 500;
private static final float MIN_DISTANCE = 0;
String provider;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// LOCATION
locationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
boolean enabledGPS = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean enabledWiFi = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
// Check if enabled and if not send user to the GSP settings
if (!enabledGPS && !enabledWiFi) {
Toast.makeText(mActivity, "GPS signal not found", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
// Define the criteria how to select the location provider -> use
// default
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
// Initialize the location fields
if (location != null) {
Toast.makeText(mActivity, "Selected Provider " + provider,
Toast.LENGTH_SHORT).show();
onLocationChanged(location);
}
locationManager.requestLocationUpdates(provider, MIN_TIME, MIN_DISTANCE, this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.app_tab_b_second_screen, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map, fragment).commit();
}
}
#Override
public void onResume() {
super.onResume();
map = fragment.getMap();
// Enabling MyLocation Layer of Google Map
map.setMyLocationEnabled(true);
// Add Marker
final LatLng TEST_MARKER = new LatLng(50.34927, 6.26887);
map.addMarker(new MarkerOptions()
.position(TEST_MARKER)
.title("Title")
.snippet("Sheeps: 4,137,400")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
}
#Override
public void onLocationChanged(Location location) {
Log.e("onLocationChanged", "called");
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 10);
map.animateCamera(cameraUpdate);
locationManager.removeUpdates(this);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) { }
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(mActivity, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(mActivity, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
BaseFragment class
public class BaseFragment extends Fragment {
public AppMainTabActivity mActivity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = (AppMainTabActivity) this.getActivity();
}
public boolean onBackPressed(){
return false;
}
public void onActivityResult(int requestCode, int resultCode, Intent data){
}
}
Manifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
I think in your onlocation change it runs but the you remove the updates and it doesn't run any more
Comment out this line in onlocationchanged
locationManager.removeUpdates(this);
And your getbestprovider method use true instead of false