I had trouble trying to retrieve user based on search distance, and have received great support from this community. The code boiled down to the following:
let userLocation = PFGeoPoint(latitude: userLatitude, longitude: userLongitude)
query.whereKey("location", nearGeoPoint:userLocation, withinKilometers: 100)
The issue is that the code is tailored to swift/xcode, and when I tried "converting it to" android it came down to
query.whereWithinKilometers("location", ParseGeoPoint point, 100);
I am not sure if this is the proper way of writing it in Java (android), and not sure what to do ParseGeoPoint point.
I have looked into https://parse.com/docs/android/api/com/parse/ParseGeoPoint.html, but is a bit stuck.
If you need any clarification, let me know.
Thanks
Update:
Below is how I store the location point of the current user into Parse
#Override
public void onLocationChanged(Location loc) {
// TODO Auto-generated method stub
double lati = loc.getLatitude();
double longi = loc.getLongitude();
ParseUser currentUser = ParseUser.getCurrentUser();
currentUser.saveInBackground();
ParseGeoPoint point = new ParseGeoPoint(lati, longi);
currentUser.put("location", point);
currentUser.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
setProgressBarIndeterminateVisibility(false);
if (e == null) {
// Success!
} else {
}
}
});
Below is how I attempt to retrieve it, and see if user who fall within range
ParseQuery<ParseUser> query = ParseUser.getQuery();
ParseGeoPoint point = new ParseGeoPoint(47, -122); //Ideally it would be best if (47, -122) reflected the current user location
query.whereWithinKilometers("location", point, 100);
I'd recommend reading through this for documentation on the Android SDK's GeoPoints. This would be the basic syntax for you.
#Override
public void onLocationChanged(Location loc) {
double lati = loc.getLatitude();
double longi = loc.getLongitude();
//User's current location
ParseGeoPoint point = new ParseGeoPoint(lati, longi);
ParseQuery<ParseObject> query = ParseQuery.getQuery("Locations");
query.whereWithinKilometers("location", point, 100);
query.findInBackground(new FindCallback<ParseObject>() { ... });
}
Related
How to get direction to the nearest location outside circle if the blue dots is the current location?
1[1
and how to display markers ONLY around the current location in radius 2000m? I have stored the mapping lanslide in database and it displays when the app launch and it needs 7-9 seconds to load these markers. now i need to display only around the current location in order the app going smooth.
[these are the mapping dots of lanslide]
im doing my final projet, and I have a fEature which is really difficult.
Im on my android project, making a warning application on android about lanslide disaster, I do the mapping dots of lanslide locations and collect about 150 couples of lattitudes and longitudes and put it on database.
I assume if the user inside a circle, they are in lanslide location and they are not safe
the red zone radius is 2KM from the center of circle.
the orange zone radius is 1km from the center of circle.
the yellow zone radius is 500m from the center of circle
when the app is launch, the map will show up and animate the camera to my current location.
and then the app will tell the user if they are safe or not.
if the user OUTSIDE THE CIRCLE, then the user is safe. but,
if the current location inside the circle, then the user is not safe.
WHEN THE USER IS NOT SAFE, THE APP will give direction to shortest path outside the circle.
My app is almost done, except the last feature, I'm out of idea how to figure it out,
HOW THE APP CAN GIVE THE DIRECTION TO THE SHORTEST PATH OUTSIDE A CIRCLE??
unfortunately, how can the app will get direction to the shorthest outside circle for user if the CURRENT LOCATION inside 3 or mores circle ? and what google's libarry i can use for solve this?
how to get direction outside many circles? please help me.
enter image description here
this is my code:
public class MenuMaps extends Fragment implements OnMapReadyCallback {
private static MenuMaps instance = null;
private SupportMapFragment sMapFragment;
private MapView mMapView;
SupportMapFragment mapFragment;
private GoogleMap mMap;
private String[] id, desa, status_des;
boolean markerD[];
private Double latitude, longitude;
private Circle mCircle;
private Marker mMarker;
LatLng lokasisekarang;
boolean mapReady = false;
private GoogleApiClient client;
private GoogleApiClient client2;
public static MenuMaps getInstance() {
if (instance == null) {
instance = new MenuMaps();
Log.d( "MenuMaps", "getInstance");
}
return instance;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState)
{
Log.d("MenuMaps", "OnCreateView");
View inflatedView = inflater.inflate(R.layout.menu_maps, container, false);
MapsInitializer.initialize(getActivity());
mMapView = (MapView) inflatedView.findViewById(R.id.map);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this);
Button btnMap = (Button) inflatedView.findViewById(R.id.btnMap);
btnMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mapReady)
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
}) ;
Button btnSatellite = (Button) inflatedView.findViewById(R.id.btnSatellite);
btnSatellite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mapReady)
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
});
Button btnHybrid = (Button) inflatedView.findViewById(R.id.btnHybrid);
btnHybrid.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mapReady)
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
});
return inflatedView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Menu Maps");
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onResume() {
mMapView.onResume();
super.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void getLokasi() {
Log.d("desaStatus", "getLokasi");
String url = "http://dharuelfshop.com/skripsi/desaStatus.php/";
StringRequest request = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("desaStatus", response);
Gson gson = new Gson();
try {
JSONObject objinduk = new JSONObject(response);
List<DesaStatus> listDesaStatus = gson.fromJson(objinduk.getString("desaStatus"), new TypeToken<List<DesaStatus>>() {
}.getType());
Circle circleTerdekat = null;
Float distanceTerdekat = null;
for (DesaStatus desaStatus : listDesaStatus
) {
Log.d("desaStatus", desaStatus.toString());
LatLng center = new LatLng(desaStatus.lat_bcn,
desaStatus.long_bcn);
MarkerOptions markerOptions = new MarkerOptions()
.position(center)
.title("Desa : " + desaStatus.nama_des)
.snippet("Status : " + desaStatus.jenis_status)
.icon(BitmapDescriptorFactory
.defaultMarker(desaStatus.kode_warna));
mMarker = mMap.addMarker(markerOptions);
CircleOptions CircleOptions = new CircleOptions()
.center(center)
.radius(desaStatus.radius)//in meters
.strokeColor(Color.parseColor(desaStatus.warna_radius))
.strokeWidth(2)
.fillColor(Color.parseColor(desaStatus.warna_radius));
mCircle = mMap.addCircle(CircleOptions);
//hitung distance dan Status circle
float[] distance = new float[2];
Location.distanceBetween( lokasisekarang.latitude, lokasisekarang.longitude,
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
if (circleTerdekat == null) {
circleTerdekat = mCircle;
distanceTerdekat = distance[0];
} else {
if (distance[0] < distanceTerdekat ) {
distanceTerdekat = distance[0];
circleTerdekat = mCircle;
}
}
}
Log.d("circleTerdekat", "center: " + circleTerdekat.getCenter().latitude + " " + circleTerdekat.getCenter().longitude );
if( distanceTerdekat > circleTerdekat.getRadius() ){
Toast.makeText(getContext(), "You are safe, distance from center: " + distanceTerdekat + " radius: " + circleTerdekat.getRadius(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getContext(), "You are not safe, distance from center: " + distanceTerdekat + " radius: " + circleTerdekat.getRadius() , Toast.LENGTH_LONG).show();
}
} catch (JSONException error) {
Log.d("desaStatusError", error.toString());
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Error woy");
//Message
builder.setMessage("Error " + error); //+ error diganti sama (VolleyError error)
//Message
//builder.setIcon()
builder.setPositiveButton("Refreshh", new DialogInterface.OnClickListener() {
#Override //O nya huruf gede
public void onClick(DialogInterface dialog, int which) {
getLokasi();
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
// menambah request ke request queue
VolleyRequest.getInstance().addToRequestQueue(request);
}
public void getCurrentLocation() {
GpsTracker gps = new GpsTracker(getActivity());
if (gps.canGetLocation()) { // gps enabled
//Getting longitude and latitude
latitude = gps.getLatitude();
longitude = gps.getLongitude();
lokasisekarang = new LatLng(latitude, longitude);
drawMarkerWithCircle(lokasisekarang);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(lokasisekarang, 14f));
// \n is for new line
//Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
}
else {
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
//gps.stopUsingGPS();
}
}
private void drawMarkerWithCircle(LatLng lokasisekarang) {
MarkerOptions markerOptions = new MarkerOptions()
.position(lokasisekarang)
.title("You are here")
.snippet("here")
.icon(BitmapDescriptorFactory
.defaultMarker(HUE_BLUE));
mMarker = mMap.addMarker(markerOptions);
CircleOptions circleOptions = new CircleOptions()
.center(lokasisekarang)
.radius(2000)
.strokeWidth(2)
.strokeColor(Color.BLUE)
.fillColor(Color.parseColor("#500084d3"));
mMap.addCircle(circleOptions);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mapReady = true;
mMap = googleMap;
getCurrentLocation();
getLokasi();
if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true); // buat enable button location
}}
In order to show directions you need 2 points the origin and destination. The origin in this case will be your user's location.
Finding the destination point:
1) Currently you are storing the centre of these circular zones and their radii (500m, 1km etc). In addition to these you can easily calculate for each circle 4 'safe' points that lie along 4 directions (say N,S,E,W) and store them.
2) These points divide your circle into 4 quadrants. Now all you need to do is find which quadrant of the circle the user's current location is in and compare the distance between the points forming the quadrant and choose the lower of the two as your destination.
3) Use the Google Maps Directions API to show directions .
If you want to increase the accuracy of the algorithm all you need to do is increase the number of directions which will effectively divide your circle into more smaller parts and the destination will be more optimal.
Here '4' was just an arbitrary number . You can have different number based on number of safe points you choose and that will determine the accuracy of the algorithm
EDIT: Handling multiple circles intersecting is also easy. All you need to do then is instead of calculating the shortest for 1 circle you calculate for all the circles where the point lies and then find the min distance
Algorithm:
1) For each circle choose 'n' safe points. These 'n' points will form n - 1 sectors in the circle.
2) Get the current location of the user ( say A) and find all the circles where this point is included.
3) For each circle where pt A lies, calculate sector in which it lies. Say it lies on sector formed by points X_i and Y_i. Calculate the distance AX_i and AY_i.
4) Choose the minimum across all distances AX_i, AY_i and show navigation instructions for those points
It doesn't matter if the markers appear visually close to each other.. You're not going to visually find the direction the computing device is going to do it. Lat/Long values have a very high order of precision anyway.
Code Summary:
MainActivity is starting the NearbyPlacesMainActivity using an intent.
In the NearbyPlacesMainActivity, I nested AsyncTask class that gets all the nearby places’ bearings and names and get it stored in an ArrayList and display it.
My Goal: My only goal is to pass the nearby places’ names and bearings ArrayList to MainActivity not to update the UI.
Question:
As I just want the nearby places’ names and bearings to get stored in ArrayList and then pass it to MainActivity for later use, not to display it right now, so is it a professional approach and suitable performance wise? If not what will be the good approach in this scenario?
NearbyPlacesMainActivity
package com.example.atifarain.customizedcamera;
public class NearbyPlacesMainActivity extends ActionBarActivity {
AlertDialogManager alert = new AlertDialogManager();
GooglePlaces googlePlaces;
PlacesList nearPlaces;
// KEY Strings
public static String KEY_REFERENCE = "reference"; // id of the place
public static String KEY_NAME = "name"; // name of the place
ArrayList<HashMap<String, String>> placesListItems = new ArrayList<HashMap<String,String>>();
ArrayList<String> nearbyData = new ArrayList<String>();
public static double lat1 ;
public static double lon1 ;
MainActivity mainActivityObj;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nearby_places_main);
bearingView = (TextView) findViewById(R.id.textView3);
Bundle extras = getIntent().getExtras();
Location location = (Location)extras.get("key1");
lat1 = location.getLatitude();
lon1 = location.getLongitude();
new LoadPlaces().execute();
}
class LoadPlaces extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... args) {
// creating Places class object
googlePlaces = new GooglePlaces();
try {
String types = "cafe|restaurant|atm";
double radius = 2000; // 1000 meters
nearPlaces = googlePlaces.search(lat1, lon1, radius, types);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
runOnUiThread(new Runnable() {
public void run() {
// Get json response status
String status = nearPlaces.status;
// Check for all possible status
if(status.equals("OK")){
// Successfully got places details
if (nearPlaces.results != null) {
// loop through each place
ArrayList<String> coordinates = new ArrayList<String>();
ArrayList<Double> bearings = new ArrayList<Double>();
for (Place p : nearPlaces.results) {
HashMap<String, String> map = new HashMap<String, String>();
// Place reference is used to get "place full details"
map.put(KEY_REFERENCE, p.reference);
map.put(KEY_NAME, p.name); // Place name
double lat2 = p.geometry.location.lat;
double lon2 = p.geometry.location.lng;
double _bearing = bearing(lat1, lon1, lat2, lon2);
bearings.add(_bearing);
String lat = Double.toString(lat2);
String lon = Double.toString(lon2);
String latlon = lat + " , " + lon;
coordinates.add(latlon);
String nearbyDat = Double.toString(_bearing)+" , "+p.name;
nearbyData.add(nearbyDat);
placesListItems.add(map); // adding HashMap to ArrayList
}
bearingView.setText("");
for (int k = 0; k < bearings.size(); k++){
bearingView.append(k+1 + ": " + nearbyData.get(k) + "\n");
}
}
}
else if(status.equals("ZERO_RESULTS")){
alert.showAlertDialog(NearbyPlacesMainActivity.this, "Near Places",
"Sorry no places found. Try to change the types of places", false);
}
else if(status.equals("UNKNOWN_ERROR")){
alert.showAlertDialog(NearbyPlacesMainActivity.this, "Places Error",
"Sorry unknown error occured.", false);
}
else if(status.equals("OVER_QUERY_LIMIT")){
alert.showAlertDialog(NearbyPlacesMainActivity.this, "Places Error",
"Sorry query limit to google places is reached", false);
}
else if(status.equals("REQUEST_DENIED")){
alert.showAlertDialog(NearbyPlacesMainActivity.this, "Places Error",
"Sorry error occured. Request is denied", false);
}
else if(status.equals("INVALID_REQUEST")){
alert.showAlertDialog(NearbyPlacesMainActivity.this, "Places Error",
"Sorry error occured. Invalid Request", false);
}
else{
alert.showAlertDialog(NearbyPlacesMainActivity.this, "Places Error", "Sorry error occured.", false);
}
}
});
}
protected double bearing(double lat1, double lon1, double lat2, double lon2) {
double Longitude_Difference = Math.toRadians(lon2 - lon1);
double latitude_1 = Math.toRadians(lat1);
double Latitude_2 = Math.toRadians(lat2);
double y = Math.sin(Longitude_Difference) * Math.cos(Latitude_2);
double x = Math.cos(latitude_1) * Math.sin(Latitude_2) - Math.sin(latitude_1) * Math.cos(Latitude_2) * Math.cos(Longitude_Difference);
double result = Math.toDegrees(Math.atan2(y, x));
return (result+360.0d)%360.0d;
}
}
}
PS. I am very new to android, though I went through all the Handler, Thread and AsyncTask stuff but didn’t get much in practical so I don’t know much about the performance things in android that which are more suitable so please bear with me and if anyone finds it off topic or too broad then before negative voting please do let me know in comments, so I could improve it. Thanks :)
Consider using EventBus library which allows you easily communicate between different parts of Android application and prevents from producing related boilerplate code.
There are few things I want to point out.
Creating an AsyncTask as an inner class of your activity could potentially cause a leak since inner classes have an implicit reference to outer one and your background thread may outlive the activity. For example if the screen is rotated while the task is executing, your activity will be destroyed/recreated, you should be handling that case.
onPostExecute already runs on UI thread as per documentation so you do not need to explicitly call runOnUiThread
There are lot of ways of communicating back to the activity if you move your async task out. I normally create an interface and have my activity implement that interface. Then pass the reference to your activity to the AsyncTask but hold on to that reference Weakly so you don't leak if your activity dies before the AsyncTask completes. And then invoke the call back from your interface in onPostExecute()
When a user clicks on a position on the map, a dialog alert box opens up and prompts the user to whether or not he or she wants to add a marker, if yes the marker is added. I am trying to write another method that if the user passes this marker, the marker changes color.
I am having trouble writing the marker checking part of this.
My code:
public void onMapClick(){
map.setOnMapClickListener(new OnMapClickListener() {
#Override
public void onMapClick(LatLng latlng) {
dialogBox(latlng);
}
});
}
private void dialogBox(final LatLng latlng) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MapActivity.this);
alertDialogBuilder.setTitle("Add Marker");
alertDialogBuilder
.setMessage("Add marker?").setCancelable(false)
.setPositiveButton("yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
double dialogLat = latlng.latitude;
double dialogLng = latlng.longitude;
dialogMarker = map.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))
.position(latlng).title("dialog maker"));
//if location hit, places marker around that area
hitLocation(dialogLat,dialogLng);
}
})
.setNegativeButton("no", new DialogInterface.OnClickListener() {
//cancels
}
}); // create alert dialog show it
}
public void hitLocation( final double dialogLat, final double dialogLng){
LocationListener ll = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
double lat = location.getLatitude();
double lon = location.getLongitude();
final LatLng currentLatLon = new LatLng(lat, lon);
//tracks weather or not person hit the location
if((lat > (dialogLat- 0.0001) && lat < (dialogLat+ 0.0001)) &&
(lon > (dialogLon - 0.0001) && lon < (dialogLon + 0.0001))){
dialogMarker = map.addMarker(new MarkerOptions().position(currentLatLon)
}
} // other location listener methods
It works up to where I pass hitLocation(doubleLat,doubleLng) inside the onClick method for the alert dialog. What I think should happen is that when I place a marker on the map, hitLocation should check whether or not I actaully hit the location that the user set.
It's really not clear how this all comes together (at least for me). For example, I don't see how hitLocation(double, double) is even called, but I do see a couple of issues.
First off. Is this a typo?
if((lat > (dialogLat- 0.0001) && lat < (dialogLng+ 0.0001))
did you mean
if((lat > (dialogLat- 0.0001) && lat < (dialogLat+ 0.0001))
dialog**Lat** vs dialog**Lng**
I think you would be better off checking if a coordinate is close by using something like this.
Math.abs(value1 - value2) < someTolerance
latitudes and longitudes are not always positive.
I'm using Mapsforge Library to develop my app. In the map, you can create your own mark by long press on the map.
Now i would like to save this marker using sharedPreferences, so if the user close the app and repp, the marker still there. Unfortunately, i have not found such information around the web on how to do so. I have found some information on how to do it using Google maps, but google map have different functions.
Can anyone help me how to do it?
this is how i add the mark on the map. the code is in the OnCreate part:
myListOverlay = new ListOverlay();
myOverlayItems = myListOverlay.getOverlayItems();
mapView.getOverlays().add(myListOverlay);
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
#Override
public void onLongPress(MotionEvent e) {
float x = e.getX();
float y = e.getY();
if (e.getAction() == MotionEvent.ACTION_DOWN) {
GeoPoint gPt = mapView.getProjection().fromPixels((int) x, (int)y);
myMarker = createMarker(gPt, R.drawable.ic_location);
myOverlayItems.add(myMarker);
byte viewMarker = mapView.getMapViewPosition().getZoomLevel();
mapView.getMapViewPosition().setZoomLevel(viewMarker);
}
}
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
myOverlayItems.remove(myMarker);
byte viewMarker = mapView.getMapViewPosition().getZoomLevel();
mapView.getMapViewPosition().setZoomLevel(viewMarker);
return true;
};
}
);
mapView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v0, MotionEvent e) {
// Only fires if Mapview touched
return mGestureDetector.onTouchEvent(e);
}
});
Thanks to zcg7009 i was able to let the shared preferences work, but still a problem. This is the code:
in onCreate
if((prefs.contains("Lat")) && (prefs.contains("Lon"))){
String lat = prefs.getString("Lat",""); //with "" it throw error " Invalid "" ", if i put "0" the marker appear somewhere in the map
String lng = prefs.getString("Lng", "");
GeoPoint l =new GeoPoint(Double.parseDouble(lat),Double.parseDouble(lng));
myMarker = createMarker(l, R.drawable.ic_location);
myOverlayItems.add(myMarker);
byte viewMarker = this.mapView.getMapViewPosition().getZoomLevel();
this.mapView.getMapViewPosition().setZoomLevel(viewMarker);
this.mapView.getMapViewPosition().setCenter(l);
}
In the LongPress method
float x = e.getX();
float y = e.getY();
GeoPoint gPt = mapView.getProjection().fromPixels((int)x, (int)y);
myMarker = createMarker(gPt, R.drawable.ic_location);
myOverlayItems.add(myMarker);
byte viewMarker = mapView.getMapViewPosition().getZoomLevel();
mapView.getMapViewPosition().setZoomLevel(viewMarker);
prefs.edit().putString("Lat",String.valueOf(gPt.latitude)).commit();
prefs.edit().putString("Lon",String.valueOf(gPt.latitude)).commit();
the problem is in the second and third line of the code inside onCreate. If i use "" it throw the error invalid "", if i use "0" , the marker appear somewhere on the map.
How can solve this?
Do something like this, in your class add
private SharedPreferecnes prefs;
Then when your activity is destroyed
#Override
public void onDestroy(){
prefs.putDouble("marker_latitude", marker.getPosition().latitude);
prefs.putDouble("marker_longitude", marker.getPosition().longitude);
}
Then in onCreate
prefs = this.getSharedPreferences("com.smashing_boxes.taskproject",
Context.MODE_PRIVATE);
double latitude = prefs.getDouble("marker_latitude", -1.0);
double longitude = prefs.getDouble("marker_latitude", -1.0);
if(latitude != -1.0 && longitude != -1.0){
Marker marker = mapView.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude)));
myOverlayItems.add(marker);
}
This says that if you have stored a latitude and longitude in your preferences, you want to draw the marker on your map at the given coordinates and add the marker to your overlay items list.
String fnail LOCATION_KEY = "key":
SharedPreferences preferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
preferences = getPreferences(MODE_APPEND);
String location = preferences = getString(LOCATION_KEY ,"default Value");
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Editor editor = preferences.edit();
editor.putString(LOCATION_KEY, "what ever you want");
editor.commit();
}
this is in generally how to use SharedPreferences just do same thing in your project
i hope this helps
Ok, so I'm editing this to include the whole class with some new code I added over the past couple of hours. Basically, I'm looking to populate a Google Map with markers that represent a Facebook user's checkins. Unfortunately, my code has not been cooperating - I've tried reviewing the documentation that Facebook provides and searching the web for answers without coming up with anything useful. So far all I've been able to get the app to do is validate the app's permissions with Facebook and display the map, though I had tested the ability to add markers with dummy values in an earlier version of the app and that worked fine.
My earlier question dealt with why my calls to the Graph API weren't displaying anything - I had made the same call as listed in the AuthorizeListener sub-class, but was merely attempting to output the raw JSON string in a log entry instead of manipulating it. I think that whatever was the cause of that problem is probably the same cause of my current problem.
Anyway, how do I get my app to display markers for locations a user has checked in to? I think my code gets me off to a pretty good start, but there are obviously issues in my AuthorizeListener sub-class. What do you guys think?
public class FBCTActivity extends MapActivity {
public static Context mContext;
List<Overlay> mapOverlays;
FBCTMarkerOverlay markerLayer;
ArrayList<OverlayItem> overlays = new ArrayList<OverlayItem>();
// Facebook Application ID
private static final String APP_ID = "";
Facebook mFacebook = new Facebook(APP_ID);
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.main);
// Set up Facebook stuff
mFacebook.authorize(this, new String[]{"user_checkins", "offline_access"}, new AuthorizeListener());
// Set up map stuff
MapView mMapView = (MapView)findViewById(R.id.map);
mMapView.setSatellite(true);
MapController mMapController = mMapView.getController();
mMapController.animateTo(getCurrentLocation());
mMapController.setZoom(3);
// Set up overlay stuff
mapOverlays = mMapView.getOverlays();
Drawable drawable = this.getResources().getDrawable(R.drawable.icon);
markerLayer = new FBCTMarkerOverlay(drawable);
// markerLayer is populated in the AuthorizeListener sub-class
mapOverlays.add(markerLayer);
}
/**
* Determines the device's current location, but does not display it.
* Used for centering the view on the device's location.
* #return A GeoPoint object that contains the lat/long coordinates for the device's location.
*/
private GeoPoint getCurrentLocation() {
LocationManager mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria mCriteria = new Criteria();
mCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
mCriteria.setPowerRequirement(Criteria.POWER_LOW);
String mLocationProvider = mLocationManager.getBestProvider(mCriteria, true);
Location mLocation = mLocationManager.getLastKnownLocation(mLocationProvider);
int mLat = (int)(mLocation.getLatitude()*1E6);
int mLong = (int)(mLocation.getLongitude()*1E6);
return new GeoPoint(mLat, mLong);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
private class AuthorizeListener implements DialogListener {
public void onComplete(Bundle values) {
new Thread() {
#Override
public void run() {
try {
String response = mFacebook.request("me/checkins"); // The JSON to get
JSONObject jObject = Util.parseJson(response);
JSONArray jArray = jObject.getJSONArray("data"); // Read the JSON array returned by the request
for (int i = 0; i < jArray.length(); i++) { // Iterate through the array
JSONObject outerPlace = jArray.getJSONObject(i); // The outer JSON object
JSONObject place = outerPlace.getJSONObject("place"); // Second-tier JSON object that contains id, name, and location values for the "place"
String placeName = place.getString("name"); // The place's name
JSONObject placeLocation = place.getJSONObject("location"); // Third-tier JSON object that contains latitude and longitude coordinates for the place's "location"
int lat = (int) (placeLocation.getDouble("latitude")*1E6); // The place's latitude
int lon = (int) (placeLocation.getDouble("longitude")*1E6); // The place's longitude
String date = outerPlace.getString("created_time"); // Timestamp of the checkin
overlays.add(new OverlayItem(new GeoPoint(lat, lon), placeName, "Checked in on: " + date)); // Add the place's details to our ArrayList of OverlayItems
}
mFacebook.logout(mContext); // Logout of Facebook
for (int i = 0; i < overlays.size(); i++) {
markerLayer.addOverlayItem(overlays.get(i));
}
} catch(IOException e) {
Log.v("FBCTActivity", e.getMessage());
} catch(JSONException e) {
Log.v("FBCTActivity", e.getMessage());
}
}
}.start();
}
public void onFacebookError(FacebookError e) {
Log.w("FBCTActivity", e.getMessage());
// TODO: Add more graceful error handling
}
public void onError(DialogError e) {
Log.w("FBCTActivity", e.getMessage());
}
public void onCancel() {
// TODO Auto-generated method stub
}
}
}
It might not be the reason but you haven't defined your app ID:
private static final String APP_ID = "";
Also, you have to override the onActivityResult in the activity where you call the mFacebook.authorize, so add this to your code:
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
mFacebook.authorizeCallback(requestCode, resultCode, data);
}
If you don't do so, your app won't get the token for the Graph and your connection will return a JSON error msg.