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
-
`Can I show the location with just GPS and without Internet connection`. Yes of course. GPS does not need internet. And an off line map doesnt either. – greenapps Dec 05 '17 at 15:03
-
But Google Maps is not offline by default and can only download small pieces of map if requested by the user (and even than can not be used by the external Maps API afaik...) :-( – Kelevandos Dec 05 '17 at 15:06
-
1Then use Openstreetmap and OsmDroid. – greenapps Dec 05 '17 at 15:08
-
Tnx @greenapps. Are these maps you mentioned as accurate and good as google maps ? Is working with them easy ? – Pedram Yazdipoor Dec 05 '17 at 15:11
-
1You dont know openstreetmap? Well have a look: http://www.openstreetmap.org/?mlat=12.1170023700276&mlon=-86.275634765625&zoom=9#map=9/12.1170/-86.2756 – greenapps Dec 05 '17 at 15:14
-
1Install OsmAnd and Maps.me on your device. They use openstreetmap all offline. There are more. Then make your own app. You can do better. And use the same maps they downloaded already. – greenapps Dec 05 '17 at 15:18
-
Yes, GPS can work on its own to acquire a fix, it needs line of sight though, you need to be in a relatively open area, if it's a cold start, and not in an open area, GPS can take quite some time for a fix. – elmorabea Dec 05 '17 at 17:50
2 Answers
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.

- 7,024
- 2
- 29
- 46
-
-
Not really, I have only worked with Google Maps, you will have to do some research here – Kelevandos Dec 05 '17 at 14:47
-
This, for example, looks promising: https://github.com/mapsme/api-android – Kelevandos Dec 05 '17 at 14:48
-
`(although it will be less precise without GSM tower localisation)`. No not at all. gsm tower is very unprecise. Better do without. Nothing beats gps. – greenapps Dec 05 '17 at 15:01
-
Even heard of GSM triangulation? Sure, GPS is required for precise pinpointing, but GSM helps a lot – Kelevandos Dec 05 '17 at 15:09
-
Yes i heard that GSM triangulation is NOT precise to begin with. And i understand that. – greenapps Dec 05 '17 at 15:10
-
Google Maps API didn't works without Internet connection: how API KEY can be checked? User will see empty white screen without any map tiles. Also using downloaded Google Maps tiles violates license agreement. – Andrii Omelchenko Dec 05 '17 at 15:14
-
Good update. But Google Maps in offline mode can't provide map of all Earth, only region, like screenshot. – Andrii Omelchenko Dec 05 '17 at 15:51
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.

- 13,183
- 12
- 43
- 79
-
This lets you obtain the location, but will not show it on a map if it is offline, as there will be no map downloaded. – Kelevandos Dec 05 '17 at 14:57
-
-
Wait what? What screenshot? Of the entire earth, in zoom? What resolution would you expect that to be? Integer.MAX_VALUE:Integer.MAX_VALUE? – Kelevandos Dec 05 '17 at 15:01
-
-
@Kelevandos Screenshot of target region, of course. You can't have tile map of whole Earth with appropriate zoom levels on your mobile device. – Andrii Omelchenko Dec 05 '17 at 15:05
-
-
Offline map of earth. Not a screenshot, how do you want to make a screenshot of the target location, @AndriiOmelchenko? Beforehand? How will you know where the user will be? – Kelevandos Dec 05 '17 at 15:07
-
tnx but this screenshot thing is not a solution at all. I need to show current location on a map with gps and without any internet connection – Pedram Yazdipoor Dec 05 '17 at 15:07
-
@Andrii Omelchenko. full map means a real map not some images – Pedram Yazdipoor Dec 05 '17 at 15:08
-
@PedramYazdipoor So, you need that map already in your mobile device. There is only one way to achieve that: use vector maps (like MapInfo .mif), but there is no free vector maps for all Earth. And you need render vector map format to raster mobile screen. – Andrii Omelchenko Dec 05 '17 at 15:10
-
Man... User will download the app from the Internet, then go into a deep forest and the desired behavior is that they will be able to check where they are, without internet connection. How hard to understand can that be? Mobile devices are not supposed to be connected to the Internet at all times (although that would make dev lives MUCH easier) – Kelevandos Dec 05 '17 at 15:15