Instagram - программа, позволяющая пользователям мобильного телефона делится своими фотографиями со всем миром. Долгое время Inspagram был доступен только обладателям iPhone. Они гордились этим фактом и всячески подчеркивали свою элитарность. Однако в 2012 году ситуация изменилась, был выпущен официальный клиент для Android. Этот шаг значительно увеличил пользовательскую базу и популярность инстаграмма. В сети появились различные фан-группы и сообщества, напримерinstagrama.ru. Одной из сильных сторон Instagram-а, как сервиса, является наличие открытого API позволяющего использовать его возможности в своих приложениях.
Процесс интеграции функциональности инстаграмма в свое Android приложение чем-то напоминает работу с Twitter-ом. Однако в случае с последним, в нашем распоряжении есть огромное количество библиотек от сторонних разработчиков. При работе с Instagram мы лишены всей этой роскоши, однако API инстаграмма очень прост, и если вы представляете, как работать с сетью в Android, то у Вас не будет никаких проблем с его использованием.
Прежде чем приступать к кодингу, нам нужно зарегистрировать свое будущее приложение вInstagram Developer Website. Процесс регистрации не вызывает трудностей. В конце вам сообщат Client ID, Client Secret, Redirect URI и другую техническую информацию, которую нужно будет сохранить, чтобы потом использовать в своем приложении.
После аутентификации ваше приложение получает маркер доступа, который затем используется для отправки запросов к Instagram. Для начала давайте сохраним значения client id и client secret, которые вы поучили после регистрации, в файле strings.xml.
<resources> <string name="instagram_id">eaa…</string> <string name="instagram_secret">71f…</string> <string name="APP_ID">449…</string> <string name="callbackurl">http:// …</string> </resources>
Зададим несколько констант, которые потом будем использовать при генерации URL адресов
private static final String AUTHURL="https://api.instagram.com/oauth/authorize/"; private static final String TOKENURL="https://api.instagram.com/oauth/access_token"; public static final String APIURL="https://api.instagram.com/v1"; public static String CALLBACKURL="Your Redirect URI";
Первый адрес используется для аутентификации, второй - для получения маркера доступа и информации о пользователе, третий - версия API, которую мы будем использовать при отправке запросов к Instagram, четвертый адрес - ссылка для редиректа. Эту ссылку вы должны были получить в процессе регистрации. Если Вы укажете ее неверно, то Instagram не будет работать с вашим приложением.
Используя эти константы, сгенерируем два URL
authURLString= AUTHURL+"?client_id="+ client_id+"&amp;redirect_uri="+ CALLBACKURL+ "&amp;response_type=code&amp;display=touch&amp;scope=likes+comments+relationships"; tokenURLString= TOKENURL+"?client_id="+ client_id+"&amp;client_secret="+ client_secret+ "&amp;redirect_uri="+ CALLBACKURL+"&amp;grant_type=authorization_code";
В authURLString входят client id, callback url, response_type и scope. Первые два параметра понятны, "response_type=code" означает, что после успешной аутентификации вы хотите получить маркер запроса, а не маркер доступа. Параметр "scope" задает права доступа которые запрашивает ваша программа. Более подробно о возможных значениях этого параметра можно прочитать в документации по Instagram API.
После того, как наши адреса готовы, покажем ссылку в WebView, чтобы пользователь мог зайти в свой Instagram аккаунт.
WebView webView=new WebView(getContext()); webView.setVerticalScrollBarEnabled(false); webView.setHorizontalScrollBarEnabled(false); webView.setWebViewClient(new AuthWebViewClient()); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl(authURLString);
В четвертой строке мы ссылаемся на класс AuthWebViewClient, который будет обрабатывать ответ сервера. Давайте напишем его.
publicclass AuthWebViewClientextends WebViewClient
Переопределим в этом классе метод shouldOverrideUrlLoading
@Override public boolean shouldOverrideUrlLoading(WebView view, String url){ if(url.startsWith(CALLBACKURL)){ System.out.println(url); String parts[]= url.split("="); request_token= parts[1];//Это наш маркер запроса. InstagramLoginDialog.this.dismiss(); returntrue; } returnfalse; }
Если вы все сделали правильно, то в переменной request_token окажется маркер запроса, который мы будем использовать для получения маркера доступа.
Создадим класс-потомок AsyncTask и поместим следующий метод в doInBackground().
try { URL url=new URL(tokenURLString); HttpsURLConnection httpsURLConnection=(HttpsURLConnection) url.openConnection(); httpsURLConnection.setRequestMethod("POST"); httpsURLConnection.setDoInput(true); httpsURLConnection.setDoOutput(true); OutputStreamWriter outputStreamWriter=new OutputStreamWriter(httpsURLConnection.getOutputStream()); outputStreamWriter.write("client_id="+client_id+ "&amp;client_secret="+ client_secret+ "&amp;grant_type=authorization_code"+ "&amp;redirect_uri="+CALLBACKURL+ "&amp;code="+ token); outputStreamWriter.flush(); String response= streamToString(httpsURLConnection.getInputStream()); JSONObject jsonObject=(JSONObject)new JSONTokener(response).nextValue(); accessTokenString= jsonObject.getString("access_token");//Это наш маркер доступа id= jsonObject.getJSONObject("user").getString("id"); //Получаем данные о пользователе username= jsonObject.getJSONObject("user").getString("username"); } catch(Exception e) { e.printStackTrace(); }
Этот код открывает HTTPS соединение и заполняет его данными, которые требуются Instagram-у для генерации для нас маркера доступа. Полученный маркер доступа нужно надежно сохранить и использовать каждый раз при обращении к Instagram.
Исходный код проекта можно скачатьздесь.
Загрузка изображений является самой базовой функцией и не требует каких-либо специальных прав (см параметр scope выше). Для запроса изображений нам нужно сформировать специальный URL
String urlString= APIURL+"/users/"+{User's Instagram Id} + "/media/recent/?access_token=" + {Маркер доступа}; URL url = new URL(urlString);
Здесь нам потребуются User's Instagram Id и маркер доступа, которые мы получили в процессе аутентификации.
Откроем соединение для получения входящего потока данных. Перед тем как использовать данные, поток нужно преобразовать в строку. Используемый для этого метод streamToString() описан ниже.
InputStream inputStream= url.openConnection().getInputStream(); String response= instagramImpl.streamToString(inputStream);
public String streamToString(InputStream is) throws IOException{ String string=""; if(is!=null){ StringBuilder stringBuilder=new StringBuilder(); String line; try{ BufferedReader reader=new BufferedReader( new InputStreamReader(is)); while((line= reader.readLine())!=null){ stringBuilder.append(line); } reader.close(); } finally{ is.close(); } string= stringBuilder.toString(); } return string; }
Instagram отправляет ответы в формате Json, поэтому нам нужно преобразовать полученную строку в Json.
JSONObject jsonObject=(JSONObject)new JSONTokener(response).nextValue(); JSONArray jsonArray= jsonObject.getJSONArray("data");
Все что нам осталось, вытащить URL картинки из JSon объекта.
JSONObject mainImageJsonObject= jsonArray.getJSONObject(index).getJSONObject("images").getJSONObject("low_resolution"); String imageUrlString= imageJsonObject.getString("url");
Instagram сохраняет изображения в трех разрешениях, соответственно Вы можете запросить одно из них: standard_resolution, low_resolution и thumbnail. Как видите, мы использовали low_resolution.
Нам осталось загнать весь этот код в отдельный AsyncTask поток и можно использовать.
Оригинал:
Instagram integration in an Android app. Part 1
Instagram integration in an Android app. Part 2
Перевод:Александр Ледков