Android: Instagram photos of a certain user

0

Scenery:

In my app I want to show a user's photos. I am authenticating, I have access to the token and I can login with username and password but after login it says that I am not allowed to open this page.

Code:

PhotosActivity.java

public static final String CLIENT_ID = "seu_id";
public static final String CLIENT_SECRET = "seu_secret";
public static final String CALLBACK_URL = "callback";
String url ="https://instagram.com/oauth/authorize?" +"response_type=token" + "&redirect_uri=" + CALLBACK_URL+"&scope=basic"+"&client_id=" + CLIENT_ID ;

WebView webview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.photo_activity);

    ActionBar bar = getActionBar();
    bar.setDisplayHomeAsUpEnabled(true);

    WebView webview = (WebView)findViewById(R.id.webView2);

    webview.setWebViewClient(new WebViewClient() {

        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            String fragment = "#access_token=";
            int start = url.indexOf(fragment);
            if (start > -1) {

                // You can use the accessToken for api calls now.
                String accessToken = url.substring(start + fragment.length(), url.length());

                Log.v(TAG, "OAuth complete, token: [" + accessToken + "].");
                Log.i(TAG, "" +accessToken);
Toast.makeText(PhotosActivity.this, "Token: " + accessToken, Toast.LENGTH_SHORT).show();
            }
        }
    });

    webview.loadUrl(url);

}
    
asked by anonymous 24.07.2014 / 17:16

1 answer

1

I had the same need as you, accessing images from a public profile on Instagram in the Android Application.

But one thing I did differently was to create a WebService which from time to time queries the Media API and updates the database. But the access core should look good.

I did this because I do not know if it's worth to leave the Client ID in the application, for security reasons, someone can spy on the requests and get the Client ID that your application is using, is invalid.

The code is a bit more complex, because I've tried to normalize the consumption of various social networking APIs, I'll just put the specific part of Instagram.

To mount the access URI to Client ID grams of instagram I did:

public String getUri(String instagramUserId, String token, int amount) throws UnsupportedEncodingException {
    StringBuilder uri = new StringBuilder("https://api.instagram.com/v1");

    // instagramUserId é uma variável local com o ID do usuário de perfil público
    // Pode ser obtido nesse site: http://jelled.com/instagram/lookup-user-id
    // token é o Client ID do aplicativo
    // amount é a quantidade de registros que devem ser retornadas

     uri.append("/users/").append(instagramUserId)
        .append("/media/recent?client_id=").append(URLEncoder.encode(token, "UTF-8"))
        .append("&count=").append(Integer.toString(amount));

    return uri.toString();
}

With this URI I made a WebService for the Instagram endpoint, as below:

@Override
public List<JSONObject> fetchInstagram(String instagramUserId, String token, int amount) {
    try {
        String uri = getUri(instagramUserId, token, amount);

        if(uri == null) {
            return Collections.EMPTY_LIST;
        }

        // Inicializa um cliente Http
        HttpClient httpClient = HttpClientBuilder.create().build();

        // Especifica o método a ser executado, GET como especificado pela documentacao do Instagram
        HttpGet get = new HttpGet(uri);

        // Definindo o Charset da resposta, a fim de evitar problemas com encoding
        // Definindo que o cliente aceita codificação gzip, para reduzir o gasto de banda do dispositivo.
        get.addHeader("Accept-Encoding", "gzip");
        get.addHeader("Accept-Charset", "UTF-8");

        System.out.println("Making request to " + uri);

        // Executa a requisicao e espera pela resposta
        HttpResponse response = httpClient.execute(get);

        // Se o Instagram nao respondeu com codigo 200 (OK), entao loga o erro
        if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
            System.out.println(EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8")));
            return null;
        }

        // Extrai a resposta em formato String
        String responseString = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));

        // Retorna a lista de registros de midia do usuario
        return parseResponse(responseString);
    } catch (MalformedURLException | ProtocolException e) {
        e.printStackTrace();
        return null;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

// Aqui poderia ser retornado o próprio JSONArray com os registros
public List<JSONObject> parseResponse(String response) {
    // Transforma a resposta String em JSON, para poder manipular
    JSONObject jsonResponse = new JSONObject(response);

    // Atributo do JSON que contem a lista de registros obtidos do usuario
    JSONArray registros = jsonResponse.getJSONArray("data");
    List<JSONObject> objetos = new ArrayList<JSONObject>();

    for(int i = 0; i < registros.length(); ++i) {
        JSONObject o = registros.getJSONObject(i);

        // Faz uma logica com o registro em si, filtragem, normalizacao, ou outro qualquer

        objetos.add(o);
    }

    return registros;
}

To use, just do:

public void callInstagram() {
    String token = "SEU_CLIENT_D";
    String instagramUserId = "USER_ID";

    int amount = 100;

    List<JSONObject> registros = fetchInstagram(instagramUserId, token, amount);

    // Processa os registros, levando em conta o tipo e as resolucoes das midias.
}

In this solution I ended up using the Apache HttpRequest fault API (to use the HttpClient, HttpGet, and HttpClientBuilder class), which can be obtained at this address: link . There is migration for Android at this address: link .

An example of an Instagram JSON response is:

{
    "data": [{
        "comments": {
            "data": [],
            "count": 0
        },
        "caption": {
            "created_time": "1296710352",
            "text": "Inside le truc #foodtruck",
            "from": {
                "username": "kevin",
                "full_name": "Kevin Systrom",
                "type": "user",
                "id": "3"
            },
            "id": "26621408"
        },
        "likes": {
            "count": 15,
            "data": [{
                "username": "mikeyk",
                "full_name": "Mike Krieger",
                "id": "4",
                "profile_picture": "..."
            }, {...subset of likers...}]
        },
        "link": "http://instagr.am/p/BWrVZ/",
        "user": {
            "username": "kevin",
            "profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_3_75sq_1295574122.jpg",
            "id": "3"
        },
        "created_time": "1296710327",
        "images": {
            "low_resolution": {
                "url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_6.jpg",
                "width": 306,
                "height": 306
            },
            "thumbnail": {
                "url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_5.jpg",
                "width": 150,
                "height": 150
            },
            "standard_resolution": {
                "url": "http://distillery.s3.amazonaws.com/media/2011/02/02/6ea7baea55774c5e81e7e3e1f6e791a7_7.jpg",
                "width": 612,
                "height": 612
            }
        },
        "type": "image",
        "users_in_photo": [],
        "filter": "Earlybird",
        "tags": ["foodtruck"],
        "id": "22721881",
        "location": {
            "latitude": 37.778720183610183,
            "longitude": -122.3962783813477,
            "id": "520640",
            "street_address": "",
            "name": "Le Truc"
        }
    },
    {
        "videos": {
            "low_resolution": {
                "url": "http://distilleryvesper9-13.ak.instagram.com/090d06dad9cd11e2aa0912313817975d_102.mp4",
                "width": 480,
                "height": 480
            },
            "standard_resolution": {
                "url": "http://distilleryvesper9-13.ak.instagram.com/090d06dad9cd11e2aa0912313817975d_101.mp4",
                "width": 640,
                "height": 640
            },
        "comments": {
            "data": [{
                "created_time": "1279332030",
                "text": "Love the sign here",
                "from": {
                    "username": "mikeyk",
                    "full_name": "Mikey Krieger",
                    "id": "4",
                    "profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_1242695_75sq_1293915800.jpg"
                },
                "id": "8"
            },
            {
                "created_time": "1279341004",
                "text": "Chilako taco",
                "from": {
                    "username": "kevin",
                    "full_name": "Kevin S",
                    "id": "3",
                    "profile_picture": "..."
                },
                "id": "3"
            }],
            "count": 2
        },
        "caption": null,
        "likes": {
            "count": 1,
            "data": [{
                "username": "mikeyk",
                "full_name": "Mikeyk",
                "id": "4",
                "profile_picture": "..."
            }]
        },
        "link": "http://instagr.am/p/D/",
        "created_time": "1279340983",
        "images": {
            "low_resolution": {
                "url": "http://distilleryimage2.ak.instagram.com/11f75f1cd9cc11e2a0fd22000aa8039a_6.jpg",
                "width": 306,
                "height": 306
            },
            "thumbnail": {
                "url": "http://distilleryimage2.ak.instagram.com/11f75f1cd9cc11e2a0fd22000aa8039a_5.jpg",
                "width": 150,
                "height": 150
            },
            "standard_resolution": {
                "url": "http://distilleryimage2.ak.instagram.com/11f75f1cd9cc11e2a0fd22000aa8039a_7.jpg",
                "width": 612,
                "height": 612
            }
        },
        "type": "video",
        "users_in_photo": null,
        "filter": "Vesper",
        "tags": [],
        "id": "363839373298",
        "user": {
            "username": "kevin",
            "full_name": "Kevin S",
            "profile_picture": "http://distillery.s3.amazonaws.com/profiles/profile_3_75sq_1295574122.jpg",
            "id": "3"
        },
        "location": null
    },
   ]
}

You will need to see which fields of each object that make up the response is necessary, and take into account that for some media types (image in this case), it provides various resolutions, which can be used on different devices (tablets or smartphone).

    
25.07.2014 / 02:21