В этот раз, этот пост можно считать небольшой заметкой к продолжению темы OAuth и Twitter, осилим вместе!.
Я хотел бы поделиться тем, как я реализовал диалог общения пользователя моего приложения с Twitter, с целью авторизации приложения пользователем.
С чего начать?
Начнем, как всегда, с малого. Первое, что нам потребуется, это организовать интерфейс между частью программы, отвечающую за реализацию Twitter API, запросы по сути, и частью - диалогом авторизации. И так, какие вариации исхода работы пользователя с нашим диалогом? Успех, ошибка или отмена. В нашем случае, ошибка и отмена одно и тоже, так что, сведем к успеху и отмене. Перейдем к реализации:
public interface OAuthDialogListener {
public abstract void onAllow(String pin);
public abstract void onDeny();
}
Вы могли заметить, что onAllow имеет параметр pin. PIN это код, которые пользователь увидит на странице twitter после успешной авторизации приложения.
Диалог. Проще - лучше!
Глупо заставлять пользователя делать какие то махинации, которые мы, как разработчики, могли бы автоматизировать. Хотя очень часто наблюдаем совсем противоположное поведение различных приложений. Значит, от диалога нам потребуется:
- Отображение веб страницы twitter для поэтапного прохода авторизации пользователя и приложения;
- Получение PIN с веб страницы, при успешной авторизации приложения;
- Отработка событий отмены и успеха в процессе авторизации приложения пользователем;
public class OAuthDialogActivity extends Activity {
public static OAuthDialogListener passOAuthDialogListener = null;
private WebView webView;
private String oauthToken;
private OAuthDialogListener dialogListener = null;
}
Диалог будет основан на Activity, так же объявим публичный статичный listener, для передачи как аргумент при создании диалога в будущем, к сожалению у Intent проблемы с передачей объектов такого рода. Далее, нам потребуется oauth_token для формирования нужной url авторизации, а так же родной listener и webView, для отображения и прохождения всех этапов авторизации приложения.
Продолжим, попробуем реализовать создание и подготовку нашего диалога:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dialogListener = passOAuthDialogListener;
webView = new WebView(this);
setContentView(webView);
WebSettings webSettings = webView.getSettings();
webSettings.setSavePassword(false);
webSettings.setSaveFormData(false);
webSettings.setJavaScriptEnabled(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setSupportMultipleWindows(false);
webSettings.supportZoom();
webView.setWebViewClient(new TwitterWebViewClient());
webView.addJavascriptInterface(new TwitterOAuthJavaScriptInterface(), "twitterOAuth");
Bundle bundle = getIntent().getExtras();
oauthToken = bundle.getString("oauth_token");
webView.loadUrl("http://api.twitter.com/oauth/authorize?oauth_token=" + oauthToken);
}
По порядку:
- Запомним аргумент listener;
- Создадим webView и установим как основной View нашего диалога (Activity);
- Заполним WebSettings так, чтобы само устройство не запоминало никаких паролей и имен, так же нам потребуется JavaScript, включим его тоже;
- Установим наш клиент-обработчик webView, о нем дальше;
- Добавим наш JavaScript (twitterOAuth) для работы с html страницами;
- Получаем oauth_token как аргумент диалога;
- Загружаем первый шаг авторизации используя полученный oauth_token;
private class TwitterWebViewClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:window.twitterOAuth.complete(document.getElementById('oauth_pin').innerHTML);");
view.loadUrl("javascript:window.twitterOAuth.denied(document.getElementsByTagName('html')[0].innerHTML);");
super.onPageFinished(view, url);
}
}
Здесь еще проще, по готовности страницы в webView, мы выполняем методы нашего JavaScript, причем, передаем элемент oauth_pin, а во втором случае, весь текст html страницы. Зачем? Если oauth_pin существует на странице, это говорит об успешности авторизации, а так же, данный элемент содержит нужный нам PIN. Что касается второго метода, нам нужна вся страница для поиска строки, которая говорила бы об отмене для текущего токена.
JavaScript -> Java
Наступило время для обработки методов JavaScritp в нашем коде. Как было раньше написано, сейчас опишем класс-javascript, который реализует наши два метода успеха и отмены:
private class TwitterOAuthJavaScriptInterface {
@SuppressWarnings("unused")
public void complete(String pin) {
if (dialogListener != null) {
dialogListener.onAllow(pin);
}
finish();
}
@SuppressWarnings("unused")
public void denied(String html) {
if (html.indexOf("oob?denied=" + oauthToken) > 0) {
if (dialogListener != null) {
dialogListener.onDeny();
}
finish();
}
}
}
Twitter Helper - Authorize
Не забудем добавить метод в наш Twitter API Helper класс, а именно, метод вызова диалога с пользовательским listener:
public static void authorize(Context context, String oauthToken, OAuthDialogListener listener) {
OAuthDialogActivity.passOAuthDialogListener = listener;
Intent intent = new Intent(context, OAuthDialogActivity.class);
intent.putExtra(OAUTH_TOKEN, oauthToken);
context.startActivity(intent);
}
Устанавливаем публичный статический аргумент диалога, создаем Intent с классом диалога, добавляем аргумент oauthToken (OAUTH_TOKEN - константа String, можете описать как вам нравится), далее запускаем наш диалог (activity).
Конечно же, не забываем, мы работаем в Android, и каждый новый activity должен быть описан в AndroidManifest.xml, а значит добавляем такую секцию:
<uses-permission android:name="android.permission.INTERNET" />
<activity android:name="com.fuhu.twitter.activity.OAuthDialogActivity"
android:noHistory="true">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Удачи в ваших личных начинаниях.
No comments:
Post a Comment