I'm using Google Maps API.
What I want is when I move into some specific location and there is a circle I already have draw on the map, it will then go to another Activity.
So it was like :
my position is a = (X,Y)
Circle position is b = (X,Y) radius = 10
When I'm inside b radius it will go to another Activity or do something.
Any ideas ?
I'm already using distanceTo(), but still haven't succeeded.
Edit: Here is updated code that still is not working for me:
public void onLocationChanged(Location location)
{
float [] distance = new float[];
Location.distanceBetween(location.getLatitude(),location.getLongitude(),-6.xxxxxxx,106.xxxxxxx,distance);
if (distance[0] < 50)
{
Intent i = new Intent(student_activity.this,indoor.class);
student_activity.this,startActivity(i);
}
}
This method setUpMapIfNeeded() is called in onCreate method :
public void circle()
{
Circle circle = mMap.addCircle (new CircleOptions()
.center(new LatLng(-6.xxxxxxx,106.xxxxxxx))
.radius(50)
.strokeColor(Color.RED)
.strokeWidth(1)
.fillColor(Color.RED)
}
You could use geofencing, but if you are simply trying to determine if your current location is within a circle drawn on a map, you could use this technique.
Simply compare the distance from the current location to the center of the circle, and check if the distance is less than the radius.
I answered a similar question here, where you can see more info, and screenshot examples.
Note that the code below uses the depricated onMyLocationChangeListener, but you could use any type of location callback to do this, including FusedLocationProviderApi.
googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
float[] distance = new float[2];
Location.distanceBetween( location.getLatitude(), location.getLongitude(),
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
if( distance[0] < mCircle.getRadius() ){
//current location is within circle
//start new activity
Intent i = new Intent(ThisActivity.this, OtherActivity.class);
ThisActivity.this.startActivity(i);
}
}
});
Edit: Here is a fully working and tested class that uses the FusedLocationApi to get the current location:
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
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.Circle;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends ActionBarActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Circle mCircle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
buildGoogleApiClient();
mGoogleApiClient.connect();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
#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);
circle();
}
public void circle()
{
double radiusInMeters = 50.0;
int strokeColor = 0xffff0000; //red outline
int shadeColor = 0x44ff0000; //opaque red fill
mCircle = mMap.addCircle (new CircleOptions()
.center(new LatLng(37.9614, -122.105))
.radius(radiusInMeters)
.fillColor(shadeColor)
.strokeColor(strokeColor)
.strokeWidth(1));
}
#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());
Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();
float[] distance = new float[2];
Location.distanceBetween( location.getLatitude(), location.getLongitude(),
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
if( distance[0] < mCircle.getRadius() ){
//current location is within circle
//start new activity
Intent i = new Intent(this, OtherActivity.class);
startActivity(i);
}
}
}
Layout xml:
<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" />
Dependencies in build.gradle:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.google.android.gms:play-services:7.0.0'
}
First I did a test without the call to startActivity() just to make sure that my current location was within the circle. As you can see in the screenshot, it was:
Then, I added the call to startActivity() in the onLocationChanged() callback, and it launched OtherActivity immediately after launching the app.
It sounds like describing Google's geofences API
Geofencing tutorial
Related
I need your help.
How can I move the camera on my current position, immediately when I open the app?
I have a button which works (if I click it, it move the camera on my current position), but when I open the app, the camera is set on the middle of the ocean.
I want to open the app and the camera is already set on my current position.
This is my code:
MapsActivity.java
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.common.api.GoogleApi;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
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.OnMapReadyCallback;
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.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private Location lastLocation;
private Marker currentUserLocationMarker;
private static final int Request_User_Location_Code = 99;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
checkUserLocationPermission();
}
// 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;
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
/*disabling toolbar (it is used to continue using this app without having to
use the official google maps app)*/
mMap.getUiSettings().setMapToolbarEnabled(false);
}
public boolean checkUserLocationPermission(){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location_Code );
}
else{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location_Code );
}
return false;
}
else{
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case Request_User_Location_Code:
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
if(googleApiClient == null){
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
}
else{
Toast.makeText(this, "Permesso vietato", Toast.LENGTH_SHORT).show();
}
return;
}
}
protected synchronized void buildGoogleApiClient(){
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
lastLocation = location;
if(currentUserLocationMarker != null){
currentUserLocationMarker.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Posizione corrente");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
currentUserLocationMarker = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(11));
if (googleApiClient != null){
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
locationRequest = new LocationRequest();
locationRequest.setInterval(1100);
locationRequest.setFastestInterval(1100);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
activity_maps.xml:
<?xml version="1.0" encoding="utf-8"?>
<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=".MapsActivity"
class="com.google.android.gms.maps.SupportMapFragment"/>
Already add this in my AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Thanks for your help.
So you have done almost all the work already. You just need to go one step further.
First to understand, setMyLocationEnabled when set to true adds that location compass button on the map. This is what you click to find your current location. Good start.
You also need to set the camera to your current location when you initialize the map.
if(locationPermissionGranted){
Task<Location> locationResult = fusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener(getActivity(), new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
if(task.isSuccessful()){
// Set the maps camera to current location
lastKnownLocation = task.getResult();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()), 12));
}
else{
Log.d(TAG, "Current location is null");
Log.e(TAG,"Exception: %s", task.getException());
map.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLocation, 12));
map.getUiSettings().setMyLocationButtonEnabled(false);
}
}
});
}
Try this. First make sure you have location permissions granted. Then try and find the last known location. (If you are using an emulator try opening Google Maps before trying this code. The location services on an emulator have never been initiated). It will try and grab your current location. If success it moves the camera to that location, if failed I have set a default location for the map to move to instead of opening in the ocean.
private LatLng defaultLocation = new LatLng(41.651031, -83.541939);
Hope this helps.
I think, I solved in this way.
I have modified my onMapReady:
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location arg0) {
float zoomLevel = 15.0f;
LatLng latLng = new LatLng(arg0.getLatitude(), arg0.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoomLevel));
}
});
}
/*disabling toolbar (it is used to continue using this app without having to
use the official google maps app)*/
mMap.getUiSettings().setMapToolbarEnabled(false);
Then, when I open my app, the camera is set on my current location.
Thanks a lot.
[Prerequisite] - Make sure you have location permission granted and location services is turned on.
public void onMapReady(GoogleMap googleMap){
mMap = googleMap;
// You can register for Location Change Once the location is updated,
// Fetch lat, lng from it. Once you have lat,lng convert it into `LatLng`
LatLng currLatLng = fetchedFromAPI();
CameraPosition newPos =
new CameraPosition.Builder()
.target(currLatLng)
.build();
if (showAnimation){
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(newPos));
}else{
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(newPos));
}
}
Instead of LocationManager, I have use LocationServices method to get current gps location and location updates.
this is the code:
public void onConnected(#Nullable Bundle bundle) {
mLocationRequest = new LocationRequest();//PRIORITY_BALANCED_POWER_ACCURACY
mLocationRequest.setInterval(1000*30*1);
mLocationRequest.setFastestInterval(1000*30*1);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest,this);
}
}
public void onLocationChanged(Location location) { mLastLocation = location;
if (mCurrLocationMarker != null)
{
mCurrLocationMarker.remove();
}
//Place current location marker
latLng = new LatLng(location.getLatitude(), location.getLongitude());
lat= location.getLatitude();
log=location.getLongitude();
trim_check_location_change(lat,log);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title(""+s);
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
CurrentLocation = latLng;
}
As I move from from one place to another, blue marker moves accordingly.
however onlocationchanged method never gets called.
I've developed fused location api demo application and utility pack here.
General Utilities
Try it if useful for you. To get location using fused location api, you just have to write following snippet...
new LocationHandler(this)
.setLocationListener(new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// Get the best known location
}
}).start();
And if you want to customise it, simply find documentation here...
https://github.com/abhishek-tm/general-utilities-android/wiki/Location-Handler
Update
I've written a sample code according to your need, try this one...
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
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.Marker;
import in.teramatrix.utilities.service.LocationHandler;
import in.teramatrix.utilities.util.MapUtils;
/**
* Lets see how to use utilities module by implementing location listener.
*
* #author Khan
*/
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, LocationListener {
private GoogleMap map;
private Marker marker;
private LocationHandler locationHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Obtaining an instance of map
FragmentManager manager = getSupportFragmentManager();
SupportMapFragment mapFragment = (SupportMapFragment) manager.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
this.locationHandler = new LocationHandler(this)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(5000)
.setFastestInterval(10000)
.setLocationListener(this);
}
#Override
public void onMapReady(GoogleMap map) {
this.map = map;
this.locationHandler.start();
}
#Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
if (marker == null) {
marker = MapUtils.addMarker(map, latLng, R.drawable.ic_current_location);
map.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14), 500, null);
} else {
marker.setPosition(latLng);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (locationHandler != null) {
locationHandler.stop();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == LocationHandler.REQUEST_LOCATION) {
locationHandler.start();
}
}
}
Hope it will help you.
Basically I am working on Google Map in which I have Google Map Activity and user click on any place of Google Map I was adding marker on this click and I have one button on this button click I take this marker position and put it to my Firebase Database.My complete code was working, but the problem is that when I click on the button which takes marker latlang to Firebase, my latlang value successfully update and my map Activity is re-transited (e.g./i.e. like Intent from current Activity to self Activity) that for my map was reloaded and I lose marker on screen.
Here is my Java code:
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.firebase.client.Firebase;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
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.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class PickUpActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, View.OnClickListener, GoogleMap.OnMapClickListener {
private static final int PERMISSION_REQUEST_CODE = 1;
public double marker_latitude;
public double marker_longitude;
private GoogleMap mMap;
private GoogleApiClient googleApiClient;
private Marker marker;
private double latitude;
private double longitude;
private Button btn;
private Bus bus;
private Firebase ref;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pick_up);
Firebase.setAndroidContext(this);
btn = (Button) findViewById(R.id.btn_pick);
ref = new Firebase(Config.FIREBASE_URL);
bus = new Bus();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mMap = mapFragment.getMap();
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
btn.setOnClickListener(this);
mMap.setOnMapClickListener(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}
#Override
public void onConnected(#Nullable Bundle bundle) {
getCurrentLocation();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
protected void onStart() {
googleApiClient.connect();
super.onStart();
}
#Override
protected void onStop() {
googleApiClient.disconnect();
super.onStop();
}
private void getCurrentLocation() {
if (!checkPermission()) {
requestPermission();
}
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
longitude = location.getLongitude();
latitude = location.getLatitude();
moveMap();
}
}
private void moveMap() {
LatLng latLng = new LatLng(latitude, longitude);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(PickUpActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(PickUpActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
Toast.makeText(PickUpActivity.this, "GPS permission allows us to access location data. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(PickUpActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getCurrentLocation();
} else {
}
break;
}
}
#Override
public void onClick(View v) {
if (v == btn) {
if (marker == null) {
Toast.makeText(PickUpActivity.this, "Please Select Any Place", Toast.LENGTH_SHORT).show();
} else {
bus.setlatitude(marker_latitude);
bus.setlongitude(marker_longitude);
ref.child("school1").child("bus1").child("parents").child("parent01").child("pickuppoint").setValue(bus);
Toast.makeText(PickUpActivity.this, "Pick Up Point Set", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onMapClick(LatLng latLng) {
mMap.clear();
marker = mMap.addMarker(new MarkerOptions()
.position(latLng) //setting position
.draggable(true) //Making the marker draggable
.title("" + latLng));
marker_latitude = latLng.latitude;
marker_longitude = latLng.longitude;
}
}
During analysis I found problem in below code:
bus.setlatitude(marker_latitude);
bus.setlongitude(marker_longitude);
ref.child("school1").child("bus1").child("parents").child("parent01").child("pickuppoint").setValue(bus);
If I put some static value on bus.setlatitude() and bus.setlongitude no re-transition occur. I don't know what I am doing wrong and what is solution for this problem.
if your user click on your Map the map will be cleared: mMap.clear();
#Override
public void onMapClick(LatLng latLng) {
mMap.addMarker(new MarkerOptions()
.position(latLng) //setting position
.draggable(true) //Making the marker draggable
.title(""+latLng));
marker_latitude = latLng.latitude;
marker_longitude= latLng.longitude;
}
I use the Google Maps API in my Android app and locate the user with
LocationManager and getLongitude(), getLatitude().
But now there have to be strange settings on the mobile phone to get a map. The location setting has to be changed to only use GPS, and even then it's not working all the time, sometimes the map is not loaded. If not loaded the app shuts down at the point the first marker is set because of NullPointerException.
Why is this and how can I prevent it?
I already tried with getMapAsync but it didn't help.
GoogleMap googleMap;
LocationManager locationManager;
String provider;
Criteria criteria;
Location myLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_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);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, true);
myLocation = locationManager.getLastKnownLocation(provider);
double latitude = myLocation.getLatitude();
double longitude = myLocation.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(14));
iconDone = R.drawable.markerdone;
icon = R.drawable.marker;
}
catch(Exception e) {
e.printStackTrace();
}
Marker marker1 = googleMap.addMarker(new MarkerOptions()
.position(new LatLng(49.793012, 9.926201))
.title(getString(R.string.Title1))
.snippet("")
.icon(BitmapDescriptorFactory.fromResource(icon)));
The problem is that you're calling getLastKnownLocation(), which will frequently return a null Location, since it doesn't explicitly request a new location lock.
So, when your app is crashing, it's due to a NullPointerException when trying to de-reference the Location object.
It's best to request location updates, and if you only need one, just un-register for location updates once the first onLocationChanged() callback comes in.
Here is an example using the FusedLocationProvider API, which automatically uses Network Location as well as GPS Location if needed:
Relevant imports for the Activity:
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
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.OnMapReadyCallback;
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.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
Activity:
public class MainActivity extends AppCompatActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
GoogleMap googleMap;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Marker marker;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buildGoogleApiClient();
mGoogleApiClient.connect();
}
#Override
protected void onResume() {
super.onResume();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(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 onMapReady(GoogleMap map) {
googleMap = map;
setUpMap();
}
public void setUpMap() {
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
#Override
public void onConnected(Bundle bundle) {
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);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
//unregister location updates
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
//remove previously placed Marker
if (marker != null) {
marker.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
//place marker where user just clicked
marker = googleMap.addMarker(new MarkerOptions()
.position(latLng)
.title("Current Location")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLng).zoom(5).build();
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
build.gradle (change to whatever version of Google Play Services you are currently 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.5.0'
}
SupportMapFragment in the layout xml (you can use a MapFragment as well):
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Using only Network Location:
The Map moves to the current location seconds after launch:
Im developing an app using Google Maps v2 for Android and I managed to put a custom icon to the user's position but I can't remove the default one, so it overlays my custom icon like in the image:
(It is that big just for now :p )
My code is like:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
map.setMyLocationEnabled(true);
map.setOnMyLocationChangeListener(new OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
if (location == null)
return;
mPositionMarker = map.addMarker(new MarkerOptions()
.flat(true)
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.logop1))
.anchor(0.5f, 1f)
.position(new LatLng(location.getLatitude(), location.getLongitude())));
}
});
}
So:
1) Is there a way to remove the default blue dot of user's current location?
2) Will the user location be updated when I move in the "real world" (I cant test it for conectivity reasons) or do I have to write/override a method to update users position?
Thanks in advance
You will have to stop using GoogleMap.setMyLocationEnabled and write a bit more code, including having your own LocationClient and adding Circle for accuracy.
You have to do that on your own.
- set to false gmaps.getUiSettings().setMyLocationButtonEnabled(false);
create your own location button
if you get your current location, set a marker with your icon on that
if you click on your location button, move the camera and center it to the map
That will remove the blue dot
map.setMyLocationEnabled(true); remove line
Thanks joao2fast4u (lol) and ṁᾶƔƏň ツ. I followed your recomendations and I managed to make it work. Since I didn't see any answer concrete to this problem I'm posting my solution here:
package com.onsoftwares.ufvquest;
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
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.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapActivity extends ActionBarActivity implements LocationListener, GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener {
private GoogleMap map;
private Marker mPositionMarker;
private LocationClient mLocationClient;
private LocationRequest mLocationRequest;
private LatLng mLatLng;
private boolean mUpdatesRequested = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
mLocationClient = new LocationClient(this, this, this);
mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the interval ceiling to one minute
mLocationRequest.setFastestInterval(1000);
// Note that location updates are off until the user turns them on
mUpdatesRequested = false;
}
#Override
protected void onStart() {
super.onStart();
mLocationClient.connect();
};
#Override
protected void onStop() {
if (mLocationClient.isConnected()) {
mLocationClient.removeLocationUpdates(this);
mLocationClient.disconnect();
}
super.onStop();
};
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle arg0) {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
// Get the current location
Location currentLocation = mLocationClient.getLastLocation();
// Display the current location in the UI
if (currentLocation != null) {
LatLng currentLatLng = new LatLng (currentLocation.getLatitude(), currentLocation.getLongitude());
if (mPositionMarker == null) {
mPositionMarker = map.addMarker(new MarkerOptions()
.position(currentLatLng)
.title("Eu")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.male_user_marker)));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15));
} else
mPositionMarker.setPosition(currentLatLng);
}
}
}