When I run the app, I get the world map, where you can see all the countries. But this is not what I want, I want it to show the map of my country or city as an example. Is there a way to do this? This is my code so far. I don't think the xml code should be necassary for this?
public class MainActivity extends Activity {
private GoogleMap gMap;
private LocationManager locationManager;
private Location location, g;
private double lati, longi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
// gMap.setMyLocationEnabled(true);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
System.out.println("Last known location: " + location);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void showUsersPosition(View v) {
gMap.setMyLocationEnabled(true);
if(location != null) {
lati = location.getLatitude();
longi = location.getLongitude();
}
gMap.addMarker(new MarkerOptions().position(new LatLng(lati, longi)).title("You are here"));
}
}
I also have added a button, where I want to show the users location when this button is clicked. This happens in the method "showUsersPosition". But at this point, Location is null, even though I try to set it when the app is beeing started. Can anyone see why it is null? When the gMap.setMyLocation(true) is called, a symbole appears at the right corner, and if I click on this, it will show me my position. But I want it so that it does this when I click the button.
So the questions again are:
1. How to show the map of my country or city, and not the world map?
2. Why is Location null?
3. How do I make it show my exact location when the button is clicked
1)
You can use this on your fragment declaration to set the default latitude and longitude.
map:cameraTargetLat="Your Latitude"
map:cameraTargetLng="Your Longitude"
Do not forget to put xmlns:map="http://schemas.android.com/apk/res-auto" on your fragment if it is not there.
2) From the docs:
If the provider is currently disabled, null is returned.
Is the GPS turned on?. Also, you should use the new Location API.
3) The exactness of your Location will be based on the Provider used to get the Location. One of the advantages of using the new Fused Provider is that the system will try to get the best Location possible for you.
Related
I am creating an app with a google maps and a circle radius centered on the user’s location. I want the user to choose the desired radius of the circle with a spinner (1-10 km radius). But when I use the value from my spinner the radius circle doesn't appear.
For the location I can get the blue dot showing my appearance by: map.setMyLocationEnabled(true); and I can manually enter a location for map to zoom into. But when I try to zoom into and set center of circle on the device location I get a nullpointerexception error. Below is my code for the location and the toast is just for me to see that I get the actual location.
private void getDeviceLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]
{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
return;
}
Task<Location> task = mFusedLocationClient.getLastLocation();
task.addOnSuccessListener(MainActivity.this, new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location != null) {
currentLocation = location;
Toast.makeText(MainActivity.this, "Current Position " + currentLocation.getLongitude(), Toast.LENGTH_LONG).show(); //Just to make sure we have a value
SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map2);
supportMapFragment.getMapAsync(MainActivity.this);
}
}
});
}
Then I use userPosition for map to zoom into and set center of circle
public void onMapReady(GoogleMap map) {
LatLng userPosition = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
mGoogleMap = map;
map.setMyLocationEnabled(true);
map.animateCamera(CameraUpdateFactory.newLatLngZoom(userPosition, 10f));
map.addCircle(new CircleOptions()
.center(userPosition)
.radius(mapRadius)
.strokeColor(0x330073FF)
.fillColor(0x330073FF)
.strokeWidth(2));
map.getUiSettings().setZoomControlsEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(true);
}
But here I get the error on the line userPosition: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at com.example.test.MainActivity.onMapReady(MainActivity.java:362).
I got the code from a tutorial and it seems to work for them and tried many different tutorials as well with slightly different code so not sure what I do wrong. I have tried searching and know others had similar problems but still haven't gotten it to work.
As for the radius, it works fine when I set a manual location and write It works well if I write the radius myself in meters. But if I try to use my spinner and the mapRadius value, the radius circle doesn’t show up at all when I run the emulator. This is the code that is in onCreate
spinnerRadius = findViewById(R.id.spinner_radius);
ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(this,
R.array.spinner_radius_option, android.R.layout.simple_spinner_item);
spinnerRadius.setAdapter(spinnerAdapter);
spinnerRadius.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mapRadiusInput = parent.getItemAtPosition(position).toString();
mapRadius = Double.parseDouble(mapRadiusInput)*1000; //converting to meters
Toast.makeText(MainActivity.this, ""+mapRadius, Toast.LENGTH_LONG).show();
}
I am a beginner when it comes to programming and android and I spent quite a bit on time on these two problem and it wouldn’t surprise me if it is easy to solve. Any help or pointers would be greatly appreciated.
When you add the circle, save the return value (Circle) in a field variable, Circle myCircle.
Then in the onItemSelected update the circle radius with the value (in meters).
So, first declare the variable as a class field variable (for scope visibility later). I'm assuming this is all in one class - if not you'll need to make this variable accessible to the onItemSelected callback instance.
private Circle myCircle;
Then when adding the circle, save it:
myCircle = map.addCircle(new CircleOptions()
.center(userPosition)
.radius(mapRadius)
.strokeColor(0x330073FF)
.fillColor(0x330073FF)
.strokeWidth(2));
And in your onItemSelected, update the circle (in meters)
myCircle.setRadius(mapRadius);
Here's another example showing same thing: https://stackoverflow.com/a/38454501/2711811
And API doc: https://developers.google.com/android/reference/com/google/android/gms/maps/model/Circle.html#setRadius(double)
The key is to save the Circle when it's created. And as you can see from the API, with the Circle reference there are other setters which can be used.
java.lang.RuntimeException: Unable to start activity ComponentInfo{in.jainrishabh.noteelite/in.jainrishabh.noteelite.MapView}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.google.android.gms.maps.GoogleMap.setOnMapClickListener(com.google.android.gms .maps.GoogleMap$OnMapClickListener)' on a null object reference
anyone know why i am getting NullPointer Exception
GoogleMap googleMap;
SharedPreferences sharedPreferences;
int locationCount = 0;
private ArrayList<UserDetailsPojo> pojoArrayList;
private float latia;
private float longia;
private Editor editor;
SharedPreferences prefs;
float lat;
float lng;
String lat_temp;
String long_temp;
private ListView userNamesListView;
private ListAdapter userListAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map_view);
prefs = this.getSharedPreferences("sharedpref", Context.MODE_PRIVATE);
latia = prefs.getFloat("latitude", -34);
longia = prefs.getFloat("longitude", 151);
LatLng myLocation = new LatLng(latia, longia);
pojoArrayList = new ArrayList<UserDetailsPojo>();
// For the third argument, we need a List that contains Strings.
//We decided to display undergraduates names on the ListView.
//Therefore we need to create List that contains undergraduates names
userListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList());
//Toast.makeText(getApplicationContext(), "lati is:"+latia, Toast.LENGTH_LONG).show();
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
// Showing status
if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
dialog.show();
}else { // Google Play Services are available
// Getting reference to the SupportMapFragment of activity_main.xml
MapFragment fm = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
// Getting GoogleMap object from the fragment
googleMap = fm.getMap();
// Enabling MyLocation Layer of Google Map
googleMap.setMyLocationEnabled(true);
// Opening the sharedPreferences object
sharedPreferences = getSharedPreferences("location", -34);
// Getting number of locations already stored
locationCount = sharedPreferences.getInt("locationCount", 151);
// Getting stored zoom level if exists else return 0
String zoom = sharedPreferences.getString("zoom", "0");
// If locations are already saved
if(locationCount!=0){
String lat = "";
String lng = "";
// Iterating through all the locations stored
for(int i=0;i<locationCount;i++){
// Getting the latitude of the i-th location
lat = lat_temp;
// Getting the longitude of the i-th location
lng = long_temp;
// Drawing marker on the map
drawMarker(new LatLng(Double.parseDouble(lat), Double.parseDouble(lng)));
}
// Moving CameraPosition to last clicked position
googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(Double.parseDouble(lat), Double.parseDouble(lng))));
//googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myLocation, 13));
// Setting the zoom level in the map on last position is clicked
googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
}
}
googleMap.setOnMapClickListener(new OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
locationCount++;
// Drawing marker on the map
drawMarker(point);
/** Opening the editor object to write data to sharedPreferences */
SharedPreferences.Editor editor = sharedPreferences.edit();
// Storing the latitude for the i-th location
editor.putString("lat"+ Integer.toString((locationCount-1)), Double.toString(point.latitude));
// Storing the longitude for the i-th location
editor.putString("lng"+ Integer.toString((locationCount-1)), Double.toString(point.longitude));
// Storing the count of locations or marker count
editor.putInt("locationCount", locationCount);
/** Storing the zoom level to the shared preferences */
editor.putString("zoom", Float.toString(googleMap.getCameraPosition().zoom));
/** Saving the values stored in the shared preferences */
editor.commit();
Toast.makeText(getBaseContext(), "Marker is added to the Map", Toast.LENGTH_SHORT).show();
}
});
googleMap.setOnMapLongClickListener(new OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng point) {
// Removing the marker and circle from the Google Map
googleMap.clear();
// Opening the editor object to delete data from sharedPreferences
SharedPreferences.Editor editor = sharedPreferences.edit();
// Clearing the editor
editor.clear();
// Committing the changes
editor.commit();
// Setting locationCount to zero
locationCount=0;
}
});
}
private void drawMarker(LatLng point){
// Creating an instance of MarkerOptions
MarkerOptions markerOptions = new MarkerOptions();
// Setting latitude and longitude for the marker
markerOptions.position(point);
// Adding marker on the Google Map
googleMap.addMarker(markerOptions);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public List<String> populateList(){
// We have to return a List which contains only String values. Lets create a List first
List<String> userNamesList = new ArrayList<String>();
// First we need to make contact with the database we have created using the DbHelper class
AndroidOpenDbHelper openHelperClass = new AndroidOpenDbHelper(this);
// Then we need to get a readable database
SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase();
// We need a a guy to read the database query. Cursor interface will do it for us
//(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
Cursor cursor = sqliteDatabase.query(AndroidOpenDbHelper.TABLE_USER, null, null, null, null, null, null);
// Above given query, read all the columns and fields of the table
startManagingCursor(cursor);
// Cursor object read all the fields. So we make sure to check it will not miss any by looping through a while loop
while (cursor.moveToNext()) {
// In one loop, cursor read one undergraduate all details
// Assume, we also need to see all the details of each and every undergraduate
// What we have to do is in each loop, read all the values, pass them to the POJO class
//and create a ArrayList of undergraduates
//int Time = cursor.getInt(cursor.getColumnIndex(AndroidOpenDbHelper.COLUMN_TIME));
double latia = cursor.getDouble(cursor.getColumnIndex(AndroidOpenDbHelper.COLUMN_LATI));
double longia = cursor.getDouble(cursor.getColumnIndex(AndroidOpenDbHelper.COLUMN_LONGI));
// Finish reading one raw, now we have to pass them to the POJO
UserDetailsPojo ugPojoClass = new UserDetailsPojo();
ugPojoClass.setLati(latia);
ugPojoClass.setLongi(longia);
// Lets pass that POJO to our ArrayList which contains undergraduates as type
pojoArrayList.add(ugPojoClass);
lat_temp = Double.toString(latia);
long_temp = Double.toString(longia);
Log.d("latis1",lat_temp);
Log.d("longis1",long_temp);
}
// If you don't close the database, you will get an error
// sqliteDatabase.close();
return userNamesList;
}
}
Blockquote
<fragment
android:id="#+id/map"
android:layout_width="wrap_content"
android:layout_height="700dp"
android:layout_weight="4"
android:name="com.google.android.gms.maps.MapFragment"
/>
This is my Mapview XML
You are probably referencing the googleMap variable before it's been instantiated. Try changing that first line GoogleMap googleMap;
to this instead. GoogleMap googleMap = new GoogleMap();
Also, be sure to set the setOnMapClickListener inside the else case so it works as intended. You don't want to set the event listener if the map object doesn't exist (aka if Google Play Services are NOT available).
I need that in my Map-application Google map markers title always will be shown without any user click. I want that this title even will not be possible hide.
Of course I searched online, and I found this: marker.showInfoWindow(); but it is not working because I have near to 30 markers and I need that all of them will be shown all the time (I guess marker.showInfoWindow(); working just when there is one marker).
............................................................................
(And I would like to know how to do that when map activity will start it will not show whole world from far, but from specific country. I mean already zoomed to this country.)
public class Map extends Activity {
static LatLng Sapphire = new LatLng(41.085078, 29.006100);
static LatLng Metrocity = new LatLng(41.076138, 29.010518);
static LatLng Istinye = new LatLng(41.114247, 29.058924);
private GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
try {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
}
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.setMyLocationEnabled(true);
googleMap.setTrafficEnabled(true);
googleMap.setIndoorEnabled(true);
googleMap.setBuildingsEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
Marker marker = googleMap.addMarker(new MarkerOptions().position(Sapphire).title("Istanbul Sapphire").snippet("Levent")); marker.showInfoWindow();
Marker marker1 = googleMap.addMarker(new MarkerOptions().position(Metrocity).title("Metrocity").snippet("Levent")); marker1.showInfoWindow();
Marker marker2 = googleMap.addMarker(new MarkerOptions().position(Istinye).title("Istinye Park").snippet("Istinye/ Pınar Mh.")); marker2.showInfoWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I'm creating an app, and I just got it to show the map on the screen. Now I was wondering how can I have it find the user and track where he/she goes. I did the setMyLocationEnabled(true), but all that does is show a button, and when you click it nothing happens. I've never used google maps api before so I don't know much about it.
There you have got this trouble good explained - http://wptrafficanalyzer.in/blog/showing-current-location-in-google-maps-using-api-v2-with-supportmapfragment/.
You have to implement getting user's location out of Google Maps API. You need to use those permissions:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
There is class example which shows that, what you want. Got this from page I wrote above:
public class MainActivity extends FragmentActivity implements LocationListener {
GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
// Showing status
if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
dialog.show();
}else { // Google Play Services are available
// Getting reference to the SupportMapFragment of activity_main.xml
SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
// Getting GoogleMap object from the fragment
googleMap = fm.getMap();
// Enabling MyLocation Layer of Google Map
googleMap.setMyLocationEnabled(true);
// Getting LocationManager object from System Service LOCATION_SERVICE
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location
Location location = locationManager.getLastKnownLocation(provider);
if(location!=null){
onLocationChanged(location);
}
locationManager.requestLocationUpdates(provider, 20000, 0, this);
}
}
#Override
public void onLocationChanged(Location location) {
TextView tvLocation = (TextView) findViewById(R.id.tv_location);
// Getting latitude of the current location
double latitude = location.getLatitude();
// Getting longitude of the current location
double longitude = location.getLongitude();
// Creating a LatLng object for the current location
LatLng latLng = new LatLng(latitude, longitude);
// Showing the current location in Google Map
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// Zoom in the Google Map
googleMap.animateCamera(CameraUpdateFactory.zoomTo(15));
// Setting latitude and longitude in the TextView tv_location
tvLocation.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
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
I have made an Android app that gets location by longitude and latitude on a button click.
At first I get the last known location reading, which is, for argument sake, inaccurate when I first load up the app/turn on gps.
What I would like to know is how to wait for it to be accurate, like in Google maps when you get the toast message 'waiting for location'.
If you see any way the code can be improved it would also be helpful.
Code for reference:
public class Clue extends Activity {
public static double latitude;
public static double longitude;
Criteria criteria;
LocationManager lm;
LocationListener ll;
Location location;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.questions);
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
ll = new MyLocationListener();
lm.requestLocationUpdates(lm.getBestProvider(criteria, true), 0, 0, ll);
}
private boolean weAreThere() {
location = getLocation();
longitude = location.getLongitude();
latitude = location.getLatitude();
return inCorrectPlace(param);
}
private Location getLocation() {
lm.requestLocationUpdates(lm.getBestProvider(criteria, true), 0, 0, ll);
return lm.getLastKnownLocation(lm.getBestProvider(criteria, true));
}
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location loc)
{
Clue.longitude = loc.getLongitude();
Clue.latitude = loc.getLatitude();
}
}
Thanks for reading, all replies will be appreciated.
Ben
If Location.hasAccuracy() returns true, you could call Location.getAccuracy() to retrieve the accuracy in meters, then filter the ones you don't consider enough accurate.
Notice you are not using LocationManager.GPS_PROVIDER so your fixes could also be obtained by other means (like WiFi).
Usually expect about a minute for the GPS chip to get "hot"* before getting GPS fixes (outdoors).
*By hot I mean having satellites coverage. Some chipsets get disconnected ("cold") after some time to preserve battery. The Time To First Fix (TTFF) is greater when the chip is cold.
Here is an excellent explanation,
http://android-developers.blogspot.com/2011/06/deep-dive-into-location.html
helps you understand exactly how to implement it.
Initially , u should get fix using getlastknownLocation ()
In addition, U can use a background service that updates location using NETWORK.PROVIDER... which shall not drain ur battery if used judiciously...and also works if GPS is turned off
If there is no network provider, then u should try and ask user to turn on GPS.
If u r using 2.2 try PASSIVE PROVIDER