Instagram API. Simple Android application with login and getting user info.

Sasha
5 min readSep 26, 2018

--

If you start using the Instagram API and want to understand how it works, I hope my experience will help you.

We will be using Android Studio 3.1.4. Instagram API v1.

Interaction with the API occurs through HTTP requests.

Login steps:
1) redirect user to the login page Instagram
2) get an access token for further requests (user name, profile picture etc)

Before we begin, we need to get all the necessary parameters for the request. To do this, register your application at https://www.instagram.com/developer/ . In the “valid redirect URI” field, write any URL. For example, https://www.instagram.com/. After registration, you will receive your client id for further use.

Create application

Now we can start creating the application. Create a new project in Android Studio with Empty Activity. Our application will send the HTTP requests. Therefore, we need permission to use the Internet. Add it to your Android Manifest before <application> tag:

<uses-permission android:name="android.permission.INTERNET" />

Add this strings in res/values/strings:

<string name="client_id">your_client_id</string>
<string name="callback_url">https://instagram.com/</string>
<string name="base_url">https://api.instagram.com/</string>

Now change activity_main.xml. Add the login button with the onClick method in the MainActivity.

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>

<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:layout_centerHorizontal="true"
android:text="INSTAGRAM LOGIN"
/>
</RelativeLayout>

MainActivity:

public void onClick(View view) {authenticationDialog = new AuthenticationDialog(this, this);
authenticationDialog.setCancelable(true);
authenticationDialog.show();
}

Dialog for authentication will be opened after button click.

AuthenticationDialog

Create a AuthenticationDialog class in your project:

public class AuthenticationDialog extends Dialog {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.auth_dialog);
}
}

Add this fields and constructor in your class:

private final String redirect_url;
private final
String request_url;
private AuthenticationListener listener;

public AuthenticationDialog(@NonNull Context context, AuthenticationListener listener) {
super(context);
this.listener = listener;
this.redirect_url = context.getResources().getString(R.string.redirect_url);
this.request_url = context.getResources().getString(R.string.base_url) +
"oauth/authorize/?client_id=" +
context.getResources().getString(R.string.client_id) +
"&redirect_uri=" + redirect_url +
"&response_type=token&display=touch&scope=public_content";
}

We are getting redirect_url from res/values/string.

We constuct request_url using client_id and redirect_url. This URL will be used to redirect user to the Instagram login page. In response we will get access token.

listener will be MainActivity. After receiving the token, we will pass it to listener's onTokenReceived method.

Create interface AuthenticationListener:

public interface AuthenticationListener {
void onTokenReceived(String auth_token);
}

And implementation it in MainActivity:

public class MainActivity extends AppCompatActivity
implements AuthenticationListener
{
...@Override
public void onTokenReceived(String auth_token) {
}
...}

Let’s get back to AuthenticationDialog. Create auth_dialog.xml.

<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/auth_dialog"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarAlwaysDrawHorizontalTrack="true"
android:scrollbars="horizontal"
>

<WebView
android:id="@+id/webView"
android:layout_width="500dp"
android:layout_height="400dp"
>
</WebView>
</LinearLayout>

</HorizontalScrollView>

We will open Instagram login page in WebView. HorizontalScrollView is necessary for convenient viewing of page.

In the onCreate() method we initialize WebView.

public class AuthenticationDialog extends Dialog {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.auth_dialog);
WebView webView = findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl(request_url);
webView.setWebViewClient(webViewClient);

}
}

Create a webViewClient. Override methods shouldOverrideUrlLoading and onPageFinished.

WebViewClient webViewClient = new WebViewClient() {

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(redirect_url)) {
AuthenticationDialog.this.dismiss();
return true;
}
return false;
}

@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (url.contains("access_token=")) {
Uri uri = Uri.EMPTY.parse(url);
String access_token = uri.getEncodedFragment();
access_token = access_token.substring(access_token.lastIndexOf("=") + 1);
listener.onTokenReceived(access_token);
}
}
}
};

After successful authentication in WebView with Instagram login page method shouldOverrideUrlLoading is called. It checks redirect_url and closes authentication dialog.

This triggers onPageFinished method where we get a access_token and pass it to the listener (MainActivity).

Save data

Using access token, we will get the user info and store it with SharedPreferences. Create AppPreferences class to get, put and clear data.

public class AppPreferences {
public static final String APP_PREFERENCES_FILE_NAME = "userdata";
public static final String USER_ID = "userID";
public static final String TOKEN = "token";
public static final String PROFILE_PIC = "profile_pic";
public static final String USER_NAME = "username";

private SharedPreferences preferences;
/
public AppPreferences(Context context) {
this.preferences = context.getSharedPreferences(APP_PREFERENCES_FILE_NAME, Context.MODE_PRIVATE);
}

public String getString(String key) {
return preferences.getString(key, null);
}

public void putString(String key, String value)
{
SharedPreferences.Editor editor = preferences.edit();
editor.putString(key, value);
editor.apply();
}

public void clear()
{
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.apply();
}
}

Get user info

Add in the MainActivity token field.

private String token = null;

And implement onTokenReceived method.

@Override
public void onTokenReceived(String auth_token) {
if (auth_token == null)
return;
appPreferences.putString(AppPreferences.TOKEN, auth_token);
token = auth_token;
getUserInfoByAccessToken(token);
}

Create getUserInfoByAccessToken method.

private void getUserInfoByAccessToken(String token) {
new RequestInstagramAPI().execute();
}

Create RequestInstagramAPI class which extends AsyncTask.

private class RequestInstagramAPI extends AsyncTask<Void, String, String> {

@Override
protected String doInBackground(Void... params) {
}

@Override
protected void onPostExecute(String response) {
}
}

We will request the user’s info in a separate thread (doInBackground).

@Override
protected String doInBackground(Void... params) {
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(getResources().getString(R.string.get_user_info_url) + token);
try {
HttpResponse response = httpClient.execute(httpGet);
HttpEntity httpEntity = response.getEntity();
return EntityUtils.toString(httpEntity);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

Add string get_user_info_url in res/values/strings.

<string name="get_user_info_url">
https://api.instagram.com/v1/users/self/?access_token=
</string>

We will save the user info after receiving the response (onPostExecute).

@Override
protected void onPostExecute(String response) {
super.onPostExecute(response);
if (response != null) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONObject jsonData = jsonObject.getJSONObject("data");
if (jsonData.has("id")) {
appPreferences.putString(AppPreferences.USER_ID, jsonData.getString("id"));
appPreferences.putString(AppPreferences.USER_NAME, jsonData.getString("username"));
appPreferences.putString(AppPreferences.PROFILE_PIC, jsonData.getString("profile_picture"));
login();
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Toast toast = Toast.makeText(getApplicationContext(),"Login error!",Toast.LENGTH_LONG);
toast.show();
}
}

Display user info

Add to activity_main.xml LinearLayout with ImageView and two TextView. Here we display user info.

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>

<Button
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:layout_centerHorizontal="true"
android:text="INSTAGRAM LOGIN"
/>

<LinearLayout
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btn_login"
android:orientation="vertical"
>
<ImageView
android:id="@+id/pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>

</RelativeLayout>

Create login() and logout() methods.

public void login() {
Button button = findViewById(R.id.btn_login);
View info = findViewById(R.id.info);
ImageView pic = findViewById(R.id.pic);
TextView id = findViewById(R.id.id);
TextView name = findViewById(R.id.name);
info.setVisibility(View.VISIBLE);
button.setText("LOGOUT");
name
.setText(appPreferences.getString(AppPreferences.USER_NAME));
id.setText(appPreferences.getString(AppPreferences.USER_ID));
Picasso.with(this).
load(appPreferences.getString(AppPreferences.PROFILE_PIC)).
into(pic);
}

login() displays user info.

public void logout() {
button.setText("INSTAGRAM LOGIN");
token = null;
info.setVisibility(View.GONE);
appPreferences.clear();
}

logout() clears user info.

Make some small changes to onClick():

public void onClick(View view) {
if(token!=null)
{
logout();
}

else {
authenticationDialog = new AuthenticationDialog(this, this);
authenticationDialog.setCancelable(true);
authenticationDialog.show();
}
}

That’s all!

Full code: https://github.com/AlexandraSova/InstagramLogin

Our application should look like this:

--

--