com.jacr.instagramtrendreader.Main.java Source code

Java tutorial

Introduction

Here is the source code for com.jacr.instagramtrendreader.Main.java

Source

/*
 * Copyright (C) 2014 Jesus A. Castro R.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jacr.instagramtrendreader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.jacr.instagramtrendreader.core.BaseActivity;
import com.jacr.instagramtrendreader.core.Global;
import com.jacr.instagramtrendreader.core.IBase;
import com.jacr.instagramtrendreader.utils.Messages;
import com.jacr.instagramtrendreader.utils.Util;

/**
 * Main Class.
 * 
 * @author j.castro 28/07/2014
 * 
 */
public class Main extends BaseActivity {

    private static final String CLASS_NAME = Main.class.getName();
    public static final String ACTION_IMAGE_CLICK = CLASS_NAME + ".action_image_click";

    private TableLayout layoutThumbnail;
    private FeedReader feedReader;
    private ViewPagerAdapter<MainFragment> mAdapter;
    private ViewPager mPager;
    private BroadcastReceiver mReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_main);

        /* Customizing ActionBar */
        Resources r = getResources();
        ActionBar ab = super.getActionBar(false);
        ab.setIcon(r.getDrawable(R.drawable.ic_menu_home));
        ab.setTitle(Util.getTitleActivity(getString(R.string.title_my_gallery_app)));

        /* Views */
        layoutThumbnail = (TableLayout) findViewById(R.id.layoutThumbnail);
        layoutThumbnail.setPadding(1, 1, 1, 1);

        /* Setting Viewpager and Indicator */
        mPager = (ViewPager) findViewById(R.id.pagerMain);
        mAdapter = new ViewPagerAdapter<MainFragment>(getSupportFragmentManager());
        mPager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageScrollStateChanged(int arg0) {
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

            @Override
            public void onPageSelected(int arg0) {
                int key = feedReader.getListThumbnailKeys().get(arg0);
                feedReader.highlightThumbnail(key);

            }

        });

        /* Receiver */
        mReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                Bundle extras = intent.getExtras();
                if (action.contentEquals(ACTION_IMAGE_CLICK)) {
                    int key = extras.getInt(ACTION_IMAGE_CLICK);
                    if (key != -1) {
                        Intent in = new Intent(Main.this, ImageDetails.class);
                        Bundle b = new Bundle();

                        /*
                         * Warning with Error FAILED BINDED TRANSACTION: it
                         * happens When the transfer of "extras" out of memory.
                         * in This case, when images are sent in intent.
                         */
                        b.putSerializable(ImageDetails.KEY_THUMBNAIL_DATA, feedReader.getListThumbnailData());
                        b.putSerializable(ImageDetails.KEY_THUMBNAIL_KEYS, feedReader.getListThumbnailKeys());
                        b.putInt(ImageDetails.KEY_THUMBNAIL_ACTUAL_KEY, key);
                        in.putExtras(b);
                        startActivity(in);
                    }

                }
            }
        };
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_IMAGE_CLICK);
        registerReceiver(mReceiver, filter);

        /* Load data from Instagram */
        cargarFeedReader();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.menu_refresh) {
            cargarFeedReader();
        }
        return true;
    }

    @Override
    protected void onDestroy() {
        if (mReceiver != null) {
            // Remove receiver
            unregisterReceiver(mReceiver);
            mReceiver = null;
        }
        super.onDestroy();

    }

    private boolean isOnline(int timeout) {
        // Test 1: Is GPRS / Wifi port ON?
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnected()) {
            try {
                // Test 2: Ping specific url
                URL url = new URL("http://www.google.com");
                HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
                urlc.setConnectTimeout(timeout);
                urlc.connect();
                if (urlc.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    return true;
                }
            } catch (MalformedURLException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private void cargarFeedReader() {
        if (!isOnline(3000)) { // Max 3s
            final String title = getString(R.string.error_title);
            final String content = getString(R.string.error_nored);
            Messages.abrirDialogoConfirmacion(Main.this, title, content);
        } else {

            feedReader = new FeedReader(this);
            feedReader.execute();
        }
    }

    private void addPage(String imageFile, int key) {
        mAdapter.addFragment(MainFragment.newInstance(key, imageFile));
    }

    private void setPageNumber(int page) {
        mPager.setCurrentItem(page);
    }

    private void setPageAdapter() {
        mPager.setAdapter(mAdapter);
    }

    private void cleanViewPager() {
        mAdapter.removeAllFragments();
        mPager.removeAllViews();
    }

    class FeedReader extends AsyncTask<Void, Void, String> implements IBase {

        // Constants to access data thumbnails
        public static final int THUMBNAIL_AUTHOR = 0;
        public static final int THUMBNAIL_DATE = 1;
        public static final int THUMBNAIL_TAGS = 2;
        public static final int THUMBNAIL_CAPTION = 3;
        public static final int THUMBNAIL_URL = 4;

        private ArrayList<Integer> listThumbnailKeys = new ArrayList<Integer>();
        private ArrayList<List<String>> listThumbnailData = new ArrayList<List<String>>();

        private Context mContext;

        FeedReader(Context mContext) {
            this.mContext = mContext;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Messages.abrirDialogoEspera(mContext, "", getString(R.string.msg_load_feed));
        }

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

            InputStream in = null;
            String response = null;
            try {

                /* URL */
                // System.setProperty("jsse.enableSNIExtension", "false");
                URL url = new URL(Global.URL_INSTAGRAM_API);
                Messages.log(getClass(), "Opening URL " + url.toString());

                /* Sending GET Http request */
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.setDoOutput(false);
                urlConnection.connect();

                /* Connection Status */
                int status = urlConnection.getResponseCode();
                if (status >= HttpStatus.SC_BAD_REQUEST) {

                    in = urlConnection.getErrorStream();
                    Messages.log(getClass(), Util.streamToString(in));

                } else {

                    in = urlConnection.getInputStream();

                    /* Get response */
                    response = Util.streamToString(in);
                    Messages.log(getClass(), response);

                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (ProtocolException pe) {
                pe.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (Exception e) {
                    }
                }
            }
            return response;
        }

        @Override
        protected void onPostExecute(String response) {
            super.onPostExecute(response);

            if (!Util.esVacio(response)) {

                // Thumbnail Index to highlight (default)
                final int idxDefaultThumbnail = 0;
                final int numColumnas = 3; // default columns per row
                int idxColumna = 0; // Column index
                boolean status = false;
                boolean flagHighlightDefaultThumbnail = false;
                ImageView defaultThumbnail = null;

                Messages.log(getClass(), "Processing data from feed ... ");

                // Instance for first row
                TableRow row = getTableRow();

                // Removing Thumbnails
                cleanThumbnails();
                try {

                    // JSON file starts with "meta" and "data" keys.
                    JSONArray jsonArray = new JSONObject(response).getJSONArray("data");

                    for (int i = 0, dataSize = jsonArray.length(); i < dataSize; i++) {
                        JSONObject iterador = (JSONObject) jsonArray.get(i);

                        // Thumbnail instance
                        ImageView imgThumb = new ImageView(mContext);
                        imgThumb.setOnClickListener(new OnClickListener() {

                            @Override
                            public void onClick(View v) {
                                ImageView imv = (ImageView) v;

                                setPageNumber(listThumbnailKeys.indexOf(imv.hashCode()));
                                highlightThumbnail(imv.hashCode());
                            }

                        });

                        // Instance ID (hash)
                        int key = imgThumb.hashCode();

                        // ID Instance list
                        listThumbnailKeys.add(key);

                        // Data associated list (per thumbnail)
                        listThumbnailData.add(getThumbnailData(iterador));

                        /* Setting thumbnail */
                        addThumbnail(imgThumb, getThumbnailDataByKey(key, THUMBNAIL_URL));

                        /* Adding rows in layout */

                        if (idxColumna < numColumnas) {
                            idxColumna++;
                        } else {
                            idxColumna = 1;

                            layoutThumbnail.addView(row);

                            if (flagHighlightDefaultThumbnail) {

                                // Highlight default Thumbnail
                                highlightThumbnail(defaultThumbnail.hashCode());
                                flagHighlightDefaultThumbnail = false;
                            }

                            // Instance for next row
                            row = getTableRow();
                        }

                        addImageAtRow(row, imgThumb, getThumbnailDataByKey(key, THUMBNAIL_CAPTION));

                        if (i == idxDefaultThumbnail) {
                            flagHighlightDefaultThumbnail = true;
                            // Default Page
                            setPageNumber(idxDefaultThumbnail);
                            // Default Item
                            defaultThumbnail = imgThumb;

                        }

                    }

                    Messages.log(getClass(), "Total thumbnails: " + countThumbnails());

                    // Add last row in layout
                    layoutThumbnail.addView(row);

                    setPageAdapter();

                    status = true;

                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (ProtocolException pe) {
                    pe.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (!status) {
                        Messages.abrirDialogoConfirmacion(mContext, getString(R.string.error_title),
                                getString(R.string.error_nomanejado));
                    }
                }
            } else {
                Messages.abrirDialogoConfirmacion(mContext, getString(R.string.error_title),
                        getString(R.string.error_nomanejado));

            }
            Messages.cerrarDialogoEspera();
        }

        @Override
        public String getThumbnailDataByKey(int key, int valueType) {
            List<String> lista = getThumbnailData(key);
            if (lista != null) {
                return lista.get(valueType);
            }
            return null;
        }

        private List<String> getThumbnailData(int key) {
            int idx = listThumbnailKeys.indexOf(key);
            if (idx != -1) {
                return listThumbnailData.get(idx);
            }
            return null;
        }

        public ArrayList<Integer> getListThumbnailKeys() {
            return listThumbnailKeys;
        }

        public ArrayList<List<String>> getListThumbnailData() {
            return listThumbnailData;
        }

        public int countThumbnails() {
            return listThumbnailKeys.size();
        }

        private List<String> getThumbnailData(JSONObject json) throws JSONException {

            // User
            String username = "";
            if (json.get("user") instanceof JSONObject) {
                username = ((JSONObject) (json.get("user"))).get("username").toString();
            }

            Messages.log(getClass(), "Dowloading images from user: " + username);

            // Published date (warning: unix format)
            String date = Util.nulo2Vacio(json.getString("created_time"));

            // Thumbnail Text
            String text = "";
            if (json.get("caption") instanceof JSONObject) {
                text = ((JSONObject) (json.get("caption"))).get("text").toString();
            }

            // tags
            String tags = "";
            final String separadorTags = ",";
            JSONArray jsonArrTags = (JSONArray) json.get("tags");
            for (int idx = 0; idx < jsonArrTags.length(); idx++) {
                tags += "#" + (jsonArrTags.getString(idx)) + ",";
            }
            if (!Util.esVacio(tags) && tags.lastIndexOf(",") != -1) {
                tags = tags.substring(0, tags.lastIndexOf(separadorTags));
            }

            /*
             * There are 3 kind of images: thumbnail, low_resolution y
             * standard_resolution. For reasons of download bit rate, we only
             * use thumbnails.
             */
            String imageUrl = null;
            if (json.get("images") instanceof JSONObject) {
                JSONObject jsonImages = (JSONObject) json.get("images");
                imageUrl = ((JSONObject) jsonImages.get("thumbnail")).getString("url");
            }

            ArrayList<String> listUser = new ArrayList<String>();
            listUser.add(username);
            listUser.add(date);
            listUser.add(tags);
            listUser.add(text);
            listUser.add(imageUrl);
            return listUser;
        }

        private void addThumbnail(ImageView imv, String url) throws MalformedURLException, IOException {
            InputStream in = new java.net.URL(url).openStream();
            Bitmap image = BitmapFactory.decodeStream(in);
            in.close();
            imv.setImageBitmap(image);
            createThumbnailFile(image, imv.hashCode());

        }

        private void createThumbnailFile(Bitmap bmp, int key) {
            String dir = ((Global) mContext.getApplicationContext()).getFilesDirectoryPath();
            String file = dir + key;
            File targetFile = new File(file);
            if (!targetFile.exists()) {
                try {
                    FileOutputStream fos = new FileOutputStream(file);
                    bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
                    fos.flush();
                    fos.close();
                    // Add image in ViewPager
                    addPage(file, key);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        public void highlightThumbnail(int hashcodeThumbnail) {
            final int colorSeleccion = mContext.getResources().getColor(R.color.thumbnail_highlight);
            final int colorNoSeleccion = mContext.getResources().getColor(R.color.thumbnail_gallery);

            for (int i = 0; i < layoutThumbnail.getChildCount(); i++) {
                View vRowIterador = layoutThumbnail.getChildAt(i);
                if (vRowIterador instanceof TableRow) {
                    TableRow rowIterador = (TableRow) vRowIterador;
                    for (int j = 0; j < rowIterador.getChildCount(); j++) {
                        LinearLayout llvRow = (LinearLayout) (rowIterador.getChildAt(j));
                        FrameLayout flvRow = (FrameLayout) ((LinearLayout) llvRow).getChildAt(0);
                        ImageView imvRow = (ImageView) ((FrameLayout) flvRow).getChildAt(0);
                        flvRow.setBackgroundColor(
                                imvRow.hashCode() == hashcodeThumbnail ? colorSeleccion : colorNoSeleccion);
                    }

                }
            }

        }

        private void cleanThumbnails() {

            listThumbnailKeys.clear();
            listThumbnailData.clear();
            layoutThumbnail.removeAllViews();

            // Remove saved images in directory
            Util.deleteAllFileDirectory(mContext);

            // Clean Viewpager
            cleanViewPager();
        }

        private void addImageAtRow(TableRow row, ImageView imv, String caption) {

            /* Layout Image */
            FrameLayout.LayoutParams imvLp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT);
            imvLp.setMargins(3, 3, 3, 3);
            imv.setLayoutParams(imvLp);

            /* Layout to highilight */
            FrameLayout ff = new FrameLayout(mContext);
            LinearLayout.LayoutParams ffLp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            ff.setLayoutParams(ffLp);

            /* Image Text */
            TextView txt = new TextView(mContext);
            txt.setText(caption);
            txt.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            txt.setTextSize(((Global) mContext.getApplicationContext()).getSmallTextSize());
            txt.setMaxWidth(imv.getDrawable().getMinimumWidth());
            // Setting up three dots effect.
            txt.setEllipsize(TextUtils.TruncateAt.END);
            txt.setSingleLine(true);

            /* Layout for symmetric width column */
            LinearLayout llu = new LinearLayout(mContext);
            TableRow.LayoutParams lluLp = new TableRow.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            lluLp.weight = 1.0f;
            lluLp.gravity = Gravity.CENTER;
            llu.setLayoutParams(lluLp);
            llu.setGravity(Gravity.CENTER);
            llu.setOrientation(LinearLayout.VERTICAL);

            // Add views
            ff.addView(imv);
            llu.addView(ff, 0);
            llu.addView(txt, 1);
            row.addView(llu);

        }

        private TableRow getTableRow() {

            /* Layout for row */
            TableRow row = new TableRow(mContext);
            TableLayout.LayoutParams rowLp = new TableLayout.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,
                    TableRow.LayoutParams.WRAP_CONTENT);
            row.setLayoutParams(rowLp);
            row.setPadding(2, 2, 2, 2);
            return row;
        }

    }

}