com.codingrhemes.steamsalesmobile.GameSaleActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.codingrhemes.steamsalesmobile.GameSaleActivity.java

Source

/*
Steam Sales Mobile - Android application to keep track of the steam sales.
    Copyright (C) 2013  Mathieu Rhaume <mathieu@codingrhemes.com>
    
    This program 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.
    
    This program 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.
*/

package com.codingrhemes.steamsalesmobile;

import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class GameSaleActivity extends FragmentActivity implements ActionBar.TabListener {

    private final static String URL_API = "http://steam-sales.codingrhemes.com/";
    private final static String API_DAILY_DEAL = "dailydeal";
    private final static String API_MOST_POPULAR = "mostpopular";
    private final static String API_SPECIAL = "special";

    // making that fragment a singleton to reload the pictures from an other class!!
    private static GamesFragment gamesFragment;
    private static MostPopularGamesFragment mostPopularFragment;
    private static DealOfTheDayFragment dailyDealFragment;

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
     * will keep every loaded fragment in memory. If this becomes too memory
     * intensive, it may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    ViewPager mViewPager;

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

        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        if (savedInstanceState == null) {
            // Setting up bundle to keep values
            Bundle mostPopGames = new Bundle();
            mostPopGames.putBoolean("isMostPopular", true);
            dailyDealFragment = new DealOfTheDayFragment();
            gamesFragment = new GamesFragment();
            mostPopularFragment = new MostPopularGamesFragment();
            // set them to the fragment
            mostPopularFragment.setArguments(mostPopGames);
        }

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the app.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        // When swiping between different sections, select the corresponding
        // tab. We can also use ActionBar.Tab#select() to do this if we have
        // a reference to the Tab.
        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                actionBar.setSelectedNavigationItem(position);
            }
        });

        // For each of the sections in the app, add a tab to the action bar.
        for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            // Create a tab with text corresponding to the page title defined by
            // the adapter. Also specify this Activity object, which implements
            // the TabListener interface, as the callback (listener) for when
            // this tab is selected.
            actionBar
                    .addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(i)).setTabListener(this));
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_game_sale_activity, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.action_about:
            startActivity(new Intent(this, AboutActivity.class));
            return true;
        case R.id.action_reload:
            switch (getActionBar().getSelectedNavigationIndex()) {
            // This is Daily Deal
            case 0:
                dailyDealFragment.reloadDataset();
                break;
            // This is Sales
            case 1:
                gamesFragment.reloadDataset();
                break;
            case 2: // Most popular
                mostPopularFragment.reloadDataset();
                break;
            }

            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
        // When the given tab is selected, switch to the corresponding page in
        // the ViewPager.
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);

        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a DummySectionFragment (defined as a static inner class
            // below) with the page number as its lone argument.

            switch (position) {
            case 0: // Deal of the day
                return dailyDealFragment;
            case 1: // Sales
                return gamesFragment;
            case 2: // Most popular
                return mostPopularFragment;
            default:
                return gamesFragment;
            }
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
            case 0:
                return getString(R.string.title_section1).toUpperCase(l);
            case 1:
                return getString(R.string.title_section2).toUpperCase(l);
            case 2:
                return getString(R.string.title_section3).toUpperCase(l);
            }
            return null;
        }
    }

    public static class DealOfTheDayFragment extends Fragment implements LoaderManager.LoaderCallbacks<Game> {
        TextView pGameName;
        TextView pPriceTag;
        ImageView pImgGame;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_deal_of_the_day, container, false);

            this.setRetainInstance(true);

            // Prepare the loader.  Either re-connect with an existing one,
            // or start a new one.
            getLoaderManager().initLoader(0, null, this);
            pGameName = (TextView) view.findViewById(R.id.text_item_dealoftheday);
            pPriceTag = (TextView) view.findViewById(R.id.price_item_dealoftheday);
            pImgGame = (ImageView) view.findViewById(R.id.picture_item_dealoftheday);
            pGameName.setText("No Games loaded from Steam yet!");
            pPriceTag.setText("");

            return view;
        }

        public void reloadDataset() {
            pGameName.setText("No Games loaded from Steam yet!");
            pPriceTag.setText("");
            pImgGame.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher));
            getLoaderManager().restartLoader(0, null, this);
        }

        @Override
        public Loader<Game> onCreateLoader(int i, Bundle bundle) {
            return new DataListLoaderDOTD(getActivity());
        }

        @Override
        public void onLoadFinished(Loader<Game> gameLoader, Game game) {
            pGameName.setText(game.getName());
            pPriceTag.setText(game.getFinal_price());
            pImgGame.setImageBitmap(game.getHeader_bitmap());
        }

        @Override
        public void onLoaderReset(Loader<Game> gameLoader) {

        }

        public static class DataListLoaderDOTD extends AsyncTaskLoader<Game> {

            Game mGame;

            public DataListLoaderDOTD(Context context) {
                super(context);
            }

            @Override
            public Game loadInBackground() {
                Game pGame;

                // Loading the data from the web yo.
                String JSON_From_API = JSON.readJSONFeed(URL_API.concat(API_DAILY_DEAL));
                try {
                    JSONObject jsonObject = new JSONObject(JSON_From_API);
                    pGame = JSON.ParseDealOfTheDayJSONFromAPI(jsonObject);
                    pGame.setHeader_bitmap(HttpThumbnails.readPictureFromTheWeb(pGame.getHeader_image()));
                } catch (Exception e) {
                    Log.d("ReadSteamJSONFeed", "Couldn't load the daily deal!");

                    // TODO GERER CAS FAIL LOAD NETWORK
                    pGame = new Game();
                    pGame.setName("Failed to load deal of the day from steam!");

                }

                return pGame;
            }

            @Override
            public void deliverResult(Game vGame) {
                mGame = vGame;

                // If the Loader is currently started, we can immediately
                // deliver its results.
                if (isStarted()) {
                    super.deliverResult(mGame);
                }
            }

            private void onReleaseResources(List<Game> oldGames) {
                // TODO Auto-generated method stub

            }

            /**
             * Handles a request to start the Loader.
             */
            @Override
            protected void onStartLoading() {
                if (mGame != null) {
                    // If we currently have a result available, deliver it
                    // immediately.
                    deliverResult(mGame);
                }

                if (takeContentChanged() || mGame == null) {
                    // If the data has changed since the last time it was loaded
                    // or is not currently available, start a load.
                    forceLoad();

                }
            }
        }

    }

    //TODO: Refactor code to remove mostpopular logic
    public static class GamesFragment extends ListFragment implements LoaderManager.LoaderCallbacks<List<Game>> {
        CustomArrayAdapter mAdapter;

        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.setRetainInstance(true);

            // Create an empty adapter we will use to display the loaded data.
            mAdapter = new CustomArrayAdapter(getActivity());
            setListAdapter(mAdapter);

            // Prepare the loader.  Either re-connect with an existing one,
            // or start a new one.
            getLoaderManager().initLoader(1, null, this);
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            setEmptyText("No Games loaded from Steam yet!");

            // Start out with a progress indicator.
            setListShown(true);
        }

        public void reloadList() {
            mAdapter.notifyDataSetChanged();
        }

        public void reloadDataset() {
            // Start out with a progress indicator.
            setListShown(false);
            mAdapter.clear();
            getLoaderManager().restartLoader(1, null, this);
        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            // Starting the webpage associated to the steam store...
            Log.i("DataListFragment", "Link clicked: " + mAdapter.getItem(position).getAppUrl());
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse(mAdapter.getItem(position).getAppUrl()));
            startActivity(intent);
        }

        @Override
        public Loader<List<Game>> onCreateLoader(int arg0, Bundle arg1) {
            return new DataListLoader(getActivity());
        }

        @Override
        public void onLoadFinished(Loader<List<Game>> arg0, List<Game> data) {
            mAdapter.setData(data);
            // The list should now be shown.
            if (isResumed()) {
                setListShown(true);
            } else {
                setListShownNoAnimation(true);
            }
        }

        public static class DataListLoader extends AsyncTaskLoader<List<Game>> {

            List<Game> mGames;

            public DataListLoader(Context context) {
                super(context);

            }

            @Override
            public List<Game> loadInBackground() {
                List<Game> lstGames;
                String JSON_From_API;

                // Loading the data from the web yo.
                JSON_From_API = JSON.readJSONFeed(URL_API.concat(API_SPECIAL));

                try {
                    JSONObject jsonObject = new JSONObject(JSON_From_API);
                    lstGames = JSON.ParseJSONFromAPI(jsonObject, false);

                    for (int iCpt = 0; iCpt < lstGames.size(); iCpt++) {
                        lstGames.get(iCpt).setHeader_bitmap(
                                HttpThumbnails.readPictureFromTheWeb(lstGames.get(iCpt).getSmall_capsule_img()));
                    }

                } catch (Exception e) {
                    Log.d("ReadSteamJSONFeed", "Couldn't load games from most popular or sales!!");

                    // TODO GERER CAS FAIL LOAD NETWORK
                    lstGames = getFailLoadGames();
                }

                return lstGames;
            }

            private List<Game> getFailLoadGames() {
                List<Game> lstGames;
                lstGames = new ArrayList<Game>(1);
                Game a = new Game();
                a.setName("I was not able to load games from the steam api. :(");
                a.setFinal_price("0.00$");
                lstGames.add(a);
                return lstGames;
            }

            @Override
            public void deliverResult(List<Game> lstGames) {
                if (isReset()) {
                    // An async query came in while the loader is stopped.  We
                    // don't need the result.
                    if (lstGames != null) {
                        onReleaseResources(lstGames);
                        lstGames = getFailLoadGames();
                    }
                }
                List<Game> oldGames = lstGames;
                mGames = lstGames;

                if (isStarted()) {
                    // If the Loader is currently started, we can immediately
                    // deliver its results.
                    super.deliverResult(lstGames);
                }

                // At this point we can release the resources associated with
                // 'oldApps' if needed; now that the new result is delivered we
                // know that it is no longer in use.
                if (oldGames != null) {
                    onReleaseResources(oldGames);
                }
            }

            private void onReleaseResources(List<Game> oldGames) {
                // TODO Auto-generated method stub

            }

            /**
             * Handles a request to start the Loader.
             */
            @Override
            protected void onStartLoading() {
                if (mGames != null) {
                    // If we currently have a result available, deliver it
                    // immediately.
                    deliverResult(mGames);
                }

                if (takeContentChanged() || mGames == null) {
                    // If the data has changed since the last time it was loaded
                    // or is not currently available, start a load.
                    forceLoad();
                }
            }

        }

        @Override
        public void onLoaderReset(Loader<List<Game>> arg0) {
        }
    }

    //TODO: Remove bundle as always most popular
    public static class MostPopularGamesFragment extends ListFragment
            implements LoaderManager.LoaderCallbacks<List<Game>> {
        CustomArrayAdapter mAdapter;

        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.setRetainInstance(true);

            // Create an empty adapter we will use to display the loaded data.
            mAdapter = new CustomArrayAdapter(getActivity());
            setListAdapter(mAdapter);

            // Prepare the loader.  Either re-connect with an existing one,
            // or start a new one.
            getLoaderManager().initLoader(0, null, this);
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            setEmptyText("No Games loaded from Steam yet!");

            // Start out with a progress indicator.
            setListShown(true);
        }

        public void reloadList() {
            mAdapter.notifyDataSetChanged();
        }

        public void reloadDataset() {
            // Start out with a progress indicator.
            setListShown(false);
            mAdapter.clear();
            getLoaderManager().restartLoader(0, null, this);
        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            // Starting the webpage associated to the steam store...
            Log.i("DataListFragment", "Link clicked: " + mAdapter.getItem(position).getAppUrl());
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse(mAdapter.getItem(position).getAppUrl()));
            startActivity(intent);
        }

        @Override
        public Loader<List<Game>> onCreateLoader(int arg0, Bundle arg1) {
            return new DataListLoaderMostPopular(getActivity());
        }

        @Override
        public void onLoadFinished(Loader<List<Game>> arg0, List<Game> data) {
            mAdapter.setData(data);
            // The list should now be shown.
            if (isResumed()) {
                setListShown(true);
            } else {
                setListShownNoAnimation(true);
            }
        }

        public static class DataListLoaderMostPopular extends AsyncTaskLoader<List<Game>> {

            List<Game> mGames;

            public DataListLoaderMostPopular(Context context) {
                super(context);

            }

            @Override
            public List<Game> loadInBackground() {
                List<Game> lstGames;
                String JSON_From_API;

                // Loading the data from the web yo.
                JSON_From_API = JSON.readJSONFeed(URL_API.concat(API_MOST_POPULAR));

                try {
                    JSONObject jsonObject = new JSONObject(JSON_From_API);
                    lstGames = JSON.ParseJSONFromAPI(jsonObject, true);

                    for (int iCpt = 0; iCpt < lstGames.size(); iCpt++) {
                        lstGames.get(iCpt).setHeader_bitmap(
                                HttpThumbnails.readPictureFromTheWeb(lstGames.get(iCpt).getSmall_capsule_img()));
                    }

                } catch (Exception e) {
                    Log.d("ReadSteamJSONFeed", "Couldn't load games from most popular or sales!!");

                    // TODO GERER CAS FAIL LOAD NETWORK
                    lstGames = getFailLoadGames();
                }

                return lstGames;
            }

            private List<Game> getFailLoadGames() {
                List<Game> lstGames;
                lstGames = new ArrayList<Game>(1);
                Game a = new Game();
                a.setName("I was not able to load games from the steam api. :(");
                a.setFinal_price("0.00$");
                lstGames.add(a);
                return lstGames;
            }

            @Override
            public void deliverResult(List<Game> lstGames) {
                if (isReset()) {
                    // An async query came in while the loader is stopped.  We
                    // don't need the result.
                    if (lstGames != null) {
                        onReleaseResources(lstGames);
                        lstGames = getFailLoadGames();
                    }
                }
                List<Game> oldGames = lstGames;
                mGames = lstGames;

                if (isStarted()) {
                    // If the Loader is currently started, we can immediately
                    // deliver its results.
                    super.deliverResult(lstGames);
                }

                // At this point we can release the resources associated with
                // 'oldApps' if needed; now that the new result is delivered we
                // know that it is no longer in use.
                if (oldGames != null) {
                    onReleaseResources(oldGames);
                }
            }

            private void onReleaseResources(List<Game> oldGames) {
                // TODO Auto-generated method stub

            }

            /**
             * Handles a request to start the Loader.
             */
            @Override
            protected void onStartLoading() {
                if (mGames != null) {
                    // If we currently have a result available, deliver it
                    // immediately.
                    deliverResult(mGames);
                }

                if (takeContentChanged() || mGames == null) {
                    // If the data has changed since the last time it was loaded
                    // or is not currently available, start a load.
                    forceLoad();
                }
            }

        }

        @Override
        public void onLoaderReset(Loader<List<Game>> arg0) {
        }
    }
}