mirror of https://github.com/kurisufriend/Clover
It is replaced by ThreadWatchNotificatons. The usage of a foreground service was already deprecated by using AlarmManager for background updates.feature/sentry
parent
8e08f0fa56
commit
0a8cc47512
@ -1,303 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/ |
|
||||||
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.os.IBinder; |
|
||||||
import android.support.annotation.Nullable; |
|
||||||
import android.support.v4.app.NotificationCompat; |
|
||||||
import android.text.TextUtils; |
|
||||||
|
|
||||||
import org.floens.chan.Chan; |
|
||||||
import org.floens.chan.R; |
|
||||||
import org.floens.chan.core.manager.WatchManager; |
|
||||||
import org.floens.chan.core.model.Post; |
|
||||||
import org.floens.chan.core.model.orm.Pin; |
|
||||||
import org.floens.chan.core.settings.ChanSettings; |
|
||||||
import org.floens.chan.ui.activity.BoardActivity; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Collections; |
|
||||||
import java.util.Comparator; |
|
||||||
import java.util.List; |
|
||||||
import java.util.regex.Pattern; |
|
||||||
|
|
||||||
import javax.inject.Inject; |
|
||||||
|
|
||||||
import static org.floens.chan.Chan.inject; |
|
||||||
|
|
||||||
public class WatchNotifier extends Service { |
|
||||||
private static final String TAG = "WatchNotifier"; |
|
||||||
private static final int NOTIFICATION_ID = 1; |
|
||||||
private static final PostAgeComparator POST_AGE_COMPARATOR = new PostAgeComparator(); |
|
||||||
private static final int SUBJECT_LENGTH = 6; |
|
||||||
private static final String IMAGE_TEXT = "(img) "; |
|
||||||
private static final Pattern SHORTEN_NO_PATTERN = Pattern.compile(">>\\d+(?=\\d{3})(\\d{3})"); |
|
||||||
|
|
||||||
private NotificationManager nm; |
|
||||||
|
|
||||||
@Inject |
|
||||||
WatchManager watchManager; |
|
||||||
|
|
||||||
@Override |
|
||||||
public IBinder onBind(final Intent intent) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onCreate() { |
|
||||||
super.onCreate(); |
|
||||||
inject(this); |
|
||||||
|
|
||||||
nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void onDestroy() { |
|
||||||
super.onDestroy(); |
|
||||||
nm.cancel(NOTIFICATION_ID); |
|
||||||
} |
|
||||||
|
|
||||||
@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(); |
|
||||||
} |
|
||||||
|
|
||||||
return START_STICKY; |
|
||||||
} |
|
||||||
|
|
||||||
public void updateNotification() { |
|
||||||
Notification notification = createNotification(); |
|
||||||
if (notification != null) { |
|
||||||
nm.notify(NOTIFICATION_ID, notification); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public void pausePins() { |
|
||||||
watchManager.pauseAll(); |
|
||||||
} |
|
||||||
|
|
||||||
@Nullable |
|
||||||
private Notification createNotification() { |
|
||||||
boolean notifyQuotesOnly = ChanSettings.watchNotifyMode.get().equals("quotes"); |
|
||||||
boolean soundQuotesOnly = ChanSettings.watchSound.get().equals("quotes"); |
|
||||||
|
|
||||||
List<Post> unviewedPosts = new ArrayList<>(); |
|
||||||
List<Post> listQuoting = new ArrayList<>(); |
|
||||||
List<Pin> pins = new ArrayList<>(); |
|
||||||
List<Pin> subjectPins = new ArrayList<>(); |
|
||||||
|
|
||||||
boolean light = false; |
|
||||||
boolean sound = false; |
|
||||||
boolean peek = false; |
|
||||||
|
|
||||||
for (Pin pin : watchManager.getWatchingPins()) { |
|
||||||
WatchManager.PinWatcher watcher = watchManager.getPinWatcher(pin); |
|
||||||
if (watcher == null || pin.isError) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
pins.add(pin); |
|
||||||
|
|
||||||
if (notifyQuotesOnly) { |
|
||||||
unviewedPosts.addAll(watcher.getUnviewedQuotes()); |
|
||||||
listQuoting.addAll(watcher.getUnviewedQuotes()); |
|
||||||
if (watcher.getWereNewQuotes()) { |
|
||||||
light = true; |
|
||||||
sound = true; |
|
||||||
peek = true; |
|
||||||
} |
|
||||||
if (pin.getNewQuoteCount() > 0) { |
|
||||||
subjectPins.add(pin); |
|
||||||
} |
|
||||||
} else { |
|
||||||
unviewedPosts.addAll(watcher.getUnviewedPosts()); |
|
||||||
listQuoting.addAll(watcher.getUnviewedQuotes()); |
|
||||||
if (watcher.getWereNewPosts()) { |
|
||||||
light = true; |
|
||||||
if (!soundQuotesOnly) { |
|
||||||
sound = true; |
|
||||||
peek = true; |
|
||||||
} |
|
||||||
} |
|
||||||
if (watcher.getWereNewQuotes()) { |
|
||||||
sound = true; |
|
||||||
peek = true; |
|
||||||
} |
|
||||||
if (pin.getNewPostCount() > 0) { |
|
||||||
subjectPins.add(pin); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (Chan.getInstance().getApplicationInForeground()) { |
|
||||||
light = false; |
|
||||||
sound = false; |
|
||||||
} |
|
||||||
|
|
||||||
if (!ChanSettings.watchPeek.get()) { |
|
||||||
peek = false; |
|
||||||
} |
|
||||||
|
|
||||||
return notifyAboutPosts(pins, subjectPins, unviewedPosts, listQuoting, notifyQuotesOnly, light, sound, peek); |
|
||||||
} |
|
||||||
|
|
||||||
@Nullable |
|
||||||
private Notification notifyAboutPosts(List<Pin> pins, List<Pin> subjectPins, List<Post> unviewedPosts, List<Post> listQuoting, |
|
||||||
boolean notifyQuotesOnly, boolean light, boolean sound, boolean peek) { |
|
||||||
if (unviewedPosts.isEmpty()) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
// New posts notification
|
|
||||||
String message; |
|
||||||
List<Post> postsForExpandedLines; |
|
||||||
if (notifyQuotesOnly) { |
|
||||||
message = getResources().getQuantityString(R.plurals.watch_new_quotes, listQuoting.size(), listQuoting.size()); |
|
||||||
postsForExpandedLines = listQuoting; |
|
||||||
} else { |
|
||||||
postsForExpandedLines = unviewedPosts; |
|
||||||
if (listQuoting.size() > 0) { |
|
||||||
message = getResources().getQuantityString(R.plurals.watch_new_quoting, unviewedPosts.size(), unviewedPosts.size(), listQuoting.size()); |
|
||||||
} else { |
|
||||||
message = getResources().getQuantityString(R.plurals.watch_new, unviewedPosts.size(), unviewedPosts.size()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
Collections.sort(postsForExpandedLines, POST_AGE_COMPARATOR); |
|
||||||
List<CharSequence> expandedLines = new ArrayList<>(); |
|
||||||
for (Post postForExpandedLine : postsForExpandedLines) { |
|
||||||
CharSequence prefix; |
|
||||||
if (postForExpandedLine.getTitle().length() <= SUBJECT_LENGTH) { |
|
||||||
prefix = postForExpandedLine.getTitle(); |
|
||||||
} else { |
|
||||||
prefix = postForExpandedLine.getTitle().subSequence(0, SUBJECT_LENGTH); |
|
||||||
} |
|
||||||
|
|
||||||
String comment = postForExpandedLine.image() != null ? IMAGE_TEXT : ""; |
|
||||||
if (postForExpandedLine.comment.length() > 0) { |
|
||||||
comment += postForExpandedLine.comment; |
|
||||||
} |
|
||||||
|
|
||||||
// Replace >>132456798 with >789 to shorten the notification
|
|
||||||
comment = SHORTEN_NO_PATTERN.matcher(comment).replaceAll(">$1"); |
|
||||||
|
|
||||||
expandedLines.add(prefix + ": " + comment); |
|
||||||
} |
|
||||||
|
|
||||||
Pin targetPin = null; |
|
||||||
if (subjectPins.size() == 1) { |
|
||||||
targetPin = subjectPins.get(0); |
|
||||||
} |
|
||||||
|
|
||||||
String smallText = TextUtils.join(", ", expandedLines); |
|
||||||
return get(message, smallText, expandedLines, light, sound, peek, true, targetPin); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Create a notification with the supplied parameters. |
|
||||||
* The style of the big notification is InboxStyle, a list of text. |
|
||||||
* |
|
||||||
* @param title The title of the notification |
|
||||||
* @param smallText The content of the small notification |
|
||||||
* @param expandedLines A list of lines for the big notification, or null if not shown |
|
||||||
* @param sound Should the notification make a sound |
|
||||||
* @param peek Peek the notification into the screen |
|
||||||
* @param alertIcon Show the alert version of the icon |
|
||||||
* @param target The target pin, or null to open the pinned pane on tap |
|
||||||
*/ |
|
||||||
private Notification get(String title, String smallText, List<CharSequence> expandedLines, |
|
||||||
boolean light, boolean sound, boolean peek, boolean alertIcon, Pin target) { |
|
||||||
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", target == null ? -1 : target.id); |
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); |
|
||||||
|
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this); |
|
||||||
if (sound || peek) { |
|
||||||
builder.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE); |
|
||||||
} |
|
||||||
|
|
||||||
if (light) { |
|
||||||
long watchLed = Long.parseLong(ChanSettings.watchLed.get(), 16); |
|
||||||
if (watchLed >= 0) { |
|
||||||
builder.setLights((int) watchLed, 1000, 1000); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
builder.setContentIntent(pendingIntent); |
|
||||||
|
|
||||||
builder.setContentTitle(title); |
|
||||||
if (smallText != null) { |
|
||||||
builder.setContentText(smallText); |
|
||||||
} |
|
||||||
|
|
||||||
if (alertIcon || peek) { |
|
||||||
builder.setSmallIcon(R.drawable.ic_stat_notify_alert); |
|
||||||
builder.setPriority(NotificationCompat.PRIORITY_HIGH); |
|
||||||
} else { |
|
||||||
builder.setSmallIcon(R.drawable.ic_stat_notify); |
|
||||||
builder.setPriority(NotificationCompat.PRIORITY_MIN); |
|
||||||
} |
|
||||||
|
|
||||||
Intent pauseWatching = new Intent(this, WatchNotifier.class); |
|
||||||
pauseWatching.putExtra("pause_pins", true); |
|
||||||
|
|
||||||
PendingIntent pauseWatchingPending = PendingIntent.getService(this, 0, pauseWatching, |
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT); |
|
||||||
|
|
||||||
builder.addAction(R.drawable.ic_action_pause, getString(R.string.watch_pause_pins), |
|
||||||
pauseWatchingPending); |
|
||||||
|
|
||||||
if (expandedLines != null) { |
|
||||||
NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); |
|
||||||
for (CharSequence line : expandedLines.subList(Math.max(0, expandedLines.size() - 10), expandedLines.size())) { |
|
||||||
style.addLine(line); |
|
||||||
} |
|
||||||
style.setBigContentTitle(title); |
|
||||||
builder.setStyle(style); |
|
||||||
} |
|
||||||
|
|
||||||
return builder.build(); |
|
||||||
} |
|
||||||
|
|
||||||
private static class PostAgeComparator implements Comparator<Post> { |
|
||||||
@Override |
|
||||||
public int compare(Post lhs, Post rhs) { |
|
||||||
if (lhs.time < rhs.time) { |
|
||||||
return 1; |
|
||||||
} else if (lhs.time > rhs.time) { |
|
||||||
return -1; |
|
||||||
} else { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue