I have implemented a map that behaves like Uber app i.e pin in center and map drags under the pin and the pin gets the location from map. But I am not able to implement the touch event for toggling the action bar just exactly Uber do. Please help me to implement that feature. First I have used support map fragment but to set touch events a view was required so later on I used MapView.Below is my code:
package com.example.myfastapp;
import java.util.List;
import java.util.Locale;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.IntentSender.SendIntentException;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
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.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.SupportMapFragment;
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;
public class mapFragment extends Fragment implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
MapView mapView;
//private View touch;
private GoogleMap map;
private LatLng center;
private LatLng currentpoint;
private Geocoder geocoder;
private List<Address> addresses;
double latitude;
double longitude;
protected Context context;
SupportMapFragment mf;
View v;
private static final CharSequence[] MAP_TYPE_ITEMS = { "Road Map",
"Satellite", "Terrain" };
// A request to connect to Location Services
private LocationRequest mLocationRequest;
private TextView markerText, Address;
private LinearLayout markerLayout;
private GoogleApiClient mGoogleApiClient;
boolean mUpdatesRequested = false;
private GPSTracker gps;
// Milliseconds per second
public static final int MILLISECONDS_PER_SECOND = 1000;
// The update interval
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
// A fast interval ceiling
public static final int FAST_CEILING_IN_SECONDS = 1;
// Update interval in milliseconds
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = MILLISECONDS_PER_SECOND
* UPDATE_INTERVAL_IN_SECONDS;
// A fast ceiling of update intervals, used when the app is visible
public static final long FAST_INTERVAL_CEILING_IN_MILLISECONDS = MILLISECONDS_PER_SECOND
* FAST_CEILING_IN_SECONDS;
public mapFragment(Context context) {
super();
this.context = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.mapfragment, container, false);
// v.setOnDragListener(new MyDragListener());
mapView = (MapView)v.findViewById(R.id.mapview);
mapView.onCreate(savedInstanceState);
ImageButton mapType = (ImageButton) v.findViewById(R.id.mapType);
mapType.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showMapTypeSelectorDialog();
}
});
ImageButton myLocationCustomButton = (ImageButton)v.findViewById(R.id.myLocationCustom);
myLocationCustomButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
gps = new GPSTracker(getActivity());
gps.canGetLocation();
latitude = gps.getLatitude();
longitude = gps.getLongitude();
currentpoint = new LatLng(latitude, longitude);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(currentpoint, 18);
map.animateCamera(cameraUpdate);
map.setMyLocationEnabled(true);
}
});
markerText = (TextView) v.findViewById(R.id.locationMarkertext);
Address = (TextView) v.findViewById(R.id.adressText);
markerLayout = (LinearLayout) v.findViewById(R.id.locationMarker);
// Getting Google Play availability status
int status = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(context);
if (status != ConnectionResult.SUCCESS) { // Google Play Services are
// not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status,
getActivity(), requestCode);
dialog.show();
} else {
// Google Play Services are available
// Getting reference to the SupportMapFragment
// Create a new global location parameters object
mLocationRequest = LocationRequest.create();
/*
* Set the update interval
*/
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
// Use high accuracy
mLocationRequest
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the interval ceiling to one minute
mLocationRequest
.setFastestInterval(FAST_INTERVAL_CEILING_IN_MILLISECONDS);
// Note that location updates are off until the user turns them on
mUpdatesRequested = false;
/*
* Create a new location client, using the enclosing class to handle
* callbacks.
*/
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
}
return v;
}
public void toggleActionBar()
{
ActionBar ab = getActivity().getActionBar();
if (ab != null)
{
if (ab.isShowing())
{
ab.hide();
}
else
{
if(!ab.isShowing())
{
ab.show();
}
}
}
}
private void setupMap() {
try {
/*map = ((SupportMapFragment) this.getChildFragmentManager()
.findFragmentById(R.id.map)).getMap();*/
map = mapView.getMap();
// Enabling MyLocation in Google Map
map.setMyLocationEnabled(true);
map.getUiSettings().setZoomControlsEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(false);
map.getUiSettings().setCompassEnabled(false);
map.getUiSettings().setRotateGesturesEnabled(true);
map.getUiSettings().setZoomGesturesEnabled(true);
try {
MapsInitializer.initialize(this.getActivity());
} catch (Exception e) {
e.printStackTrace();
}
PendingResult<Status> result = LocationServices.FusedLocationApi
.requestLocationUpdates(mGoogleApiClient, mLocationRequest,
new LocationListener() {
#Override
public void onLocationChanged(Location location) {
markerText.setText("Location received: "
+ location.toString());
}
});
Log.e("Reached", "here");
result.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
Log.e("Result", "success");
} else if (status.hasResolution()) {
// Google provides a way to fix the issue
try {
status.startResolutionForResult(getActivity(), 100);
} catch (SendIntentException e) {
e.printStackTrace();
}
}
}
});
gps = new GPSTracker(getActivity());
gps.canGetLocation();
latitude = gps.getLatitude();
longitude = gps.getLongitude();
currentpoint = new LatLng(latitude, longitude);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(currentpoint).zoom(16f).tilt(30).bearing(90).build();
map.setMyLocationEnabled(true);
map.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
map.clear();
map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition arg0) {
// TODO Auto-generated method stub
//toggleActionBar();
center = map.getCameraPosition().target;
markerText.setText(" Set your Location ");
map.clear();
markerLayout.setVisibility(View.VISIBLE);
try
{
new GetLocationAsync(center.latitude, center.longitude)
.execute();
} catch (Exception e) {
}
}
});
markerLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
LatLng latLng1 = new LatLng(center.latitude,
center.longitude);
Marker m = map.addMarker(new MarkerOptions()
.position(latLng1)
.title(" Set your Location ")
.snippet("")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.my_location)));
m.setDraggable(true);
markerLayout.setVisibility(View.GONE);
} catch (Exception e) {
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
}
#Override
public void onConnected(Bundle connectionHint) {
setupMap();
}
#Override
public void onConnectionSuspended(int cause) {
}
#Override
public void onLocationChanged(Location location) {
}
private class GetLocationAsync extends AsyncTask<String, Void, String> {
// boolean duplicateResponse;
double x, y;
StringBuilder str;
public GetLocationAsync(double latitude, double longitude) {
// TODO Auto-generated constructor stub
x = latitude;
y = longitude;
}
#Override
protected void onPreExecute() {
Address.setText(" Getting location ");
}
#Override
protected String doInBackground(String... params) {
try {
geocoder = new Geocoder(context, Locale.ENGLISH);
addresses = geocoder.getFromLocation(x, y, 1);
str = new StringBuilder();
if (Geocoder.isPresent()) {
Address returnAddress = addresses.get(0);
String localityString = returnAddress.getLocality();
String city = returnAddress.getCountryName();
String region_code = returnAddress.getCountryCode();
String zipcode = returnAddress.getPostalCode();
str.append(localityString + " ");
str.append(city + " " + region_code + " ");
str.append(zipcode + " ");
}
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(String result) {
try {
Address.setText(addresses.get(0).getAddressLine(0) + ", "
+ addresses.get(0).getAddressLine(1) + " ");
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
/*
* public void addMarker(double lati, double longi) {
*
* LatLng latlng = new LatLng(lati, longi);
*
* MarkerOptions mo = new MarkerOptions(); mo.position(latlng);
* mo.icon(BitmapDescriptorFactory.fromResource(R.drawable.my_location));
* mo.title("My Location:"+ latlng); map.addMarker(mo);
*
* //map.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng,
* 15));//previous code CameraPosition cameraPosition = new
* CameraPosition.Builder() .target(latlng) .zoom(11.0f) .bearing(90) //
* Orientation of the camera to east .tilt(30) // Tilt of the camera to 30
* degrees .build();
* map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
* map.setMyLocationEnabled(true);
* map.getUiSettings().setCompassEnabled(true);
* map.getUiSettings().setZoomControlsEnabled(true);
* //map.setMapType(GoogleMap.MAP_TYPE_NORMAL); }
*/
public void showMapTypeSelectorDialog() {
// Prepare the dialog by setting up a Builder.
final String fDialogTitle = "Select Map Type";
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(fDialogTitle);
// Find the current map type to pre-check the item representing the
// current state.
int checkItem = map.getMapType() - 1;
System.out.print(checkItem);
// Add an OnClickListener to the dialog, so that the selection will be
// handled.
builder.setSingleChoiceItems(MAP_TYPE_ITEMS, checkItem,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item)
{
// Locally create a finalised object.
// Perform an action depending on which item was
// selected.
switch (item)
{
case 1:
map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case 2:
map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
default:
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
dialog.dismiss();
}
});
// Build the dialog and show it.
AlertDialog fMapTypeDialog = builder.create();
fMapTypeDialog.setCanceledOnTouchOutside(true);
fMapTypeDialog.show();
}
#Override
public void onResume()
{
super.onResume();
mapView.onResume();
mapView.getMap();
}
#Override
public void onPause()
{
super.onPause();
mapView.onPause();
}
#Override
public void onLowMemory()
{
super.onLowMemory();
mapView.onLowMemory();
}
}
The onCameraChangeListener is deprecated, but good news is that google has released 3 new listeners.
See: GoogleMap.OnCameraChangeListener
This interface was deprecated.
Replaced by GoogleMap.OnCameraMoveStartedListener, GoogleMap.OnCameraMoveListener and GoogleMap.OnCameraIdleListener. The order in which the deprecated onCameraChange method will be called in relation to the methods in the new camera change listeners is undefined.
I have used these listeners and now i am able get the hold and release event on map.
I believe you should add an onMarkerDragListener to your map object and do your code inside.
map.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
#Override
public void onMarkerDragStart(Marker marker) {
}
#Override
public void onMarkerDrag(Marker marker) {
}
#Override
public void onMarkerDragEnd(Marker marker) {
}
});
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
<ImageButton
android:id="#+id/fabButton"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:background="#drawable/fab_bcg"
android:src="#drawable/ic_favorite_outline_white_24dp"
android:contentDescription="Desc"/>
This is methods for show and hide views
private void hideViews() {
mToolbar.animate().translationY(-mToolbar.getHeight()).setInterpolator(new AccelerateInterpolator(2));
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mFabButton.getLayoutParams();
int fabBottomMargin = lp.bottomMargin;
mFabButton.animate().translationY(mFabButton.getHeight()+fabBottomMargin).setInterpolator(new AccelerateInterpolator(2)).start();
}
private void showViews() {
mToolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
mFabButton.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start();
}
Related
I have a MapsActivity Class, where it starts at a fixed point set on the map. I'm calling a Thread, where Map is only fully loaded, when the return is true. (I'll do a search on a DB through the Web Service where it will return me Lat and Long values to play on the map, and that value will be changed every 15 seconds).
I needed to know, how do I change the position of a Marker out of the class onMapReady.
Follows the MapsActivity class
package com.example.patrickcamargo.myapplication.Maps;
import android.app.ProgressDialog;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.annotation.NonNull;
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.location.FusedLocationProviderClient;
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.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;
import com.google.android.gms.tasks.OnSuccessListener;
public class MapsActivity extends SupportMapFragment implements GoogleMap.OnMyLocationButtonClickListener, OnMapReadyCallback,
ActivityCompat.OnRequestPermissionsResultCallback, GoogleMap.OnMapClickListener {
private GoogleMap mMap;
Marker marker;
LatLng latLng = new LatLng(-23.497444, -47.440722);
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
private FusedLocationProviderClient mFusedLocationClient;
public Double latitude, longitude;
public ProgressDialog getProgress() {
return progress;
}
public void setProgress(ProgressDialog progress) {
this.progress = progress;
}
private ProgressDialog progress;
boolean teste = true;
boolean teste2 = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getMapAsync(this);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
mFusedLocationClient.getLastLocation().addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
Toast toast = Toast.makeText(getContext(),"LAT: " + location.getLatitude() + "LONG: " + location.getLongitude(),Toast.LENGTH_LONG);
toast.show();
}
}
});
//TESTE DE EVENTO
progress = new ProgressDialog(getContext());
progress.setMessage("AGUARDE ENQUANTO IDENTIFICAMOS O SERVIÇO...");
progress.show();
progress.setCanceledOnTouchOutside(false);
ThreadCarregarChamado threadCarregarChamado = new ThreadCarregarChamado();
threadCarregarChamado.setMapsActivity(this);
threadCarregarChamado.start();
//CRIADO UM LOOP INFINITO, PARA QUE SÓ SEJA CARREGADO O MAPA TOTALMENTE, QUANDO O RETORNO DO CHAMADO JÁ TIVER UM FUNCIONARIO DISPONIVEL
//E TAMBEM VINCULADO COM ESSE CHAMADO QUE FOI ABERTO
//ENQUANTO NÃO FOR VINCULADO UM FUNCIONARIO, NÃO IRA SER EXECUTADO DAQUI PRA FRENTE
while (teste);
//onMapReady(mMap);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
enableMyLocation();
mMap = googleMap;
mMap.setOnMapClickListener(this);
// Add a marker in Sydney and move the camera
marker = mMap.addMarker(new MarkerOptions()
.position(latLng)
.title("Testando")
.snippet("Population: 776733"));
}
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
PermitirLocalizacao.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
android.Manifest.permission.ACCESS_FINE_LOCATION, true);
} else if (mMap != null) {
mMap.setMyLocationEnabled(true);//BOTÃO PARA MUDAR CAMERA PARA POSIÇÃO ATUAL}
LatLng latLng = new LatLng(latitude, longitude);
//mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); JOGA O ZOOM DIRETO NA POSIÇÃO ATUAL DO CLIENTE
//mMap.animateCamera(CameraUpdateFactory.zoomTo(80));
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) {
return;
}
if (PermitirLocalizacao.isPermissionGranted(permissions, grantResults,
android.Manifest.permission.ACCESS_FINE_LOCATION)) {
enableMyLocation();
} else {
//resume.mPermissionDenied = true;
}
}
#Override
public boolean onMyLocationButtonClick() {
return false;
}
#Override
public void onMapClick(LatLng latLng) {
Toast toast = Toast.makeText(getContext(),"Coordenadas: " + latLng.toString(),Toast.LENGTH_LONG);
toast.show();
}
public void MarcarGuincho()
{
teste=false;
marker.setPosition(new LatLng(-25.63356, -47.440722));
//latLng = (-23.497444, -47.440722);
}
}
Now my Thread
package com.example.patrickcamargo.myapplication.Maps;
import android.app.ProgressDialog;
import android.content.Context;
import com.example.patrickcamargo.myapplication.Conexao;
import com.example.patrickcamargo.myapplication.ConexaoInterface;
import org.json.JSONException;
public class ThreadCarregarChamado extends Thread implements ConexaoInterface{
private ProgressDialog progress;
private Context context;
Conexao conexao;
public MapsActivity getMapsActivity() {
return mapsActivity;
}
public void setMapsActivity(MapsActivity mapsActivity) {
this.mapsActivity = mapsActivity;
}
private MapsActivity mapsActivity;
#Override
public void run() {
//conexao = new Conexao(context, this, "ThreadCarregarChamado.java");
//conexao.execute("teste.php?","");
try {
depoisDownload("OK");
Thread.sleep(5000);
} catch (JSONException e) {
} catch (InterruptedException e) {
}
}
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
#Override
public void depoisDownload(String result) throws JSONException {
if(result.equals("FALSE\r"))
{
run();
}
else {
mapsActivity.MarcarGuincho();
ProgressDialog progress;
progress = mapsActivity.getProgress();
progress.dismiss();
mapsActivity.setProgress(progress);
}
}
}
In the MarcarGuincho class, this is where I need to change the position of the marker set above, but it is giving me as null for me, so this is giving error ...
Error in this line
marker.setPosition(new LatLng(-25.63356, -47.440722));
Logcat
10-02 13:29:43.628 29584-30901/com.example.patrickcamargo.myapplication E/AndroidRuntime: FATAL EXCEPTION: Thread-240709
Process: com.example.patrickcamargo.myapplication, PID: 29584
com.google.maps.api.android.lib6.common.apiexception.c: Not on the main thread
at com.google.maps.api.android.lib6.common.k.b(:com.google.android.gms.DynamiteModulesB#11517436:11)
at com.google.maps.api.android.lib6.common.p.a(:com.google.android.gms.DynamiteModulesB#11517436:5)
at com.google.maps.api.android.lib6.impl.cz.c(:com.google.android.gms.DynamiteModulesB#11517436:176)
at com.google.android.gms.maps.model.internal.q.onTransact(:com.google.android.gms.DynamiteModulesB#11517436:18)
at android.os.Binder.transact(Binder.java:387)
at com.google.android.gms.internal.zzed.zza(Unknown Source)
at com.google.android.gms.maps.model.internal.zzr.getPosition(Unknown Source)
at com.google.android.gms.maps.model.Marker.getPosition(Unknown Source)
at com.example.patrickcamargo.myapplication.Maps.MapsActivity.MarcarGuincho(MapsActivity.java:148)
at com.example.patrickcamargo.myapplication.Maps.ThreadCarregarChamado.depoisDownload(ThreadCarregarChamado.java:55)
at com.example.patrickcamargo.myapplication.Maps.ThreadCarregarChamado.run(ThreadCarregarChamado.java:30)
at com.example.patrickcamargo.myapplication.Maps.ThreadCarregarChamado.depoisDownload(ThreadCarregarChamado.java:60)
at com.example.patrickcamargo.myapplication.Maps.ThreadCarregarChamado.run(ThreadCarregarChamado.java:30)
at com.example.patrickcamargo.myapplication.Maps.ThreadCarregarChamado.depoisDownload(ThreadCarregarChamado.java:60)
at com.example.patrickcamargo.myapplication.Maps.ThreadCarregarChamado.run(ThreadCarregarChamado.java:30)
Line 148 = marker.remove();
Try using
teste = false;
LatLng latLng1 = new LatLng(-25.63356, -47.440722);
if(marker != null)
{
marker.remove();
marker = mMap.addMarker(new MarkerOptions()
.position(latLng1)
.title("Testando")
.snippet("Population: 776733"));
}
I am trying to use Geofire to store and display the users that are logged in on a map i am new in android studio
i am getting this error
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.parthtiwari.trace/com.example.parthtiwari.trace.tracking}: java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.maps.model.Circle com.google.android.gms.maps.GoogleMap.addCircle(com.google.android.gms.maps.model.CircleOptions)' on a null object reference
import android.app.AlertDialog;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.FragmentActivity;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import com.firebase.geofire.GeoFire;
import com.firebase.geofire.GeoLocation;
import com.firebase.geofire.GeoQuery;
import com.firebase.geofire.GeoQueryEventListener;
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.*;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import java.util.HashMap;
import java.util.Map;
public class tracking extends FragmentActivity implements
GeoQueryEventListener,OnMapReadyCallback,
GoogleMap.OnCameraChangeListener{
private static final GeoLocation INITIAL_CENTER = new GeoLocation(22.7789,
-78.4017);
private static final int INITIAL_ZOOM_LEVEL = 14;
private static final String GEO_FIRE_DB = "https://trace-
5fa8c.firebaseio.com";
private static final String GEO_FIRE_REF = GEO_FIRE_DB + "/_geofire";
private GoogleMap mMap;
private GoogleMap map;
private Circle searchCircle;
private GeoFire geoFire;
private GeoQuery geoQuery;
private Map<String,Marker> markers;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tracking);
// Obtain the SupportMapFragment and get notified when the map is ready
to be used.
SupportMapFragment mapFragment = (SupportMapFragment)
getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync((OnMapReadyCallback) this);
LatLng latLngCenter = new LatLng(INITIAL_CENTER.latitude,
INITIAL_CENTER.longitude);
this.searchCircle = this.map.addCircle(new
CircleOptions().center(latLngCenter).radius(1000));
this.searchCircle.setFillColor(Color.argb(66, 255, 0, 255));
this.searchCircle.setStrokeColor(Color.argb(66, 0, 0, 0));
this.map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLngCenter,
INITIAL_ZOOM_LEVEL));
this.map.setOnCameraChangeListener(this);
FirebaseOptions options = new FirebaseOptions.Builder().setApplicationId("geofire").setDatabaseUrl(GEO_FIRE_DB).build();
FirebaseApp app = FirebaseApp.initializeApp(this, options);
// setup GeoFire
this.geoFire = new GeoFire(FirebaseDatabase.getInstance(app).getReferenceFromUrl(GEO_FIRE_REF));
// radius in km
this.geoQuery = this.geoFire.queryAtLocation(INITIAL_CENTER, 1);
// setup markers
this.markers = new HashMap<String, Marker>();
}
#Override
protected void onStop() {
super.onStop();
// remove all event listeners to stop updating in the background
this.geoQuery.removeAllListeners();
for (Marker marker: this.markers.values()) {
marker.remove();
}
this.markers.clear();
}
#Override
protected void onStart() {
super.onStart();
// add an event listener to start updating locations again
this.geoQuery.addGeoQueryEventListener(this);
}
#Override
public void onKeyEntered(String key, GeoLocation location) {
// Add a new marker to the map
Marker marker = this.map.addMarker(new MarkerOptions().position(new
LatLng(location.latitude, location.longitude)));
this.markers.put(key, marker);
}
#Override
public void onKeyExited(String key) {
// Remove any old marker
Marker marker = this.markers.get(key);
if (marker != null) {
marker.remove();
this.markers.remove(key);
}
}
#Override
public void onKeyMoved(String key, GeoLocation location) {
// Move the marker
Marker marker = this.markers.get(key);
if (marker != null) {
this.animateMarkerTo(marker, location.latitude, location.longitude);
}
}
#Override
public void onGeoQueryReady() {
}
#Override
public void onGeoQueryError(DatabaseError error) {
new AlertDialog.Builder(this)
.setTitle("Error")
.setMessage("There was an unexpected error querying GeoFire: " +
error.getMessage())
.setPositiveButton(android.R.string.ok, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
// Animation handler for old APIs without animation support
private void animateMarkerTo(final Marker marker, final double lat, final
double lng) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final long DURATION_MS = 3000;
final Interpolator interpolator = new
AccelerateDecelerateInterpolator();
final LatLng startPosition = marker.getPosition();
handler.post(new Runnable() {
#Override
public void run() {
float elapsed = SystemClock.uptimeMillis() - start;
float t = elapsed/DURATION_MS;
float v = interpolator.getInterpolation(t);
double currentLat = (lat - startPosition.latitude) * v +
startPosition.latitude;
double currentLng = (lng - startPosition.longitude) * v +
startPosition.longitude;
marker.setPosition(new LatLng(currentLat, currentLng));
// if animation is not finished yet, repeat
if (t < 1) {
handler.postDelayed(this, 16);
}
}
});
}
private double zoomLevelToRadius(double zoomLevel) {
// Approximation to fit circle into view
return 16384000/Math.pow(2, zoomLevel);
}
#Override
public void onCameraChange(CameraPosition cameraPosition) {
LatLng center = cameraPosition.target;
double radius = zoomLevelToRadius(cameraPosition.zoom);
this.searchCircle.setCenter(center);
this.searchCircle.setRadius(radius);
this.geoQuery.setCenter(new GeoLocation(center.latitude,
center.longitude));
// radius in km
this.geoQuery.setRadius(radius/1000);
}
#Override
public void onMapReady(GoogleMap googleMap) {
}
}
You are requesting the GoogleMap instance asynchronously with this statement:
mapFragment.getMapAsync((OnMapReadyCallback) this);
When the map is available for use, it will be reported to you in this callback:
#Override
public void onMapReady(GoogleMap googleMap) {
}
You need to take all initialization code that uses the map out of your activity's onCreate() method and move it into onMapReady() or methods that are called from onMapReady(). For example:
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
//mMap = googleMap; // not used?
// all the map init stuff
LatLng latLngCenter = new LatLng(INITIAL_CENTER.latitude,
INITIAL_CENTER.longitude);
this.searchCircle = this.map.addCircle(new
CircleOptions().center(latLngCenter).radius(1000));
this.searchCircle.setFillColor(Color.argb(66, 255, 0, 255));
this.searchCircle.setStrokeColor(Color.argb(66, 0, 0, 0));
this.map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLngCenter,
INITIAL_ZOOM_LEVEL));
this.map.setOnCameraChangeListener(this);
}
It's not clear why you are creating another app instance. I don't think Geofire needs it. Try using the default:
//FirebaseOptions options = new FirebaseOptions.Builder().setApplicationId("geofire").setDatabaseUrl(GEO_FIRE_DB).build();
//FirebaseApp app = FirebaseApp.initializeApp(this, options);
// setup GeoFire
this.geoFire = new GeoFire(FirebaseDatabase.getInstance().getReferenceFromUrl(GEO_FIRE_REF));
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 need a little bit of help. I'm building a GPS tracking app where the app draws polylines of my movement and when I stop the tracking of my movement and click start again the app would erase all of the previously drawed polylines and start drawing newones. Bud everytime I start the polylinedrawing again the app after a while shows the previously drawed lines (even after they been erased).
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
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.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import java.util.ArrayList;
import java.util.List;
public class MapsActivity extends AppCompatActivity implements LocationListener {
private GoogleMap mMap;
Button start,stop;
double OLDlatitude = 100;
double OLDlongitude = 100;
boolean draw = false;
int width = 5;
int color = Color.BLUE;
LocationManager locationManager;
Polyline polyline = null;
PolylineOptions polylineOptions;
List<Polyline> mPolylines = new ArrayList<Polyline>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
stop.setEnabled(false);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startK();
}});
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
stopK();
}});
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mMap=mapFragment.getMap();
polylineOptions = new PolylineOptions();
polylineOptions.width(width);
polylineOptions.color(color);
polylineOptions.geodesic(true);
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean gps_enabled = false;
try {
gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {}
if(!gps_enabled ) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Aplikácia potrebuje aktívne GPS na fungovanie. Chcete ho zapnúť ?")
.setCancelable(false)
.setPositiveButton("Áno", new DialogInterface.OnClickListener() {
public void onClick(#SuppressWarnings("unused") final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton("Nie", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
dialog.cancel();
System.exit(0);
}
});
final AlertDialog alert = builder.create();
alert.show();
}
Criteria criteria = new Criteria();
String provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
if(location!=null){
onLocationChanged(location);
}
locationManager.requestLocationUpdates(provider, 2000, 0, this);
Toast.makeText(this, "Na začatie kreslenia polohy kliknite na štart", Toast.LENGTH_LONG).show();
}
#Override
public void onLocationChanged(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
LatLng NEWlatLng = new LatLng(latitude, longitude);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(NEWlatLng)
.zoom(17)
.bearing(0)
.tilt(0)
.build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
if(draw)
{
if(OLDlatitude==100 && OLDlongitude==100)
{
OLDlatitude = latitude;
OLDlongitude = longitude;
}
Location loc1 = new Location("");
loc1.setLatitude(OLDlatitude);
loc1.setLongitude(OLDlongitude);
Location loc2 = new Location("");
loc2.setLatitude(latitude);
loc2.setLongitude(longitude);
float distanceInMeters = loc1.distanceTo(loc2);
if(distanceInMeters >= 1.0 )
{
polylineOptions.add(NEWlatLng);
mPolylines.add(this.mMap.addPolyline(polylineOptions));
OLDlatitude = latitude;
OLDlongitude = longitude;
}
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
public void startK() {
Toast.makeText(this, "Kreslenie bolo začaté", Toast.LENGTH_LONG).show();
draw = true;
stop.setEnabled(true);
start.setEnabled(false);
if(mPolylines.size() != 0)
{
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Na mape je nakreslená trasa chcete túto trasu uložiť ?")
.setCancelable(false)
.setPositiveButton("Áno", new DialogInterface.OnClickListener() {
public void onClick(#SuppressWarnings("unused") final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
}
})
.setNegativeButton("Nie", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
for(Polyline line : mPolylines)
{
line.remove();
}
mPolylines.clear();
mPolylines = new ArrayList<Polyline>();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
}
public void stopK() {
Toast.makeText(this, "Kreslenie bolo zastavené", Toast.LENGTH_LONG).show();
OLDlongitude = 100;
OLDlatitude = 100;
draw = false;
stop.setEnabled(false);
start.setEnabled(true);
}
#Override
protected void onPause() {
if (this.isFinishing()){
draw = false;
locationManager.removeUpdates(this);
}
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
}
You should clear your map:
mMap.clear();
https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.html#public-methods
public final void clear ()
Removes all markers, polylines, polygons, overlays, etc from the map.
Just figured it by my self instead of
mPolylines = new ArrayList<Polyline>();
I've put there
polylineOptions = new PolylineOptions();
not entirely shore but I think polylineOptions keeps track of all added latlang objects even when they are erased from arrayList. If someone have some more complex explanation I would gratefully apprishiate it.
I have an activity called LocationTest and in my application that get the latitude and longitude and it is working properly.This activity includes a button that take us to another activity that called MapLocation that shows graphically the location on a map.But when I click the app will stop working.I will post the code of the 2 activities if somebody can help plz.I think the error is in the second activity
LocationTest Activity
public class LocationTest extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private FusedLocationProviderApi locationProvider = LocationServices.FusedLocationApi;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
public final static int MILLISECONDS_PER_SECOND=1000;
public final static int MINUTE = 60*MILLISECONDS_PER_SECOND;
private double longitude=0;
private double latitude=0;
private TextView lblLong;
private TextView lblLat;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_test);
//this here is for the map
Button mapBtn =(Button)findViewById(R.id.mapBtn);
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mapBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent=new Intent(LocationTest.this,MapLocation.class);
startActivity(intent);
}
});
locationRequest= new LocationRequest();
/*locationRequest.setInterval(MINUTE);*/
locationRequest.setInterval((MINUTE));
locationRequest.setFastestInterval(15 * MILLISECONDS_PER_SECOND);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
lblLong = (TextView)findViewById(R.id.lblLong);
lblLat = (TextView)findViewById(R.id.lblLat);
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
googleApiClient.disconnect();
}
#Override
protected void onResume() {
super.onResume();
if(googleApiClient.isConnected()){
requestLocationUpdates();
}
}
#Override
public void onConnected(Bundle bundle) {
requestLocationUpdates();
}
private void requestLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onLocationChanged(Location location) {
Toast.makeText(this, "Your Location Has Been Set: " + location.getLatitude() + " " + location.getLongitude(), Toast.LENGTH_LONG).show();
longitude = location.getLongitude();
latitude = location.getLatitude();
lblLong.setText(Double.toString(longitude));
lblLat.setText(Double.toString(latitude));
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
MapLocation Activity
public class MapLocation extends AppCompatActivity implements LocationListener{
GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isGooglePlayServicesAvailable()) {
finish();
}
setContentView(R.layout.activity_map_location);
SupportMapFragment supportMapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap);
googleMap = supportMapFragment.getMap();
googleMap.setMyLocationEnabled(true);
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(bestProvider);
if (location != null) {
onLocationChanged(location);
}
locationManager.requestLocationUpdates(bestProvider, 20000, 0, this);
}
#Override
public void onLocationChanged(Location location) {
TextView locationTv = (TextView) findViewById(R.id.latlongLocation);
double latitude = location.getLatitude();
double longitude = location.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
googleMap.addMarker(new MarkerOptions().position(latLng));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
locationTv.setText("Latitude:" + latitude + ", Longitude:" + longitude);
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
}
In order to show a map in your app, you will need the following steps:
1) Get you API key from https://developers.google.com/maps/documentation/android-api/ and set your permissions like this in your manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="Your package name" >
...
<!-- Creating Permission to receive Google Maps -->
<permission
android:name="com.arshad.map.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<!-- Permission to receive Google Maps -->
<uses-permission android:name="com.arshad.map.permission.MAPS_RECEIVE" />
<!-- Maps API needs OpenGL ES 2.0. -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
...
<!-- Maps API -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="Replace with your API key" />
...
</application>
</manifest>
2) Here is an example using fragments:
import android.Manifest;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import R;
public class MapFragment extends Fragment implements OnMapReadyCallback {
private static final String ARG_LONGITUDE = "longitude";
private static final String ARG_LATITUDE = "latitude";
private static final String LOG_TAG = MapFragment.class.getSimpleName();
private String mLongitude;
private String mLatitude;
//Google maps parameters initialization
static LatLng location = new LatLng(21, 57);
public static MapFragment newInstance(String longitude, String latitude) {
MapFragment fragment = new MapFragment();
Bundle args = new Bundle();
args.putString(ARG_LONGITUDE, longitude);
args.putString(ARG_LATITUDE, latitude);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
//Get lattitude and longitude
mLongitude = getArguments().getString(ARG_LONGITUDE);
mLatitude = getArguments().getString(ARG_LATITUDE);
Log.d(LOG_TAG, "Long = " + mLongitude + " lat = " + mLatitude);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_map, container, false);
MapFragment mapFragment = new MapFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.rl_map_container, mapFragment).commit();
mapFragment.getMapAsync(this);
return view;
}
#Override
public void onMapReady(GoogleMap map) {
//Setting the position of camera in the important location
map.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(Double.valueOf(mLatitude), Double.valueOf(mLongitude)), 17));
//Adding a marker with customized icon
map.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_<Your icon name>))
.anchor(0.0f, 1.0f) // Anchors the marker on the bottom left
.position(new LatLng(Double.valueOf(mLatitude), Double.valueOf(mLongitude))));
// MAP_TYPE_TERRAIN, MAP_TYPE_HYBRID and MAP_TYPE_NONE
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
}
3) Make your layout like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".fragments.MapFragment"
>
<FrameLayout
android:id="#+id/rl_map_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Also, you can get more information in https://developers.google.com/maps/documentation/android-api/