My geofence is trigering actions once when i open map. Basically i want it to show a toast and make a button visible once i enter a circle and show a toast and make a button invisible once i leave the circle. I can't find a solution so maybe you guys can help.
Here's my code:
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback, Geofence {
#Override
public void onMapReady(GoogleMap googleMap) {
Toast.makeText(this, "Map is Ready", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onMapReady: Map is ready");
mMap = googleMap;
if (mLocationPermissionsGranted) {
try {
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(
this, R.raw.mapstyle));
if (!success) {
Log.e(TAG, "Style parsing failed.");
}
} catch (Resources.NotFoundException e) {
Log.e(TAG, "Can't find style. Error: ", e);
}
getDeviceLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
}
for (LatLng latLng : InfoArea) {
mMap.addCircle(new CircleOptions()
.center(latLng)
.radius(5)
.strokeColor(0xffff0000)
.fillColor(0x44ff0000)
.strokeWidth(1));
}
Geofencesetup(); //calling geofence setup
}
private static final String TAG = "MapActivity";
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int PERMISSION_CODE = 1234;
private static final float DEFAULT_ZOOM = 15f;
//vars
private Boolean mLocationPermissionsGranted = false;
private GoogleMap mMap;
private FusedLocationProviderClient mFusedLocationProviderClient;
private List<LatLng> InfoArea;
private String GEOFENCE_KEY = "451";
PendingIntent pendingIntent;
GeofencingClient geofencingClient;
Button infobut;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
getLocationPermission();
pendingIntent = PendingIntent.getBroadcast(this,0,
new Intent(".ACTION_RECEIVE_GEOFENCE"),PendingIntent.FLAG_UPDATE_CURRENT);
geofencingClient = LocationServices.getGeofencingClient(this);
infobut = findViewById(R.id.Speak);
}
private void getDeviceLocation() {
Log.d(TAG, "getDeviceLocation: getting the current location");
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
try {
if (mLocationPermissionsGranted) {
final Task location = mFusedLocationProviderClient.getLastLocation();
location.addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.isSuccessful()) {
Log.d(TAG, "onComplete: found location!");
final Location currentLocation = (Location) task.getResult();
moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),
DEFAULT_ZOOM);
} else {
Log.d(TAG, "onComplete: current location is null");
Toast.makeText(MapActivity.this, "unable to get current location", Toast.LENGTH_SHORT).show();
}
}
});
}
} catch (SecurityException e) {
Log.e(TAG, "getDeviceLocation: SecurityException: " + e.getMessage());
}
}
private void moveCamera(LatLng latLng, float zoom) {
Log.d(TAG, "moveCamera: moving camera to: lat: " + latLng.latitude + ", lng: " + latLng.longitude);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
}
private void initMap() {
Log.d(TAG, "initMap: initializing map");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(MapActivity.this);
initArea();
}
private void initArea() {
InfoArea = new ArrayList<>();
InfoArea.add(new LatLng(54.021410, 23.954885));
}
private void Geofencesetup(){ //Part of the problem
Geofence.Builder geofencecreator = new Geofence.Builder();
geofencecreator.setRequestId(GEOFENCE_KEY);
geofencecreator.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT);
geofencecreator.setCircularRegion(54.021410, 23.954885, 10); //latlng and radius of the circle
geofencecreator.setExpirationDuration(Geofence.NEVER_EXPIRE);
GeofencingRequest.Builder geoBuilder = new GeofencingRequest.Builder();
geoBuilder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_EXIT);
geoBuilder.addGeofence(geofencecreator.build());
Task task = geofencingClient.addGeofences(geoBuilder.build(), pendingIntent);
task.addOnSuccessListener(new OnSuccessListener() {
#Override
public void onSuccess(Object o) {
Log.i(TAG,"You're inside the zone");
activityinsidecircleMaker();
}
});
task.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.i(TAG,"You're outside the zone");
activityoutsidecircleMaker();
}
});
} //................................................................................
private void activityinsidecircleMaker(){ //the toast and the button i want it to show when user is inside a circle
Toast.makeText(this,"You're inside a circle",Toast.LENGTH_SHORT).show();
infobut.setVisibility(View.VISIBLE);
}
private void activityoutsidecircleMaker(){ //the toast and the button i want it to show when user is outside a circle(in this case button should become invisible)
Toast.makeText(this,"You are now outside the circle",Toast.LENGTH_SHORT).show();
infobut.setVisibility(View.INVISIBLE);
}//.............................................................................................
private void getLocationPermission() {
Log.d(TAG, "getLocationPermission: getting location permissions");
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionsGranted = true;
initMap();
} else {
ActivityCompat.requestPermissions(this,
permissions,
PERMISSION_CODE);
}
} else {
ActivityCompat.requestPermissions(this,
permissions,
PERMISSION_CODE);
}
}
#Override
public String getRequestId() {
return null;
}
The actions that i want my program to do when user is inside or outside the circle are marked like this: //......... , so you guys could see it better. Also i think that is where the problem actually is i just can't find a way to solve it
Related
'''
public class GpsActivity extends FragmentActivity implements OnMapReadyCallback {
private static final int PRIORITY_HIGH_ACCURACY = 100;
private GoogleMap mMap;
private static final int PERMISSIONS_FINE_LOCATION = 99;
Location loc;
LatLng curPo;
boolean state = false;
private LocationRequest locationRequest;
private FusedLocationProviderClient fusedLocationProviderClient;
Button rstart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationRequest = LocationRequest.create()
.setInterval(5000)
.setPriority(PRIORITY_HIGH_ACCURACY)
.setSmallestDisplacement(5);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(locationRequest);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(GpsActivity.this);
setContentView(R.layout.activity_gps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
rstart = findViewById(R.id.rstart);
rstart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
changeState();
}
});
askforPermission();
}
#SuppressLint("MissingPermission")
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if(checkPermission()){
mMap.setMyLocationEnabled(true);
}
mMap.getUiSettings().setMyLocationButtonEnabled(true);
}
#Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart");
if (checkPermission()) {
Log.d(TAG, "onStart : call mFusedLocationClient.requestLocationUpdates");
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, null);
if (mMap!=null)
mMap.setMyLocationEnabled(true);
}
}
#Override
protected void onStop() {
super.onStop();
if(fusedLocationProviderClient != null){
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
}
}
// Methods
private void askforPermission(){
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED){
LocationCallback mCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
for(Location location : locationResult.getLocations()){
setCurrentLocation(location);
}
}
};
fusedLocationProviderClient.requestLocationUpdates(locationRequest,mCallback,null);
fusedLocationProviderClient.removeLocationUpdates(mCallback);
}else{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_FINE_LOCATION);
}
}
}
private boolean checkPermission() {
int hasFineLocationPermission = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION);
int hasCoarseLocationPermission = ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION);
if (hasFineLocationPermission == PackageManager.PERMISSION_GRANTED &&
hasCoarseLocationPermission == PackageManager.PERMISSION_GRANTED ) {
return true;
}
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case PERMISSIONS_FINE_LOCATION:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
askforPermission();
}else{
Toast.makeText(this,"this App requires permission for gps", Toast.LENGTH_SHORT).show();
finish();
}
}
}
public void setCurrentLocation(Location location) {
LatLng startLatLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(startLatLng, 15);
mMap.moveCamera(cameraUpdate);
//mMap.addMarker(new MarkerOptions().position(currentLatLng)); //확인용
}
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
List<Location> savedLocation = locationResult.getLocations();
if(savedLocation.size() > 0){
loc = savedLocation.get(savedLocation.size() - 1);
curPo = new LatLng(loc.getLatitude(), loc.getLongitude());
String curPoLog = "Lat: " + loc.getLatitude() + "Long: " + loc.getLongitude();
Log.d(TAG,"OnLocationResult: " + curPoLog);
setCurrentLocation(loc);
}
}
};
public void changeState() {
if(!state){
mMap.clear();
state = true;
Toast.makeText(this, "Recording Start", Toast.LENGTH_SHORT).show();
if(state && checkPermission()){
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
addMarkerSingle();
}
rstart.setText("Stop");
}else{
state = false;
Toast.makeText(this, "Recording Stop", Toast.LENGTH_SHORT).show();
if(!state) {
addMarkerSingle();
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
}
rstart.setText("Start");
}
}
public void addMarkerSingle(){
if(checkPermission()){
fusedLocationProviderClient.getLastLocation()
.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
double markerLat = location.getLatitude();
double markerLong = location.getLongitude();
LatLng startEnd = new LatLng(markerLat, markerLong);
mMap.addMarker(new MarkerOptions().position(startEnd));
}
});
}
}
}
'''
Hi I'm a noob to programming this is my first project after learning 3month and I have no
idea how to make it happen
I want to draw a real time foot print tracking polyline but no matter what I do, it never works I tried to get a LatLng and draw a polyline from inside LocationCallback and I also tried making a new Thread to handle it I tried in onCreate, onMapReady and everything but it never works. so I came here to ask how you guys handle these kindda stuff.
I know it's shitty code and I know I suck plz understand, among 3 month of lessons java class went for only 2weeks we never even got to using Thread part, plz help me out.
the code above is code with out any errors. I can check my location on real time and there is start marker and end marker. What I want to do is track the paths I walked and show it with polyline. not after i finish I want it to keep updating real time
Thank you for your time and help
You need to store/cache the list of LatLng you get from LocationCallback.
Create a property
private ArrayList<String> myPath = new ArrayList<>();
Now every time a new location is received in the LocationCallback you add it to the myPath and update your map
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
List<Location> savedLocation = locationResult.getLocations();
if(savedLocation.size() > 0){
loc = savedLocation.get(savedLocation.size() - 1);
curPo = new LatLng(loc.getLatitude(), loc.getLongitude());
String curPoLog = "Lat: " + loc.getLatitude() + "Long: " + loc.getLongitude();
Log.d(TAG,"OnLocationResult: " + curPoLog);
setCurrentLocation(loc);
//add this
myPath.add(loc)
updateMap()
}
}
};
Your updateMap() method might look like this
PolylineOptions polylineOptions = new PolylineOptions();
polylineOptions.addAll(myPath);
polylineOptions.width(10f)
.color(Color.RED)
.geodesic(true);
if(mMap != null {
mMap.addPolyline(polylineOptions);
}
polyLineCollection.addPolyline(polylineOptions)
tempLine.tag = MarkerID(line.id, line.layerId , null)
try this code
//...
LocationCallback locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
List<Location> savedLocation = locationResult.getLocations();
Polyline polyline1 = googleMap.addPolyline(new PolylineOptions()
.clickable(false);
for(int i = 0; i<savedLocation.size; i++){
polyline1.add(new LatLng(savedLocation[i].latitude, savedLocation[i].longitude)));
}
// Store a data object with the polyline, used here to indicate an arbitrary type.
polyline1.setTag("A");
// Style the polyline.
stylePolyline(polyline1);
if(savedLocation.size() > 0){
loc = savedLocation.get(savedLocation.size() - 1);
curPo = new LatLng(loc.getLatitude(), loc.getLongitude());
String curPoLog = "Lat: " + loc.getLatitude() + "Long: " + loc.getLongitude();
Log.d(TAG,"OnLocationResult: " + curPoLog);
setCurrentLocation(loc);
}
}
};
...//
Here is my code:
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,
LocationListener,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
GoogleMap mMap;
SupportMapFragment mapFragment;
LocationRequest mLocationRequest;
GoogleApiClient client;
Location mLastLocation;
Marker mCurrLocationMarker;
LatLng latLongCurrent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
getSupportActionBar().setTitle("Map location");
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
public void findRestaurant(View view) {
StringBuilder stringBuilder = new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
stringBuilder.append("location=" + latLongCurrent.latitude + "," + latLongCurrent.longitude); //error attempt to read from field 'double...on a null object reference
stringBuilder.append("&radius=" + 1000);
stringBuilder.append("&keyword=" + "restaurant");
stringBuilder.append("&key=" + getResources().getString(R.string.google_places_key));
String url = stringBuilder.toString();
Object dataTransfer[] = new Object[2];
dataTransfer[0] = mMap;
dataTransfer[1] = url;
NearbySearch nearbySearch = new NearbySearch(this);
nearbySearch.execute(dataTransfer);
}
#Override
public void onPause() {
super.onPause();
//stop location updates when Activity is no longer active
if (client != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(client, this);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.map_options, menu);
return true;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Initializing the Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
} else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
protected synchronized void buildGoogleApiClient() {
client = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
client.connect();
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(client, mLocationRequest, this);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Change the map type based on the user's selection.
switch (item.getItemId()) {
case R.id.normal_map:
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
return true;
case R.id.hybrid_map:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
return true;
case R.id.satellite_map:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
return true;
case R.id.terrain_map:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("My current Position");
mCurrLocationMarker = mMap.addMarker(markerOptions);
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
private void checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
new AlertDialog.Builder(MapsActivity.this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept this to use the location functionality")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(MapsActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
}
}).create().show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (client == null) {
buildGoogleApiClient();
}
mMap.setMyLocationEnabled(true);
}
} else {
Toast.makeText(this, "Permission is denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}
private void moveCamera(LatLng latLang, float zoom, String title) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLang, zoom));
//writing the code to drop the pin or marker
MarkerOptions options = new MarkerOptions().position(latLang).title(title);
mMap.addMarker(options);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
and this is my class NearbySearch.java code below:
public class NearbySearch extends AsyncTask<Object, String, String> {
GoogleMap mMap;
String url;
InputStream is;
BufferedReader bufferedReader;
StringBuilder stringBuilder;
String data;
public NearbySearch(MapsActivity mapsActivity) {
}
#Override
protected String doInBackground(Object... objects) {
//requesting for the response from the google places API
mMap = (GoogleMap) objects[0];
try {
URL myUrl = new URL(url);
HttpURLConnection httpURLConnection = (HttpURLConnection) myUrl.openConnection();
is = httpURLConnection.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(is));
String line = "";
stringBuilder = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
//Receiving the data from json
data = stringBuilder.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
#Override
protected void onPostExecute(String s) {
try {
JSONObject parentObject = new JSONObject(s);
JSONArray resultArray = parentObject.getJSONArray("results");
for (int i = 0; i < resultArray.length(); i++) {
JSONObject jsonObject = resultArray.getJSONObject(i);
JSONObject locationObject = jsonObject.getJSONObject("geometry").getJSONObject("location");
String latitude = jsonObject.getString("lat");
String longitude = jsonObject.getString("lng");
JSONObject nameObject = resultArray.getJSONObject(i);
String nameRestaurant = nameObject.getString("name");
String vicinity = nameObject.getString("vicinity");
LatLng latLng = new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude));
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.title(vicinity);
markerOptions.position(latLng);
mMap.addMarker(markerOptions);
}
} catch (JSONException e) {
e.printStackTrace();
}
super.onPostExecute(s);
}
}
I'm successfully fetching the user's current location but cannot find the solution to find the nearby restaurants from the current location. Please help to get rid of it as I'm stuck for 2 days here. Kindly tell me if any other solution is there too. Thanks!
Here is my code. I am getting null in googleapiclient.
public class MapsActivity extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener, AdapterView.OnItemClickListener, DriverListner {
View view;
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private static String TAG = "MAP LOCATION";
Context mContext;
TextView mLocationMarkerText;
private LatLng mCenterLatLong;
private AddressResultReceiver mResultReceiver;
protected String mAddressOutput;
protected String mAreaOutput;
protected String mCityOutput;
protected String mStateOutput;
EditText mLocationAddress;
TextView mLocationText;
private static final int REQUEST_CODE_AUTOCOMPLETE = 1;
AutoCompleteTextView edtDropLocation;
LatLng source;
LatLng destination;
LinearLayout lytBottomView;
private List < DriverDetail > driverDetailsList = new ArrayList < > ();
DriverListAdapter driverListAdapter;
RecyclerView rv_driver_truck;
DriverDetail driverDetail;
Button book;
int driverId = 0, userId = 0;
String currentLocation = "", dropLocation = "", currentLat = "", currentLong = "", dropLat = "", dropLong = "", token = "",
vehicleId = "", bookingDateTime = "", truckRent = "";
private LocationRequest mLocationRequest;
Date currentTime;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_maps, container, false);
SupportMapFragment mapFragment = (SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map);
userId = Integer.parseInt(TruckApplication.ReadStringPreferences(SharedPrefData.PREF_UserId));
token = TruckApplication.ReadStringPreferences(SharedPrefData.PREF_TOKEN);
currentTime = Calendar.getInstance().getTime();
Log.e("##dateandtime", String.valueOf(currentTime));
mLocationMarkerText = view.findViewById(R.id.locationMarkertext);
rv_driver_truck = view.findViewById(R.id.rv_driver_truck);
mLocationAddress = view.findViewById(R.id.Address);
mLocationText = view.findViewById(R.id.Locality);
edtDropLocation = view.findViewById(R.id.edtDropLocation);
lytBottomView = view.findViewById(R.id.lytBottomView);
book = view.findViewById(R.id.book);
edtDropLocation.setAdapter(new MapFragment.GooglePlacesAutocompleteAdapter(getActivity(), R.layout.list_item_text));
edtDropLocation.setOnItemClickListener(this);
mLocationText.setOnClickListener(view - > openAutocompleteActivity());
mapFragment.getMapAsync(this);
if (checkPlayServices()) {
if (!AppUtils.isLocationEnabled(getContext())) {
AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
dialog.setMessage("Location not enabled!");
dialog.setPositiveButton("Open location settings", (paramDialogInterface, paramInt) - > {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
});
dialog.setNegativeButton("Cancel", (paramDialogInterface, paramInt) - > {});
dialog.show();
}
buildGoogleApiClient();
} else {
Toast.makeText(mContext, "Location not supported in this device", Toast.LENGTH_SHORT).show();
}
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
rv_driver_truck.setLayoutManager(linearLayoutManager);
rv_driver_truck.setItemAnimator(new DefaultItemAnimator());
getDriverList();
book.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendBookRequest();
}
});
mResultReceiver = new AddressResultReceiver(new Handler());
return view;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnCameraChangeListener(cameraPosition - > {
Log.d("##Camera postion change" + "", cameraPosition + "");
mCenterLatLong = cameraPosition.target;
mMap.clear();
try {
Location mLocation = new Location("");
mLocation.setLatitude(mCenterLatLong.latitude);
mLocation.setLongitude(mCenterLatLong.longitude);
currentLat = String.valueOf(mCenterLatLong.latitude);
currentLong = String.valueOf(mCenterLatLong.longitude);
startIntentService(mLocation);
mLocationMarkerText.setText(getCompleteAddressString(mLocation.getLatitude(), mLocation.getLongitude()));
} catch (Exception e) {
e.printStackTrace();
}
});
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
}
#Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
changeMap(mLastLocation);
Log.d(TAG, "ON connected");
} else
try {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
} catch (Exception e) {
e.printStackTrace();
}
try {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
try {
if (location != null)
changeMap(location);
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.build();
}
#Override
public void onStart() {
super.onStart();
try {
mGoogleApiClient.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onStop() {
super.onStop();
try {
} catch (RuntimeException e) {
e.printStackTrace();
}
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getContext());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {}
return false;
}
return true;
}
private void changeMap(Location location) {
Log.d(TAG, "Reaching map" + mMap);
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (mMap != null) {
mMap.getUiSettings().setZoomControlsEnabled(false);
LatLng latLong;
latLong = new LatLng(location.getLatitude(), location.getLongitude());
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLong).zoom(10 f).tilt(50).build();
mMap.setMyLocationEnabled(true);
/* mMap.getUiSettings().setMyLocationButtonEnabled(true);*/
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
// mLocationMarkerText.setText("Lat : " + location.getLatitude() + "," + "Long : " + location.getLongitude());
getCompleteAddressString(location.getLatitude(), location.getLongitude());
mLocationMarkerText.setText(getCompleteAddressString(location.getLatitude(), location.getLongitude()));
startIntentService(location);
} else {
Toast.makeText(getContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
#Override
public void onItemClick(AdapterView << ? > parent, View view, int position, long id) {
String str = (String) parent.getItemAtPosition(position);
Toast.makeText(getActivity(), str, Toast.LENGTH_SHORT).show();
LatLng lastLocation = source;
edtDropLocation.setText(str);
dropLocation = str;
Geocoder coder = new Geocoder(getContext());
try {
ArrayList < Address > adresses = (ArrayList < Address > ) coder.getFromLocationName(str, 50);
for (Address add: adresses) {
double longitude = add.getLongitude();
double latitude = add.getLatitude();
dropLat = String.valueOf(latitude);
dropLong = String.valueOf(longitude);
destination = new LatLng(latitude, longitude);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(destination);
mMap.clear();
markerOptions.title(str);
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.droppoint));
mMap.animateCamera(CameraUpdateFactory.newLatLng(destination));
mMap.addMarker(markerOptions);
getDriverList();
lytBottomView.setVisibility(View.VISIBLE);
driverListAdapter = new DriverListAdapter(getActivity(), driverDetailsList, this);
rv_driver_truck.setAdapter(driverListAdapter);
/* new GetPathFromLocation(lastLocation, destination, new DirectionPointListener() {
#Override
public void onPath(PolylineOptions polyLine) {
mMap.addPolyline(polyLine);
lytBottomView.setVisibility(View.VISIBLE);
}
}).execute();*/
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public DriverDetail driverDetail(DriverDetail driverDetail1) {
driverDetail = driverDetail1;
driverId = driverDetail1.getId();
truckRent = driverDetail1.getVehicleRent();
// Log.e("##DriverId", truckRent);
return driverDetail;
}
class AddressResultReceiver extends ResultReceiver {
public AddressResultReceiver(Handler handler) {
super(handler);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
mAddressOutput = resultData.getString(AppUtils.LocationConstants.RESULT_DATA_KEY);
mAreaOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_AREA);
mCityOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_CITY);
mStateOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_STREET);
displayAddressOutput();
if (resultCode == AppUtils.LocationConstants.SUCCESS_RESULT) {
}
}
}
protected void displayAddressOutput() {
try {
if (mAreaOutput != null)
mLocationAddress.setText(mAddressOutput);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void startIntentService(Location mLocation) {
Intent intent = new Intent(getContext(), FetchAddressIntentService.class);
intent.putExtra(AppUtils.LocationConstants.RECEIVER, mResultReceiver);
intent.putExtra(AppUtils.LocationConstants.LOCATION_DATA_EXTRA, mLocation);
getActivity().startService(intent);
}
private void openAutocompleteActivity() {
try {
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
.build(getActivity());
startActivityForResult(intent, REQUEST_CODE_AUTOCOMPLETE);
} catch (GooglePlayServicesRepairableException e) {
GoogleApiAvailability.getInstance().getErrorDialog(getActivity(), e.getConnectionStatusCode(),
0 /* requestCode */ ).show();
} catch (GooglePlayServicesNotAvailableException e) {
String message = "Google Play Services is not available: " +
GoogleApiAvailability.getInstance().getErrorString(e.errorCode);
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_AUTOCOMPLETE) {
if (resultCode == RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(mContext, data);
LatLng latLong;
latLong = place.getLatLng();
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLong).zoom(19 f).tilt(70).build();
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(mContext, data);
} else if (resultCode == RESULT_CANCELED) {
}
}
#SuppressLint("LongLogTag")
private String getCompleteAddressString(double LATITUDE, double LONGITUDE) {
String strAdd = "";
Geocoder geocoder = new Geocoder(getContext(), Locale.getDefault());
try {
List < Address > addresses = geocoder.getFromLocation(LATITUDE, LONGITUDE, 1);
if (addresses != null) {
Address returnedAddress = addresses.get(0);
StringBuilder strReturnedAddress = new StringBuilder("");
for (int i = 0; i <= returnedAddress.getMaxAddressLineIndex(); i++) {
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n");
}
strAdd = strReturnedAddress.toString();
currentLocation = strAdd;
Log.e("My Current loction address", strReturnedAddress.toString());
} else {
Log.w("My Current loction address", "No Address returned!");
}
} catch (Exception e) {
e.printStackTrace();
Log.w("My Current loction address", "Canont get Address!");
}
return strAdd;
}
private void getDriverList() {
ApiInterface apiInterface = RetrofitManager.getInstance().create(ApiInterface.class);
Call < OnlineDriverList > call = apiInterface.getDriverList();
call.enqueue(new Callback < OnlineDriverList > () {
#Override
public void onResponse(#NonNull Call < OnlineDriverList > call, Response < OnlineDriverList > response) {
// refreshLayout.setRefreshing(false);
if (response.isSuccessful()) {
OnlineDriverList onlineDriverList = response.body();
if (onlineDriverList.getDriverDetails().size() == 0) {
Toast.makeText(getContext(), "No Driver is Available at current Time ", Toast.LENGTH_SHORT).show();
} else {
driverDetailsList = onlineDriverList.getDriverDetails();
TruckBo.getInstance().setDriverArrayList(driverDetailsList);
// driverListAdapter.setData(driverDetailsList);
// refreshLayout.setVisibility(View.VISIBLE);
}
}
}
#Override
public void onFailure(Call < OnlineDriverList > call, Throwable t) {
//refreshLayout.setRefreshing(false);
Log.d("Error", t.getLocalizedMessage());
}
});
}
public void sendBookRequest() {
ApiInterface apiInterface = RetrofitManager.getInstance().create(ApiInterface.class);
Call < UserRegistration > call = apiInterface.booking(driverId, userId, truckRent, currentLocation, dropLocation,
currentLat, currentLong, dropLat, dropLong, token, "", ""
);
call.enqueue(new Callback < UserRegistration > () {
#Override
public void onResponse(Call < UserRegistration > call, Response < UserRegistration > response) {
if (response.isSuccessful()) {
Toast.makeText(getContext(), "Wait For Respond From Driver Side", Toast.LENGTH_SHORT).show();
lytBottomView.setVisibility(View.GONE);
} else {}
}
#Override
public void onFailure(Call < UserRegistration > call, Throwable t) {
Log.e("Error", t.getLocalizedMessage());
}
});
}
}
I am getting null here:
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(getContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.build();
}
The first time it is not going to the current location and I am getting null googleapiclient, and on move marker, I am fetching address in starting I am not getting current location.
I had created a tracking apps using Firebase. The apps have 2 type user log in user's (driver & parent) with different layout and different task.
Driver user will updated their location on Firebase database continuously into their own root of their tree.
Parent user will retrieve the data continuously to be shown on map layout and geofence layout as a latlng for the geofence coordinate.
My problem is on the geofence activity. The button 'Start Geofence' will toast " Geofence Successfully Added " and it is done perfectly. But when I click the button, its seems to get the value of latlng only static position while the data are continuously updated according to the Driver user's location.
I have done testing on mock situation. My friends log in as driver and drive from location A to location B (my location) and I log in as parent to track my friends location. When I click 'Start Geofence' button, the text " Geofence Successfully Added " are successfully toasted. But my geofence alarm not trigerred when my friends are near to location B. But when I click again, the alarm are triggered.
I assume that my geofence only take the CURRENT latlng data when I press/click the button 'Start Geofence', not continuously get updated latlng data from Firebase Database.
Can someone explain me why?
I need to use the location of the driver as my geofence coordinate, so it will be a moving geofence.
Here my ParentsActivity.java
public class ParentActivity extends AppCompatActivity implements ValueEventListener, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<Status> {
private static final String TAG = "ParentActivity";
private Button btnTrack, btnGeofence, signout;
private FirebaseAuth auth;
private DatabaseReference databaseReference;
private GoogleApiClient googleApiClient;
private Location lastLocation;
double lat;
double lng;
LatLng latLng;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Get Firebase auth instance
auth = FirebaseAuth.getInstance();
if (auth.getCurrentUser() == null) {
startActivity(new Intent(ParentActivity.this, LoginActivity.class));
finish();
}
databaseReference = FirebaseDatabase.getInstance().getReference().child("yKlWu19vhqQXfL2tDlBNfMSduMe2");
// set the view now
setContentView(R.layout.activity_parent);
btnTrack = (Button) findViewById(R.id.btn_track);
btnGeofence = (Button) findViewById(R.id.btn_geo);
signout = (Button) findViewById(R.id.sign_out);
btnTrack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(ParentActivity.this, MapsActivity.class));
}
});
signout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
auth.signOut();
finish();
startActivity(new Intent(ParentActivity.this, LoginActivity.class));
}
});
btnGeofence.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startGeofence();
}
});
createGoogleApi();
}
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
lat = dataSnapshot.child("location/latitude").getValue(Double.class);
lng = dataSnapshot.child("location/longitude").getValue(Double.class);
latLng = new LatLng(lat, lng);
}
// Create GoogleApiClient instance
private void createGoogleApi() {
Log.d(TAG, "createGoogleApi()");
if ( googleApiClient == null ) {
googleApiClient = new GoogleApiClient.Builder( this )
.addConnectionCallbacks( this )
.addOnConnectionFailedListener( this )
.addApi( LocationServices.API )
.build();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
#Override
protected void onStart() {
super.onStart();
databaseReference.addValueEventListener(this);
googleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
googleApiClient.disconnect();
}
// GoogleApiClient.ConnectionCallbacks connected
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i(TAG, "onConnected()");
getLastKnownLocation();
}
private void getLastKnownLocation() {
Log.d(TAG, "getLastKnownLocation()");
if ( checkPermission() ) {
lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if ( lastLocation != null ) {
Log.i(TAG, "LasKnown location. " +
"Long: " + lastLocation.getLongitude() +
" | Lat: " + lastLocation.getLatitude());
startLocationUpdates();
} else {
Log.w(TAG, "No location retrieved yet");
startLocationUpdates();
}
}
else askPermission();
}
private LocationRequest locationRequest;
// Defined in mili seconds.
// This number in extremely low, and should be used only for debug
private final int UPDATE_INTERVAL = 1000 * 60;
private final int FASTEST_INTERVAL = 1000 * 30;
// Start location Updates
private void startLocationUpdates(){
Log.i(TAG, "startLocationUpdates()");
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
if ( checkPermission() )
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged ["+location+"]");
lastLocation = location;
}
// Check for permission to access Location
private boolean checkPermission() {
Log.d(TAG, "checkPermission()");
// Ask for permission if it wasn't granted yet
return (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED );
}
// Asks for permission
private void askPermission() {
Log.d(TAG, "askPermission()");
ActivityCompat.requestPermissions(
this,
new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION },
100
);
}
// Verify user's response of the permission requested
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult()");
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch ( requestCode ) {
case 100: {
if ( grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED ){
// Permission granted
getLastKnownLocation();
} else {
// Permission denied
permissionsDenied();
}
break;
}
}
}
// App cannot work without the permissions
private void permissionsDenied() {
Log.w(TAG, "permissionsDenied()");
}
// GoogleApiClient.ConnectionCallbacks suspended
#Override
public void onConnectionSuspended(int i) {
Log.w(TAG, "onConnectionSuspended()");
}
// GoogleApiClient.OnConnectionFailedListener fail
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.w(TAG, "onConnectionFailed()");
}
private static final long GEO_DURATION = 60 * 60 * 1000;
private static final String GEOFENCE_REQ_ID = "My Geofence";
private static final float GEOFENCE_RADIUS_IN_METERS = 300; // in meters
// Create a Geofence
private Geofence createGeofence(double latitude, double longitude, float radius ) {
Log.d(TAG, "createGeofence");
return new Geofence.Builder()
.setRequestId(GEOFENCE_REQ_ID)
.setCircularRegion( latitude, longitude, radius)
.setExpirationDuration( GEO_DURATION )
.setTransitionTypes( Geofence.GEOFENCE_TRANSITION_ENTER
| Geofence.GEOFENCE_TRANSITION_EXIT )
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest( Geofence geofence ) {
Log.d(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger( GeofencingRequest.INITIAL_TRIGGER_ENTER )
.addGeofence( geofence )
.build();
}
private final int GEOFENCE_REQ_CODE = 0;
private PendingIntent createGeofencePendingIntent() {
Intent intent = new Intent( this, GeofenceTransitionIntentService.class);
return PendingIntent.getService(this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT );
}
// Add the created GeofenceRequest to the device's monitoring list
private void addGeofence(GeofencingRequest request) {
Log.d(TAG, "addGeofence");
if (checkPermission())
LocationServices.GeofencingApi.addGeofences(
googleApiClient,
request,
createGeofencePendingIntent()
).setResultCallback(this);
}
#Override
public void onResult(#NonNull Status status) {
Log.i(TAG, "onResult: " + status);
if ( status.isSuccess() ) {
Toast.makeText(getApplicationContext(), "GEOFENCE SUCCESSFUL ADDED", Toast.LENGTH_SHORT).show();
return;
} else {
Toast.makeText(getApplicationContext(), "ERROR", Toast.LENGTH_SHORT).show();
return;// inform about fail
}
}
// Start Geofence creation process
private void startGeofence() {
Log.i(TAG, "startGeofence()");
Geofence geofence = createGeofence(lat, lng, GEOFENCE_RADIUS_IN_METERS );
GeofencingRequest geofenceRequest = createGeofenceRequest( geofence );
addGeofence( geofenceRequest );
}
Here my GeofenceIntentService.java
public class GeofenceTransitionIntentService extends IntentService {
private static final String TAG = "GeofenceTransitionIS";
public GeofenceTransitionIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "onHandleIntent");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
//String errorMessage = GeofenceErrorMessages.getErrorString(this,
// geofencingEvent.getErrorCode());
Log.e(TAG, "Goefencing Error " + geofencingEvent.getErrorCode());
return;
}
// Get the transition type.
int geofenceTransition = geofencingEvent.getGeofenceTransition();
Log.i(TAG, "geofenceTransition = " + geofenceTransition + " Enter : " + Geofence.GEOFENCE_TRANSITION_ENTER + "Exit : " + Geofence.GEOFENCE_TRANSITION_EXIT);
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL){
showNotification("Entered", "Entered the Location");
playAlarm();
Toast.makeText(getApplicationContext(), " Van Nearby", Toast.LENGTH_SHORT).show();
}
else if(geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
Log.i(TAG, "Showing Notification...");
showNotification("Exited", "Exited the Location");
Toast.makeText(getApplicationContext(), "Van Exited", Toast.LENGTH_SHORT).show();
} else {
// Log the error.
showNotification("Error", "Error");
Log.e(TAG, "Error ");
}
}
public void showNotification(String text, String bigText) {
// 1. Create a NotificationManager
NotificationManager notificationManager =
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
// 2. Create a PendingIntent for AllGeofencesActivity
Intent intent = new Intent(getApplicationContext(), ParentActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 3. Create and send a notification
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.icon_a)
.setContentTitle("Notification!")
.setContentText(text)
.setContentIntent(pendingNotificationIntent)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build();
notificationManager.notify(0, notification);
}
private void playAlarm() {
Intent i = new Intent(getBaseContext(), AlarmActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
and here my AlarmActivity.java
public class AlarmActivity extends Activity {
private MediaPlayer mMediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setFinishOnTouchOutside(false);
setContentView(R.layout.activity_alarm);
playAlarm();
}
private void playAlarm() {
mMediaPlayer = MediaPlayer.create(getApplicationContext(),
R.raw.intruder_alarm);
mMediaPlayer.setLooping(true);
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer arg0) {
mMediaPlayer.start();
}
});
}
public void dismissAlarm(View view) {
mMediaPlayer.release();
this.finish();
}
How to draw a route direction from current location to the destination using Google Maps API v2?
public class Trazo_Rutas extends FragmentActivity implements
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap mMap;
GoogleApiClient googleApiClient;
LocationRequest locationRequest;
Location lastLocation;
Marker userLocation;
private static final int Request_User_Location_Code = 99;
PlaceAutocompleteFragment placeAutoComplete;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_trazo__rutas);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkUserLocationPermission();
}
//Check if Google Play Services Available or not
if (!CheckGooglePlayServices()) {
Log.d("onCreate", "Finishing test case since Google Play Services are not available");
finish();
}
else {
Log.d("onCreate","Google Play Services available.");
}
//AutoComplete search bar
placeAutoComplete = (PlaceAutocompleteFragment) getFragmentManager().findFragmentById(R.id.place_autocomplete);
placeAutoComplete.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
Log.d("Maps", "Place selected: " + place.getName());
}
#Override
public void onError(Status status) {
Log.d("Maps", "An error occurred: " + status);
}
});
// 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);
}
private boolean CheckGooglePlayServices() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int result = googleAPI.isGooglePlayServicesAvailable(this);
if(result != ConnectionResult.SUCCESS) {
if(googleAPI.isUserResolvableError(result)) {
googleAPI.getErrorDialog(this, result,
0).show();
}
return false;
}
return true;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
//get latlong for corners for specified place
LatLng corner1 = new LatLng(25.64379, -103.60966);
LatLng corner2 = new LatLng(25.64317, -103.20935);
LatLng corner3 = new LatLng(25.43872, -103.61104);
LatLng corner4 = new LatLng(25.43748, -103.20866);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(corner1);
builder.include(corner2);
builder.include(corner3);
builder.include(corner4);
LatLngBounds bounds = builder.build();
//add them to builder
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
// 20% padding
int padding = (int) (width * 0.20);
//set latlng bounds
mMap.setLatLngBoundsForCameraTarget(bounds);
//move camera to fill the bound to screen
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding));
//set zoom to level to current so that you won't be able to zoom out viz. move outside bounds
mMap.setMinZoomPreference(mMap.getCameraPosition().zoom);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
} else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
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, "Se requieren Permisos de Google", Toast.LENGTH_SHORT).show();
finish();
}
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 (userLocation != null) {
userLocation.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.draggable(true);
markerOptions.title("Tu ubicación");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
userLocation = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16));
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);
}
}
This code is only for adding a marker.
How to draw the direction from current location to destination?
There are multiple ways of doing that..
Using browser, pass source and destination
public void showDirections(View view) {
final Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://maps.google.com/maps?" + "saddr="+ latitude + "," + longitude + "&daddr=" + latitude + "," + longitude));
intent.setClassName("com.google.android.apps.maps","com.google.android.maps.MapsActivity");
startActivity(intent);
}
Using Projection inside map See How to draw straight path between two points. Its not perfect solution for your issue, But you will get idea.