com.keithandthegirl.ui.activity.GuestsDashboardFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.keithandthegirl.ui.activity.GuestsDashboardFragment.java

Source

/**
 *  This file is part of KeithAndTheGirl for Android
 * 
 *  KeithAndTheGirl for Android is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  KeithAndTheGirl for Android is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with KeithAndTheGirl for Android.  If not, see <http://www.gnu.org/licenses/>.
 *   
 * This software can be found at <https://github.com/dmfrey/KeithAndTheGirl/>
 *
 */
package com.keithandthegirl.ui.activity;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import org.springframework.http.ContentCodingType;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.social.support.ClientHttpRequestFactorySelector;
import org.springframework.web.client.RestTemplate;

import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.keithandthegirl.MainApplication;
import com.keithandthegirl.R;
import com.keithandthegirl.api.guests.Guest;
import com.keithandthegirl.api.guests.Guests;
import com.keithandthegirl.api.guests.Url;
import com.keithandthegirl.services.download.DownloadService.Resource;
import com.keithandthegirl.services.download.DownloadServiceHelper;
import com.keithandthegirl.utils.NotificationHelper;
import com.keithandthegirl.utils.NotificationHelper.NotificationType;

/**
 * @author Daniel Frey
 *
 */
public class GuestsDashboardFragment extends ListFragment {

    private final static String TAG = GuestsDashboardFragment.class.getSimpleName();

    private static final String DATA_DIR = "Data";

    private static final int REFRESH_ID = Menu.FIRST + 10;
    private static final int MOST_RECENT_ID = Menu.FIRST + 11;
    private static final int TOP_COUNT_ID = Menu.FIRST + 12;
    private static final int NAME_ID = Menu.FIRST + 13;

    private static final String GUESTS_DIR = "Guests";

    private MainApplication mainApplication;

    private NotificationHelper mNotificationHelper;
    private boolean notify = false;

    private List<Guest> guestList = new ArrayList<Guest>();

    private GuestRowAdapter adapter;
    private Map<Integer, Bitmap> images = new TreeMap<Integer, Bitmap>();

    private DownloadReceiver downloadReceiver;
    private DownloadServiceHelper mDownloadServiceHelper;

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.v(TAG, "onCreate : enter");
        super.onCreate(savedInstanceState);

        mainApplication = (MainApplication) getActivity().getApplicationContext();

        Log.v(TAG, "onCreate : enter");
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onActivityCreated(android.os.Bundle)
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        Log.v(TAG, "onActivityCreated : enter");
        super.onActivityCreated(savedInstanceState);

        setHasOptionsMenu(true);
        setRetainInstance(true);

        mNotificationHelper = new NotificationHelper(getActivity());

        setupAdapter();

        Log.v(TAG, "onActivityCreated : exit");
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onPause()
     */
    @Override
    public void onPause() {
        Log.v(TAG, "onPause : enter");
        super.onPause();

        if (null != downloadReceiver) {
            try {
                getActivity().unregisterReceiver(downloadReceiver);
                downloadReceiver = null;
            } catch (IllegalArgumentException e) {
                Log.e(TAG, e.getLocalizedMessage(), e);
            }
        }

        Log.v(TAG, "onPause : exit");
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onResume()
     */
    @Override
    public void onResume() {
        Log.v(TAG, "onResume : enter");
        super.onResume();

        mDownloadServiceHelper = DownloadServiceHelper.getInstance(getActivity());

        IntentFilter downloadFilter = new IntentFilter(DownloadServiceHelper.DOWNLOAD_RESULT);
        downloadFilter.setPriority(IntentFilter.SYSTEM_LOW_PRIORITY);
        downloadReceiver = new DownloadReceiver();
        getActivity().registerReceiver(downloadReceiver, downloadFilter);

        if (null != mainApplication.getGuest()) {
            Log.v(TAG, "onResume : already downloaded guest list");

            if (null != mainApplication.getGuest().getGuests()
                    && !mainApplication.getGuest().getGuests().isEmpty()) {
                Log.v(TAG, "onResume : guestList has entries");

                guestList = mainApplication.getGuest().getGuests();
            }
        }

        if (guestList.isEmpty()) {
            Log.v(TAG, "onResume : guestList is empty");

            File root;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
                root = getActivity().getExternalCacheDir();
            } else {
                root = Environment.getExternalStorageDirectory();
            }

            File dataDir = new File(root, DATA_DIR);
            dataDir.mkdirs();

            File f = new File(dataDir, "Guests.xml");
            if (f.exists()) {

                Serializer serializer = new Persister();

                try {
                    Guests guests = serializer.read(Guests.class, f);
                    setDownloadedGuests(guests);
                } catch (Exception e) {
                    Log.w(TAG, "onResume : error reading guests file");
                }
            } else {
                mainApplication.setGuestSort(MainApplication.Sort.MOST_RECENT);
                new DownloadGuestTask().execute(MainApplication.Sort.MOST_RECENT);
            }

        } else {
            setupAdapter();
        }

        Log.v(TAG, "onResume : exit");
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onCreateOptionsMenu(android.view.Menu, android.view.MenuInflater)
     */
    @Override
    @TargetApi(11)
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        Log.v(TAG, "onCreateOptionsMenu : enter");
        super.onCreateOptionsMenu(menu, inflater);

        MenuItem refresh = menu.add(Menu.NONE, REFRESH_ID, Menu.NONE,
                getResources().getString(R.string.menu_refresh));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            refresh.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
        }

        MenuItem mostRecent = menu.add(Menu.NONE, MOST_RECENT_ID, Menu.NONE,
                getResources().getString(R.string.menu_most_recent));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            mostRecent.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        }

        MenuItem topCount = menu.add(Menu.NONE, TOP_COUNT_ID, Menu.NONE,
                getResources().getString(R.string.menu_top_count));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            topCount.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        }

        MenuItem name = menu.add(Menu.NONE, NAME_ID, Menu.NONE, getResources().getString(R.string.menu_name));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            name.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
        }

        Log.v(TAG, "onCreateOptionsMenu : exit");
    }

    /* (non-Javadoc)
     * @see android.support.v4.app.Fragment#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Log.v(TAG, "onOptionsItemSelected : enter");
        Log.v(TAG, "onOptionsItemSelected : item=" + item.getItemId());

        notify = true;

        switch (item.getItemId()) {
        case REFRESH_ID:
            Log.v(TAG, "onOptionsItemSelected : refresh selected");

            if (null == mainApplication.getGuestSort()) {
                mainApplication.setGuestSort(MainApplication.Sort.MOST_RECENT);
            }

            new DownloadGuestTask().execute(mainApplication.getGuestSort());

            return true;
        case MOST_RECENT_ID:
            Log.v(TAG, "onOptionsItemSelected : most recent selected");

            mainApplication.setGuestSort(MainApplication.Sort.MOST_RECENT);
            new DownloadGuestTask().execute(MainApplication.Sort.MOST_RECENT);

            return true;
        case TOP_COUNT_ID:
            Log.v(TAG, "onOptionsItemSelected : top count selected");

            mainApplication.setGuestSort(MainApplication.Sort.TOP_COUNT);
            new DownloadGuestTask().execute(MainApplication.Sort.TOP_COUNT);

            return true;
        case NAME_ID:
            Log.v(TAG, "onOptionsItemSelected : name selected");

            mainApplication.setGuestSort(MainApplication.Sort.NAME);
            new DownloadGuestTask().execute(MainApplication.Sort.NAME);

            return true;
        }

        Log.v(TAG, "onOptionsItemSelected : exit");
        return super.onOptionsItemSelected(item);
    }

    // internal helpers

    private void setupAdapter() {

        getListView().invalidate();
        adapter = new GuestRowAdapter(getActivity().getApplicationContext(), guestList);

        setListAdapter(adapter);
        getListView().setFastScrollEnabled(true);

    }

    private void setDownloadedGuests(Guests guests) {

        this.guestList = guests.getGuests();
        mainApplication.setGuest(guests);
        setupAdapter();

        adapter.notifyDataSetChanged();

    }

    private class GuestRowAdapter extends BaseAdapter {

        //private Context mContext;
        private LayoutInflater mInflater;

        private List<Guest> guests;

        public GuestRowAdapter(Context context, List<Guest> guests) {
            Log.v(TAG, "GuestRowAdapter : enter");

            //mContext = context;
            mInflater = LayoutInflater.from(context);

            this.guests = guests;

            Log.v(TAG, "GuestRowAdapter : exit");
        }

        @Override
        public int getCount() {
            if (null != guests) {
                return guests.size();
            }

            return 0;
        }

        @Override
        public Guest getItem(int position) {
            if (null != guests) {
                return guests.get(position);
            }

            return null;
        }

        @Override
        public long getItemId(int position) {
            if (null != guests) {
                return position;
            }

            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            Log.v(TAG, "GuestRowAdapter.getView : enter");

            View v = convertView;
            ViewHolder mHolder;

            if (null == v) {
                //Log.v( TAG, "GuestRowAdapter.getView : creating new view holder" );

                v = mInflater.inflate(R.layout.guest_row, parent, false);

                mHolder = new ViewHolder();
                mHolder.image = (ImageView) v.findViewById(R.id.guest_image);
                mHolder.name = (TextView) v.findViewById(R.id.guest_name);
                mHolder.description = (TextView) v.findViewById(R.id.guest_description);

                mHolder.facebook = (ImageView) v.findViewById(R.id.guest_facebook);
                mHolder.twitter = (ImageView) v.findViewById(R.id.guest_twitter);
                mHolder.www = (ImageView) v.findViewById(R.id.guest_www);

                v.setTag(mHolder);
            } else {
                //Log.v( TAG, "GuestRowAdapter.getView : retrieving cached view holder" );

                mHolder = (ViewHolder) v.getTag();
            }

            Guest guest = getItem(position);
            if (null == guest.getPictureUrl() || "".equals(guest.getPictureUrl())) {
                Log.v(TAG, "GuestRowAdapter.getView : guest does not have an image");

                mHolder.image.setVisibility(View.GONE);
            } else {
                //Log.v( TAG, "GuestRowAdapter.getView : guest has an image" );

                mHolder.image.setVisibility(View.VISIBLE);

                File root;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
                    root = getActivity().getExternalCacheDir();
                } else {
                    root = Environment.getExternalStorageDirectory();
                }

                File pictureDir = new File(root, GUESTS_DIR);
                pictureDir.mkdirs();

                File f = new File(pictureDir, guest.getShowGuestId() + ".jpg");
                if (f.exists()) {
                    //Log.v( TAG, "GuestRowAdapter.getView : guest image exists in cache dir" );

                    if (!images.containsKey(guest.getShowGuestId())) {
                        //Log.v( TAG, "GuestRowAdapter.getView : guest image not in fragment cache" );

                        try {
                            InputStream is = new FileInputStream(f);
                            Bitmap bitmap = BitmapFactory.decodeStream(is);

                            images.put(guest.getShowGuestId(), bitmap);
                            mHolder.image.setImageBitmap(bitmap);
                            //Log.v( TAG, "GuestRowAdapter.getView : banner added to adapter cache" );
                        } catch (Exception e) {
                            Log.e(TAG, "GuestRowAdapter.getView : error reading file", e);
                        }
                    } else {
                        //Log.v( TAG, "GuestRowAdapter.getView : guest image exists in fragment cache" );

                        mHolder.image.setImageBitmap(images.get(guest.getShowGuestId()));
                    }
                } else {
                    //Log.v( TAG, "GuestRowAdapter.getView : image does not exist in cache dir" );

                    mDownloadServiceHelper.download(guest.getPictureUrl(), guest.getShowGuestId(), GUESTS_DIR,
                            String.valueOf(guest.getShowGuestId()), Resource.JPG);
                }

            }
            mHolder.name.setText(guest.getRealName()
                    + (guest.getEpisodeCount() > 1 ? " (" + guest.getEpisodeCount() + " shows)" : ""));
            mHolder.description.setText(guest.getDescription());

            Map<String, String> urls = new HashMap<String, String>();
            if (null != guest.getUrls() && null != guest.getUrls().getUrls()) {
                for (Url url : guest.getUrls().getUrls()) {
                    if (url.getAddress().indexOf("facebook") != -1) {
                        urls.put("facebook", url.getAddress());
                    }

                    if (url.getAddress().indexOf("twitter") != -1) {
                        urls.put("twitter", url.getAddress());
                    }

                    if (url.getAddress().indexOf("facebook") == -1 && url.getAddress().indexOf("twitter") == -1) {
                        urls.put("www", url.getAddress());
                    }

                }
            }

            if (urls.containsKey("facebook")) {
                mHolder.facebook.setVisibility(View.VISIBLE);

                final String url = urls.get("facebook");
                mHolder.facebook.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {

                        Intent facebookIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(facebookIntent);

                    }
                });
            } else {
                mHolder.facebook.setVisibility(View.GONE);
            }

            if (urls.containsKey("twitter")) {
                mHolder.twitter.setVisibility(View.VISIBLE);

                final String url = urls.get("twitter");
                mHolder.twitter.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {

                        Intent twitterIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(twitterIntent);

                    }
                });
            } else {
                mHolder.twitter.setVisibility(View.GONE);
            }

            if (urls.containsKey("www")) {
                mHolder.www.setVisibility(View.VISIBLE);

                final String url = urls.get("www");
                mHolder.www.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {

                        Intent wwwIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(wwwIntent);

                    }
                });
            } else {
                mHolder.www.setVisibility(View.GONE);
            }

            Log.v(TAG, "GuestRowAdapter.getView : exit");
            return v;
        }

        private class ViewHolder {

            ImageView image;

            TextView name;
            TextView description;

            ImageView facebook;
            ImageView twitter;
            ImageView www;

            ViewHolder() {
            }

        }

    }

    private class DownloadReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.v(TAG, "DownloadReceiver.onReceive : enter");

            adapter.notifyDataSetChanged();

            Log.v(TAG, "DownloadReceiver.onReceive : exit");
        }

    }

    private class DownloadGuestTask extends AsyncTask<MainApplication.Sort, Void, Guests> {

        @Override
        protected Guests doInBackground(MainApplication.Sort... params) {
            Log.v(TAG, "DownloadGuestsTask.doInBackground : enter");

            MainApplication.Sort sortType = (MainApplication.Sort) params[0];

            RestTemplate template = new RestTemplate(true, ClientHttpRequestFactorySelector.getRequestFactory());

            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_XML));
            requestHeaders.setAcceptEncoding(Collections.singletonList(ContentCodingType.GZIP));

            HttpEntity<?> entity = new HttpEntity<Object>(requestHeaders);

            try {
                if (notify) {
                    mNotificationHelper.createNotification("KeithAndTheGirl", "Refreshing Guest List",
                            NotificationType.SYNC);
                }

                Log.v(TAG, "DownloadGuestsTask.doInBackground : url=" + MainApplication.KATG_GUEST_URL
                        + "?sortType=" + sortType.getType());
                ResponseEntity<Guests> responseEntity = template.exchange(
                        MainApplication.KATG_GUEST_URL + "?sortType=" + sortType.getType(), HttpMethod.GET, entity,
                        Guests.class);
                switch (responseEntity.getStatusCode()) {
                case OK:
                    Log.v(TAG, "DownloadGuestsTask.doInBackground : exit, Ok");

                    return responseEntity.getBody();
                default:
                    Log.v(TAG, "DownloadGuestsTask.doInBackground : exit, error");

                    return null;
                }
            } catch (Exception e) {
                Log.e(TAG, "DownloadGuestsTask.doInBackground : exit, error", e);

                return null;
            }

        }

        /* (non-Javadoc)
         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
         */
        @Override
        protected void onPostExecute(Guests result) {
            Log.v(TAG, "DownloadGuestsTask.onPostExecute : enter");

            if (notify) {
                mNotificationHelper.completed();
            }

            notify = false;

            if (null != result) {
                Log.v(TAG, "DownloadGuestsTask.onPostExecute : updating guests");

                try {
                    File root;
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
                        root = getActivity().getExternalCacheDir();
                    } else {
                        root = Environment.getExternalStorageDirectory();
                    }

                    File dataDir = new File(root, DATA_DIR);
                    dataDir.mkdirs();

                    File f = new File(dataDir, "Guests.xml");
                    if (f.exists()) {
                        f.delete();

                        f = new File(dataDir, "Guests.xml");
                    }

                    Serializer serializer = new Persister();
                    serializer.write(result, f);

                } catch (Exception e) {
                    Log.e(TAG, "error saving file", e);
                }

                setDownloadedGuests(result);
            }

            Log.v(TAG, "DownloadGuestsTask.onPostExecute : exit");
        }

    }

}