Android Open Source - holoreader Add Feed Task






From Project

Back to project page holoreader.

License

The source code is released under:

GNU General Public License

If you think the Android project holoreader 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 de.hdodenhof.holoreader.tasks;
//from  www  .j a  v  a  2 s . c  o  m
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.Patterns;

import de.hdodenhof.holoreader.R;
import de.hdodenhof.holoreader.provider.RSSContentProvider;
import de.hdodenhof.holoreader.provider.SQLiteHelper.FeedDAO;

public class AddFeedTask extends AsyncTask<URL, Void, Integer> {

    @SuppressWarnings("unused")
    private static final String TAG = AddFeedTask.class.getSimpleName();

    public static final int SUCCESS = 0;
    public static final int ERROR_IOEXCEPTION = 1;
    public static final int ERROR_XMLPULLPARSEREXCEPTION = 2;
    public static final int ERROR_NOCONTENT = 3;
    public static final int ERROR_NOFEED = 4;

    private Handler mMainUIHandler;
    private Context mContext;
    private int mReturnCondition = SUCCESS;

    public AddFeedTask(Handler mainUIHandler, Context context) {
        mMainUIHandler = mainUIHandler;
        mContext = context;
    }

    protected Integer doInBackground(URL... params) {
        URL url = params[0];
        String name;

        try {
            URLConnection connection = connect(url);

            HttpURLConnection httpConnection = (HttpURLConnection) connection;
            int httpResponse = httpConnection.getResponseCode();

            if (httpResponse == HttpURLConnection.HTTP_MOVED_PERM) {
                String redir = connection.getHeaderField("Location");
                url = new URL(redir);
                connection = connect(url);
            }

            String contentType = connection.getContentType();
            if (contentType != null && contentType.contains("xml")) {
                InputStream inputStream = connection.getInputStream();
                name = validateFeedAndExtractName(inputStream);
                inputStream.close();

                if (mReturnCondition == SUCCESS && name != null) {
                    return storeFeed(url.toString(), name);
                }
            } else {
                String alternateUrl = discoverFeed(url);
                if (alternateUrl == null) {
                    mReturnCondition = ERROR_NOFEED;
                } else {
                    URLConnection secondConnection = new URL(alternateUrl).openConnection();
                    secondConnection.setRequestProperty("User-agent", mContext.getResources().getString(R.string.AppName) + "/"
                            + mContext.getResources().getString(R.string.AppVersionName));
                    secondConnection.setConnectTimeout(2000);
                    secondConnection.setReadTimeout(2000);
                    secondConnection.connect();

                    InputStream inputStream = secondConnection.getInputStream();
                    name = validateFeedAndExtractName(inputStream);
                    inputStream.close();

                    if (mReturnCondition == SUCCESS && name != null) {
                        return storeFeed(alternateUrl.toString(), name);
                    }
                }
            }

        } catch (IOException e) {
            mReturnCondition = ERROR_IOEXCEPTION;
        }
        return null;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Integer result) {
        Message msg = Message.obtain();
        if (mReturnCondition == SUCCESS) {
            msg.what = 1;
            msg.arg1 = result;
        } else {
            msg.what = 8;
            msg.arg1 = mReturnCondition;
        }
        mMainUIHandler.sendMessage(msg);
    }

    private URLConnection connect(URL url) throws IOException {
        URLConnection connection = url.openConnection();
        connection.setRequestProperty("User-agent",
                mContext.getResources().getString(R.string.AppName) + "/" + mContext.getResources().getString(R.string.AppVersionName));
        connection.connect();

        return connection;
    }

    private int storeFeed(String url, String name) {
        ContentResolver contentResolver = mContext.getContentResolver();
        ContentValues contentValues = new ContentValues();

        contentValues.put(FeedDAO.NAME, name);
        contentValues.put(FeedDAO.URL, url.toString());

        Uri newFeed = contentResolver.insert(RSSContentProvider.URI_FEEDS, contentValues);
        return Integer.parseInt(newFeed.getLastPathSegment());
    }

    private String validateFeedAndExtractName(InputStream inputStream) {
        String name = null;
        boolean isFeed = false;
        boolean isArticle = false;
        boolean hasContent = false;
        boolean hasSummary = false;
        boolean foundName = false;

        try {
            XmlPullParserFactory parserFactory = XmlPullParserFactory.newInstance();
            parserFactory.setNamespaceAware(true);
            XmlPullParser pullParser = parserFactory.newPullParser();
            pullParser.setInput(inputStream, null);

            int eventType = pullParser.getEventType();

            while (eventType != XmlPullParser.END_DOCUMENT) {
                if (eventType == XmlPullParser.START_TAG) {
                    String currentTag = pullParser.getName();
                    String currentPrefix = pullParser.getPrefix();

                    if (currentPrefix == null) {
                        currentPrefix = "";
                    }

                    if (currentTag.equalsIgnoreCase("rss") || currentTag.equalsIgnoreCase("feed") || currentTag.equalsIgnoreCase("rdf")) {
                        isFeed = true;
                    } else if (currentTag.equalsIgnoreCase("title") && isFeed && foundName == false) {
                        name = pullParser.nextText();
                        foundName = true;
                    } else if ((currentTag.equalsIgnoreCase("item") || currentTag.equalsIgnoreCase("entry")) && isFeed) {
                        isArticle = true;
                    } else if (((currentTag.equalsIgnoreCase("encoded") && currentPrefix.equalsIgnoreCase("content")) || (currentTag
                            .equalsIgnoreCase("content") && currentPrefix.equalsIgnoreCase(""))) && isArticle == true) {
                        hasContent = true;
                    } else if ((currentTag.equalsIgnoreCase("summary") || currentTag.equalsIgnoreCase("description")) && isArticle == true
                            && currentPrefix.equalsIgnoreCase("")) {
                        hasSummary = true;
                    }
                } else if (eventType == XmlPullParser.END_TAG) {
                    String currentTag = pullParser.getName();

                    if ((currentTag.equalsIgnoreCase("item") || currentTag.equalsIgnoreCase("entry")) && isFeed) {
                        break;
                    }
                }
                eventType = pullParser.next();
            }

            if (isFeed && (hasContent || hasSummary)) {
                return name;
            } else if (isFeed) {
                mReturnCondition = ERROR_NOCONTENT;
            } else {
                mReturnCondition = ERROR_NOFEED;
            }

        } catch (XmlPullParserException e) {
            mReturnCondition = ERROR_XMLPULLPARSEREXCEPTION;
        } catch (IOException e) {
            mReturnCondition = ERROR_IOEXCEPTION;
        }
        return null;
    }

    private String discoverFeed(URL url) {
        try {
            Document document = Jsoup.connect(url.toString())
                    .userAgent(mContext.getResources().getString(R.string.AppName) + "/" + mContext.getResources().getString(R.string.AppVersionName))
                    .timeout(2000).get();
            String rssUrl = document.select("link[rel=alternate][type=application/rss+xml]").attr("href");
            if (rssUrl == null || rssUrl == "") {
                rssUrl = document.select("link[rel=alternate][type=application/atom+xml]").attr("href");
            }

            if (rssUrl == null || rssUrl == "") {
                return null;
            } else {
                if (rssUrl.length() <= 7 || (!rssUrl.substring(0, 7).equalsIgnoreCase("http://") && !rssUrl.substring(0, 8).equalsIgnoreCase("https://"))) {
                    String protocol = url.getProtocol();
                    String host = url.getHost();
                    if (rssUrl.substring(0, 1).equalsIgnoreCase("/")) {
                        rssUrl = protocol + "://" + host + rssUrl;
                    } else {
                        rssUrl = protocol + "://" + host + "/" + rssUrl;
                    }
                }

                Pattern pattern = Patterns.WEB_URL;
                Matcher matcher = pattern.matcher(rssUrl);

                if (matcher.matches()) {
                    return rssUrl;
                } else {
                    return null;
                }
            }
        } catch (IOException e) {
            return null;
        }
    }
}




Java Source Code List

de.hdodenhof.holoreader.Config.java
de.hdodenhof.holoreader.activities.DisplayArticleActivity.java
de.hdodenhof.holoreader.activities.DisplayFeedActivity.java
de.hdodenhof.holoreader.activities.EditFeedsActivity.java
de.hdodenhof.holoreader.activities.HoloReaderActivity.java
de.hdodenhof.holoreader.activities.HomeActivity.java
de.hdodenhof.holoreader.fragments.ArticleFragment.java
de.hdodenhof.holoreader.fragments.ArticleListFragment.java
de.hdodenhof.holoreader.fragments.CustomListFragment.java
de.hdodenhof.holoreader.fragments.DynamicDialogFragment.java
de.hdodenhof.holoreader.fragments.EditFeedsFragment.java
de.hdodenhof.holoreader.fragments.FeedListFragment.java
de.hdodenhof.holoreader.gcm.GCMIntentService.java
de.hdodenhof.holoreader.gcm.GCMReceiver.java
de.hdodenhof.holoreader.gcm.GCMServerUtilities.java
de.hdodenhof.holoreader.gcm.VOFeed.java
de.hdodenhof.holoreader.listadapters.EditFeedAdapter.java
de.hdodenhof.holoreader.listadapters.RSSAdapter.java
de.hdodenhof.holoreader.listadapters.RSSArticleAdapter.java
de.hdodenhof.holoreader.listadapters.RSSFeedAdapter.java
de.hdodenhof.holoreader.misc.ArticleViewPager.java
de.hdodenhof.holoreader.misc.ChangelogDialog.java
de.hdodenhof.holoreader.misc.CheckableLinearLayout.java
de.hdodenhof.holoreader.misc.CustomScrollView.java
de.hdodenhof.holoreader.misc.DiskLruImageCache.java
de.hdodenhof.holoreader.misc.FragmentCallback.java
de.hdodenhof.holoreader.misc.Helpers.java
de.hdodenhof.holoreader.misc.MarkReadRunnable.java
de.hdodenhof.holoreader.misc.OnArticleChangedListener.java
de.hdodenhof.holoreader.provider.RSSContentProvider.java
de.hdodenhof.holoreader.provider.SQLiteHelper.java
de.hdodenhof.holoreader.services.RefreshFeedListener.java
de.hdodenhof.holoreader.services.RefreshFeedService.java
de.hdodenhof.holoreader.tasks.AddFeedTask.java