com.achow101.bitcointalkforum.NotificationService.java Source code

Java tutorial

Introduction

Here is the source code for com.achow101.bitcointalkforum.NotificationService.java

Source

/*
 * Copyright (c) 2015 Andrew Chow
 *
 * 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 com.achow101.bitcointalkforum;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.text.Html;
import android.text.Spanned;

import com.achow101.bitcointalkforum.MainActivity;
import com.achow101.bitcointalkforum.R;
import com.achow101.bitcointalkforum.items.Post;
import com.achow101.bitcointalkforum.items.Poster;
import com.achow101.bitcointalkforum.items.Topic;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class NotificationService extends Service {

    private PowerManager.WakeLock mWakeLock;
    private String sound;
    private boolean vibrate;

    public NotificationService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void handleIntent(Intent intent) {
        // obtain the wake lock
        PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NotificationService");
        mWakeLock.acquire();

        // get sessid and username from intent
        String sessId = intent.getStringExtra("SESSION ID");
        String mUsername = intent.getStringExtra("Username");

        // check the global background data setting
        ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        if (!cm.getBackgroundDataSetting()) {
            stopSelf();
            return;
        }

        // Get preferences
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        // Check that notifications are wanted
        boolean getNotifs = prefs.getBoolean("notifications_new_message", true);

        // do stuff if notifications are wanted
        if (getNotifs) {
            // get remaining booleans
            boolean getWatchlist = prefs.getBoolean("notifications_watchlist", true);
            boolean getUnreadposts = prefs.getBoolean("notifications_unreadposts", false);
            boolean getUnreadreplies = prefs.getBoolean("notifications_unreadreplies", false);
            boolean getMessages = prefs.getBoolean("notifications_messages", true);

            // Get notification settings stuff
            sound = prefs.getString("notifications_new_message_ringtone",
                    "content://settings/system/notification_sound");
            vibrate = prefs.getBoolean("notifications_new_message_vibrate", true);

            // do the actual work, in a separate thread
            new PollTask(getWatchlist, getUnreadposts, getUnreadreplies, getMessages, sessId, mUsername).execute();
        }
    }

    private class PollTask extends AsyncTask<Void, Void, List<List<Object>>> {

        private boolean getWatchlist;
        private boolean getUnreadPosts;
        private boolean getUnreadReplies;
        private boolean getMessages;
        private String sessId;
        private String mUsername;

        public PollTask(boolean getWatchlist, boolean getUnreadPosts, boolean getUnreadReplies, boolean getMessages,
                String sessId, String mUsername) {

            this.getWatchlist = getWatchlist;
            this.getUnreadPosts = getUnreadPosts;
            this.getUnreadReplies = getUnreadReplies;
            this.getMessages = getMessages;
            this.sessId = sessId;
            this.mUsername = mUsername;

        }

        @Override
        protected List<List<Object>> doInBackground(Void... params) {

            System.out.println("Begin notifications fetch");

            List<List<Object>> out = new ArrayList<List<Object>>();
            List<Object> watchlistNotifTopics = new ArrayList<Object>();
            List<Object> unreadPostNotifTopics = new ArrayList<Object>();
            List<Object> unreadRepliesNotifTopics = new ArrayList<Object>();
            List<Object> messageNotif = new ArrayList<Object>();

            // Check watchlist
            if (getWatchlist) {
                try {

                    // Read the local file and get the first lastpostcol data
                    FileInputStream fis = getApplicationContext().openFileInput("watchlist.html");
                    InputStreamReader isr = new InputStreamReader(fis);
                    BufferedReader bufferedReader = new BufferedReader(isr);
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        sb.append(line);
                    }

                    Document localDoc = Jsoup.parse(sb.toString());
                    Element localBody = localDoc.getElementById("bodyarea");
                    Elements localWindowbg2Elements = localBody.select(
                            "table.bordercolor > tbody > tr > td > table.bordercolor > tbody > tr:not(titlebg) > td.windowbg2");
                    List<Element> localLastPostCols = new ArrayList<Element>();
                    for (Element elem : localWindowbg2Elements) {
                        if (elem.outerHtml().contains("<td class=\"windowbg2\" valign=\"middle\" width=\"22%\">")) {
                            localLastPostCols.add(elem);
                        }
                    }

                    // Get the page and get the first lastpostcol data
                    Document remoteDoc = Jsoup.connect("https://bitcointalk.org/index.php?action=watchlist;start=0")
                            .cookie("PHPSESSID", sessId).get();
                    Element remoteBody = remoteDoc.getElementById("bodyarea");
                    Elements remoteWindowbg2Elements = remoteBody.select(
                            "table.bordercolor > tbody > tr > td > table.bordercolor > tbody > tr:not(titlebg) > td.windowbg2");
                    List<Element> remoteLastPostCols = new ArrayList<Element>();
                    for (Element elem : remoteWindowbg2Elements) {
                        if (elem.outerHtml().contains("<td class=\"windowbg2\" valign=\"middle\" width=\"22%\">")) {
                            remoteLastPostCols.add(elem);
                        }
                    }

                    // write remoteDoc to file
                    try {
                        FileOutputStream os = getApplicationContext().openFileOutput("watchlist.html",
                                Context.MODE_PRIVATE);
                        os.write(remoteDoc.html().getBytes());
                        os.close();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    // If they are the not same, get everything
                    if (!localLastPostCols.isEmpty() && !remoteLastPostCols.isEmpty()
                            && !localLastPostCols.get(0).text().equals(remoteLastPostCols.get(0).text())) {
                        List<Topic> localTopics = getTopicsFromBody(localBody);
                        List<Topic> remoteTopics = getTopicsFromBody(remoteBody);

                        watchlistNotifTopics.addAll(remoteTopics);

                        // Compare all the posts and find the ones different in the downloaded data
                        for (Topic localTopic : localTopics) {
                            for (Topic remoteTopic : remoteTopics) {
                                if (remoteTopic.getLastPostURL().equals(localTopic.getLastPostURL())) {
                                    watchlistNotifTopics.remove(remoteTopic);
                                }
                            }
                        }
                    } else if (localLastPostCols.isEmpty() && !remoteLastPostCols.isEmpty()) {
                        List<Topic> remoteTopics = getTopicsFromBody(remoteBody);

                        watchlistNotifTopics.addAll(remoteTopics);
                    }

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // Check Unreadposts
            if (getUnreadPosts) {
                try {

                    // Read the local file and get the first lastpostcol data
                    FileInputStream fis = getApplicationContext().openFileInput("unreadposts.html");
                    InputStreamReader isr = new InputStreamReader(fis);
                    BufferedReader bufferedReader = new BufferedReader(isr);
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        sb.append(line);
                    }

                    Document localDoc = Jsoup.parse(sb.toString());
                    Element localBody = localDoc.getElementById("bodyarea");
                    Elements localWindowbg2Elements = localBody.select(
                            "table.bordercolor > tbody > tr > td > table.bordercolor > tbody > tr:not(titlebg) > td.windowbg2");
                    List<Element> localLastPostCols = new ArrayList<Element>();
                    for (Element elem : localWindowbg2Elements) {
                        if (elem.outerHtml().contains("<td class=\"windowbg2\" valign=\"middle\" width=\"22%\">")) {
                            localLastPostCols.add(elem);
                        }
                    }

                    // Get the page and get the first lastpostcol data
                    Document remoteDoc = Jsoup.connect("https://bitcointalk.org/index.php?action=unread;start=0")
                            .cookie("PHPSESSID", sessId).get();
                    Element remoteBody = remoteDoc.getElementById("bodyarea");
                    Elements remoteWindowbg2Elements = remoteBody.select(
                            "table.bordercolor > tbody > tr > td > table.bordercolor > tbody > tr:not(titlebg) > td.windowbg2");
                    List<Element> remoteLastPostCols = new ArrayList<Element>();
                    for (Element elem : remoteWindowbg2Elements) {
                        if (elem.outerHtml().contains("<td class=\"windowbg2\" valign=\"middle\" width=\"22%\">")) {
                            remoteLastPostCols.add(elem);
                        }
                    }

                    // write remoteDoc to file
                    try {
                        FileOutputStream os = getApplicationContext().openFileOutput("unreadposts.html",
                                Context.MODE_PRIVATE);
                        os.write(remoteDoc.html().getBytes());
                        os.close();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    // If they are the not same, get everything
                    if (!localLastPostCols.isEmpty() && !remoteLastPostCols.isEmpty()
                            && !localLastPostCols.get(0).text().equals(remoteLastPostCols.get(0).text())) {
                        List<Topic> localTopics = getTopicsFromBody(localBody);
                        List<Topic> remoteTopics = getTopicsFromBody(remoteBody);

                        unreadPostNotifTopics.addAll(remoteTopics);

                        // Compare all the posts and find the ones different in the downloaded data
                        for (Topic localTopic : localTopics) {
                            for (Topic remoteTopic : remoteTopics) {
                                if (remoteTopic.getLastPostURL().equals(localTopic.getLastPostURL())) {
                                    unreadPostNotifTopics.remove(remoteTopic);
                                }
                            }
                        }
                    } else if (localLastPostCols.isEmpty() && !remoteLastPostCols.isEmpty()) {
                        List<Topic> remoteTopics = getTopicsFromBody(remoteBody);

                        unreadPostNotifTopics.addAll(remoteTopics);
                    }

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // Check Unread Replies
            if (getUnreadReplies) {
                try {

                    // Read the local file and get the first lastpostcol data
                    FileInputStream fis = getApplicationContext().openFileInput("unreadreplies.html");
                    InputStreamReader isr = new InputStreamReader(fis);
                    BufferedReader bufferedReader = new BufferedReader(isr);
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        sb.append(line);
                    }

                    Document localDoc = Jsoup.parse(sb.toString());
                    Element localBody = localDoc.getElementById("bodyarea");
                    Elements localWindowbg2Elements = localBody.select(
                            "table.bordercolor > tbody > tr > td > table.bordercolor > tbody > tr:not(titlebg) > td.windowbg2");
                    List<Element> localLastPostCols = new ArrayList<Element>();
                    for (Element elem : localWindowbg2Elements) {
                        if (elem.outerHtml().contains("<td class=\"windowbg2\" valign=\"middle\" width=\"22%\">")) {
                            localLastPostCols.add(elem);
                        }
                    }

                    // Get the page and get the first lastpostcol data
                    Document remoteDoc = Jsoup
                            .connect("https://bitcointalk.org/index.php?action=unreadreplies;start=0")
                            .cookie("PHPSESSID", sessId).get();
                    Element remoteBody = remoteDoc.getElementById("bodyarea");
                    Elements remoteWindowbg2Elements = remoteBody.select(
                            "table.bordercolor > tbody > tr > td > table.bordercolor > tbody > tr:not(titlebg) > td.windowbg2");
                    List<Element> remoteLastPostCols = new ArrayList<Element>();
                    for (Element elem : remoteWindowbg2Elements) {
                        if (elem.outerHtml().contains("<td class=\"windowbg2\" valign=\"middle\" width=\"22%\">")) {
                            remoteLastPostCols.add(elem);
                        }
                    }

                    // write remoteDoc to file
                    try {
                        FileOutputStream os = getApplicationContext().openFileOutput("unreadreplies.html",
                                Context.MODE_PRIVATE);
                        os.write(remoteDoc.html().getBytes());
                        os.close();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    // If they are the not same, get everything
                    if (!localLastPostCols.isEmpty() && !remoteLastPostCols.isEmpty()
                            && !localLastPostCols.get(0).text().equals(remoteLastPostCols.get(0).text())) {
                        List<Topic> localTopics = getTopicsFromBody(localBody);
                        List<Topic> remoteTopics = getTopicsFromBody(remoteBody);

                        unreadRepliesNotifTopics.addAll(remoteTopics);

                        // Compare all the posts and find the ones different in the downloaded data
                        for (Topic localTopic : localTopics) {
                            for (Topic remoteTopic : remoteTopics) {
                                if (remoteTopic.getLastPostURL().equals(localTopic.getLastPostURL())) {
                                    unreadRepliesNotifTopics.remove(remoteTopic);
                                }
                            }
                        }
                    } else if (localLastPostCols.isEmpty() && !remoteLastPostCols.isEmpty()) {
                        List<Topic> remoteTopics = getTopicsFromBody(remoteBody);

                        unreadRepliesNotifTopics.addAll(remoteTopics);
                    }

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            // Check messages
            if (getMessages) {
                try {

                    // Read the local file and get the first lastpostcol data
                    FileInputStream fis = getApplicationContext().openFileInput("messages.html");
                    InputStreamReader isr = new InputStreamReader(fis);
                    BufferedReader bufferedReader = new BufferedReader(isr);
                    StringBuilder sb = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        sb.append(line);
                    }

                    Document localDoc = Jsoup.parse(sb.toString());
                    Element localBody = localDoc.select("div#bodyarea").first();
                    Elements localDateElements = localBody.select(
                            "table > tbody > tr > td > form > table.bordercolor > tbody > tr.windowbg > td");
                    String localFirstDate = localDateElements.get(1).text();

                    // Get the page and get the first lastpostcol data
                    Document remoteDoc = Jsoup
                            .connect("https://bitcointalk.org/index.php?action=pm;f=inbox;sort=date;desc;start=0")
                            .cookie("PHPSESSID", sessId).get();
                    Element remoteBody = remoteDoc.select("div#bodyarea").first();
                    Elements remoteDateElements = remoteBody.select(
                            "table > tbody > tr > td > form > table.bordercolor > tbody > tr.windowbg > td");
                    String remoteFirstDate = remoteDateElements.get(1).text();

                    // write remoteDoc to file
                    try {
                        FileOutputStream os = getApplicationContext().openFileOutput("messages.html",
                                Context.MODE_PRIVATE);
                        os.write(remoteDoc.html().getBytes());
                        os.close();
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    // If they are the not same, get everything
                    if (!remoteFirstDate.equals(localFirstDate)) {
                        List<Post> localTopics = getMessagesFromDoc(localDoc);
                        List<Post> remoteTopics = getMessagesFromDoc(remoteDoc);

                        messageNotif.addAll(remoteTopics);

                        // Compare all the posts and find the ones different in the downloaded data
                        for (Post localTopic : localTopics) {
                            for (Post remoteTopic : remoteTopics) {
                                if (remoteTopic.getPostedTime().equals(localTopic.getPostedTime())) {
                                    messageNotif.remove(remoteTopic);
                                }
                            }
                        }
                    }

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            out.add(watchlistNotifTopics);
            out.add(unreadPostNotifTopics);
            out.add(unreadRepliesNotifTopics);
            out.add(messageNotif);

            return out;
        }

        private List<Post> getMessagesFromDoc(Document doc) {
            List<Post> posts = new ArrayList<Post>();

            // Get body
            Elements body = doc.select("div#bodyarea");

            // Get the table with posts
            Element pmTable = body.select("form[name=pmFolder] > table[cellpadding=0]").first();

            // Get the elements with pms
            Elements pmIds = pmTable.select("tbody > tr > td[style=padding: 1px 1px 0 1px;] > a[name]");

            List<Long> ids = new ArrayList<Long>();
            for (Element id : pmIds) {
                ids.add(Long.parseLong(id.attr("name").substring(3)));
            }

            Elements pmElements = pmTable
                    .select("table[cellpadding=4] > tbody > tr:not(.windowbg):not(.windowbg2)");

            // Get data from each post
            for (int i = 0; i < pmElements.size(); i++) {
                Element post = pmElements.get(i);

                // Get element with posterInfo
                Element posterInfo = post.select("td[style=overflow: hidden;]").first();

                // Get poster name
                String posterName = posterInfo.select("b > a[href]").text();

                // Get poster rank and activity
                String posterText = posterInfo.text();

                String posterActivityStr = "";
                String posterPersText = "";
                if (!posterText.equals("Bitcoin Forum Guest")) {
                    posterActivityStr = posterText.substring(posterText.indexOf("Activity"),
                            posterText.indexOf(" ", posterText.indexOf("Activity") + 10));
                    posterPersText = posterText.substring(
                            posterText.indexOf(posterActivityStr) + posterActivityStr.length(),
                            posterText.lastIndexOf("Trust"));
                } else {
                    posterName = "Bitcoin Forum";
                }

                // Get rank
                String posterRank = "Brand New";
                if (posterText.contains("Brand New"))
                    posterRank = "Brand New";
                else if (posterText.contains("Newbie"))
                    posterRank = "Newbie";
                else if (posterText.contains("Jr. Member"))
                    posterRank = "Jr. Member";
                else if (posterText.contains("Full Member"))
                    posterRank = "Full Member";
                else if (posterText.contains("Sr. Member"))
                    posterRank = "Sr. Member";
                else if (posterText.contains("Hero Member"))
                    posterRank = "Hero Member";
                else if (posterText.contains("Legendary"))
                    posterRank = "Legendary";
                else if (posterText.contains("Member"))
                    posterRank = "Member";
                else if (posterText.contains("Guest"))
                    posterRank = "Guest";
                // get special positions
                String specialPosition = null;
                if (posterText.contains("Staff"))
                    specialPosition = "Staff";
                else if (posterText.contains("Global Moderator"))
                    specialPosition = "Global Moderator";
                else if (posterText.contains("Moderator"))
                    specialPosition = "Moderator";
                else if (posterText.contains("Administrator"))
                    specialPosition = "Administrator";
                else if (posterText.contains("Founder"))
                    specialPosition = "Founder";
                else if (posterText.contains(" Donator"))
                    specialPosition = "Donator";
                else if (posterText.contains("VIP"))
                    specialPosition = "VIP";

                // Get poster avatar
                Elements avatarImgs = posterInfo.select("img.avatar");
                BitmapDrawable avatar = null;

                // Create poster object
                Poster poster = new Poster(posterName, avatar, posterPersText, posterActivityStr, posterRank);
                if (specialPosition != null)
                    poster.setSpecialPos(specialPosition);

                // Get header element
                Element pmHead = post.select("td.windowbg > table > tbody > tr > td[align=left]").first();

                if (pmHead == null)
                    pmHead = post.select("td.windowbg2 > table > tbody > tr > td[align=left]").first();

                // Get header right
                Element pmHeadRight = post.select("td.windowbg > table > tbody > tr > td[align=right]").first();
                if (pmHeadRight == null)
                    pmHeadRight = post.select("td.windowbg2 > table > tbody > tr > td[align=right]").first();

                // Get quote reply and delete strings
                String quoteURL = pmHeadRight.select("a[href]").first().attr("href");
                String replyURL = pmHeadRight.select("a[href]").get(0).attr("href");
                String deleteURL = pmHeadRight.select("a[href]").get(1).attr("href");

                // Get subject and post times
                String subject = pmHead.select("b").first().text();
                String pmedTime = pmHead.text().replaceAll(subject, "");
                pmedTime = pmedTime.substring(pmedTime.indexOf("on:") + 3, pmedTime.indexOf(""));

                // Get elements with post and header
                Element pm = post.select("div.personalmessage").first();

                // Get body of post
                String postBodyStr = pm.html();
                Spanned postBody = Html.fromHtml(postBodyStr);

                // Create post object
                Post postObj = new Post(poster, pmedTime, subject, postBody, ids.get(i), quoteURL, replyURL,
                        deleteURL);
                posts.add(postObj);
            }

            return posts;
        }

        private List<Topic> getTopicsFromBody(Element body) {
            List<Topic> topics = new ArrayList<Topic>();
            Elements allElements = body.select(
                    "table.bordercolor > tbody > tr > td > table.bordercolor > tbody > tr:not(titlebg) > td");
            List<String> subjects = new ArrayList<String>();
            List<String> starters = new ArrayList<String>();
            List<Integer> repliesCount = new ArrayList<Integer>();
            List<Integer> viewCount = new ArrayList<Integer>();
            List<String> lastPoster = new ArrayList<String>();
            List<Boolean> stickies = new ArrayList<Boolean>();
            List<Boolean> locked = new ArrayList<Boolean>();
            List<Long> ids = new ArrayList<Long>();
            List<String> topicURLs = new ArrayList<String>();
            List<String> lastPostURLs = new ArrayList<String>();
            for (Element elem : allElements) {
                if (elem.html().contains(".0;topicseen\">")) {
                    String subject = elem.text();

                    // Get only the subject
                    if (subject.contains("")) {
                        subject = subject.substring(0, subject.indexOf(" "));
                    }
                    subjects.add(subject);

                    // Check for sticky
                    if (elem.html().contains(
                            "<img src=\"https://bitcointalk.org/Themes/custom1/images/icons/show_sticky.gif\"")) {
                        stickies.add(true);
                    } else {
                        stickies.add(false);
                    }

                    // Check for locked
                    if (elem.html().contains(
                            "<img src=\"https://bitcointalk.org/Themes/custom1/images/icons/quick_lock.gif\"")) {
                        locked.add(true);
                    } else {
                        locked.add(false);
                    }

                    // Get the id
                    long id = Long.parseLong(elem.html().substring(elem.html().indexOf("topic=") + 6,
                            elem.html().indexOf(".", elem.html().indexOf("topic="))));
                    ids.add(id);

                    // Get the URLs
                    topicURLs.add(elem.select("a[href]").get(0).attr("href"));
                } else if (elem.html().contains("title=\"View the profile of")) {
                    starters.add(elem.text());
                } else if (elem.outerHtml()
                        .contains("<td class=\"windowbg\" valign=\"middle\" width=\"4%\" align=\"center\">")) {
                    int number = Integer.parseInt(elem.text());
                    if (repliesCount.size() == viewCount.size()) {
                        repliesCount.add(number);
                    } else if (repliesCount.size() > viewCount.size()) {
                        viewCount.add(number);
                    }
                } else if (elem.outerHtml().contains("<td class=\"windowbg2\" valign=\"middle\" width=\"22%\">")) {
                    lastPoster.add(elem.text());
                    lastPostURLs.add(elem.select("a[href]").attr("href"));
                }
            }

            for (int i = 0; i < subjects.size(); i++) {
                Topic topicObj = new Topic(subjects.get(i), starters.get(i), repliesCount.get(i), viewCount.get(i),
                        lastPoster.get(i), stickies.get(i), locked.get(i), true, ids.get(i));
                topicObj.setURL(topicURLs.get(i));
                topicObj.setLastPostURL(lastPostURLs.get(i));
                topics.add(topicObj);
            }

            return topics;
        }

        @Override
        protected void onPostExecute(List<List<Object>> result) {

            int numMessages = 0;
            for (List<Object> list : result) {
                if (!list.isEmpty()) {
                    numMessages += list.size();
                }
            }
            if (numMessages > 0) {
                NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext())
                        .setSmallIcon(R.drawable.ic_notification).setLargeIcon(BitmapFactory
                                .decodeResource(getApplicationContext().getResources(), R.mipmap.ic_launcher));

                // Set the title String with number of messages
                mBuilder.setContentTitle(numMessages + " Messages");

                // Set the content of notification to be title of first of each
                String text = "";
                for (int i = 0; i < result.size(); i++) {
                    List<Object> list = result.get(i);
                    if (!list.isEmpty()) {
                        if (i == 3) {
                            text = text + ((Post) list.get(0)).getSubject() + "\n";
                        } else {
                            text = text + ((Topic) list.get(0)).getSubject() + "\n";
                        }
                    }
                }
                mBuilder.setContentText(text);
                mBuilder.setSound(Uri.parse(sound));
                if (vibrate)
                    mBuilder.setVibrate(new long[] { 0, 400, 50, 200 });

                // Creates an explicit intent for an Activity in your app
                Intent resultIntent = new Intent(getApplicationContext(), MainActivity.class);
                resultIntent.putExtra("SESSION ID", sessId);
                resultIntent.putExtra("Username", mUsername);

                // The stack builder object will contain an artificial back stack for the
                // started Activity.
                // This ensures that navigating backward from the Activity leads out of
                // your application to the Home screen.
                TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext());
                // Adds the back stack for the Intent (but not the Intent itself)
                stackBuilder.addParentStack(MainActivity.class);
                // Adds the Intent that starts the Activity to the top of the stack
                stackBuilder.addNextIntent(resultIntent);
                PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
                        PendingIntent.FLAG_UPDATE_CURRENT);
                mBuilder.setContentIntent(resultPendingIntent);
                NotificationManager mNotificationManager = (NotificationManager) getSystemService(
                        Context.NOTIFICATION_SERVICE);
                // mId allows you to update the notification later on.
                mNotificationManager.notify(1, mBuilder.build());
            }

            stopSelf();
        }
    }

    /**
     * This is called on 2.0+ (API level 5 or higher). Returning
     * START_NOT_STICKY tells the system to not restart the service if it is
     * killed because of poor resource (memory/cpu) conditions.
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        handleIntent(intent);
        return START_NOT_STICKY;
    }

    /**
     * In onDestroy() we release our wake lock. This ensures that whenever the
     * Service stops (killed for resources, stopSelf() called, etc.), the wake
     * lock will be released.
     */
    public void onDestroy() {
        super.onDestroy();
        mWakeLock.release();
    }
}