Android Open Source - RssReader Network Utils






From Project

Back to project page RssReader.

License

The source code is released under:

GNU General Public License

If you think the Android project RssReader 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

/**
 * RssReader//  w w  w  .  j  a va2s. c  om
 *
 * Copyright (c) 2013-2014 teejoe
 *
 *     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.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Some parts of this software are based on "FeedEx" (see below)
 *
 * Copyright (c) 2012-2013 Frederic Julian
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


package org.m2x.rssreader.util;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.Html;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;

import org.m2x.rssreader.Constants;
import org.m2x.rssreader.MainApplication;
import org.m2x.rssreader.provider.FeedData;

public class NetworkUtils {

    public static final File IMAGE_FOLDER_FILE = new File(MainApplication.getContext()
        .getCacheDir(), "images/");
    
    public static final String IMAGE_FOLDER = IMAGE_FOLDER_FILE.getAbsolutePath() + '/';
    public static final String TEMP_PREFIX = "TEMP__";
    public static final String ID_SEPARATOR = "__";

    private static final String GZIP = "gzip";
    private static final String FILE_FAVICON = "/favicon.ico";
    private static final String PROTOCOL_SEPARATOR = "://";
    private static final String _HTTP = "http";
    private static final String _HTTPS = "https";

    private static class PictureFilenameFilter implements FilenameFilter {
        private static final String REGEX = "__[^\\.]*\\.[A-Za-z]*";

        private Pattern pattern;

        public PictureFilenameFilter() {
        }

        public void setEntryId(String entryId) {
            pattern = Pattern.compile(entryId + REGEX);
        }

        @Override
        public boolean accept(File dir, String filename) {
            return pattern.matcher(filename).find();
        }
    }

    public static String getDownloadedImagePath(long entryId, String imgUrl) {
        return IMAGE_FOLDER + entryId + ID_SEPARATOR + getMd5(imgUrl);
    }

    public static String getTempDownloadedImagePath(long entryId, String imgUrl) {
        return IMAGE_FOLDER + TEMP_PREFIX + entryId + ID_SEPARATOR + getMd5(imgUrl);
    }

    public static void downloadImage(long entryId, String imgUrl) throws IOException {
        String tempImgPath = getTempDownloadedImagePath(entryId, imgUrl);
        String finalImgPath = getDownloadedImagePath(entryId, imgUrl);

        if (!new File(tempImgPath).exists() && !new File(finalImgPath).exists()) {
            HttpURLConnection imgURLConnection = null;
            try {
                IMAGE_FOLDER_FILE.mkdir(); // create images dir

                // Compute the real URL (without "&eacute;", ...)
                String realUrl = Html.fromHtml(imgUrl).toString();
                imgURLConnection = setupConnection(realUrl);

                FileOutputStream fileOutput = new FileOutputStream(tempImgPath);
                InputStream inputStream = imgURLConnection.getInputStream();

                byte[] buffer = new byte[2048];
                int bufferLength;
                while ((bufferLength = inputStream.read(buffer)) > 0) {
                    fileOutput.write(buffer, 0, bufferLength);
                }
                fileOutput.flush();
                fileOutput.close();
                inputStream.close();

                new File(tempImgPath).renameTo(new File(finalImgPath));
            } catch (IOException e) {
                new File(tempImgPath).delete();
                throw e;
            } finally {
                if (imgURLConnection != null) {
                    imgURLConnection.disconnect();
                }
            }
        }
    }

    public static synchronized void deleteFeedImagesCache(Uri entriesUri, String selection) {
        if (IMAGE_FOLDER_FILE.exists()) {
            PictureFilenameFilter filenameFilter = new PictureFilenameFilter();

            Cursor cursor = MainApplication.getContext().getContentResolver().query(
                entriesUri, FeedData.EntryColumns.PROJECTION_ID, selection, null, null);

            while (cursor.moveToNext()) {
                filenameFilter.setEntryId(cursor.getString(0));

                File[] files = IMAGE_FOLDER_FILE.listFiles(filenameFilter);
                if (files != null) {
                    for (File file : files) {
                        file.delete();
                    }
                }
            }
            cursor.close();
        }
    }

    public static String getBaseUrl(String link) {
        String baseUrl = link;
        int index = link.indexOf('/', 8); // this also covers https://
        if (index > -1) {
            baseUrl = link.substring(0, index);
        }

        return baseUrl;
    }

    public static byte[] getBytes(InputStream inputStream) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();

        byte[] buffer = new byte[4096];

        int n;
        while ((n = inputStream.read(buffer)) > 0) {
            output.write(buffer, 0, n);
        }

        byte[] result = output.toByteArray();

        output.close();
        inputStream.close();
        return result;
    }

    public static void retrieveFavicon(Context context, URL url, String id) {
        boolean success = false;
        HttpURLConnection iconURLConnection = null;

        try {
            iconURLConnection = setupConnection(new URL(url.getProtocol() + PROTOCOL_SEPARATOR 
                + url.getHost() + FILE_FAVICON));

            byte[] iconBytes = getBytes(getConnectionInputStream(iconURLConnection));
            if (iconBytes != null && iconBytes.length > 0) {
                Bitmap bitmap = BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length);
                if (bitmap != null && bitmap.getWidth() != 0 && bitmap.getHeight() != 0) {
                    ContentValues values = new ContentValues();
                    values.put(FeedData.FeedColumns.ICON, iconBytes);
                    context.getContentResolver().update(FeedData.FeedColumns.CONTENT_URI(id), 
                        values, null, null);
                    success = true;
                }
                bitmap.recycle();
            }
        } catch (Throwable ignored) {
        } finally {
            if (iconURLConnection != null) {
                iconURLConnection.disconnect();
            }
        }

        if (!success) {
            // no icon found or error
            ContentValues values = new ContentValues();
            values.putNull(FeedData.FeedColumns.ICON);
            context.getContentResolver().update(FeedData.FeedColumns.CONTENT_URI(id), values, 
                null, null);
        }
    }

    public static HttpURLConnection setupConnection(String url) throws IOException {
        return setupConnection(new URL(url));
    }

    public static HttpURLConnection setupConnection(URL url) throws IOException {
        return setupConnection(url, 0);
    }

    public static HttpURLConnection setupConnection(URL url, int cycle) throws IOException {
        Proxy proxy = null;
        
        // Try to get the system proxy
        try {
            ProxySelector defaultProxySelector = ProxySelector.getDefault();
            List<Proxy> proxyList = defaultProxySelector.select(url.toURI());
            if (!proxyList.isEmpty()) {
                proxy = proxyList.get(0);
            }
        } catch (Throwable ignored) {
        }
 

        HttpURLConnection connection = proxy == null ? (HttpURLConnection) url.openConnection() 
            : (HttpURLConnection) url.openConnection(proxy);

        connection.setDoInput(true);
        connection.setDoOutput(false);
        connection.setRequestProperty(
            "User-agent", "Mozilla/5.0 (compatible) AppleWebKit Chrome Safari"); // some feeds need this to work properly
        connection.setConnectTimeout(30000);
        connection.setReadTimeout(30000);
        connection.setUseCaches(false);

        connection.setRequestProperty("accept", "*/*");
        connection.connect();

        String location = connection.getHeaderField("Location");

        if (location != null
                && (url.getProtocol().equals(_HTTP) && location.startsWith(Constants.HTTPS_SCHEME) 
                || url.getProtocol().equals(_HTTPS) && location.startsWith(Constants.HTTP_SCHEME))) {
            // if location != null, the system-automatic redirect has failed
            // which indicates a protocol change

            connection.disconnect();

            if (cycle < 5) {
                return setupConnection(new URL(location), cycle + 1);
            } else {
                throw new IOException("Too many redirects.");
            }
        }
        return connection;
    }

    /**
     * This is a small wrapper for getting the properly encoded inputstream if is is gzip compressed and not properly recognized.
     */
    public static InputStream getConnectionInputStream(HttpURLConnection connection) 
        throws IOException {
        InputStream inputStream = connection.getInputStream();

        if (GZIP.equals(connection.getContentEncoding()) && 
            !(inputStream instanceof GZIPInputStream)) {
            return new GZIPInputStream(inputStream);
        } else {
            return inputStream;
        }
    }
    
    private static String getMd5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            BigInteger number = new BigInteger(1, messageDigest);
            return number.toString(16);
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }
}




Java Source Code List

org.m2x.rssreader.Constants.java
org.m2x.rssreader.MainApplication.java
org.m2x.rssreader.activity.AddChannelActivity.java
org.m2x.rssreader.activity.EditChannelActivity.java
org.m2x.rssreader.activity.MainActivity.java
org.m2x.rssreader.activity.PreferenceActivity.java
org.m2x.rssreader.activity.RssArticleActivity.java
org.m2x.rssreader.activity.RssItemListActivity.java
org.m2x.rssreader.adapter.ChannelListAdapter.java
org.m2x.rssreader.adapter.RssArticlePagerAdapter.java
org.m2x.rssreader.adapter.RssItemListAdapter.java
org.m2x.rssreader.fragment.ChannelListFragment.java
org.m2x.rssreader.fragment.RssArticleFragment.java
org.m2x.rssreader.fragment.RssItemListFragment.java
org.m2x.rssreader.provider.DatabaseHelper.java
org.m2x.rssreader.provider.FeedDataProvider.java
org.m2x.rssreader.provider.FeedData.java
org.m2x.rssreader.service.FetcherService.java
org.m2x.rssreader.service.RefreshService.java
org.m2x.rssreader.util.HtmlUtils.java
org.m2x.rssreader.util.NetworkUtils.java
org.m2x.rssreader.util.OPML.java
org.m2x.rssreader.util.PrefUtils.java
org.m2x.rssreader.util.RssAtomParser.java
org.m2x.rssreader.util.StringUtils.java
org.m2x.rssreader.util.UiUtils.java
org.m2x.rssreader.view.RssArticleView.java