FoursquareのOAuth

[kazoo04](http://twitter.com/kazoo04)さんに命じられた気がしたのでまとめました。

初めに、[Foursquareのデベロッパ向けページ](https://ja.foursquare.com/)からアプリの登録を行なってください。
今回はAndroid専用アプリとして作ったので、Callback URLにはoboenikui://foursquareのような実在しないURLを設定しました。

```java:MainActivity.java
public class MainActivity extends Activity {

    private String accessToken = null;
    final private String CALLBACK_URL = "設定したCallback URL";
    final private String CLIENT_ID = "取得したClient ID";
    final private String CLIENT_SECRET = "取得したClient Secret";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //認証ページをブラウザで開く
        Intent intent = new Intent(Intent.ACTION_VIEW,
                Uri.parse("https://foursquare.com/oauth2/authenticate?client_id="+CLIENT_ID+
                          "&response_type=code&redirect_uri="+CALLBACK_URL));
        startActivity(intent);
    }

    @Override
    public void onNewIntent(Intent intent) {
        final Uri uri = intent.getData();
        if(uri == null) {
            //urlがうまく取得できなかったとき
            return ;
        }
        
        String code = uri.getQueryParameter("code");
        final String getAccessTokenUrl = "https://foursquare.com/oauth2/access_token?client_id="+CLIENT_ID+
                                         "&client_secret="+CLIENT_SECRET+
                                         "&grant_type=authorization_code&redirect_uri="+CALLBACK_URL+
                                         "&code="+code;
        new Thread(new Runnable() {
            public void run() {
                String source;
                try {
                    source = getHtmlSource(getAccessTokenUrl);
                    //「{"access_token":"**********"}」の形でAccess Tokenを取得するので余分なものをカットする
                    int start = source.indexOf("{\"access_token\":\"");
                    int end = source.indexOf("\"}");
                    accessToken = source.substring(start+17, end);
                    //今回はとりあえずログ出力のみ
                    Log.d("access_token",accessToken);
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //HTMLのソースを取得
    public String getHtmlSource(String url) throws ClientProtocolException, IOException {
        HttpClient client = new DefaultHttpClient();
        String source = null;
        try {
            HttpGet hg=new HttpGet(url);
            HttpResponse response = client.execute(hg);
            final int statusCode = response.getStatusLine().getStatusCode();
            // Bad status
            if (statusCode != HttpStatus.SC_OK) {
                source = null;
            }
            // Good status
            else {
                source = EntityUtils.toString(response.getEntity());
            }
        }
        finally {
            client.getConnectionManager().shutdown();
        }
        return source;
    }
}
```

また、AndroidManifest.xmlにパーミッションの追加とインテントフィルタの設定が必要。

```
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```

```
<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:launchMode="singleTask" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="foursquare"
            android:scheme="oboenikui"/>
    </intent-filter>
</activity>
```
dataのところは自分の設定したように直してください。
AccessTokenは取得できたので、次はAPIを利用したものを書きたいです…

<余談>
ソース書くよりQiitaにまとめる方が時間かかった…