Android и ВКонтакте, часть 2 (авторизация и получение прав)

В первой части я рассказал вам, как можно быстро создать авторизацию через ВКонтакте, используя библиотеку "Kate Mobile". В этом же посте я хочу рассказать вам, как, без сторонних библиотек, добавить авторизацию через ВКонтакте в ваше Android приложение.

Первым делом создадим layout для нашего activity авторизации и назовем его webview.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                android:background="@drawable/bg"
                                android:layout_width="fill_parent"
                                android:layout_height="fill_parent">
    <WebView
            android:id="@+id/web"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:visibility="gone"
            />
    <ProgressBar style="@style/wrap_content" android:layout_centerInParent="true" android:id="@+id/progress" />
<RelativeLayout>

Это будет основной layout для авторизации, его же можно использовать для авторизации через Facebook или Twitter. Идем дальше и создаем VkontakteActivity.java, это именно тот класс, который и будет выполнять авторизацию.

public class VkontakteActivity extends Activity {

    WebView webview;
    ProgressBar progress;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview);

        //Получаем элементы
        webview = (WebView) findViewById(R.id.web);
        progress = (ProgressBar) findViewById(R.id.progress);

        webview.getSettings().setJavaScriptEnabled(true);
        webview.setVerticalScrollBarEnabled(false);
        webview.setHorizontalScrollBarEnabled(false);
        webview.clearCache(true);

        //Чтобы получать уведомления об окончании загрузки страницы
        webview.setWebViewClient(new VkWebViewClient());

        String url = "http://oauth.vk.com/authorize?client_id=" + Settings.vk_api_id + "&scope=wall,offline&redirect_uri="+ URLEncoder.encode(Settings.vk_redirect_url) + "&response_type=token";
        webview.loadUrl(url);
        webview.setVisibility(View.VISIBLE);
    }

    class VkWebViewClient extends WebViewClient {
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            progress.setVisibility(View.VISIBLE);
            parseUrl(url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if( url.startsWith("http://oauth.vk.com/authorize") || url.startsWith("http://oauth.vk.com/oauth/authorize") ) {
                progress.setVisibility(View.GONE);
            }
        }
    }

    private void parseUrl(String url) {
        try {
            if( url == null ) {
                return;
            }
            if( url.startsWith(Settings.vk_redirect_url) ) {
                if( !url.contains("error") ) {
                    String[] auth = VKUtil.parseRedirectUrl(url);
                    webview.setVisibility(View.GONE);
                    progress.setVisibility(View.VISIBLE);

                    //Строим данные
                    Intent intent = new Intent();
                    intent.putExtra("token", auth[0]);
                    intent.putExtra("uid", auth[1]);

                    //Возвращаем данные
                    setResult(Activity.RESULT_OK, intent);
                } else {
                    setResult(RESULT_CANCELED);
                    finish();
                }
            } else if( url.contains("error?err") ) {
                setResult(RESULT_CANCELED);
                finish();
            }
        } catch( Exception e ) {
            e.printStackTrace();
            setResult(RESULT_CANCELED);
            finish();
        }
    }
}

Соответственно у вас должен быть создан класс Settings с параметрами, либо вы их можете прописать прямо в самом VkontakteActivity. Создадим еще один класс VKUtil, для парсинга ответа от сервера контакта.

public class VKUtil {
    public static String[] parseRedirectUrl(String url) throws Exception {
        String access_token = extractPattern(url, "access_token=(.*?)&");
        String user_id = extractPattern(url, "user_id=(\\d*)");
        if( user_id == null || user_id.length() == 0 || access_token == null || access_token.length() == 0 ) {
            throw new Exception("Failed to parse redirect url " + url);
        }
        return new String[]{access_token, user_id};
    }

    public static String extractPattern(String string, String pattern){
        Pattern p = Pattern.compile(pattern);
        Matcher m = p.matcher(string);
        if (!m.find())
            return null;
        return m.toMatchResult().group(1);
    }
}

С этим разобрались, осталось только вызвать данное активити из вашего приложения:

startActivityForResult(new Intent(this, VkontakteActivity.class), AUTH_VK);

После авторизации, VkontakteActivity закроется и вернет ответ, также будут переданы token и uid. Чтобы отловить результат, пропишите в вашем MainActivity:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch( requestCode ) {
        case AUTH_VK:
            if( resultCode == Activity.RESULT_OK ) {
                //todo какое то действие
            }
            break;
    }
}

Ну вот на этом пожалуй и все, удачи вам в ваших начинаниях...

update: Авторизация с использованием Android VK SDK.

P.Nixx, 21.05.2013, 15:28