/******************************************************************************* * This file is part of RedReader. * * RedReader 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. * * RedReader 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 RedReader. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package org.quantumbadger.redreader.receivers; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; import org.quantumbadger.redreader.R; import org.quantumbadger.redreader.account.RedditAccount; import org.quantumbadger.redreader.account.RedditAccountManager; import org.quantumbadger.redreader.activities.BugReportActivity; import org.quantumbadger.redreader.activities.InboxListingActivity; import org.quantumbadger.redreader.cache.CacheManager; import org.quantumbadger.redreader.cache.CacheRequest; import org.quantumbadger.redreader.cache.downloadstrategy.DownloadStrategyAlways; import org.quantumbadger.redreader.common.Constants; import org.quantumbadger.redreader.common.PrefsUtility; import org.quantumbadger.redreader.jsonwrap.JsonBufferedArray; import org.quantumbadger.redreader.jsonwrap.JsonBufferedObject; import org.quantumbadger.redreader.jsonwrap.JsonValue; import org.quantumbadger.redreader.reddit.things.RedditComment; import org.quantumbadger.redreader.reddit.things.RedditMessage; import org.quantumbadger.redreader.reddit.things.RedditThing; import java.net.URI; import java.util.UUID; public class NewMessageChecker extends BroadcastReceiver { private static final String PREFS_SAVED_MESSAGE_ID = "LastMessageId"; private static final String PREFS_SAVED_MESSAGE_TIMESTAMP = "LastMessageTimestamp"; public void onReceive(Context context, Intent intent) { checkForNewMessages(context); } public static void checkForNewMessages(Context context) { Log.i("RedReader", "Checking for new messages."); boolean notificationsEnabled = PrefsUtility.pref_behaviour_notifications(context, PreferenceManager.getDefaultSharedPreferences(context)); if (!notificationsEnabled) return; final RedditAccount user = RedditAccountManager.getInstance(context).getDefaultAccount(); if(user.isAnonymous()) { return; } final CacheManager cm = CacheManager.getInstance(context); final URI url = Constants.Reddit.getUri("/message/unread.json?limit=2"); final CacheRequest request = new CacheRequest( url, user, null, Constants.Priority.API_INBOX_LIST, 0, DownloadStrategyAlways.INSTANCE, Constants.FileType.INBOX_LIST, CacheRequest.DOWNLOAD_QUEUE_REDDIT_API, true, true, context) { @Override protected void onDownloadNecessary() {} @Override protected void onDownloadStarted() {} @Override protected void onCallbackException(final Throwable t) { BugReportActivity.handleGlobalError(context, t); } @Override protected void onFailure(final @CacheRequest.RequestFailureType int type, final Throwable t, final Integer status, final String readableMessage) { Log.e("NewMessageChecker", "Request failed", t); } @Override protected void onProgress(final boolean authorizationInProgress, final long bytesRead, final long totalBytes) {} @Override protected void onSuccess(final CacheManager.ReadableCacheFile cacheFile, final long timestamp, final UUID session, final boolean fromCache, final String mimetype) {} @Override public void onJsonParseStarted(final JsonValue value, final long timestamp, final UUID session, final boolean fromCache) { try { final JsonBufferedObject root = value.asObject(); final JsonBufferedObject data = root.getObject("data"); final JsonBufferedArray children = data.getArray("children"); children.join(); final int messageCount = children.getCurrentItemCount(); if(messageCount < 1) { return; } final RedditThing thing = children.get(0).asObject(RedditThing.class); String title; final String text = context.getString(R.string.notification_message_action); final String messageID; final long messageTimestamp; switch(thing.getKind()) { case COMMENT: { final RedditComment comment = thing.asComment(); title = context.getString(R.string.notification_comment, comment.author); messageID = comment.name; messageTimestamp = comment.created_utc; break; } case MESSAGE: { final RedditMessage message = thing.asMessage(); title =context.getString(R.string.notification_message, message.author); messageID = message.name; messageTimestamp = message.created_utc; break; } default: { throw new RuntimeException("Unknown item in list."); } } // Check if the previously saved message is the same as the one we just received final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); final String oldMessageId = prefs.getString(PREFS_SAVED_MESSAGE_ID, ""); final long oldMessageTimestamp = prefs.getLong(PREFS_SAVED_MESSAGE_TIMESTAMP, 0); if(oldMessageId == null || (!messageID.equals(oldMessageId) && oldMessageTimestamp <= messageTimestamp)) { prefs.edit() .putString(PREFS_SAVED_MESSAGE_ID, messageID) .putLong(PREFS_SAVED_MESSAGE_TIMESTAMP, messageTimestamp) .apply(); if(messageCount > 1) { title = context.getString(R.string.notification_message_multiple); } createNotification(title, text, context); } } catch(Throwable t) { notifyFailure(CacheRequest.REQUEST_FAILURE_PARSE, t, null, "Parse failure"); } } }; cm.makeRequest(request); } private static void createNotification(String title, String text, Context context) { final Notification.Builder notification = new Notification.Builder(context) .setSmallIcon(R.drawable.icon_notif) .setContentTitle(title) .setContentText(text) .setAutoCancel(true); final Intent intent = new Intent(context, InboxListingActivity.class); notification.setContentIntent(PendingIntent.getActivity(context, 0, intent, 0)); final NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); nm.notify(0, notification.getNotification()); } }