Хочу поделиться с вами небольшим опытом использования Flickr API в Android приложениях и рассказать об авторизации пользователя Flickr. Которую в дальнейшем можно будет использовать например для вывода списка альбомов и изображений.
Регистрация приложения
Первым делом нам нужно получить API Key, приложения будем использовать не в коммерческих целях, для регистрации переходим по ссылке Create an App.

Нас просят ввести «Название», «Цель» и «Соглашения с правами», отправляем наши данные и в результати получаем API Key и API Secret. Они нужны нам в дальнейшем для формирования запроса к серверу.

После этого нам нужно редактировать некоторые данные, в этом же окне переходим на Edit auth flow for this app.

Описания и логотип нам не интересны, вводить можете по желанию. В поле Callback URL нам обязательно нужно задать адрес обратного вызова, который мы будем использовать для возвращения к нашему Activity. В моем случае я задаю appforflickr://callback. В болке <intent-filter> это буде выглядеть следующим образом:
... <data android:scheme="appforflickr" android:host="callback"/> ...
App Type — выбираем Web Application и Сохраняем изменения.
Далее переходим непосредственно к построения самого приложения.
В манифесте приложения добавляем «android.permission.INTERNET» и блок <intent-filter> в результате получаем:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="test.testflickrapi" > <uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".ui.activities.MainActivity" android:label="@string/app_name" > <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:scheme="appforflickr" android:host="callback"/> </intent-filter> </activity> </application> </manifest>
Создание ссылки для авторизации пользователя
Для авторизации пользователей в приложении мы будем запускать Activity с WebView. Но сначала сформируем адрес для входа. Шаблон выглядет следующим образом:
http://flickr.com/services/auth/?api_key=[api_key]&perms=[perms]&api_sig=[api_sig]
[api_key] — это наш ключ полученый при регистрации приложения. [perms] — уровень доступа к аккаунту, может принимать следующие значения:
- read — разрешения на чтения личной информации
- write — разрешения на добавления и редактирования фотографий и информации(включает в себя ‘read’)
- delete — разрешения на удаления фотографий(включает в себя ‘read’ и ‘write ‘)
[api_sig] — подпись, она включает в себя Secret полученый при регистрации приложения и список аргументов в алфавитном порядке, имя и значения.
В нашем случае API Key: 5744fadec815a7e8142d03901065c97b, API Secret: 8b2c12e80b67970b, права доступа write, подпись это строка из:
secret + 'api_key' + [api_key] + 'perms' + [perms]
, то есть мы имеем: 8b2c12e80b67970bapi_key5744fadec815a7e8142d03901065c97bpermswrite и теперь нужно зашифровать эту строку в MD5. Для этого используем следующий метод:
public static final String md5SumOfString(final String s) { try { MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); digest.update(s.getBytes()); byte messageDigest[] = digest.digest(); StringBuffer hexString = new StringBuffer(); for (int i = 0; i < messageDigest.length; i++) hexString.append(Integer.toHexString(0xFF & messageDigest[i])); return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }
и получем значения [api_sig].
В итоге адрес для авторизация пользователя будет выглядеть следующим образом:
http://www.flickr.com/services/auth/?api_key=9a0554259914a86fb9e7eb014e4e5d52&perms=write&api_sig=b8d7c1ae026d5f86f1f44944f5257f3
В onCreate() добавляем
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
, где url — это вышеуказанный адрес. После запуска приложения мы открываем веб-страницу, чтобы указать логин и пароль. Если введеные данные будут верны нас по Callback URL автоматически перенаправит на наше приложеня. К url добавляеться параметр frob из значениям, то есть в нашем случае это выглядит так:
appforflickr://callback?frob=72157650137623777-b09eae52121bf8ad-130818926
Frob нужен для получения Access token.
Добавим условия в onCreate(), чтобы получить frob:
Uri uri = getIntent().getData(); if (uri != null) { String frob = uri.getQueryParameter("frob"); } else startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
После того обработки вызываем метод flickr.auth.getToken из API для получения token и nsid, которые понадобятся для дальнейших запросов, а так же username и fullname пользователя.
Для отправки запросов создадим class HttpRequest:
public class HttpRequest extends AsyncTask<String, String, String> { public static final String TAG = HttpRequest.class.getSimpleName(); @Override protected void onPreExecute() { Log.d(TAG, "START"); } @Override protected String doInBackground(String... params) { String result = ""; try { String uri = params[0]; HttpGet httpGet = new HttpGet(uri); HttpResponse response = HttpClientHelper.getHttpClient().execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream inStream = entity.getContent(); result = InputStreamConverter.convertStreamToString(inStream); inStream.close(); } return result; } catch (IllegalStateException e) { return result; } catch (ClientProtocolException e) { return result; } catch (IOException e) { return result; } } @Override protected void onPostExecute(String result) { Log.d(TAG, "STOP"); } }
Class HttpClientHelper для получения HttpClient:
public class HttpClientHelper { private static HttpClient httpClient = null; private static final int REGISTRATION_TIMEOUT = 30 * 1000; private static final int WAIT_TIMEOUT = 30 * 1000; private HttpClientHelper() {} public static synchronized HttpClient getHttpClient() { if (httpClient == null) { HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET); HttpProtocolParams.setUseExpectContinue(params, true); ConnManagerParams.setTimeout(params, WAIT_TIMEOUT); HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT); SchemeRegistry schemeReg = new SchemeRegistry(); schemeReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schemeReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ClientConnectionManager connectionMgr = new ThreadSafeClientConnManager(params, schemeReg); httpClient = new DefaultHttpClient(connectionMgr, params); } return httpClient; } }
Class InputStreamConverter для конвертации InputStream в String:
public class InputStreamConverter { private InputStreamConverter() {} public static String convertStreamToString(InputStream inputStream) { BufferedReader reader = new BufferedReader(new InputStreamReader( inputStream)); StringBuilder builder = new StringBuilder(); String line = null; try { while ((line = reader.readLine()) != null) { builder.append(line + "\n"); } } catch (IOException e) { e.printStackTrace(); } finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } return builder.toString(); } }
Адрес для получения token:
https://api.flickr.com/services/rest/?method=flickr.auth.getToken&api_key=9a0554259914a86fb9e7eb014e4e5d52&frob=72157650137623777-b09eae52121bf8ad-130818926&format=json&nojsoncallback=1&perms=write&api_sig=8fd09b55f670ec9a4ba07c076e520ae8
, чтобы ответ пришел в виде json мы добавили пераметры из значениями format=json и nojsoncallback=1
Вносим еще раз изминения в onCreate() для отправки запроса:
Uri uri = getIntent().getData(); if (uri != null) { String frob = uri.getQueryParameter("frob"); String url = "..."; // Наш сформированый адрес для получения token String response = ""; HttpRequest httpRequest = new HttpRequest(this); httpRequest.execute(url); try { response = httpRequest.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } else startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
Далее полученый ответ:
{"auth":{"token":{"_content":"12134650097774510-014feda8303a4a64"},"perms":{"_content":"write"},"user":{"nsid":"230211065@N05","username":"user","fullname":"User Alex"}},"stat":"ok"}
можна розпарсить получить желанный token и nsid при помощи таких библиотек как gson или jackson это уже на любителя.
Надеюсь моя статья будет кому-то полезна.
PS. Это мой первый пост на Хабре, так что извините за немногословность и не судите строго.
ссылка на оригинал статьи http://habrahabr.ru/post/249961/
Добавить комментарий