Hi I am a bit new to android and I have been wanted to develop an android app which is supposed to show the current location of the user on a map like google map in offline mode. Can I show the location with just GPS and without Internet connection ? Needless to say that this offline thing is vitally important for me. Any help would be appreciated. Tnx in advance
You can get the GPS location (although it will be less precise without GSM tower localisation). However, the map part may be tricky. You can use the Google Maps API in your app, like MapActivity, but the map itself has to be downloaded from the web.
So you will need some custom solution for this, probably through a different map provider than Google Maps.
You may be able to do it a bit differently - obtain the location in your app and then open Google Maps with an Intent, passing the received coordinates. This should allow the user to use any offline-stored maps they may have.
You can get raw NMEA data from GPS via NmeaListener or better OnNmeaMessageListener (IMHO it more complex), and parse RMC sentence like this:
public class CustomNmeaListener implements GpsStatus.NmeaListener{
private GoogleMap mGoogleMap;
private Marker mMarkerPosition = null;
private BitmapDescriptor mMarkerMoveDescriptor;
private BitmapDescriptor mMarkerStopDescriptor;
public CustomNmeaListener(GoogleMap googleMap, int markerMoveResource, int markerStopResource){
this.mGoogleMap = googleMap;
mMarkerMoveDescriptor = BitmapDescriptorFactory.fromResource(markerMoveResource);
mMarkerStopDescriptor = BitmapDescriptorFactory.fromResource(markerStopResource);
}
#Override
public void onNmeaReceived(long timestamp, String nmea) {
double latitude;
double longitude;
float speed;
float angle;
// parse NMEA RMC sentence
// Example $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
// nmea [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
if (nmea.startsWith("$GPRMC")) {
String[] nmeaParts = nmea.split(",");
// if RMC data valid ("active")
if (nmeaParts[2].equals("A")) {
latitude = parseLatitude(nmeaParts[3], nmeaParts[4]);
longitude = parseLongitude(nmeaParts[5], nmeaParts[6]);
speed = parseSpeed(nmeaParts[7]);
angle = parseAngle(nmeaParts[8]);
// remove marker on "old" position
if (mMarkerPosition != null) {
mMarkerPosition.remove();
}
MarkerOptions positionMarkerOptions;
if (speed > 0) {
positionMarkerOptions = new MarkerOptions()
.position(new LatLng(latitude, longitude))
.icon(mMarkerMoveDescriptor)
.anchor(0.5f, 0.5f)
.rotation(angle);
} else {
positionMarkerOptions = new MarkerOptions()
.position(new LatLng(latitude, longitude))
.icon(mMarkerStopDescriptor)
.anchor(0.5f, 0.5f)
.rotation(0);
}
mMarkerPosition = mGoogleMap.addMarker(positionMarkerOptions);
}
}
}
static float parseLatitude(String lat, String sign) {
float latitude = Float.parseFloat(lat.substring(2)) / 60.0f;
latitude += Float.parseFloat(lat.substring(0, 2));
if(sign.startsWith("S")) {
latitude = -latitude;
}
return latitude;
}
static float parseLongitude(String lon, String sign) {
float longitude = Float.parseFloat(lon.substring(3)) / 60.0f;
longitude += Float.parseFloat(lon.substring(0, 3));
if(sign.startsWith("W")) {
longitude = -longitude;
}
return longitude;
}
static float parseSpeed(String knots) {
float speed;
try {
speed = Float.parseFloat(knots);
} catch (Exception e) {
speed = 0;
}
return speed;
}
static float parseAngle(String ang) {
float angle;
try {
angle = Float.parseFloat(ang);
} catch (Exception e) {
angle = 0;
}
return angle;
}
}
and set RMC sentence interval on requestLocationUpdates() call
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
<your_update_interval>,
LOCATION_DISTANCE,
this
);
} catch (java.lang.SecurityException ex) {
Log.d(TAG, "fail to request location update, ignore", ex);
}
And for map service you should use custom solution, because, even for offline maps Google Maps need Internet connection at least for MAPS API KEY check. As first approach you can use simple ImageView with map screenshot.
Related
I'm making an app that when it opens ,it shows the user's current location.The thing is that I want also to put all the details(home address,postal code,country) by pressing on the marker just like this application
Application Photo
Code:
private GoogleMap mMap;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private Location lastLocation;
private Marker currentUserLocationMarker;
here is the method that contains the marker
#Override
public void onLocationChanged(Location location) {
lastLocation=location;
if(currentUserLocationMarker!=null)
{
currentUserLocationMarker.remove();
}
LatLng latLng= new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions= new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Test");
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker_mini));
currentUserLocationMarker = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomBy(15));
if(googleApiClient != null)
{
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient,this);
}
}
You can use the Geocoding API and use reverse geocoding to get the details from the latlng. Here is an example reverse geocoding query,
https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=YOUR_API_KEY
This will return a json response with multiple address results with first address as the most prominent result.
You can also use Geocoder in android as follows, (This example gets the list of addresses and logs the formatted adress line from the returned results)
Geocoder geocoder=new Geocoder(this);
try {
List<Address> addressList=geocoder.getFromLocation(40.714232,-73.9612889,10);
for(Address address:addressList){
Log.d("TAG",address.getAddressLine(0));
}
} catch (IOException e) {
e.printStackTrace();
}
The parms of getFromLocation(..) are lat,lng and maximum number of results you want to retrieve with first againg being the prominent one.
Checkout the documentation of Geocoding API to know what else you can do,
https://developers.google.com/maps/documentation/geocoding/intro#reverse-example
Also checkout the documentation of Geocoder,
https://developer.android.com/reference/android/location/Geocoder#Geocoder(android.content.Context,%20java.util.Locale)
I want to draw a path between two locations using on android google map.I have tired this code
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
if (cursor.moveToFirst()) {
do {
// latitude and longitude
double latitude = 0.00;
double longitude = 0.00;
Log.i("lat", cursor.getString(10));
Log.i("lat", cursor.getString(11));
try {
latitude = Double.parseDouble(cursor.getString(10));
} catch (Exception e) {
}
try {
longitude = Double.parseDouble(cursor.getString(11));
} catch (Exception e) {
}
if (latitude == 0.00 || longitude == 0.00) {
} else {
i++;
LatLng point = new LatLng(latitude,longitude);
options.add(point);
// create marker
MarkerOptions marker = new MarkerOptions().position(
new LatLng(latitude, longitude)).title(cursor.getString(1));
}
}
while (cursor.moveToNext());
}
cursor.close();
googleMap.addPolyline(options);
but i got straight line.like this
I want to get paths on actual roads.
Thanks..!!
If you want to draw a polyline between 2 points and following road, you can try with the library Google-Directions-Android
You can add the library on gradle with compile 'com.github.jd-alexander:library:1.0.7'
You can use all your point (Latlng) and use them into the waypoint method.
Routing routing = new Routing.Builder()
.travelMode(/* Travel Mode */)
.withListener(/* Listener that delivers routing results.*/)
.waypoints(/*waypoints*/)
.build();
routing.execute();
I have this problem.
I want to show a specific location on maps in android. Like if user has entered India in Edit text, then how can i show INDIA on Map. I basically want to know how to get the latitude and longitude of any location.
Please help
My Code:
public class Map extends Activity{
private GoogleMap map;
private LatLng myLoc;
#SuppressLint("NewApi") protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
Intent i=getIntent();
String loc=i.getStringExtra("loc");
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
Geocoder geoCoder = new Geocoder(getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocationName(
loc, 5);
if (addresses.size() > 0) {
myLoc = new LatLng(
(int) (addresses.get(0).getLatitude() * 1E6),
(int) (addresses.get(0).getLongitude() * 1E6));
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(myLoc, 14);
map.animateCamera(update);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
It is not Working. Please Help
It seems that Geocoder functions are blocked and use network. Because of onCreate is running on main thread, you can get this error(in older versions of android). Thus, you have to create AsyncTask and move geocoder's function to AsyncTask.doInBackground().
And after, in AsyncTask.onPostExecute() you should perfom the other operations with google map. (It will be on main thread in this case, how it must be)
Use
map.setMyLocationEnabled(true);
A blue circle will be appeared on map. It will show the current location.
When you select India from edittext call this function:
public void showSelectedCountry(String countryName) {
if (countryName.equals("India")) {
LatLngBounds boundsIndia = new LatLngBounds(new LatLng(23.63936, 68.14712), new LatLng(28.20453, 97.34466));
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(boundsIndia, padding);
mMap.animateCamera(cameraUpdate);
}
}
I'm trying to build a string with origin and destination gps coordinates for google mapping purposes. The first thing that I need to do is to get the gps coordinates of my current location, since this is the origin point. Then, I need to concatenate these coordinates into a larger string that I use to get directions.
I have code that gets these coordinates, and also code that concatenates them into the correct string format. However, my problem is that my string building code is running first, which is leaving me with null pointer issues since the string is referencing gps coordinates that haven't processed yet.
Here it is. The gotLocation() method comes from implementing advice in this post:
Public class DirectionsActivity extends Activity {
String myLat, myLng;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Parser parser;
LocationResult locationResult = new LocationResult(){
#Override
public void gotLocation(final Location location){
try {
Double lat = location.getLatitude();
Double lng = location.getLongitude();
if (lat != 0.0 && lng != 0.0) {
myLat = Double.toString(lat);
myLng = Double.toString(lng);
String gps_location = myLat + " " + myLng;
Toast.makeText(getBaseContext(), "First Message", Toast.LENGTH_SHORT).show();
}
}catch (Exception e) {
}
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);
Toast.makeText(getBaseContext(), "Second Message", Toast.LENGTH_LONG).show();
buildString();
setContentView(R.layout.activity_directions);
}
The toast output when I run this is "Second Message" followed by "First Message". They should display in the opposite order.
Getting a location is an asynchronous operation, you don't have control on the time at which you get the answer from the system.
How would you be sure to find a satellite or cell phone mat before your toast appears ? :)
I want to show a route between the user's current location and the location he entered in the searchview. Here is my code for the onQueryTextSubmit method
#Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
try
{
if(direction.isChecked() == false)
{
gc = new Geocoder(this);
addresses = gc.getFromLocationName(query,5);
String add = "";
if (addresses.size() > 0)
{
p = new GeoPoint(
(int) (addresses.get(0).getLatitude() * 1E6),
(int) (addresses.get(0).getLongitude() * 1E6));
mc.animateTo(p);
mc.setZoom(9);
mapView.invalidate();
searchView.clearFocus();
}
else
{
Toast.makeText(this, " Location not found.",
Toast.LENGTH_LONG).show();
}
return true;
}
else
{
// draw a route between the locations
return true;
}
}
catch(IOException ex)
{
}
return false;
}
what is the simplest way to do it? (examples will help me understand more)
Thank You
Once you have your destination GeoPoint you could do an http request to google in this address:
String url = "http://maps.google.com/maps?f=d&hl=es&saddr="+ origin +"&daddr=" + destination + "&ie=UTF8&om=0&output=dragdir";
being origin and destination (latitude, longitude) points.
For example, this request gives you this json:
{tooltipHtml:" (86,4 km / 55 minutos)",polylines:[{id:"route0",points:"wa{uFt|kUoAkE??jDyE??uFuLqFaH??mAl#gAZ??q#[Yg#KwCBkATq#X[bCu#??tMsBrIuBrDoA~J}EbC{#pCy#dIeA`JBrDThd#nFpDRnTkAdBGVFhRyC`McA|KkAzCK|CP??lA~#NZHn#I~#Q`#c#\\[Hu#KYWUe#Gc#D{BnG}a#`Kcb#|A}JvAkOXmHDgFKcMMmDkBgW??SaCEoFBaCb#mH`AwGdE_Qh#sCf#}Db#yGFcFIqE]iGcAkLUyGB{K^aHf#_EfC_PtAqOlB}X|AiNrCyTnE{WjDqOtCqK~DoMhHoSvX}u#~KeYpI}VrSkk#zBiJ`#_Ct#oG`#mGPoGCcLMoDq#wHiCaSe#qE_BgTMuEEoIDsJxA_`#DcHGoCw#iJkAoHsCwN_AcHk#mG]wGOcLLeJZiG\\gEr#kGhBeKpB{H~#uCvB{F~CuGbBuCdE_GlE}ElBgBfQeNpCsCtCmDtCoEnBsD~BmFdBqFz#_DdByIt#iGb#iFZeJBiYJ{GRkGf#{HpAaMdDwRzB{IrCsIrCoGbHiMzGmJnEaFjCeCdCwBfE}CdC_BzHiErNyG~NsFdN}DnQuDzK}A~KcAxKm#hJQhLAfhAhA~HQnFm#xGsAtFqBdCoAdEgC|GaGtEiF~GwIfGsGdD{CtEcDpQwKvCwBdFeE|HmIxEoGtCwElLiVfDeGxDkFvNsOvDaFbDqFnI{PtBwDfDiF`FkG~UeVfC{ClD{EpMyRzDyEdE_EvHwFpGiDfDsA|DmAhE_AdEk#hGa#jHCpLJlEIrDUnDa#fFaArF_BnGmCpHiEbVgPzBmBhBoB|B_D|AqCdAaCtGaRvAuC~EeI??jSk[zBcEnAuCnD}Jd#iBlBwJ`AgIPuBF_GKaHEeAq#mGs#gE?Ue#_Bi#mAaCwEeCgEw#qBcB}G_#gDKsB?kEJuCR}Bn#sDt#qCxAqDtCmEtAwAfCuB|AcAvCsAhBm#bDo#xGq#~Ci#fEsAvDuBdDsCrBgChBsCtEqJnC{DfDuC`EmBzCq#bDM`DNdBZxFzAlBPxCBrKaAvCCfMhA~A#vCKpCg#vD}ArA{#xBmBlBcC~A{Cx#uB|#oD^}BlAkKl#iDl#{BzAwDzBsDpBaCnBiBlB_CnFoIfD_ExAoAfEgC`CaAnDgAnCi#rAKfHLfCCzAQfDmApBuAjBmBtFgKfAyAbCwBnEsCzAoAlBaCfD{FhByDtBsFZcBPiBTqIRiB\\eBTm#t#uA`AeApBqAtB]xBExS`#bEIz#OnAe#lAy#v#y#hAkBp#qBv#}CjEwT~#uCpEwIbK{QlE}FnFeF`CeBrDsB`EaBlDaApE{#zgAqPhFiAbAc#bC{Az#{#hHwIdOqRnA{Bx#oBbRoe#fBmFzAcGtA{I`#yEzEiv#X_Cz#aEpBaGtB{DvRmW`BaC`AoBbAsCl#eCf#iDn#}G`#mC`AwD~AuDhJ{OdCuGfA{Ej#eEZwDzEgu#x#sJ^qBj#kBdD}HbAkDhEaX^gDJgC?iCKiCw#iIK_EL}Db#qDbAqD|#uBjOuVxIgQ~DsK|AuFpAaHt#_F`AqK^gL#yG_#u\\HeHNwEv#oKx#eHbDgPzDuNlAuD~F{O~BoF`AiBnBoCzFwF~CoDlBcEfAaD|Kc_#r#yBtAgD`AaBbHsJ|CsCrP_LpBwB`BqChAgDr#yDR}BhBs\\VuBx#kDlAyCdBkCdDqClQcHlC_B|CuDlJcQbA{AlAqA~_Ags#lSiSrBaCfOiWtVs]z`#_s#zMiVvAuBzPyTfRg[rBuD`B_EtCkIvKs]nCaHlEuIfHaMbMoRv[kd#lEqFfo#qp#|C{Cf#[bQsHrBoA~AsAbAqA|GsMtBiC|B_BlHwD`Au#vA{AnAmB|#wB|#eDbEmThAsEh#_BzAcDnKmP~z#}kA|AcBbDcCvFyBvSgGnBa#~TiGnNmC|DkB??xCoApDU|#UtAeAZm#\\gARkBQeK#i#^cC??pBkHvFy]Pm#ZCHQVuAAc#hAyC~#m#dBYzPq#??Jd#NJR?VSBi#pBq#l#e#d#e#jAoB\\_A\\_BnBePTCN[A[SWtIsr#Aq#VCLSAg#OQpDwX^kE??rAJrB]p#[tAuA",levels:"BBBBB?BB?BB???#??BB??????#???#???????BB??#???#????#???#????BB???#????#??????#??????#??#????#??A???#????#????#?????#????A?????#?????#???#???#?????#???A?#???#????#???#???#???A?????#????#??????????#??????#????#?????#???#???#?????BB??#???#??????#????#??#???#??A???#?????#????#?#??????????#???A???#?????#?????#???#?????#???????#??#???#???#????#???#????#???#???#??#????A????#????#????#?????#???#???#?????#??????#???#???#?????#??#???#????#???#?????#??????A???#???#??#??????#????#??#?##???#???#???#??????#?#??#????BB????#????BB???????#??BB??????#???#????????????BB???B",numLevels:4,zoomFactor:16}]}
The String with name points is the polyline you have to draw on your map. But before drawing you have to decode it. Take a look here for that duty.
Once you have your GeoPoint list, you can draw it on your map. For that you need an overlay if you're using google api v1. I'd recommend you to have a look into api v2. It's easier to add polylines to map objects via the addPolyline method in GoogleMap class and PolylineOptions.
Hope that helps.
by two ways we can draw route on map.
1.use Map OverLay concept in android
2.use this url
http://maps.google.com/maps?&saddr=from latitude value,from longitude value &daddr= to latitude value,to longitude value