Android Open Source - RSSFeedReader-App Task Fragment






From Project

Back to project page RSSFeedReader-App.

License

The source code is released under:

GNU General Public License

If you think the Android project RSSFeedReader-App listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package tan.chesley.rssfeedreader;
//from  w  ww  .j  a  v  a 2s  .co  m
import android.app.Activity;
import android.app.Fragment;
import android.app.Service;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

// Credits to Alex Lockwood for original model of a task fragment
public class TaskFragment extends Fragment {

    public static interface TaskCallbacks {

        void onPreExecute ();

        void onProgressUpdate ();

        void onCancelled ();

        void onPostExecute ();
    }

    public static final String TASK_COMPLETE = "tan.chesley.rssfeedreader.taskcomplete";
    private long SYNC_TIMEOUT; // Timeout in milliseconds for syncing
    private Context context;
    private String[] FEEDS;

    public String[] getFEEDS (Service callerService) {
        if (!(callerService instanceof RssSyncService)) {
            throw new ClassCastException("This method may only be called by an instance of RssSyncService.");
        }
        return FEEDS;
    }

    public void setFEEDS (Service callerService, String[] FEEDS) {
        if (!(callerService instanceof RssSyncService)) {
            throw new ClassCastException("This method may only be called by an instance of RssSyncService.");
        }
        this.FEEDS = FEEDS;
    }

    public Context getContext (Service callerService) {
        if (!(callerService instanceof RssSyncService)) {
            throw new ClassCastException("This method may only be called by an instance of RssSyncService.");
        }
        return context;
    }

    public void setContext (Service callerService, Context context) {
        if (!(callerService instanceof RssSyncService)) {
            throw new ClassCastException("This method may only be called by an instance of RssSyncService.");
        }
        this.context = context;
    }

    public long getSYNC_TIMEOUT (Service callerService) {
        if (!(callerService instanceof RssSyncService)) {
            throw new ClassCastException("This method may only be called by an instance of RssSyncService.");
        }
        return SYNC_TIMEOUT;
    }

    public void setSYNC_TIMEOUT (Service callerService, long SYNC_TIMEOUT) {
        if (!(callerService instanceof RssSyncService)) {
            throw new ClassCastException("This method may only be called by an instance of RssSyncService.");
        }
        this.SYNC_TIMEOUT = SYNC_TIMEOUT;
    }

    private TaskCallbacks mCallbacks;
    private GetRssFeedTask mTask;
    private InputStream feedStream;
    private boolean aborted = false;
    private boolean taskCompleted = false;

    @Override
    public void onAttach (Activity activity) {
        super.onAttach(activity);
        FEEDS = new SourcesOpenHelper(activity).getEnabledSources();
        mCallbacks = (TaskCallbacks) ((RSSFeed) activity)
            .getHeadlinesFragment();
        context = activity.getApplicationContext();
    }

    @Override
    public void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        SYNC_TIMEOUT = 1000 * PreferenceManager.getDefaultSharedPreferences(getActivity()).getInt(SettingsActivity.KEY_PREF_SYNC_TIMEOUT, getResources().getInteger(R.integer.sync_timeout_default));
        if (savedInstanceState != null) {
            taskCompleted = savedInstanceState.getBoolean(TASK_COMPLETE);
        }
        else {
            if (!taskCompleted) {
                Log.e("TaskFragment", "Starting new sync task.");
                mTask = new GetRssFeedTask();
                mTask.execute(FEEDS);
                new Handler().postDelayed(new Runnable() {

                    public void run () {
                        if (mTask.getStatus() != AsyncTask.Status.FINISHED) {
                            abortInputStreams();
                            mTask.cancel(true);
                            mTask.onCancelled();
                            if (mCallbacks != null) {
                                Toaster.showToast(
                                    ((HeadlinesFragment) mCallbacks).getActivity(),
                                    "Sync connection timeout",
                                    Toast.LENGTH_SHORT);
                            }
                        }
                        else {
                            Log.e("Feed", "Feed sync completed successfully.");
                        }
                    }
                }, SYNC_TIMEOUT);
            }
        }
    }

    @Override
    public void onDetach () {
        super.onDetach();
        mCallbacks = null;
    }

    @Override
    public void onSaveInstanceState (Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(TASK_COMPLETE, taskCompleted);
    }

    @Override
    public void onDestroy () {
        super.onDestroy();
        abortInputStreams();
        if (mTask != null) {
            mTask.cancel(true);
        }
        //Log.e("TaskFragment","Destroying TaskFragment.");
    }

    public void abortInputStreams () {
        if (feedStream != null) {
            try {
                aborted = true;
                Log.e("Feed", "InputStream interrupted.");
                feedStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public class GetRssFeedTask extends AsyncTask<String, Void, Void> {

        long startTime = System.currentTimeMillis();
        final long longRequestTime = 4000;
        private RSSHandler myRSSHandler;

        @Override
        protected Void doInBackground (String... urls) {
            SAXParserFactory mySAXParserFactory = SAXParserFactory
                .newInstance();
            SAXParser mySAXParser = null;
            XMLReader myXMLReader = null;
            try {
                mySAXParser = mySAXParserFactory.newSAXParser();
                myXMLReader = mySAXParser.getXMLReader();
            } catch (SAXException e) {
                e.printStackTrace();
                Log.e("Feed", "Could not connect to RSS feed! Error 1");
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
                Log.e("Feed", "Could not connect to RSS feed! Error 2.");
            }
            myRSSHandler = new RSSHandler(this, FEEDS.length, SYNC_TIMEOUT, context);
            myXMLReader.setContentHandler(myRSSHandler);
            InputSource myInputSource;
            URL url = null;
            for (String s : urls) {
                // Stop syncing if the task has been aborted or cancelled
                if (aborted || isCancelled()) {
                    break;
                }
                // Callback to show Toast to update user of progress
                publishProgress((Void) null);
                Log.e("Feed", "Syncing feed " + s);
                // Try to create a new URL from the String
                try {
                    url = new URL(s);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    Log.e("Feed", "Cannot connect to RSS feed! Error 3.");
                    continue;
                }
                // Try to open an InputStream with the URL
                try {
                    feedStream = url.openStream();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e("Feed", "Cannot connect to RSS feed! Error 4.");
                    continue;
                }
                if (aborted || isCancelled()) {
                    break;
                }
                // Create a new InputSource using the InputStream
                myInputSource = new InputSource(feedStream);

                    if (aborted || isCancelled()) {
                        break;
                    }
                    // Notify the RSSHandler of the current source's URL
                    myRSSHandler.notifyCurrentSource(url.toString());
                    // Try to parse XML from the InputSource
                    try {
                        myXMLReader.parse(myInputSource);
                    } catch (IOException e) {
                        e.printStackTrace();
                        Log.e("Feed", "Cannot connect to RSS feed! Error 5.");
                    } catch (SAXException e) {
                        e.printStackTrace();
                        Log.e("Feed", "Cannot connect to RSS feed! Error 6.");
                        if (aborted || isCancelled()) {
                            break;
                        }
                        else {
                            continue;
                        }
                    }
            }
            return null;
        }

            @Override
            protected void onPreExecute () {
                super.onPreExecute();
                if (mCallbacks != null) {
                    mCallbacks.onPreExecute();
                }
            }

            @Override
            protected void onPostExecute (Void v){
                if (mCallbacks != null && !taskCompleted) {
                    deliverData();
                    mCallbacks.onPostExecute();
                }
            }

            @Override
            protected void onCancelled () {
                super.onCancelled();
                if (mCallbacks != null && !taskCompleted) {
                    deliverData();
                    mCallbacks.onCancelled();
                }
            }

            @Override
            protected void onProgressUpdate (Void...values){
                super.onProgressUpdate(values);
                if (System.currentTimeMillis() - startTime > longRequestTime) {
                    if (!isCancelled()) {
                        if (mCallbacks != null && !taskCompleted) {
                            mCallbacks.onProgressUpdate();
                        }
                    }
                }
            }

        private void deliverData () {
            // Constrain the database size
            new RSSDataBundleOpenHelper(getActivity().getApplicationContext()).constrainDatabaseSize(getActivity().getApplicationContext());
            if (myRSSHandler == null) {
                Log.e("TaskFragment", "Data delivery failed... myRSSHandler was null!");
                return;
            }
            if (mCallbacks == null) {
                Log.e("TaskFragment", "Data delivery failed... mCallbacks was null!");
                return;
            }
            ((HeadlinesFragment) mCallbacks).setRssData(myRSSHandler.getData(), true);
            taskCompleted = true;
        }

        public ArrayList<RSSDataBundle> getFetchedData() {
            if (myRSSHandler == null) {
                return null;
            }
            return myRSSHandler.getData();
        }

    }
}




Java Source Code List

android.support.v4.app.FixedFragmentStatePagerAdapter.java
tan.chesley.rssfeedreader.AddSourceDialogFragment.java
tan.chesley.rssfeedreader.ArticleAgeLimitNumberPickerDialog.java
tan.chesley.rssfeedreader.ArticleViewFragment.java
tan.chesley.rssfeedreader.ArticleView.java
tan.chesley.rssfeedreader.AutosyncTimePickerDialog.java
tan.chesley.rssfeedreader.BrightnessControl.java
tan.chesley.rssfeedreader.DepthPageTransformer.java
tan.chesley.rssfeedreader.HeadlinesFragment.java
tan.chesley.rssfeedreader.MaxArticlesNumberPickerDialog.java
tan.chesley.rssfeedreader.MaxDatabaseSizeNumberPickerDialog.java
tan.chesley.rssfeedreader.ModifySourceDialogFragment.java
tan.chesley.rssfeedreader.ModifySources.java
tan.chesley.rssfeedreader.NumberPickerDialogPreference.java
tan.chesley.rssfeedreader.RSSDataBundleOpenHelper.java
tan.chesley.rssfeedreader.RSSDataBundle.java
tan.chesley.rssfeedreader.RSSFeed.java
tan.chesley.rssfeedreader.RSSHandler.java
tan.chesley.rssfeedreader.RssSyncService.java
tan.chesley.rssfeedreader.SettingsActivity.java
tan.chesley.rssfeedreader.SettingsFragment.java
tan.chesley.rssfeedreader.SourcesOpenHelper.java
tan.chesley.rssfeedreader.SyncTimeoutNumberPickerDialog.java
tan.chesley.rssfeedreader.TaskFragment.java
tan.chesley.rssfeedreader.TimePickerDialogPreference.java
tan.chesley.rssfeedreader.Toaster.java