Постоянный OAuth с использованием Android и Twitter4J
Поэтому я пытаюсь справиться с этим OAuth
для твиттера используя Twitter4J
библиотека.
Я дам немного фона.
Я настроил свою учетную запись разработчика Twitter, используя метод Browser и обратные вызовы (которые я настроил как фильтр намерений) в моем AndroidManifest.xml
,
У меня есть действие, которое полностью обрабатывает мою аутентификацию в твиттере.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set up the datahelper
dh = new DataHelper(this, null);
tae = dh.GetAuthenticationObject();
setContentView(R.layout.main);
}
@Override
protected void onResume() {
super.onResume();
selectOption(getIntent());
}
public void selectOption(Intent intent) {
Uri uri = intent.getData();
if (uri != null && uri.toString().startsWith(CALLBACKURL) && tae.hasBeenAuthenticatedTwitter()) {
completeAuth(intent);
} else {
doOauth();
}
}
private void doOauth() {
try {
consumer = new CommonsHttpOAuthConsumer(Enums.TWITTER_APPLICATION_KEY,
Enums.TWITTER_APPLICATION_SECTRET);
provider = new DefaultOAuthProvider(
Enums.TWITTER_REQUEST_TOKEN_URL,
Enums.TWITTER_ACCESS_TOKEN_URL,
Enums.TWITTER_AUTHORIZE_URL);
String authUrl = provider.retrieveRequestToken(
consumer, CALLBACKURL);
tae.TwitterToken = consumer.getToken();
tae.TwitterTokenSecret = consumer.getTokenSecret();
dh.SaveAuthenticationObject(tae);
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse(authUrl)));
} catch (Exception e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
/**
* After use authorizes this is the function where we get back callbac with
* user specific token and secret token. You might want to store this token
* for future use.
*/
public void completeAuth(Intent intent) {
Uri uri = intent.getData();
if (uri != null && uri.toString().startsWith(CALLBACKURL)) {
tae = dh.GetAuthenticationObject();
String verifier = uri
.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
tae.TwitterVerifier = verifier;
dh.SaveAuthenticationObject(tae);
}
Intent settingsIntent = new Intent(this, com.undetowdevelopment.kontakt.Settings.class);
settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
settingsIntent.putExtra("REQUEST_CODE", Enums.REQUEST_CODE_TWITTER_LOGIN);
settingsIntent.putExtra("RESULT_CODE", Activity.RESULT_OK);
startActivity(settingsIntent);
}
Этот класс делает именно то, что я ожидаю. Он открывает страницу аутентификации Twitter, возвращает к активности и я сохраняю Token & Secret
на мои общие предпочтения.
мой AndroidManifest.xml
похоже:
<activity android:name=".TwitterSuccess" android:label="@string/app_name" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="myapp" android:host="mainactivity"/>
</intent-filter>
</activity>
Однако, когда мое приложение запускается, я хотел бы проверить, прошел ли аутентификация пользователя, и не должен постоянно просить пользователя проходить аутентификацию снова.
Из всех моих действий у меня есть метод, который возвращает объект Twitter, который я хотел бы использовать, чтобы установить статус или получить друзей пользователя.
Я использую следующий метод для этого:
public Twitter getTwitterObject()
{
AuthenticationEntity ae = GetAuthenticationObject();
CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(Enums.TWITTER_APPLICATION_KEY, Enums.TWITTER_APPLICATION_SECTRET);
//Set the requestToken and the tokenSecret that you got earlier by calling retrieveRequestToken.
consumer.setTokenWithSecret(ae.TwitterToken, ae.TwitterTokenSecret);
//The provider object is lost, too, so instantiate it again.
DefaultOAuthProvider provider = new DefaultOAuthProvider(
Enums.TWITTER_REQUEST_TOKEN_URL,
Enums.TWITTER_ACCESS_TOKEN_URL,
Enums.TWITTER_AUTHORIZE_URL);
//Now that's really important. Because you don't perform the retrieveRequestToken method at this moment, the OAuth method is not detected automatically (there is no communication with Twitter). So, the default is 1.0 which is wrong because the initial request was performed with 1.0a.
provider.setOAuth10a(true);
try {
provider.retrieveAccessToken(consumer, ae.TwitterVerifier);
} catch (Exception e) {
Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Enums.TWITTER_APPLICATION_KEY, Enums.TWITTER_APPLICATION_SECTRET);
twitter.setOAuthAccessToken(new AccessToken(consumer.getToken(), consumer.getTokenSecret()));
return twitter;
}
Теперь это работает нормально, если пользователь только что вошел в систему, но если я снова запустите приложение (что не должно иметь значения, потому что я использую только данные из моих статических переменных и общих настроек), я не могу аутентифицироваться и получаю следующее исключение:
01-24 11:41:54.075: WARN/System.err(14612): oauth.signpost.exception.OAuthCommunicationException: Communication with the service provider failed: http://twitter.com/oauth/access_token
01-24 11:41:54.075: WARN/System.err(14612): at oauth.signpost.AbstractOAuthProvider.retrieveToken(AbstractOAuthProvider.java:214)
01-24 11:41:54.075: WARN/System.err(14612): at oauth.signpost.AbstractOAuthProvider.retrieveAccessToken(AbstractOAuthProvider.java:97)
01-24 11:41:54.075: WARN/System.err(14612): at com.undetowdevelopment.kontakt.helpers.DataHelper.getTwitterObject(DataHelper.java:129)
01-24 11:41:54.075: WARN/System.err(14612): at com.undetowdevelopment.kontakt.Settings.checkTwitterStatus(Settings.java:118)
01-24 11:41:54.075: WARN/System.err(14612): at com.undetowdevelopment.kontakt.Settings.setUIComponents(Settings.java:60)
01-24 11:41:54.075: WARN/System.err(14612): at com.undetowdevelopment.kontakt.Settings.onCreate(Settings.java:39)
01-24 11:41:54.075: WARN/System.err(14612): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069)
01-24 11:41:54.085: WARN/System.err(14612): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751)
01-24 11:41:54.085: WARN/System.err(14612): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
01-24 11:41:54.085: WARN/System.err(14612): at android.app.ActivityThread.access$2300(ActivityThread.java:135)
01-24 11:41:54.085: WARN/System.err(14612): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
01-24 11:41:54.085: WARN/System.err(14612): at android.os.Handler.dispatchMessage(Handler.java:99)
01-24 11:41:54.085: WARN/System.err(14612): at android.os.Looper.loop(Looper.java:144)
01-24 11:41:54.085: WARN/System.err(14612): at android.app.ActivityThread.main(ActivityThread.java:4937)
01-24 11:41:54.085: WARN/System.err(14612): at java.lang.reflect.Method.invokeNative(Native Method)
01-24 11:41:54.085: WARN/System.err(14612): at java.lang.reflect.Method.invoke(Method.java:521)
01-24 11:41:54.085: WARN/System.err(14612): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-24 11:41:54.085: WARN/System.err(14612): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-24 11:41:54.085: WARN/System.err(14612): at dalvik.system.NativeStart.main(Native Method)
01-24 11:41:54.085: WARN/System.err(14612): Caused by: java.io.FileNotFoundException: http://twitter.com/oauth/access_token
01-24 11:41:54.085: WARN/System.err(14612): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1162)
01-24 11:41:54.085: WARN/System.err(14612): at oauth.signpost.basic.HttpURLConnectionResponseAdapter.getContent(HttpURLConnectionResponseAdapter.java:18)
01-24 11:41:54.085: WARN/System.err(14612): at oauth.signpost.AbstractOAuthProvider.handleUnexpectedResponse(AbstractOAuthProvider.java:228)
01-24 11:41:54.085: WARN/System.err(14612): at oauth.signpost.AbstractOAuthProvider.retrieveToken(AbstractOAuthProvider.java:189)
01-24 11:41:54.085: WARN/System.err(14612): ... 18 more
01-24 11:41:54.885: WARN/System.err(14612): http://api.twitter.com/1/account/verify_credentials.json?include_entities=falseRelevant discussions can be on the Internet at:
01-24 11:41:54.885: WARN/System.err(14612): http://www.google.co.jp/search?q=2486d84d or
01-24 11:41:54.885: WARN/System.err(14612): http://www.google.co.jp/search?q=0d00203c
01-24 11:41:54.885: WARN/System.err(14612): TwitterException{exceptionCode=[2486d84d-0d00203c 175a68e8-9303e317], statusCode=-1, retryAfter=0, rateLimitStatus=null, version=2.1.12-SNAPSHOT(build: e7bec3eec13cedc774926ee24f4c5368d218c9d4)}
01-24 11:41:54.885: WARN/System.err(14612): at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:214)
01-24 11:41:54.885: WARN/System.err(14612): at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:75)
01-24 11:41:54.885: WARN/System.err(14612): at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:103)
01-24 11:41:54.885: WARN/System.err(14612): at twitter4j.Twitter.verifyCredentials(Twitter.java:1397)
01-24 11:41:54.885: WARN/System.err(14612): at twitter4j.Twitter.getScreenName(Twitter.java:191)
01-24 11:41:54.885: WARN/System.err(14612): at com.undetowdevelopment.kontakt.Settings.checkTwitterStatus(Settings.java:120)
01-24 11:41:54.885: WARN/System.err(14612): at com.undetowdevelopment.kontakt.Settings.setUIComponents(Settings.java:60)
01-24 11:41:54.885: WARN/System.err(14612): at com.undetowdevelopment.kontakt.Settings.onCreate(Settings.java:39)
01-24 11:41:54.885: WARN/System.err(14612): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069)
01-24 11:41:54.885: WARN/System.err(14612): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751)
01-24 11:41:54.885: WARN/System.err(14612): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
01-24 11:41:54.885: WARN/System.err(14612): at android.app.ActivityThread.access$2300(ActivityThread.java:135)
01-24 11:41:54.885: WARN/System.err(14612): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
01-24 11:41:54.885: WARN/System.err(14612): at android.os.Handler.dispatchMessage(Handler.java:99)
01-24 11:41:54.885: WARN/System.err(14612): at android.os.Looper.loop(Looper.java:144)
01-24 11:41:54.885: WARN/System.err(14612): at android.app.ActivityThread.main(ActivityThread.java:4937)
01-24 11:41:54.885: WARN/System.err(14612): at java.lang.reflect.Method.invokeNative(Native Method)
01-24 11:41:54.885: WARN/System.err(14612): at java.lang.reflect.Method.invoke(Method.java:521)
01-24 11:41:54.885: WARN/System.err(14612): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-24 11:41:54.885: WARN/System.err(14612): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-24 11:41:54.885: WARN/System.err(14612): at dalvik.system.NativeStart.main(Native Method)
01-24 11:41:54.885: WARN/System.err(14612): Caused by: java.io.FileNotFoundException: http://api.twitter.com/1/account/verify_credentials.json?include_entities=false
01-24 11:41:54.885: WARN/System.err(14612): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1162)
01-24 11:41:54.885: WARN/System.err(14612): at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:47)
01-24 11:41:54.895: WARN/System.err(14612): at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:178)
01-24 11:41:54.895: WARN/System.err(14612): ... 20 more
01-24 11:41:54.995: WARN/InputManagerService(99): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@46113ee8 (uid=10060 pid=14093)
Как я уже говорил, когда я только что завершил аутентификацию, все работает нормально, но если я снова запускаю свое приложение, я получаю это сообщение.
Я использую HTC Incredible
работает под управлением Android 2.2. Приложение разрабатывается для Android 1.6+.
Любые комментарии или помощь будут с благодарностью!
Лучший,
Игнус
1 ответ
Я не совсем уверен, что вы делаете, но вы можете взглянуть на Zwitscher https://github.com/pilhuhn/ZwitscherA и здесь, особенно на https://github.com/pilhuhn/ZwitscherA/blob/v065/src/de/bsd/zwitscher/LoginActivity.java метод, который затем вызывается в TwitterHelper.
Когда пользователь впервые входит в систему и никогда не входил в систему, действие проверяет это и показывает экран с кнопкой "getPinFromTwitter" - это перенаправляет пользователя в твиттер, где он может войти в систему и получить пин-код. Пользователь снова запускает приложение, вводит пин-код и нажимает "setPin". В этой версии Zwitscher учетная запись хранится в базе данных; в более ранних версиях (просто проверьте тег v065, например: https://github.com/pilhuhn/ZwitscherA/tree/v065), это делается с помощью общих настроек. Источник в настоящее время немного в движении.