diff --git a/Clover/app/src/main/AndroidManifest.xml b/Clover/app/src/main/AndroidManifest.xml
index 0ffe1cf0..3eb26f25 100644
--- a/Clover/app/src/main/AndroidManifest.xml
+++ b/Clover/app/src/main/AndroidManifest.xml
@@ -136,7 +136,7 @@ along with this program. If not, see .
diff --git a/Clover/app/src/main/java/org/floens/chan/ChanApplication.java b/Clover/app/src/main/java/org/floens/chan/ChanApplication.java
index 982f5baf..4630c98b 100644
--- a/Clover/app/src/main/java/org/floens/chan/ChanApplication.java
+++ b/Clover/app/src/main/java/org/floens/chan/ChanApplication.java
@@ -28,27 +28,31 @@ import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import org.floens.chan.core.manager.BoardManager;
-import org.floens.chan.core.manager.PinnedManager;
-import org.floens.chan.core.manager.PinnedManager.PinListener;
import org.floens.chan.core.manager.ReplyManager;
+import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.net.BitmapLruImageCache;
import org.floens.chan.database.DatabaseManager;
-import org.floens.chan.service.WatchService;
import org.floens.chan.utils.IconCache;
-import org.floens.chan.utils.ThemeHelper;
+import org.floens.chan.utils.Logger;
import java.io.File;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChanApplication extends Application {
+ private static final String TAG = "ChanApplication";
-public class ChanApplication extends Application implements PinListener {
private static ChanApplication instance;
private static RequestQueue volleyRequestQueue;
private static ImageLoader imageLoader;
private static BoardManager boardManager;
- private static PinnedManager pinnedManager;
+ private static WatchManager watchManager;
private static ReplyManager replyManager;
private static DatabaseManager databaseManager;
- private static ThemeHelper themeHelper;
+
+ private List foregroundChangedListeners = new ArrayList<>();
+ private int activityForegroundCounter = 0;
public ChanApplication() {
instance = this;
@@ -70,8 +74,8 @@ public class ChanApplication extends Application implements PinListener {
return boardManager;
}
- public static PinnedManager getPinnedManager() {
- return pinnedManager;
+ public static WatchManager getWatchManager() {
+ return watchManager;
}
public static ReplyManager getReplyManager() {
@@ -115,15 +119,50 @@ public class ChanApplication extends Application implements PinListener {
databaseManager = new DatabaseManager(this);
boardManager = new BoardManager();
- pinnedManager = new PinnedManager(this);
- pinnedManager.addPinListener(this);
+ watchManager = new WatchManager(this);
replyManager = new ReplyManager(this);
+ }
- WatchService.updateRunningState(this);
+ public void activityEnteredForeground() {
+ boolean lastForeground = getApplicationInForeground();
+
+ activityForegroundCounter++;
+
+ if (getApplicationInForeground() != lastForeground) {
+ for (ForegroundChangedListener listener : foregroundChangedListeners) {
+ listener.onForegroundChanged(getApplicationInForeground());
+ }
+ }
}
- @Override
- public void onPinsChanged() {
- WatchService.updateRunningState(this);
+ public void activityEnteredBackground() {
+ boolean lastForeground = getApplicationInForeground();
+
+ activityForegroundCounter--;
+ if (activityForegroundCounter < 0) {
+ Logger.wtf(TAG, "activityForegroundCounter below 0");
+ }
+
+ if (getApplicationInForeground() != lastForeground) {
+ for (ForegroundChangedListener listener : foregroundChangedListeners) {
+ listener.onForegroundChanged(getApplicationInForeground());
+ }
+ }
+ }
+
+ public boolean getApplicationInForeground() {
+ return activityForegroundCounter > 0;
+ }
+
+ public void addForegroundChangedListener(ForegroundChangedListener listener) {
+ foregroundChangedListeners.add(listener);
+ }
+
+ public void removeForegroundChangedListener(ForegroundChangedListener listener) {
+ foregroundChangedListeners.remove(listener);
+ }
+
+ public static interface ForegroundChangedListener {
+ public void onForegroundChanged(boolean foreground);
}
}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java b/Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java
index 858534d3..039e1138 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/ChanPreferences.java
@@ -20,7 +20,6 @@ package org.floens.chan.core;
import android.content.SharedPreferences;
import org.floens.chan.ChanApplication;
-import org.floens.chan.service.WatchService;
public class ChanPreferences {
private static SharedPreferences p() {
@@ -64,8 +63,7 @@ public class ChanPreferences {
public static void setWatchEnabled(boolean enabled) {
if (getWatchEnabled() != enabled) {
p().edit().putBoolean("preference_watch_enabled", enabled).commit();
- WatchService.updateRunningState(ChanApplication.getInstance());
- ChanApplication.getPinnedManager().onPinsChanged();
+ ChanApplication.getWatchManager().onWatchEnabledChanged(enabled);
}
}
@@ -73,9 +71,9 @@ public class ChanPreferences {
return p().getBoolean("preference_watch_background_enabled", false);
}
- public static long getWatchBackgroundTimeout() {
- String number = p().getString("preference_watch_background_timeout", "0");
- return Integer.parseInt(number) * 1000L;
+ public static int getWatchBackgroundTimeout() {
+ String number = p().getString("preference_watch_background_timeout", "60");
+ return Integer.parseInt(number);
}
public static boolean getVideoAutoPlay() {
diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/PinnedManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/PinnedManager.java
deleted file mode 100644
index b7af3626..00000000
--- a/Clover/app/src/main/java/org/floens/chan/core/manager/PinnedManager.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Clover - 4chan browser https://github.com/Floens/Clover/
- * Copyright (C) 2014 Floens
- *
- * 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 .
- */
-package org.floens.chan.core.manager;
-
-import android.content.Context;
-
-import org.floens.chan.ChanApplication;
-import org.floens.chan.core.model.Loadable;
-import org.floens.chan.core.model.Pin;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PinnedManager {
- private final List listeners = new ArrayList<>();
- private final List pins;
-
- public PinnedManager(Context context) {
- pins = ChanApplication.getDatabaseManager().getPinned();
- }
-
- public void addPinListener(PinListener l) {
- listeners.add(l);
- }
-
- public void removePinListener(PinListener l) {
- listeners.remove(l);
- }
-
- /**
- * Look for a pin that has an loadable that is equal to the supplied
- * loadable.
- *
- * @param other
- * @return The pin whose loadable is equal to the supplied loadable, or null
- * if no pin was found.
- */
- public Pin findPinByLoadable(Loadable other) {
- for (Pin pin : pins) {
- if (pin.loadable.equals(other)) {
- return pin;
- }
- }
-
- return null;
- }
-
- public Pin findPinById(int id) {
- for (Pin pin : pins) {
- if (pin.id == id) {
- return pin;
- }
- }
-
- return null;
- }
-
- public List getPins() {
- return pins;
- }
-
- public List getWatchingPins() {
- List l = new ArrayList<>();
-
- for (Pin p : pins) {
- if (p.watching)
- l.add(p);
- }
-
- return l;
- }
-
- /**
- * Add a pin
- *
- * @param pin
- * @return true if it was added, false if it wasn't (duplicated)
- */
- public boolean add(Pin pin) {
- // No duplicates
- for (Pin e : pins) {
- if (e.loadable.equals(pin.loadable)) {
- return false;
- }
- }
-
- pins.add(pin);
- ChanApplication.getDatabaseManager().addPin(pin);
-
- onPinsChanged();
-
- return true;
- }
-
- /**
- * Remove a pin
- *
- * @param pin
- */
- public void remove(Pin pin) {
- pins.remove(pin);
- ChanApplication.getDatabaseManager().removePin(pin);
- pin.destroyWatcher();
-
- onPinsChanged();
- }
-
- /**
- * Update the pin in the database
- *
- * @param pin
- */
- public void update(Pin pin) {
- ChanApplication.getDatabaseManager().updatePin(pin);
-
- onPinsChanged();
- }
-
- /**
- * Updates all the pins to the database. This will run in a new thread
- * because it can be an expensive operation. (this will be an huge headache
- * later on when we get concurrent problems)
- */
- public void updateAll() {
- new Thread(new Runnable() {
- @Override
- public void run() {
- ChanApplication.getDatabaseManager().updatePins(pins);
- }
- }).start();
- }
-
- public void onPinViewed(Pin pin) {
- pin.getPinWatcher().onViewed();
-
- onPinsChanged();
- }
-
- public void onPinsChanged() {
- for (PinListener l : listeners) {
- l.onPinsChanged();
- }
- }
-
- public static interface PinListener {
- public void onPinsChanged();
- }
-}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java
index 766e8060..cdb8600f 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/manager/ThreadManager.java
@@ -124,9 +124,9 @@ public class ThreadManager implements Loader.LoaderListener {
public void bottomPostViewed() {
if (loader != null && loader.getLoadable().isThreadMode()) {
- Pin pin = ChanApplication.getPinnedManager().findPinByLoadable(loader.getLoadable());
+ Pin pin = ChanApplication.getWatchManager().findPinByLoadable(loader.getLoadable());
if (pin != null) {
- ChanApplication.getPinnedManager().onPinViewed(pin);
+ ChanApplication.getWatchManager().onPinViewed(pin);
}
updateLastSeen();
@@ -565,7 +565,7 @@ public class ThreadManager implements Loader.LoaderListener {
}
private void updateLastSeen() {
- Pin pin = ChanApplication.getPinnedManager().findPinByLoadable(loader.getLoadable());
+ Pin pin = ChanApplication.getWatchManager().findPinByLoadable(loader.getLoadable());
if (pin != null) {
Post last = pin.getLastSeenPost();
if (last != null) {
diff --git a/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java b/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java
new file mode 100644
index 00000000..c1d0bb7d
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java
@@ -0,0 +1,320 @@
+/*
+ * Clover - 4chan browser https://github.com/Floens/Clover/
+ * Copyright (C) 2014 Floens
+ *
+ * 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 .
+ */
+package org.floens.chan.core.manager;
+
+import android.content.Context;
+import android.content.Intent;
+
+import org.floens.chan.ChanApplication;
+import org.floens.chan.core.ChanPreferences;
+import org.floens.chan.core.model.Loadable;
+import org.floens.chan.core.model.Pin;
+import org.floens.chan.ui.service.WatchNotifier;
+import org.floens.chan.utils.Logger;
+import org.floens.chan.utils.Utils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+public class WatchManager implements ChanApplication.ForegroundChangedListener {
+ private static final String TAG = "WatchManager";
+ private static final int FOREGROUND_TIME = 10;
+
+ private final Context context;
+ private final List listeners = new ArrayList<>();
+ private final List pins;
+ private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+ private PendingTimer pendingTimer;
+
+ public WatchManager(Context context) {
+ this.context = context;
+
+ pins = ChanApplication.getDatabaseManager().getPinned();
+
+ ChanApplication.getInstance().addForegroundChangedListener(this);
+
+ updateTimerState();
+ updateNotificationServiceState();
+ }
+
+ /**
+ * Look for a pin that has an loadable that is equal to the supplied
+ * loadable.
+ *
+ * @param other
+ * @return The pin whose loadable is equal to the supplied loadable, or null
+ * if no pin was found.
+ */
+ public Pin findPinByLoadable(Loadable other) {
+ for (Pin pin : pins) {
+ if (pin.loadable.equals(other)) {
+ return pin;
+ }
+ }
+
+ return null;
+ }
+
+ public Pin findPinById(int id) {
+ for (Pin pin : pins) {
+ if (pin.id == id) {
+ return pin;
+ }
+ }
+
+ return null;
+ }
+
+ public List getPins() {
+ return pins;
+ }
+
+ public List getWatchingPins() {
+ if (ChanPreferences.getWatchEnabled()) {
+ List l = new ArrayList<>();
+
+ for (Pin p : pins) {
+ if (p.watching)
+ l.add(p);
+ }
+
+ return l;
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ /**
+ * Add a pin
+ *
+ * @param pin
+ * @return true if it was added, false if it wasn't (duplicated)
+ */
+ public boolean addPin(Pin pin) {
+ // No duplicates
+ for (Pin e : pins) {
+ if (e.loadable.equals(pin.loadable)) {
+ return false;
+ }
+ }
+
+ pins.add(pin);
+ ChanApplication.getDatabaseManager().addPin(pin);
+
+ onPinsChanged();
+
+ return true;
+ }
+
+ /**
+ * Remove a pin
+ *
+ * @param pin
+ */
+ public void removePin(Pin pin) {
+ pins.remove(pin);
+ ChanApplication.getDatabaseManager().removePin(pin);
+ pin.destroyWatcher();
+
+ onPinsChanged();
+ }
+
+ /**
+ * Update the pin in the database
+ *
+ * @param pin
+ */
+ public void updatePin(Pin pin) {
+ ChanApplication.getDatabaseManager().updatePin(pin);
+
+ onPinsChanged();
+ }
+
+ /**
+ * Updates all the pins to the database. This will run in a new thread
+ * because it can be an expensive operation. (this will be an huge headache
+ * later on when we get concurrent problems)
+ */
+ public void updateDatabase() {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ ChanApplication.getDatabaseManager().updatePins(pins);
+ }
+ }).start();
+ }
+
+ public void onPinViewed(Pin pin) {
+ pin.getPinWatcher().onViewed();
+
+ onPinsChanged();
+ }
+
+ public void addPinListener(PinListener l) {
+ listeners.add(l);
+ }
+
+ public void removePinListener(PinListener l) {
+ listeners.remove(l);
+ }
+
+ public void onPinsChanged() {
+ for (PinListener l : listeners) {
+ l.onPinsChanged();
+ }
+
+ updateTimerState();
+ updateNotificationServiceState();
+ }
+
+ public void pausePins() {
+ List watchingPins = getWatchingPins();
+ for (Pin pin : watchingPins) {
+ pin.watching = false;
+ }
+
+ onPinsChanged();
+ updateDatabase();
+ }
+
+ public void onWatchEnabledChanged(boolean watchEnabled) {
+ updateNotificationServiceState(watchEnabled, getWatchBackgroundEnabled());
+ updateTimerState(watchEnabled, getWatchBackgroundEnabled());
+ }
+
+ public void onBackgroundWatchingChanged(boolean backgroundEnabled) {
+ updateNotificationServiceState(getWatchEnabled(), backgroundEnabled);
+ updateTimerState(getWatchEnabled(), backgroundEnabled);
+ }
+
+ @Override
+ public void onForegroundChanged(final boolean foreground) {
+ updateNotificationServiceState();
+ updateTimerState();
+ }
+
+ public boolean getWatchEnabled() {
+ // getWatchingPins returns an empty list when ChanPreferences.getWatchEnabled() is false
+ return getWatchingPins().size() > 0;
+ }
+
+ public boolean getWatchBackgroundEnabled() {
+ return ChanPreferences.getWatchBackgroundEnabled();
+ }
+
+ private void updateNotificationServiceState() {
+ updateNotificationServiceState(getWatchEnabled(), getWatchBackgroundEnabled());
+ }
+
+ private void updateNotificationServiceState(boolean watchEnabled, boolean backgroundEnabled) {
+ if (watchEnabled && backgroundEnabled) {
+ // Also calls onStartCommand, which updates the notification
+ context.startService(new Intent(context, WatchNotifier.class));
+ } else {
+ context.stopService(new Intent(context, WatchNotifier.class));
+ }
+ }
+
+ private void updateTimerState() {
+ updateTimerState(getWatchEnabled(), getWatchBackgroundEnabled());
+ }
+
+ private void updateTimerState(boolean watchEnabled, boolean backgroundEnabled) {
+ if (watchEnabled) {
+ if (ChanApplication.getInstance().getApplicationInForeground()) {
+ setTimer(FOREGROUND_TIME);
+ } else {
+ if (backgroundEnabled) {
+ setTimer(ChanPreferences.getWatchBackgroundTimeout());
+ } else {
+ if (pendingTimer != null) {
+ pendingTimer.cancel();
+ pendingTimer = null;
+ Logger.d(TAG, "Canceled timer");
+ }
+ }
+ }
+ } else {
+ if (pendingTimer != null) {
+ pendingTimer.cancel();
+ pendingTimer = null;
+ Logger.d(TAG, "Canceled timer");
+ }
+ }
+ }
+
+ private void setTimer(int time) {
+ if (pendingTimer != null && pendingTimer.time == time) {
+ return;
+ }
+
+ if (pendingTimer != null) {
+ pendingTimer.cancel();
+ pendingTimer = null;
+ Logger.d(TAG, "Canceled timer");
+ }
+
+ ScheduledFuture scheduledFuture = executor.schedule(new Runnable() {
+ @Override
+ public void run() {
+ Utils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ timerFired();
+ }
+ });
+ }
+ }, time, TimeUnit.SECONDS);
+ pendingTimer = new PendingTimer(scheduledFuture, time);
+ Logger.d(TAG, "Timer firing in " + time + " seconds");
+ }
+
+ private void timerFired() {
+ Logger.d(TAG, "Timer fired");
+ pendingTimer = null;
+
+ for (Pin pin : getWatchingPins()) {
+ pin.updateWatch();
+ }
+
+ updateTimerState();
+ }
+
+ public static interface PinListener {
+ public void onPinsChanged();
+ }
+
+ private static class PendingTimer {
+ public ScheduledFuture scheduledFuture;
+ public int time;
+
+ public PendingTimer(ScheduledFuture scheduledFuture, int time) {
+ this.scheduledFuture = scheduledFuture;
+ this.time = time;
+ }
+
+ public void cancel() {
+ scheduledFuture.cancel(false);
+ }
+ }
+}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/model/Pin.java b/Clover/app/src/main/java/org/floens/chan/core/model/Pin.java
index 3ff9a0da..a909d5ee 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/model/Pin.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/model/Pin.java
@@ -79,9 +79,10 @@ public class Pin {
public void toggleWatch() {
watching = !watching;
- ChanApplication.getPinnedManager().onPinsChanged();
+ ChanApplication.getWatchManager().onPinsChanged();
+
if (watching) {
- updateWatch();
+ getPinWatcher().update();
}
}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java b/Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java
index d324ae35..b52e0109 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java
@@ -19,12 +19,13 @@ package org.floens.chan.core.watch;
import com.android.volley.VolleyError;
+import org.floens.chan.ChanApplication;
import org.floens.chan.core.loader.Loader;
import org.floens.chan.core.loader.LoaderPool;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
-import org.floens.chan.service.WatchService;
import org.floens.chan.utils.Logger;
+import org.floens.chan.utils.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -37,6 +38,7 @@ public class PinWatcher implements Loader.LoaderListener {
private final List posts = new ArrayList<>();
private boolean wereNewQuotes = false;
+ private boolean wereNewPosts = false;
public PinWatcher(Pin pin) {
this.pin = pin;
@@ -64,6 +66,7 @@ public class PinWatcher implements Loader.LoaderListener {
pin.quoteLastCount = pin.quoteNewCount;
wereNewQuotes = false;
+ wereNewPosts = false;
}
public List getNewPosts() {
@@ -92,6 +95,15 @@ public class PinWatcher implements Loader.LoaderListener {
}
}
+ public boolean getWereNewPosts() {
+ if (wereNewPosts) {
+ wereNewPosts = false;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
public Post getLastSeenPost() {
int i = posts.size() - pin.getNewPostsCount() - 1;
if (i >= 0 && i < posts.size()) {
@@ -106,7 +118,12 @@ public class PinWatcher implements Loader.LoaderListener {
Logger.e(TAG, "PinWatcher onError: ", error);
pin.isError = true;
- WatchService.onPinWatcherResult();
+ Utils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ChanApplication.getWatchManager().onPinsChanged();
+ }
+ });
}
@Override
@@ -116,14 +133,14 @@ public class PinWatcher implements Loader.LoaderListener {
posts.clear();
posts.addAll(result);
+ int lastQuoteNewCount = pin.quoteNewCount;
+ int lastWatchNewCount = pin.watchNewCount;
+
if (pin.watchLastCount < 0)
pin.watchLastCount = result.size();
pin.watchNewCount = result.size();
- // If there are more replies than last time, let the notification make a sound
- int lastCounterForSoundNotification = pin.quoteNewCount;
-
// Get list of saved posts
int total = 0;
for (Post saved : result) {
@@ -134,15 +151,24 @@ public class PinWatcher implements Loader.LoaderListener {
pin.quoteNewCount = total;
- if (pin.quoteNewCount > lastCounterForSoundNotification) {
+ if (pin.quoteNewCount > lastQuoteNewCount) {
wereNewQuotes = true;
}
+ if (pin.watchNewCount > lastWatchNewCount) {
+ wereNewPosts = true;
+ }
+
if (Logger.debugEnabled()) {
- Logger.d(TAG, String.format("postlast=%d postnew=%d quotelast=%d quotenew=%d werenewquotes=%b",
- pin.watchLastCount, pin.watchNewCount, pin.quoteLastCount, pin.quoteNewCount, wereNewQuotes));
+ Logger.d(TAG, String.format("postlast=%d postnew=%d werenewposts=%b quotelast=%d quotenew=%d werenewquotes=%b",
+ pin.watchLastCount, pin.watchNewCount, wereNewPosts, pin.quoteLastCount, pin.quoteNewCount, wereNewQuotes));
}
- WatchService.onPinWatcherResult();
+ Utils.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ChanApplication.getWatchManager().onPinsChanged();
+ }
+ });
}
}
diff --git a/Clover/app/src/main/java/org/floens/chan/service/WatchService.java b/Clover/app/src/main/java/org/floens/chan/service/WatchService.java
deleted file mode 100644
index b0c15ca0..00000000
--- a/Clover/app/src/main/java/org/floens/chan/service/WatchService.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Clover - 4chan browser https://github.com/Floens/Clover/
- * Copyright (C) 2014 Floens
- *
- * 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 .
- */
-package org.floens.chan.service;
-
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.IBinder;
-
-import org.floens.chan.ChanApplication;
-import org.floens.chan.core.ChanPreferences;
-import org.floens.chan.core.model.Pin;
-import org.floens.chan.core.watch.WatchNotifier;
-import org.floens.chan.utils.Logger;
-import org.floens.chan.utils.Utils;
-
-import java.util.List;
-
-public class WatchService extends Service {
- private static final String TAG = "WatchService";
-
- private static final long FOREGROUND_INTERVAL = 10000L;
-
- private static WatchService instance;
- private static boolean activityInForeground = false;
-
- private Thread loadThread;
- private boolean running = true;
- private WatchNotifier watchNotifier;
-
- public static void onActivityStart() {
- activityInForeground = true;
- if (instance != null) {
- instance.onActivityInForeground();
- }
- }
-
- public static void onActivityStop() {
- activityInForeground = false;
- if (instance != null) {
- instance.onActivityInBackground();
- }
- }
-
- public static boolean getActivityInForeground() {
- return activityInForeground;
- }
-
- public static void updateRunningState(Context context) {
- if (ChanPreferences.getWatchEnabled()) {
- if (ChanApplication.getPinnedManager().getWatchingPins().size() == 0) {
- if (getRunning()) {
- disable(context);
- }
- } else {
- if (!getRunning()) {
- enable(context);
- }
- }
- } else {
- if (getRunning()) {
- disable(context);
- }
- }
- }
-
- public static void enable(Context context) {
- if (!getRunning()) {
- context.startService(new Intent(context, WatchService.class));
- }
- }
-
- public static void disable(Context context) {
- if (getRunning()) {
- context.stopService(new Intent(context, WatchService.class));
-
- List pins = ChanApplication.getPinnedManager().getWatchingPins();
- for (Pin pin : pins) {
- pin.destroyWatcher();
- }
-
- instance.watchNotifier.destroy();
- }
- }
-
- public static boolean getRunning() {
- return instance != null;
- }
-
- public static void onPinWatcherResult() {
- Utils.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ChanApplication.getPinnedManager().onPinsChanged();
- if (instance != null) {
- instance.watchNotifier.update();
- }
- }
- });
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
-
- instance = this;
-
- watchNotifier = new WatchNotifier(this);
-
- Logger.i(TAG, "WatchService created");
-
- startThread();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- instance = null;
-
- running = false;
- if (loadThread != null) {
- loadThread.interrupt();
- }
-
- Logger.i(TAG, "WatchService destroyed");
- }
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- if (intent != null && intent.getExtras() != null && intent.getExtras().getBoolean("pause_pins", false)) {
- if (watchNotifier != null) {
- watchNotifier.onPausePinsClicked();
- }
- }
-
- return START_STICKY;
- }
-
- private void startThread() {
- running = true;
-
- if (loadThread == null) {
- loadThread = new Thread(new Runnable() {
- @Override
- public void run() {
- while (running) {
- Logger.d(TAG, "Loadthread loop");
-
- if (!running)
- return;
-
- long timeout = activityInForeground ? FOREGROUND_INTERVAL : getBackgroundTimeout();
- if (timeout < 0L) {
- Logger.d(TAG, "Waiting for interrupt...");
- try {
- Object o = new Object();
- synchronized (o) {
- o.wait();
- }
- } catch (InterruptedException e) {
- Logger.d(TAG, "Interrupted!");
- }
- } else {
- update();
-
- try {
- Thread.sleep(timeout);
- } catch (InterruptedException e) {
- Logger.d(TAG, "Interrupted!");
- }
- }
- }
- }
- });
-
- loadThread.start();
- }
- }
-
- private void onActivityInForeground() {
- if (loadThread != null) {
- loadThread.interrupt();
- }
- watchNotifier.onForegroundChanged();
- }
-
- private void onActivityInBackground() {
- watchNotifier.onForegroundChanged();
- }
-
- /**
- * Returns the sleep time the user specified for background iteration
- *
- * @return the sleep time in ms, or -1 if background reloading is disabled
- */
- private long getBackgroundTimeout() {
- if (ChanPreferences.getWatchBackgroundEnabled()) {
- return ChanPreferences.getWatchBackgroundTimeout();
- } else {
- return -1;
- }
- }
-
- private void update() {
- List pins = ChanApplication.getPinnedManager().getWatchingPins();
- for (Pin pin : pins) {
- pin.updateWatch();
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/BaseActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/BaseActivity.java
index 2fcc434b..791a5106 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/activity/BaseActivity.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/BaseActivity.java
@@ -46,7 +46,7 @@ import android.widget.ShareActionProvider;
import org.floens.chan.ChanApplication;
import org.floens.chan.R;
-import org.floens.chan.core.manager.PinnedManager;
+import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
import org.floens.chan.ui.BadgeDrawable;
@@ -58,7 +58,7 @@ import org.floens.chan.utils.Utils;
import java.util.List;
-public abstract class BaseActivity extends Activity implements PanelSlideListener, PinnedManager.PinListener {
+public abstract class BaseActivity extends Activity implements PanelSlideListener, WatchManager.PinListener {
public static boolean doRestartOnResume = false;
private final static int ACTION_OPEN_URL = 1;
@@ -102,7 +102,7 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
threadPane = (SlidingPaneLayout) findViewById(R.id.pane_container);
initPane();
- ChanApplication.getPinnedManager().addPinListener(this);
+ ChanApplication.getWatchManager().addPinListener(this);
updateIcon();
}
@@ -111,7 +111,7 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
protected void onDestroy() {
super.onDestroy();
- ChanApplication.getPinnedManager().removePinListener(this);
+ ChanApplication.getWatchManager().removePinListener(this);
}
@Override
@@ -203,7 +203,7 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
}
private void updateIcon() {
- List list = ChanApplication.getPinnedManager().getWatchingPins();
+ List list = ChanApplication.getWatchManager().getWatchingPins();
if (list.size() > 0) {
int count = 0;
boolean color = false;
@@ -226,15 +226,15 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
}
public void addPin(Pin pin) {
- ChanApplication.getPinnedManager().add(pin);
+ ChanApplication.getWatchManager().addPin(pin);
}
public void removePin(Pin pin) {
- ChanApplication.getPinnedManager().remove(pin);
+ ChanApplication.getWatchManager().removePin(pin);
}
public void updatePin(Pin pin) {
- ChanApplication.getPinnedManager().update(pin);
+ ChanApplication.getWatchManager().updatePin(pin);
}
private void changePinTitle(final Pin pin) {
@@ -318,7 +318,10 @@ public abstract class BaseActivity extends Activity implements PanelSlideListene
}
NdefMessage message = new NdefMessage(new NdefRecord[]{record});
- adapter.setNdefPushMessage(message, this);
+ try {
+ adapter.setNdefPushMessage(message, this);
+ } catch (Exception e) {
+ }
}
Intent share = new Intent(android.content.Intent.ACTION_SEND);
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java
index b39a69c5..93d41fe9 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/BoardActivity.java
@@ -48,7 +48,6 @@ import org.floens.chan.core.ChanPreferences;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
-import org.floens.chan.service.WatchService;
import org.floens.chan.ui.fragment.ThreadFragment;
import org.floens.chan.utils.Logger;
import org.floens.chan.utils.Utils;
@@ -118,24 +117,22 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel
}
}
- Bundle extras = startIntent.getExtras();
- if (extras != null) {
- int pinId = extras.getInt("pin_id", -2);
- if (pinId != -2) {
- if (pinId == -1) {
- pinDrawer.openDrawer(pinDrawerView);
- } else {
- Pin pin = ChanApplication.getPinnedManager().findPinById(pinId);
- if (pin != null) {
- startLoadingThread(pin.loadable);
- }
- }
- }
+ if (startIntent.getExtras() != null) {
+ handleExtraBundle(startIntent.getExtras());
}
ignoreNextOnItemSelected = true;
}
+ @Override
+ protected void onNewIntent(final Intent intent) {
+ super.onNewIntent(intent);
+
+ if (intent.getExtras() != null) {
+ handleExtraBundle(intent.getExtras());
+ }
+ }
+
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@@ -148,21 +145,21 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel
protected void onStart() {
super.onStart();
- WatchService.onActivityStart();
+ ChanApplication.getInstance().activityEnteredForeground();
}
@Override
protected void onStop() {
super.onStop();
- WatchService.onActivityStop();
+ ChanApplication.getInstance().activityEnteredBackground();
}
@Override
protected void onPause() {
super.onPause();
- ChanApplication.getPinnedManager().updateAll();
+ ChanApplication.getWatchManager().updateDatabase();
}
@Override
@@ -236,6 +233,20 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel
updateActionBarState();
}
+ private void handleExtraBundle(Bundle extras) {
+ int pinId = extras.getInt("pin_id", -2);
+ if (pinId != -2) {
+ if (pinId == -1) {
+ pinDrawer.openDrawer(pinDrawerView);
+ } else {
+ Pin pin = ChanApplication.getWatchManager().findPinById(pinId);
+ if (pin != null) {
+ startLoadingThread(pin.loadable);
+ }
+ }
+ }
+ }
+
private void updatePaneState() {
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
@@ -458,7 +469,7 @@ public class BoardActivity extends BaseActivity implements AdapterView.OnItemSel
if (loadable.mode == Loadable.Mode.INVALID)
return;
- Pin pin = ChanApplication.getPinnedManager().findPinByLoadable(loadable);
+ Pin pin = ChanApplication.getWatchManager().findPinByLoadable(loadable);
if (pin != null) {
// Use the loadable from the pin.
// This way we can store the listview position in the pin loadable,
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java
index 6b12577f..fae4c297 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/WatchSettingsActivity.java
@@ -23,6 +23,7 @@ import android.app.FragmentTransaction;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
@@ -38,6 +39,7 @@ import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
+import org.floens.chan.ChanApplication;
import org.floens.chan.R;
import org.floens.chan.core.ChanPreferences;
import org.floens.chan.utils.ThemeHelper;
@@ -153,6 +155,15 @@ public class WatchSettingsActivity extends Activity implements OnCheckedChangeLi
return true;
}
});
+
+ ((CheckBoxPreference)findPreference("preference_watch_background_enabled")).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(final Preference preference, final Object newValue) {
+ ChanApplication.getWatchManager().onBackgroundWatchingChanged((Boolean)newValue);
+
+ return true;
+ }
+ });
}
private void updateListSummary(ListPreference backgroundTimeout, String value) {
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/adapter/PinnedAdapter.java b/Clover/app/src/main/java/org/floens/chan/ui/adapter/PinnedAdapter.java
index ba2f30d2..f5864cdd 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/adapter/PinnedAdapter.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/adapter/PinnedAdapter.java
@@ -163,7 +163,7 @@ public class PinnedAdapter extends BaseAdapter {
public void reload() {
pins.clear();
- pins.addAll(ChanApplication.getPinnedManager().getPins());
+ pins.addAll(ChanApplication.getWatchManager().getPins());
notifyDataSetChanged();
}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java
index 83260c7e..5ad3cbfe 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/fragment/ReplyFragment.java
@@ -520,7 +520,7 @@ public class ReplyFragment extends DialogFragment {
// Pin thread on successful post
Pin pin = new Pin();
pin.loadable = loadable;
- ChanApplication.getPinnedManager().add(pin);
+ ChanApplication.getWatchManager().addPin(pin);
closeReply();
} else {
diff --git a/Clover/app/src/main/java/org/floens/chan/core/watch/WatchNotifier.java b/Clover/app/src/main/java/org/floens/chan/ui/service/WatchNotifier.java
similarity index 58%
rename from Clover/app/src/main/java/org/floens/chan/core/watch/WatchNotifier.java
rename to Clover/app/src/main/java/org/floens/chan/ui/service/WatchNotifier.java
index 1e371a04..ab7f9369 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/watch/WatchNotifier.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/service/WatchNotifier.java
@@ -15,72 +15,85 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package org.floens.chan.core.watch;
+package org.floens.chan.ui.service;
+import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
+import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import org.floens.chan.ChanApplication;
import org.floens.chan.R;
-import org.floens.chan.core.ChanPreferences;
+import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post;
-import org.floens.chan.service.WatchService;
+import org.floens.chan.core.watch.PinWatcher;
import org.floens.chan.ui.activity.BoardActivity;
-import org.floens.chan.utils.Logger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-public class WatchNotifier {
+public class WatchNotifier extends Service {
private static final String TAG = "WatchNotifier";
+ private static final int NOTIFICATION_ID = 1;
- private final int NOTIFICATION_ID = 1;
+ private NotificationManager nm;
+ private WatchManager wm;
- private final Context context;
- private final NotificationManager nm;
+ @Override
+ public IBinder onBind(final Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
- public WatchNotifier(Context context) {
- this.context = context;
- nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ wm = ChanApplication.getWatchManager();
+
+ startForeground(NOTIFICATION_ID, getIdleNotification());
}
- public void destroy() {
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
nm.cancel(NOTIFICATION_ID);
}
- public void update() {
- if (!WatchService.getActivityInForeground() && ChanPreferences.getWatchBackgroundEnabled()) {
- prepareNotification();
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (intent != null && intent.getExtras() != null && intent.getExtras().getBoolean("pause_pins", false)) {
+ pausePins();
+ } else {
+ updateNotification();
}
- }
- public void onForegroundChanged() {
- if (WatchService.getActivityInForeground()) {
- nm.cancel(NOTIFICATION_ID);
- }
+ return START_STICKY;
}
- public void onPausePinsClicked() {
- nm.cancel(NOTIFICATION_ID);
-
- List watchingPins = ChanApplication.getPinnedManager().getWatchingPins();
- for (Pin pin : watchingPins) {
- pin.watching = false;
+ public void updateNotification() {
+ Notification notification = createNotification();
+ if (notification != null) {
+ nm.notify(NOTIFICATION_ID, notification);
+ } else {
+ nm.notify(NOTIFICATION_ID, getIdleNotification());
}
+ }
- ChanApplication.getPinnedManager().onPinsChanged();
- ChanApplication.getPinnedManager().updateAll(); // Can be the last thing this app does
+ public void pausePins() {
+ wm.pausePins();
}
- private void prepareNotification() {
- List watchingPins = ChanApplication.getPinnedManager().getWatchingPins();
+ private Notification createNotification() {
+ List watchingPins = wm.getWatchingPins();
List pins = new ArrayList<>();
int newPostsCount = 0;
@@ -88,6 +101,7 @@ public class WatchNotifier {
List posts = new ArrayList<>();
boolean makeSound = false;
boolean show = false;
+ boolean wereNewPosts = false;
for (Pin pin : watchingPins) {
PinWatcher watcher = pin.getPinWatcher();
@@ -97,6 +111,9 @@ public class WatchNotifier {
boolean add = false;
if (pin.getNewPostsCount() > 0) {
+ if (watcher.getWereNewPosts()) {
+ wereNewPosts = true;
+ }
newPostsCount += pin.getNewPostsCount();
for (Post p : watcher.getNewPosts()) {
p.title = pin.loadable.title;
@@ -129,7 +146,6 @@ public class WatchNotifier {
}
String tickerText = title + " in ";
-
if (pins.size() == 1) {
tickerText += pins.get(0).loadable.title;
} else {
@@ -159,54 +175,67 @@ public class WatchNotifier {
targetPin = pins.get(0);
}
- showNotification(tickerText, title, tickerText, Integer.toString(newPostsCount), lines, makeSound, targetPin);
+ boolean showTickerText = !ChanApplication.getInstance().getApplicationInForeground() && wereNewPosts;
+ return getNotificationFor(showTickerText ? tickerText : null, title, tickerText, Integer.toString(newPostsCount), lines, makeSound, targetPin);
+ } else {
+ return null;
}
}
+ private Notification getIdleNotification() {
+ List watchingPins = wm.getWatchingPins();
+ int s = watchingPins.size();
+ String message = "Watching " + s + " thread" + (s != 1 ? "s" : "");
+
+ return getNotificationFor(null, message, message, "", null, false, null);
+ }
+
@SuppressWarnings("deprecation")
- private void showNotification(String tickerText, String title, String content, String contentInfo,
- List lines, boolean makeSound, Pin targetPin) {
+ private Notification getNotificationFor(String tickerText, String title, String content, String count,
+ List lines, boolean makeSound, Pin targetPin) {
- Intent intent = new Intent(context, BoardActivity.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+ Intent intent = new Intent(this, BoardActivity.class);
+ intent.setAction(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.putExtra("pin_id", targetPin == null ? -1 : targetPin.id);
- PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
- NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(pendingIntent);
builder.setTicker(tickerText);
builder.setContentTitle(title);
builder.setContentText(content);
- builder.setContentInfo(contentInfo);
+ builder.setContentInfo(count);
builder.setSmallIcon(R.drawable.ic_stat_notify);
- Intent pauseWatching = new Intent(context, WatchService.class);
+ Intent pauseWatching = new Intent(this, WatchNotifier.class);
pauseWatching.putExtra("pause_pins", true);
- PendingIntent pauseWatchingPending = PendingIntent.getService(context, 0, pauseWatching,
+ PendingIntent pauseWatchingPending = PendingIntent.getService(this, 0, pauseWatching,
PendingIntent.FLAG_UPDATE_CURRENT);
- builder.addAction(R.drawable.ic_action_pause, context.getString(R.string.watch_pause_pins),
+ builder.addAction(R.drawable.ic_action_pause, getString(R.string.watch_pause_pins),
pauseWatchingPending);
if (makeSound) {
builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
}
- NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
- for (CharSequence line : lines.subList(Math.max(0, lines.size() - 10), lines.size())) {
- style.addLine(line);
+ if (lines != null) {
+ NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
+ for (CharSequence line : lines.subList(Math.max(0, lines.size() - 10), lines.size())) {
+ style.addLine(line);
+ }
+ style.setBigContentTitle(title);
+ builder.setStyle(style);
}
- style.setBigContentTitle(title);
- // style.setSummaryText(content);
-
- builder.setStyle(style);
- Logger.i(TAG, "Showing notification");
- nm.notify(NOTIFICATION_ID, builder.getNotification());
+ return builder.getNotification();
}
private static class PostAgeComparer implements Comparator {