본문 바로가기

android/Twitter

Android app에서 Twitter 연동하기 3

http://jeehun.egloos.com/4002292

상단에 원본 링크 입니다. 아래 포스트는 제가 작성한 것이 아니고 egloos.com에 접속되지 않는 분들은 위한 글임을 미리 밝혀 둡니다.
너무 잘 작성된 예제라서 가져옴을 다시 알려드립니다.

안녕하세요
지난시간에 이어 이번에는 트위터에 로그인 해서 Access token을
가져오는 부분을 진행하도록 하겠습니다.

트위터 로그인은 WebView를 하나 만들어서 처리하도록 할 것입니다.
WebView에서 로그인 처리를 하여서 Access Token 과 Access Token Secret를
가져오도록 하겠습니다.

그럼 시작하겠습니다.

먼저 C.java 라는 상수를 저장하는 클래스를 하나 만들겠습니다.

********************************* C.java ************************************
package com.android.twittercon;

public class C
{
public static final String LOG_TAG = "TwitterCon";
public static final String TWITTER_API_KEY = "Twitter.com에서 받아온 API 키입니다.";
public static final String TWITTER_CONSUMER_KEY = "역시 twitter.com에서 받아옵니다.";
public static final String TWITTER_CONSUMER_SECRET = "역시 twitter.com에서 받아옵니다.;
public static final String TWITTER_CALLBACK_URL = "http://m.daum.net";
public static final String MOVE_TWITTER_LOGIN = "com.android.twittercon.TWITTER_LOGIN"; // 인텐트 호출시 사용할 것입니다.
public static final int TWITTER_LOGIN_CODE = 10;

public static boolean D = true;
}
*****************************************************************************

다음은 매니페스트 파일을 수정합니다.
<action android:name="com.android.twittercon.TWITTER_LOGIN" />
위의 action name 부분은 암시적으로 인텐트를 호출할 때 사용하기 위한
정의입니다.
******************************** 매니페스트 **********************************
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.twittercon"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".TwitterCon"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!-- ACT : Twitter Login -->
<activity android:name=".TwitterLogin" android:label="Twitter Login"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden"
android:configChanges="orientation|keyboardHidden"
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="com.android.twittercon.TWITTER_LOGIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>

</application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
*****************************************************************************

다음은 Webview Activity를 하나 만듭니다.
TwitterLogin.java 라고 이름 짓겠습니다.
여기서 중요한 부부은 onPageFinished 부분입니다. 이 메서드는
webview에서 페이지가 다 뿌려지고 나면 호출되는 부분으로
이부분에서 로그인 후 처리를 해줄 수 있습니다.

예를 들면 현재 코딩을 보면 로그인이 성공적으로 끝나면
트위터는 미리 지정한 callback url로 페이지를 리다이렉트
해줍니다. 이때 콜백 URL을 m.daum.net으로 해놨다고하면
페이지 로딩이 끝나고 현재 URL이 m.daum.net으로 시작하면
로그인이 성공했다고 판단하고 accesstoken을 인텐트에
담아 Webview를 호출한 activity로 넘겨주고 webview
자신은 finish 시켜주도록 하고 있습니다.
***************************** TwitterLogin.java *******************************
package com.android.twittercon;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class TwitterLogin extends Activity
{
// INTENT
Intent mIntent;

public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.twitter_login);
WebView webView = (WebView) findViewById(R.id.webView);

// 화면 전환시 WebView에서 화면 전환하도록한다.
// 이렇게하지 않으면 표준 브라우저가 열려 버린다.
webView.setWebViewClient(new WebViewClient()
{
public void onPageFinished(WebView view, String url)
{
// page 렌더링이 완료되면 호출됨.
super.onPageFinished(view, url);

// 로그아웃을 처리한후에는 바로 Activity를 종료시킨다.
if (url != null && url.equals("http://mobile.twitter.com/"))
{
finish();
}
// 로그인이 성공하면
else if (url != null && url.startsWith(C.TWITTER_CALLBACK_URL))
{
String[] urlParameters = url.split("\\?")[1].split("&");
String oauthToken = "";
String oauthVerifier = "";

try
{
if (urlParameters[0].startsWith("oauth_token"))
{
oauthToken = urlParameters[0].split("=")[1];
}
else if (urlParameters[1].startsWith("oauth_token"))
{
oauthToken = urlParameters[1].split("=")[1];
}

if (urlParameters[0].startsWith("oauth_verifier"))
{
oauthVerifier = urlParameters[0].split("=")[1];
}
else if (urlParameters[1].startsWith("oauth_verifier"))
{
oauthVerifier = urlParameters[1].split("=")[1];
}

mIntent.putExtra("oauth_token", oauthToken);
mIntent.putExtra("oauth_verifier", oauthVerifier);

setResult(RESULT_OK, mIntent);
finish();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
});

mIntent = getIntent();
String url1 = mIntent.getStringExtra("auth_url");
webView.loadUrl(url1);
}
}
*****************************************************************************

다음은 Webview 액티비티가 사용할 layout xml 파일을 만듭니다.
****************************twitter_login.xml *********************************
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<WebView
android:id="@+id/webView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
</LinearLayout>
*****************************************************************************

다음은 TwitterCon.java 파일을 수정합니다.
login() 메서드가 트위터 로그인을 처리하는 TwitterLogin.java를
인텐트로 호출하고 있습니다.
살펴보면 먼저 getOAuthRequestToken 메서드를 이용해
OAuth용 리퀘스트 토큰을 받습니다. 이 토큰을 TwitterLogin.java
액티비티를 인텐트로 부를때 인자로 넘겨주면 TwitterLogin 액티비티는
이를 이용해 로그인 처리를 하게 됩니다.
그리고 로그인이 성공적으로 끝나면 TwitterCon 액티비티의
onActivityResult 로 그 결과를 받게 됩니다.
C.TWITTER_LOGIN_CODE 은 미리 상수 클래스에 정의한
코드값(여기서는 10)입니다. 이것으로 startActivityForResult
메서드로 호출한 액티비티의 결과를 받아서 처리할 수 있게 됩니다.
********************************TwitterCon.java ******************************
package com.android.twittercon;

import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class TwitterCon extends Activity implements View.OnClickListener
{
private Twitter mTwitter;
private RequestToken mRqToken;
private AccessToken mAccessToken;
private Button mBtnLogin, mBtnFeed, mBtnLogout;
private EditText mEtContent;

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mEtContent = (EditText) findViewById(R.id.etContent);

mBtnLogin = (Button) findViewById(R.id.btnLogin);
mBtnFeed = (Button) findViewById(R.id.btnFeed);
mBtnLogout = (Button) findViewById(R.id.btnLogout);

mBtnLogin.setOnClickListener(this);
mBtnFeed.setOnClickListener(this);
mBtnLogout.setOnClickListener(this);
}

// 버튼 클릭 이벤트 처리
@Override
public void onClick(View v)
{
switch(v.getId())
{
case R.id.btnLogin: // Twitter login
login();
break;
case R.id.btnFeed: // Twitter에 글쓰기
break;
case R.id.btnLogout: // Twitter logout
break;
default:
break;
}
}

private void login()
{
try
{
TwitterFactory factory = new TwitterFactory();
mTwitter = factory.getOAuthAuthorizedInstance(C.TWITTER_CONSUMER_KEY, C.TWITTER_CONSUMER_SECRET);
mRqToken = mTwitter.getOAuthRequestToken(C.TWITTER_CALLBACK_URL);
Log.v(C.LOG_TAG, "AuthorizationURL >>>>>>>>>>>>>>> " + mRqToken.getAuthorizationURL());

// Intent intent = new Intent(C.MOVE_TWITTER_LOGIN); // 이렇게 암시적으로 호출해도 되고
Intent intent = new Intent(this, TwitterLogin.class); // 이렇게 명시적으로 호출해도 상관 없습니다.
intent.putExtra("auth_url", mRqToken.getAuthorizationURL());
startActivityForResult(intent, C.TWITTER_LOGIN_CODE);
}
catch (Exception e)
{
e.printStackTrace();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);

// 액티비티가 정상적으로 종료되었을 경우
if(resultCode == RESULT_OK)
{
if (requestCode == C.TWITTER_LOGIN_CODE)
{
try
{
mAccessToken = mTwitter.getOAuthAccessToken(mRqToken, data.getStringExtra("oauth_verifier"));

Log.v(C.LOG_TAG, "Twitter Access Token : " + mAccessToken.getToken());
Log.v(C.LOG_TAG, "Twitter Access Token Secret : " + mAccessToken.getTokenSecret());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
*****************************************************************************

여기까지 하면 프로젝트는 다음처럼 구성됩니다.


자 이제 컴파일 하고 로그인 버튼을 누르시면 다음처럼 로그인 창이 뜹니다.
아이디 / 패스워드를 넣고 허용을 클릭하면 다음처럼 화면이 뜹니다.

여기서 Allow를 눌러주면 로그인이 성공적으로 진행되었다면
mRqToken = mTwitter.getOAuthRequestToken(C.TWITTER_CALLBACK_URL); 에서
호출한 콜백 URL로 넘어가게 됩니다. (트위터에 등록한 콜백 URL로 넘어가는게 아닙니다.)
우리는 콜백 URL을 m.daum.net 으로 해줬으니까 그쪽으로 넘어갈 겁니다.
이렇게요..
콜백 URL로 넘어온 상태에서 조금 기다리면 Webview가 finish되면서
다음과 같이 logcat으로 액세스 토큰과 액세스 토큰 시크릿을 확인 할 수 있습니다.
왜냐하면 우리는 TwitterLogin.java의

// 로그인이 성공하면
else if (url != null && url.startsWith(C.TWITTER_CALLBACK_URL))
{
...
}


에서 페이지의 URL이 콜백 URL로 시작하면 로그인 후 처리를 하고
WebView 액티비티를 끝내도록 처리해 놓았으니까요...
자.. 이번에는 액세스 토큰과 액세스 토큰 시크릿을 가지고 오는부분 까지 진행했습니다.
다음번에는 이를 이용해 글을 쓰는걸 해보도록 하겠습니다.