I new in the developping of android applications using ArcGIS android runtime API.
I am trying to zoom to an extend and hightlights that extend . But it is not working in my case.
Feature layer url ishttps://services7.arcgis.com/7FyZZrSIYfiWYztL/ArcGIS/rest/services/MyGisFileTest/FeatureServer/0
which is getting from ArcGIS online portal.
i have added the layer in the map
ArcGISFeatureLayer fl1 = new ArcGISFeatureLayer(
"https://services7.arcgis.com/7FyZZrSIYfiWYztL/ArcGIS/rest/services/MyGisFileTest/FeatureServer/0",
ArcGISFeatureLayer.MODE.ONDEMAND);
fl1.setOnStatusChangedListener(statusChangedListener);
mMapView.addLayer(fl1);
Here i am getting my ward_name from the user input by using the edittext andi am submitting that to an asyn class to fetch data .
I am calling the sync task on button click and passing the user inputed values to the async task.
declaration section
//query task
private Callout mCallout;
private ViewGroup mCalloutContent;
private Graphic mIdentifiedGraphic;
private String mFeatureServiceURL;
private GraphicsLayer mGraphicsLayer;
private ProgressDialog progress;
EditText _EdtTxtTextToZoom;
Button _BtnZoomToExtend;
In my oncreate method i am definig all the things
mGraphicsLayer = new GraphicsLayer();
mMapView.addLayer(mGraphicsLayer);
LayoutInflater inflater = getLayoutInflater();
mCallout = mMapView.getCallout();
// Get the layout for the Callout from
// layout->identify_callout_content.xml
mFeatureServiceURL="https://services7.arcgis.com/7FyZZrSIYfiWYztL/ArcGIS/rest/services/MyMapService/FeatureServer/0";
mCalloutContent = (ViewGroup) inflater.inflate(R.layout.identify_callout_content, null);
mCallout.setContent(mCalloutContent);
mIdentifiedGraphic = getFeature(fl1);
_EdtTxtTextToZoom=(EditText)findViewById(R.id.EdtTxtTextToZoom);
_BtnZoomToExtend=(Button)findViewById(R.id.BtnZoomToExtend);
_BtnZoomToExtend.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String tempEdtTxtTextToZoom= "";
try {
tempEdtTxtTextToZoom = _EdtTxtTextToZoom.getText().toString();
new QueryFeatureLayer().execute(tempEdtTxtTextToZoom);
} catch (NumberFormatException e) {
e.printStackTrace();
}
Toast.makeText(MainActivity.this, "tempEdtTxtTextToZoom.."+tempEdtTxtTextToZoom, Toast.LENGTH_SHORT).show();
}
});
AsyncTask
private class QueryFeatureLayer extends AsyncTask<String, Void, FeatureResult> {
// default constructor
public QueryFeatureLayer() {
}
#Override
protected void onPreExecute() {
progress = ProgressDialog.show(MainActivity.this, "", "Please wait....query task is executing");
}
#Override
protected FeatureResult doInBackground(String... params) {
Log.e("params[0]--",params[0]);
String whereClause = "ward_name ='" + params[0] + "'";
Log.e("whereClause--",whereClause);
// Define a new query and set parameters
QueryParameters mParams = new QueryParameters();
mParams.setWhere(whereClause);
mParams.setReturnGeometry(true);
// Define the new instance of QueryTask
QueryTask queryTask = new QueryTask(mFeatureServiceURL);
FeatureResult results;
try {
// run the querytask
results = queryTask.execute(mParams);
Log.e("results---", String.valueOf(results));
return results;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(FeatureResult results) {
// Remove the result from previously run query task
mGraphicsLayer.removeAll();
// Define a new marker symbol for the result graphics
SimpleMarkerSymbol mGreenMarkerSymbol = new SimpleMarkerSymbol(Color.GREEN, 15, SimpleMarkerSymbol.STYLE.CIRCLE);
// Envelope to focus on the map extent on the results
Envelope extent = new Envelope();
// iterate through results
for (Object element : results) {
// if object is feature cast to feature
if (element instanceof Feature) {
Feature feature = (Feature) element;
// convert feature to graphic
Graphic graphic = new Graphic(feature.getGeometry(), mGreenMarkerSymbol, feature.getAttributes());
// merge extent with point
extent.merge((Point)graphic.getGeometry());
Log.e("points----", String.valueOf(graphic.getGeometry()));
// add it to the layer
mGraphicsLayer.addGraphic(graphic);
}
}
Log.e("points----", String.valueOf(extent));
// Set the map extent to the envelope containing the result graphics
mMapView.setExtent(extent, 100);
// Disable the progress dialog
progress.dismiss();
}
}
Can you please figure it out where i am doing the mistake ?
In the above example im trying to zoom points but actually i wanted the polygon Below is the correct code to zoom a particular polygons extent
for (Object element : results) {
progress.incrementProgressBy(size / 100);
if (element instanceof Feature) {
Feature feature = (Feature) element;
// turn feature into graphic
Graphic graphic = new Graphic(feature.getGeometry(),
feature.getSymbol(), feature.getAttributes());
Polygon p = (Polygon) graphic.getGeometry();
p.queryEnvelope(extent);
extent.merge(extent);
// add graphic to layer
mGraphicsLayer.addGraphic(graphic);
Related
I am trying to display data from a an array list but after the marker onclick
it only displays the last element in the array list in the material dialog box
DriverLocationDataManager gets all the data snapshots of the geopoints of the drivers in the database
after adding in all the driver data, i use the addMarker function which gets the geopoints and set the markers on the map.
//Init data manager
drivers = new ArrayList<>(0);
dataManager = new DriverLocationDataManager(this) {
#Override
public void onDataLoaded(List<Driver> data) {
if (data.isEmpty()) {
Snackbar.make(container, "Sorry!. UG Shuttle service is currently unavailable",
Snackbar.LENGTH_INDEFINITE).show();
} else {
drivers.addAll(data);
List<Marker> markers = addMarkers(data);
for (int i = 0; i < markers.size(); i++){
markers.get(i);
Driver driver = drivers.get(i);
map.setOnMarkerClickListener(marker -> {
// Get custom view
View v = getLayoutInflater().inflate(R.layout.driver_popup, null, false);
//Assign props
TextView username = v.findViewById(R.id.driver_username);
CircularImageView profile = v.findViewById(R.id.driver_profile);
ImageView status = v.findViewById(R.id.driver_status);
TextView shuttle = v.findViewById(R.id.driver_bus_number);
ViewGroup viewGroup = v.findViewById(R.id.group);
//Init props
Glide.with(getApplicationContext())
.load(driver.getProfile())
.apply(RequestOptions.circleCropTransform())
.apply(RequestOptions.placeholderOf(R.drawable.avatar_placeholder))
.apply(RequestOptions.errorOf(R.drawable.avatar_placeholder))
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.AUTOMATIC))
.transition(withCrossFade())
.into(profile);
username.setText(driver.getDriver()); //Driver's username
shuttle.setText(driver.getCarNumber()); //Driver's car number
//Attach to dialog
Builder materialDialog = new Builder(HomeActivity.this)
.customView(v, true)
.negativeText("Dismiss")
.onPositive((dialog, which) -> {
dialog.dismiss();
enableTracking(marker);
})
.onNegative((dialog, which) -> dialog.dismiss());
if (driver.isStatus()) {
status.setImageResource(android.R.color.holo_green_light); //Online
//Enable tracking when driver is online
materialDialog.positiveText("Track")
.onPositive((dialog, which) -> {
dialog.dismiss();
enableTracking(marker);
});
} else {
//Tracking is disabled
status.setImageResource(android.R.color.holo_red_light); //Offline
}
materialDialog.build().show();
return true;
});
}
}
}
};
I invite you to read the official developer guide here. It explains how to properly use Dialogs, how to display a list in it, and even how to implement a custom view if you need one to display your list.
i'm trying to download a list of cases from a server and then populate an arraylist to use it in my RecyclerView Adapter but every time i try to populate the array list from asynctask i can print the data in every single step from the populating bu not from the Arraylist i'm using (i'm trying to store in an arrayList that contains objects of the type Case which i created)
this is the part of the code with the problem
this is my AsyncTask...
`
public class downloadingNewCases extends AsyncTask<Void,Void ,Boolean>{
private String userid ;
private String state ;
public downloadingNewCases(String userid ,String state ){
this.userid = userid ;
this.state = state ;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.d(AppController.DEBUG, "download New Cases Started");
}
#Override
protected Boolean doInBackground(Void... params){
Log.d(AppController.DEBUG , "user id in the get cases link.." + userid);
String url = AppController.ApiUrl + "GetCases?UserName="+ userid +"&stat="+state;
Log.d(AppController.DEBUG_LINK,url);
try {
JsonArrayRequest request = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d("TEST", String.valueOf(response.length()));
for (int i = 0; i < response.length(); i++) {
try {
Log.d("TEST","downloading data" );
JSONObject object = response.getJSONObject(i);
JSONArray specs = object.getJSONArray("Spe");
ArrayList<Specialities> spe = new ArrayList<>();
for (int j = 0; j < specs.length(); j++) {
Log.d("TEST",specs.getJSONObject(j).getString("SName") );
spe.add(new Specialities(null, specs.getJSONObject(j).getString("SName")));
}
Case ca = new Case(object.getString("ID")
, object.getString("Serial")
, object.getString("Name")
, object.getString("gender")
, object.getString("Age")
, object.getString("NatioanlityID")
, object.getString("HealthProblem")
, object.getString("CityID")
, object.getString("Problem")
, object.getString("Date")
, object.getString("Status")
, spe);
Log.d("TEST",ca.toString());
cases.add(ca);
spe.clear();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d(AppController.DEBUG , volleyError.toString());
}
});
request.setRetryPolicy(new DefaultRetryPolicy(
0,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingleton.getmInstance(getActivity()).addToRequestQueue(request);
}catch (Exception e){
Log.d(AppController.DEBUG,"error in the asynctask in the new cases freagment... ");
Log.d(AppController.DEBUG ,e.toString());
}
Log.d(AppController.DEBUG, "Cases size ::" + cases.size());
return true;
}
#Override
protected void onPostExecute(Boolean bool) {
super.onPostExecute(bool);
/* if(listener != null){
listener.getCases(cases);
}*/
adapter.notifyDataSetChanged();
// Log.d(AppController.DEBUG, "new Cases Downloaded...");
}
}
`
(I'm sure that the adapter and recycler view code is correct because I could use the same code now but when I came to test it again it did not work anymore and I can't remember if I changed some thing in it or not - I think not)..
this is my onViewCreate Method .
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.doctor_new_cases_fragment,container,false);
Log.d(AppController.DEBUG_SHARED,"userID in the new case activity ..." + userID);
SharedPreferences prefs = getActivity().getSharedPreferences(AppController.PREFERENCES_NAME , Context.MODE_PRIVATE);
userID = prefs.getString(DoctorProfileSubmitActivity.Shared_userid,null) ;
downloadingNewCases tast = new downloadingNewCases(userID ,"");
tast.execute();
recyclerView = (RecyclerView)view.findViewById(R.id.recyclervew_new_cases);
adapter = new CasesAdapter(view.getContext(), cases);
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null){
parent.removeView(view);
}
return view;
}
and finally the Array list is declared as an instance variable of the class (the class extends Fragment + it is a fragment that I'm using in my view pager as a tab layout for my tabbed Activity .)
here's the ArrayList declaration
private final ArrayList<Case> cases = new ArrayList<>();
Since you say you can print the data every step of the way, the problem is probably not related to your data. The problem might be your Arraylist of case And your CaseAdapter.
Let's try a simple test, instead of filling your adapter with case objects, create a new ArrayList of string and fill it with object.getString("name") in your on response. Then change your oncreateview to display this list of names using a normal string arrayadapter.
If you can successfully display the names, the it means the bug is in your case and caseadapter, you would have to show more code for us to help.
sorry guys it was not worth it to add a question on the site right away
i fixed the problem . (it appears that my problem was here)
Case ca = new Case(object.getString("ID")
, object.getString("Serial")
, object.getString("Name")
, object.getString("gender")
, object.getString("Age")
, object.getString("NatioanlityID")
, object.getString("HealthProblem")
, object.getString("CityID")
, object.getString("Problem")
, object.getString("Date")
, object.getString("Status")
, spe);
i accidentally changed object.getString("Gender") to object.getString("gender")
which caused me a JSONException .
i fixed that and everything is working again .
thanks for your help and i'm sorry if i rushed to ask the question without a proper debugging session first .
In my first AsyncTask doInBackground method I run a method that get a list of places from Google Place Api. Inside the postExecute of this first AsyncTask, I get all the names of these places and show them all in a ListView.
I now would like to show the driving distance of a single place from my current location (I can already get it). To do so, I created, in another class, another AsyncTask to get this distance. Here is the code:
public class Distance extends AsyncTask<Double, Double, String> {
GooglePlaces googlePlaces;
String distancePlace = null;
#Override
final protected String doInBackground(Double... params) {
double lat1,lat2,lon1,lon2;
lat1=params[0];
lon1=params[1];
lat2=params[2];
lon2=params[3];
googlePlaces = new GooglePlaces();
distancePlace= googlePlaces.getDistance(lat1,lon1,lat2,lon2);
return distancePlace;
}
}
and this is the code of my first AsyncTask postExecute:
protected void onPostExecute(String s) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//get json status
String status = nearPlaces.status;
if (status.equals("OK")){
if (nearPlaces.results != null){
//every single place
for (Place p : nearPlaces.results){
//just a try, here I would like to get the distance
/*
Double[] myparams = {gps.getLatitude(),gps.getLongitude(),
p.geometry.location.lat,p.geometry.location.lng};
new Distance().execute(myparams);*/
HashMap<String,String> map = new HashMap<String, String>();
map.put(KEY_NAME,p.name);
//add hashmap
placesListItems.add(map);
}
ListAdapter adapter = new SimpleAdapter(GpsActivity.this, placesListItems, R.layout.list_item, new String[] {KEY_REFERENCE,KEY_NAME},
new int[] {R.id.reference, R.id.name});
//add into listview
lv.setAdapter(adapter);
}
My problem is how to execute the "distance AsyncTask" inside my postExecute and return its result into my first AsyncTask, to show it in my ListView.
You can do something like this:
Distance distance = new Distance(){
protected void onPostExecute(final String result1) {
// First AsyncTask result.
Distance distance2 = new Distance(){
protected void onPostExecute(String result2) {
// process the second result.
// Because the first result "result1" is "final",
// it can be accessed inside this method.
}
};
distance2.execute(...);
}
};
distance.execute(...);
Also, you don't need to use runOnUiThread(...) because the onPostExecute(...) method is executed on the UI thread.
I am using a Listview of two graphs plotted using androidplot library. I don't know how to constantly update the listview whenever I have new incoming data.
I have a method which receives random data from a device continuously. I have to update the two graphs with this new data. I use a custom view adapter built from Array adapter as found below.
class MyViewAdapter extends ArrayAdapter<View> {
public MyViewAdapter(Context context, int resId, List<View> views) {
super(context, resId, views);
}
#Override
public int getCount() {
return 2;
}
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
LayoutInflater inf = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = convertView;
if (v == null) {
v = inf.inflate(R.layout.listview_example_item, parent, false);
}
p = (XYPlot) v.findViewById(R.id.xyplot);
Random generator = new Random();
p.setTitle("plot" + pos);
for (int k = 0; k < NUM_SERIES_PER_PLOT; k++) {
double rl = Math.random();
double gl = Math.random();
double bl = Math.random();
double rp = Math.random();
double gp = Math.random();
double bp = Math.random();
if(setArrayValues != null){
if(pos == 0) {
XYSeries series = new SimpleXYSeries(setArrayValues.getSeries1Numbers(), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "RPM");
//XYSeries series = new SimpleXYSeries(nums, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "RPM");
p.addSeries(series, new LineAndPointFormatter(
Color.rgb(new Double(rl * 255).intValue(), new Double(gl * 255).intValue(), new Double(bl * 255).intValue()),
Color.rgb(new Double(rp * 255).intValue(), new Double(gp * 255).intValue(), new Double(bp * 255).intValue()),
null, null));
}
else{
XYSeries series = new SimpleXYSeries(setArrayValues.getSeries2Numbers(), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "SPEED");
//XYSeries series = new SimpleXYSeries(nums, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "SPEED");
p.addSeries(series, new LineAndPointFormatter(
Color.rgb(new Double(rl * 255).intValue(), new Double(gl * 255).intValue(), new Double(bl * 255).intValue()),
Color.rgb(new Double(rp * 255).intValue(), new Double(gp * 255).intValue(), new Double(bp * 255).intValue()),
null, null));
}
}
}
p.redraw();
return v;
}
}
The below method receives data from a device and updates relevant Arraylists.
public void receivePackage() throws SocketException {
new Thread() {
byte[] packet = new byte[64];
DatagramPacket data = new DatagramPacket(packet,
packet.length);
DatagramSocket socket = new DatagramSocket(null);
JSONObject json;
#Override
public void run() {
try {
isRunning = true;
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(50009));
} catch (SocketException e1) {
e1.printStackTrace();
}
try {
while (isRunning) {
socket.receive(data);
final String string = new String(
data.getData(), 0,
data.getLength(), "UTF-8");
json = new JSONObject(string);
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
int wiper = json.getInt("wiper");
int speed = json.getInt("speed");
speed = speed + 2000;
setArrayValues.addValues(wiper,speed);
lv.invalidateViews();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
socket.close(); // keep this out of while
}
}.start();
}
Actually I cannot plot the data points in the graph. I have used
setArrayValues.addValues(wiper,speed);
I have a separate helper class which sets the values to two different ArrayLists which I use in the line
XYSeries series = new SimpleXYSeries(setArrayValues.getSeries1Numbers(), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "RPM");
XYSeries series = new SimpleXYSeries(setArrayValues.getSeries2Numbers(), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "RPM");
But the values are not displayed in the plot. Can you suggest any solution for this.
The notifyDatasetChanged will retrigger the getView for your visible views.
Be careful that you'll have to reset the graphs before setting the new data.
It's not gonna be efficient tho.
Why are you using a listView if you only have two graphs? A ScrollView with a linearlayout would be much easier to manage.
Without seeing all of your code, I would guess that one of the following is the case.
1) You never initialize setArrayValues, so that setArrayValues == null, and hence the series are never created.
2) You are not calling notifyDataSetChanged on your adapter. For instance, if you want the graphs to repeatedly update, then you need to call notifyDataSetChanged on your adapter, which will trigger a call to getView(), where you are creating the plots.
The problem seems to be outside of the code you have displayed. Something is not being done properly. Its hard to even tell if you actually set up an adapter. For instance, it seems like the easiest way to set up your code would be to have an ArrayAdapter, and then call notifyDataSetChanged. It seems like you are trying to accomplish the same thing by using lv.invalidateViews();, where I'm guessing that lv stands for ListView. If this is the case, then that is the problem... You need to have some type of adapter for the listView, and it seems like you don't have one. Try setting up an arrayAdapter, then in place of lv.invalidateViews();, use
myAdapter.notifyDataSetChanged();
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.