This is my second post about using Oauth enabled API on Android. This time i’ll try to explain how to use Foursquare API V2 within Android application. I built my own Android implementation for Foursquare API based on my previous implementation for Twitter API that can be used to post Twitter status from Android. To use Foursquare API within an Android application, first you have to register your application on Foursquare to get the client id and client secret key.
I. Register application
To register your application:
- Go to Foursquare Oauth page and login with your username and password
- After logged in, click the ‘REGISTER A NEW CONSUMER’ button
- Fill the registration form with your application name, application website url and the callback url. For callback url, you can use any url or string if your app is for mobile application only, for example myapp://connect
<
- After finishing the registration , you’ll get client id and client secret key that will be used later to connect to Foursquare from Android app.
- Get access token by letting user grant access to the app using a webview based authentication dialog
- Save access token on shared preferences
- Use the access token to access Foursquare API endpoints
I’ve included a sample project in this tutorial that can be downloaded on my github repo here. I’ll explain how to use my implementation based on the sample project. In my sample project, i create three classes used to handle authentication and connection to Foursquare: FoursquareApp.java (handle oauth authentification), FoursquareSession.java (save access token on shared preferences) and FoursquareDialog.java (webview authentication dialog).
Main.java
public class Main extends Activity { private FoursquareApp mFsqApp; private ListView mListView; private NearbyAdapter mAdapter; private ArrayList<FsqVenue> mNearbyList; private ProgressDialog mProgress; public static final String CLIENT_ID = "your client id"; public static final String CLIENT_SECRET = "your client secret"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView nameTv = (TextView) findViewById(R.id.tv_name); Button connectBtn = (Button) findViewById(R.id.b_connect); final EditText latitudeEt = (EditText) findViewById(R.id.et_latitude); final EditText longitudeEt = (EditText) findViewById(R.id.et_longitude); Button goBtn = (Button) findViewById(R.id.b_go); mListView = (ListView) findViewById(R.id.lv_places); mFsqApp = new FoursquareApp(this, CLIENT_ID, CLIENT_SECRET); mAdapter = new NearbyAdapter(this); mNearbyList = new ArrayList<FsqVenue>(); mProgress = new ProgressDialog(this); mProgress.setMessage("Loading data ..."); if (mFsqApp.hasAccessToken()) nameTv.setText("Connected as " + mFsqApp.getUserName()); FsqAuthListener listener = new FsqAuthListener() { @Override public void onSuccess() { Toast.makeText(Main.this, "Connected as " + mFsqApp.getUserName(), Toast.LENGTH_SHORT).show(); nameTv.setText("Connected as " + mFsqApp.getUserName()); } @Override public void onFail(String error) { Toast.makeText(Main.this, error, Toast.LENGTH_SHORT).show(); } }; mFsqApp.setListener(listener); //get access token and user name from foursquare connectBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mFsqApp.authorize(); } }); //use access token to get nearby places goBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String latitude = latitudeEt.getText().toString(); String longitude = longitudeEt.getText().toString(); if (latitude.equals("") || longitude.equals("")) { Toast.makeText(Main.this, "Latitude or longitude is empty", Toast.LENGTH_SHORT).show(); return; } double lat = Double.valueOf(latitude); double lon = Double.valueOf(longitude); loadNearbyPlaces(lat, lon); } }); } private void loadNearbyPlaces(final double latitude, final double longitude) { mProgress.show(); new Thread() { @Override public void run() { int what = 0; try { mNearbyList = mFsqApp.getNearby(latitude, longitude); } catch (Exception e) { what = 1; e.printStackTrace(); } mHandler.sendMessage(mHandler.obtainMessage(what)); } }.start(); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { mProgress.dismiss(); if (msg.what == 0) { if (mNearbyList.size() == 0) { Toast.makeText(Main.this, "No nearby places available", Toast.LENGTH_SHORT).show(); return; } mAdapter.setData(mNearbyList); mListView.setAdapter(mAdapter); } else { Toast.makeText(Main.this, "Failed to load nearby places", Toast.LENGTH_SHORT).show(); } } }; }
The example above shows how to authenticate user to get access token, display the webview authentication dialog then use the access token to access Foursquare API endpoint which in this example is to get the nearby venues.
[ad]
Line 8-9: First, replace the CLIENT_ID and CLIENT_SECREET with your app client id and client secret
Line 24: Create an instance of FoursquareApp class and pass the CLIENT_ID and CLIENT_SECRET as parameters
Line 32: Check if user has access token (already authorized the app before) using hasAccessToken
method.
Line 34: Setup listener to handle authorization result event (success or fail)
Line 53: Display the authentication dialog
Line 87: Get nearby venues, an example how to access Foursquare API endpoint. The getNearbyVenue method was defined in FourquareApp.java
FoursquareApp.java
public static final String CALLBACK_URL = "myapp://connect"; private static final String AUTH_URL = "https://foursquare.com/oauth2/authenticate?response_type=code"; private static final String TOKEN_URL = "https://foursquare.com/oauth2/access_token?grant_type=authorization_code"; private static final String API_URL = "https://api.foursquare.com/v2";
Line 1: Replace the CALLBACK_URL with your callback url set before on web settings.
Line 4: API_URL is the root url for Foursquare API endpoint. Do not change this url unless Foursqure make changes on their API url.
public ArrayList
ArrayList
try {
String ll = String.valueOf(latitude) + “,” + String.valueOf(longitude);
URL url = new URL(API_URL + “/venues/search?ll=” + ll + “&oauth_token=” + mAccessToken);
Log.d(TAG, “Opening URL ” + url.toString());
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod(“GET”);
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.connect();
String response = streamToString(urlConnection.getInputStream());
JSONObject jsonObj = (JSONObject) new JSONTokener(response).nextValue();
JSONArray groups = (JSONArray) jsonObj.getJSONObject(“response”).getJSONArray(“groups”);
int length = groups.length();
if (length > 0) {
for (int i = 0; i < length; i++) {
JSONObject group = (JSONObject) groups.get(i);
JSONArray items = (JSONArray) group.getJSONArray("items");
int ilength = items.length();
for (int j = 0; j < ilength; j++) {
JSONObject item = (JSONObject) items.get(j);
FsqVenue venue = new FsqVenue();
venue.id = item.getString("id");
venue.name = item.getString("name");
JSONObject location = (JSONObject) item.getJSONObject("location");
Location loc = new Location(LocationManager.GPS_PROVIDER);
loc.setLatitude(Double.valueOf(location.getString("lat")));
loc.setLongitude(Double.valueOf(location.getString("lng")));
venue.location = loc;
venue.address = location.getString("address");
venue.distance = location.getInt("distance");
venue.herenow = item.getJSONObject("hereNow").getInt("count");
venue.type = group.getString("type");
venueList.add(venue);
}
}
}
} catch (Exception ex) {
throw ex;
}
return venueList;
}
[/java]
To access Foursquare API endpoint, use standard HTTPURLConnection class, where the url depends on what endpoint you want to access. Complete list of Foursquare API endpoints can be found here.







I have problems when i’ve click on Get Nearby Places button and LogCat this:
https://lh4.googleusercontent.com/-pIiUO2mUj9Y/Tm-3b9aFmwI/AAAAAAAAAJk/rDJArR6ReSs/s912/asFSDGldgew.jpg
Could you please give me some hint?
That means the json response has no ‘address’ field. You can check if the field exists using: jsonObj.isNull(‘address’) to prevent parsing error.
So how do you fix this JSON error? Am i just inputting invalid lat/long coordinates, and thus it isn’t returning anything?
For instance I type in
Long: -84.3566371
Latitude: 33.7744506
(Atlanta, GA)
but it just keeps giving me “failed to load nearby places”, with a similar JSON error as listed above
Hi Andy,could you give me the log cat error messages?
Errors look pretty much the same as Neritae posted:
http://andy.dorkfort.com/store/Error%20LogCapture.PNG
I also tried hooking it up to the actual GPS (you’ll see that in the Logcat too) to feed into the Lat and Long fields, and it gave me the same errors before and after.
thanks for all your help!
What’s also weird is that if i paste the returned URL from logcat into a browser it gives me correct stuff back like:
{“meta”:{“code”:200,”errorType”:”deprecated”,”errorDetail”:”This endpoint will stop returning groups in the future. Please use a current version, see http://bit.ly/lZx3NU.”},”notifications”:[{“type”:”notificationTray”,”item”:{“unreadCount”:0}}],”response”:{“groups”:[{“type”:”nearby”,”name”:”Nearby”,”items”:
Wordked well also. Thank you again for this work.
Great…thanx for the feedback 😉
Let me thank you because after a ton of searching, i think this is exactly what i was looking for!
its not working for me.pls help me out!When i login it shows that failed to get access token.
give me the logcat please..;)
Thanx for ur reply lorenz,
10-01 15:17:14.417: WARN/System.err(1032): java.io.FileNotFoundException: https://foursquare.com/oauth2/access_token?grant_type=authorization_code&client_id=FFJAXQVBJNRQ50B52PF0EWJMRZD1U30EBW3STLDGVJCDPNFA&client_secret=B5RXEEGR2MIIL3DR5EXNQN1POMQSBCXQHCTWCBPJ1ABU0QN4&redirect_uri=myapp://connect&code=redirect_uri_mismatch
10-01 15:17:14.436: WARN/System.err(1032): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1061)
10-01 15:17:14.436: WARN/System.err(1032): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnection.getInputStream(HttpsURLConnection.java:252)
10-01 15:17:14.436: WARN/System.err(1032): at net.londatiga.fsq.FoursquareApp$3.run(FoursquareApp.java:102)
Hi Bala, seems that you’ve set different callback url between web settings and java code.
Thanx for ur instant reply,Could you pls refine the answer lorenz.
thanx lorenz! its working!.The issue is different Callback Url
Great!!! 🙂
Sir please help me to find out code for check in at a place.
The above lines are my logcat lines lorenz.pls help me out to get this lorenz
Ahhh! now i know what you mean, I guess some foursquare entities don’t have an address field. In case anyone wants to know, I put in this line of code in to fix it
if(!jlocation.isNull(“address”)){
venue.address = jlocation.getString(“address”);
}
Great!!! 😀
where do you put this code?
Thank you very much for the great code
Failed to get access token 🙁
It looks like the CallBack url is the problem, what should be a valid address to this parameter? Thanks!
10-23 23:41:58.337: WARN/System.err(372): java.io.FileNotFoundException: https://foursquare.com/oauth2/access_token?grant_type=authorization_code&client_id=XXX&client_secret=XXX&redirect_uri=myapp://connect&code=redirect_uri_mismatch
Make sure you have the same callback url between web settings and application. That url is valid..
To fix the distance problem (shows any time “0m”) change line 60 in NearbyAdapter.java from:
holder.mDistanceTxt.setText(formatDistance(venue.direction));
to:
holder.mDistanceTxt.setText(formatDistance(venue.distance));
Out of this you can delete all parts in the sourcecode that deal with “direction”.
Hi Vaan…thanks for your correction..;D
om, kenapa aku failed load nearby place trs ya kalo pake ll = -6.168788, 106.726746..
kira2 kenapa ya om ?
thx
Udah coba test langsung dari api console di web dev nya foursquare ? jalan gak?
nice tutorial
Thanks for posting
Nice stuff
Thanks for posting
Thank you so much for the sample code. It helped me to save a lot of time trying to understand the authentication.
You’re welcome Sebastián
https://github.com/foursquare/android-oauth-example
This example using ajax seems to be simpler
Sir, i have done this. now i want to write code for checkin. please help me, how can i write code for checkin of a user.
Hi, you can read the foursquare api documentation and apply the checkin api using http connection. Sorry i don’t have time to write the code.
Terrific stuff…. Helped a lot… Thanks
Hi,
i used your code and i get a message invalid_request…
The only thing i changed was the client_id and client_secret
https://foursquare.com/oauth2/authenticate?response_type=code&client_id=XXXX&redircet_uri=myapp://connect
Problem solved… 🙂
There is a spelling error in the redirect_uri
Thx for the tutorial
Hi Lorenz,
I tried your application , But am getting access token token failed and failed to load NearByValues, I only changed the Client_id and Client_secret and callback url . I got the following error in my logCat
03-30 15:31:08.382: W/System.err(516): java.io.IOException: Received authentication challenge is null
03-30 15:31:08.382: W/System.err(516): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequestInternal(HttpURLConnectionImpl.java:1694)
03-30 15:31:08.391: W/System.err(516): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequest(HttpURLConnectionImpl.java:1649)
03-30 15:31:08.391: W/System.err(516): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1153)
03-30 15:31:08.391: W/System.err(516): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:253)
03-30 15:31:08.391: W/System.err(516): at net.londatiga.fsq.FoursquareApp.getNearby(FoursquareApp.java:214)
03-30 15:31:08.391: W/System.err(516): at net.londatiga.fsq.Main$5.run(Main.java:121)
pls give me whats wrong in this?
I will thanks for your help!
Awesome stuff…
hi,
i am use your code in my app. but i got error when redirect after login.
error like “you have not permission to open this page”
what changes do i need to make in the above project if i dont have website … i only have android app
for more info I am getting:
System.err(9405): java.io.FileNotFoundException: https://api.foursquare.com/v2/users/self?oauth_token=CBVR2KICI4VRRQ0EMCSPC2DNDL12KDOO2XT3MWVI2HOVT42L
And on UI im getting “Connected as null”
05-14 12:07:32.892: W/System.err(331): java.io.FileNotFoundException: https://foursquare.com/oauth2/access_token?grant_type=authorization_code&client_id=RN4AHD3UMQSIWUIEMIZAK4ZIPP4X5RHDII1RS03VFCTQS3YZ&client_secret=QZCFZGVPJG0VRZR2AKO0OY4UQEPJW2G3SNHY5C1AF2JNTXUR&redirect_uri=myapp://connect&code=redirect_uri_mismatch
05-14 12:07:32.892: W/System.err(331): java.io.FileNotFoundException: https://foursquare.com/oauth2/access_token?grant_type=authorization_code&client_id=RN4AHD3UMQSIWUIEMIZAK4ZIPP4X5RHDII1RS03VFCTQS3YZ&client_secret=QZCFZGVPJG0VRZR2AKO0OY4UQEPJW2G3SNHY5C1AF2JNTXUR&redirect_uri=MyProject://connect&code=redirect_uri_mismatch
awsm work 🙂
Hi Lorenz,
I’ve got the access token successfully BUT I am connected as a NULL. How do I get self username? Thx
I have the same problem as victor, connected as null, and failed to get the file in the logcat, how to solve this problem, Please help Lorenz. Thanks for the great work.
Ok, i’ll check the problem and give the solution soon..
Thanks Lorenz. By the way, just to confirm that user, secID and callback are the only three place we need to change, right? Thanks.
Hi Rorenz,
What’s the value it needs to be in first name and last name fields in fetch name method of FourSquareApp. We do not have chance to input the name in these two fields. If no, then what the value it should be? Second, I think it has problem in JSONObject creation, it fails to create the object from string. Thanks.
I guess it’s the url, it’s not composed correctly. Can you give a sample of correct url? Many thanks.
Hi danzil, sorry for the late reply.
The problem was in HttpURLConnection (if you use SDK 4.0/ICS or newer). Since ICS, if you choose to set the setDoOutput() to “true”, the HTTP method would be POST even if you set the setRequestMethod() to “GET”. So in FoursquareApp.java, in method fetchUserName (https://github.com/lorensiuswlt/AndroidFoursquare/blob/master/src/net/londatiga/fsq/FoursquareApp.java), comment or delete the row
“urlConnection.setDoOutput(true);”
Hope it helps.
Yes thats right..;)
found Connected as null solution.
add &v=20120801 to end of connection parameter
for more details https://developer.foursquare.com/overview/versioning
and change connection type as below
RL url = new URL(API_URL + “/users/self?oauth_token=”
+ mAccessToken + “&v=201208201”);
Log.d(TAG, “Opening URL ” + url.toString());
HttpGet httpRequest = null;
httpRequest = new HttpGet(url.toURI());
HttpClient httpclient = new DefaultHttpClient();
HttpResponse httpresponse = (HttpResponse) httpclient
.execute(httpRequest);
HttpEntity entity = httpresponse.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(
entity);
InputStream input = bufHttpEntity.getContent();
String response = streamToString(input);
Hi Eray,
Thanks for the solution, currently thats not a mandatory, you can still use the API without versioning.
But it is recommended to use versioning for compatibility in the future API update. The real problem with my codes was in HttpConnection (see my answer to danzil). The solution is to remove the “urlConnection.setDoOutput(true);” line or replace the HttpConnection with HttpClient for making connection with http as you described in your solution code..
Dear Lorenz,
herenow parameter is no longer returned from API.
There are :
“stats”: {
“checkinsCount”: 285,
“usersCount”: 181,
“tipCount”: 1
},
and
“beenHere”: {
“count”: 0
},
oops if we add parameter v=yyyyMMdd then it returns
Don’t forget to add versioning parameter ;D.
Halo Om Lorenz saya mau tanya donk.
Kok setiap get nearby places failed mulu y?
ni logcat ny om :
09-07 16:35:21.619: W/System.err(23522): org.json.JSONException: No value for groups
09-07 16:35:21.629: W/System.err(23522): at org.json.JSONObject.get(JSONObject.java:354)
09-07 16:35:21.629: W/System.err(23522): at org.json.JSONObject.getJSONArray(JSONObject.java:544)
09-07 16:35:21.639: W/System.err(23522): at net.londatiga.fsq.FoursquareApp.getNearby(FoursquareApp.java:221)
09-07 16:35:21.639: W/System.err(23522): at net.londatiga.fsq.Main$5.run(Main.java:122)
09-07 16:35:21.759: W/asset(23522): deep redirect failure from 0x01030046 => 0x02060015, defStyleAttr=0x01010084, defStyleRes=0x01030022, style=0x00000000
mohon bantuannya om. 😀
09-07 16:35:21.619: W/System.err(23522): org.json.JSONException: No value for groups
09-07 16:35:21.629: W/System.err(23522): at org.json.JSONObject.get(JSONObject.java:354)
09-07 16:35:21.629: W/System.err(23522): at org.json.JSONObject.getJSONArray(JSONObject.java:544)
09-07 16:35:21.639: W/System.err(23522): at net.londatiga.fsq.FoursquareApp.getNearby(FoursquareApp.java:221)
09-07 16:35:21.639: W/System.err(23522): at net.londatiga.fsq.Main$5.run(Main.java:122)
09-07 16:35:21.759: W/asset(23522): deep redirect failure from 0x01030046 => 0x02060015, defStyleAttr=0x01010084, defStyleRes=0x01030022, style=0x00000000
Hi Lorenz, first thanks a lot for posting this. It helped me a lot. But I got some kind of an error in the pop up layout. It says :-
Connecting failed
This app has a configuration problem and was unable to connect to your foursquare account.
By the I gave internet permission on the android manifest file.
Please help me.
Thank you
Freind,
Is it possible to create my own app that uses four squares data and be available to sell on Google Play?
wrong email address: menusofamerica@gmail.com
Sorry
Hi
I am trying to register as new consumer with the link posted but it’s not working. Can any one please tell me the stepsto get my ClientID and Client Secret.
I am not able to locate it on Foursquare api website.
Thanks alot
I am getting Authorization failed Error.. Please Help..
I am getting Authorization failed error. Please help
I have problems when i’ve click on Get Nearby Places button and LogCat this:https://lh4.googleusercontent.com/-pIiUO2mUj9Y/Tm-3b9aFmwI/AAAAAAAAAJk/rDJArR6ReSs/s912/asFSDGldgew.jpgCould you please give me some hint?
hello all,
at this point they(foursquare have removed firstname,lasname detail on json,and also removed “groups” field . )
So when u start app please debug on eclipse or any IDE and then try to hit URL on webbrowser u will see json response and check that response.
hello, I tried to run this example, but not JSON comes complete, when I run the url in the browser works normally.
what’s going?
Hey hi,
I has been set all the required value as you said.But i don’t know, i’m getting “Authorization failed” Exception.
Required value:-
1.Client ID
2.Secrete key
3.CALLBACK URI 🙁https://www.jhakas.com/redirect_uri)
Please your help will be very appreciable
thank you in advance
Hey hi,
I has been set the required value as you said.But i don’t know, I’m getting “Authorization failed ” message.
Required changes:
1.Client ID
2.Secrete key
3.Call back URI(https://www.jhakas.com/redirect_uri)
Please you help will be appreciable
thank you
Hey hi ,
First of all i just want to say thank for your great work. this is claudia again with new error, Last one error, some how I has been solved.
Now when the get the palces…It gives a JSONException “No value for groups ” What does that means…..
Please help me out
Thanks
Om, help me ni ko failed to get nearby places terus ni di logcat nya “org.json.JSONException: No value for groups” ..
gimana ya ?
Om, help me ni selalu “failed to load nearby places”,
error di logcatnya begini “org.json.JSONException: No value for groups”.
help me donk
hi,
I am unable to get the near by places as it says ‘failed to load the nearby places” with the following logcat :
04-19 10:31:10.830: D/FoursquareApi(10756): Opening URL https://api.foursquare.com/v2/venues/search?ll=43.89765,77.123455&oauth_token=H0SURUVPG2DKXLSSTRBLBQ2OT4UKMQDAOFFBOVUJSZYT0R0C&v=20130419
04-19 10:31:13.342: W/System.err(10756): org.json.JSONException: No value for groups
04-19 10:31:13.342: W/System.err(10756): at org.json.JSONObject.get(JSONObject.java:354)
04-19 10:31:13.342: W/System.err(10756): at org.json.JSONObject.getJSONArray(JSONObject.java:544)
04-19 10:31:13.342: W/System.err(10756): at com.example.nearbyplaces.FoursquareApp.getNearby(FoursquareApp.java:217)
04-19 10:31:13.352: W/System.err(10756): at com.example.nearbyplaces.MainActivity$5.run(MainActivity.java:108)
I am done with this foursquare integration. If i want to add setting which means in foursquare site “Settings->Sharing with other networks” through my mobile application. How can i do that?
Please Reply me as soon as possible.
Thanks in Advance.
Hi
I am unable to use your library properly.
Your mentioned Foursquare Oauth link doesnt exist anymore !
I have created a Test app in foursquare but unable to use it with the library !Am i missing anything
what if i wanted the app to use the phone location automatically instead of entering the longtude and latitude