diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainApplication.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainApplication.java index 907bccef4..4a6849194 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainApplication.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/MainApplication.java @@ -17,6 +17,8 @@ import android.app.Application; import android.os.StrictMode; import com.evernote.android.job.JobManager; import fr.gouv.etalab.mastodon.jobs.ApplicationJob; +import fr.gouv.etalab.mastodon.jobs.HomeTimelineSyncJob; +import fr.gouv.etalab.mastodon.jobs.NotificationsSyncJob; import fr.gouv.etalab.mastodon.jobs.StreamingSyncJob; /** @@ -32,6 +34,8 @@ public class MainApplication extends Application{ super.onCreate(); JobManager.create(this).addJobCreator(new ApplicationJob()); JobManager.instance().getConfig().setVerbose(false); + NotificationsSyncJob.schedule(false); + HomeTimelineSyncJob.schedule(false); StreamingSyncJob.schedule(false); StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java index f40609d04..e937253ac 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java @@ -235,6 +235,9 @@ public class Helper { //Refresh job + //Refresh job + public static final int MINUTES_BETWEEN_NOTIFICATIONS_REFRESH = 15; + public static final int MINUTES_BETWEEN_HOME_TIMELINE = 30; public static final int MINUTES_BETWEEN_STREAMING_CHECK_ALIVE = 15; //Intent diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java index 61b7159bf..2908b9dcd 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/ApplicationJob.java @@ -26,6 +26,10 @@ public class ApplicationJob implements JobCreator { @Override public Job create(String tag) { switch (tag) { + case NotificationsSyncJob.NOTIFICATION_REFRESH: + return new NotificationsSyncJob(); + case HomeTimelineSyncJob.HOME_TIMELINE: + return new HomeTimelineSyncJob(); case StreamingSyncJob.STREAMING: return new StreamingSyncJob(); case ScheduledTootsSyncJob.SCHEDULED_TOOT: diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java new file mode 100644 index 000000000..5ec34f4bc --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/HomeTimelineSyncJob.java @@ -0,0 +1,204 @@ +package fr.gouv.etalab.mastodon.jobs; +/* Copyright 2017 Thomas Schneider + * + * This file is a part of Mastalab + * + * 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. + * + * Mastalab 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 Mastalab; if not, + * see . */ + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.sqlite.SQLiteDatabase; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.view.View; + +import com.evernote.android.job.Job; +import com.evernote.android.job.JobManager; +import com.evernote.android.job.JobRequest; +import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; +import com.nostra13.universalimageloader.core.DisplayImageOptions; +import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; +import com.nostra13.universalimageloader.core.assist.FailReason; +import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer; +import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; + +import java.io.File; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import fr.gouv.etalab.mastodon.activities.MainActivity; +import fr.gouv.etalab.mastodon.asynctasks.RetrieveHomeTimelineServiceAsyncTask; +import fr.gouv.etalab.mastodon.client.APIResponse; +import fr.gouv.etalab.mastodon.client.Entities.Account; +import fr.gouv.etalab.mastodon.client.Entities.Status; +import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader; +import fr.gouv.etalab.mastodon.helper.Helper; +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveHomeTimelineServiceInterface; +import fr.gouv.etalab.mastodon.sqlite.AccountDAO; +import fr.gouv.etalab.mastodon.sqlite.Sqlite; +import mastodon.etalab.gouv.fr.mastodon.R; + +import static fr.gouv.etalab.mastodon.helper.Helper.HOME_TIMELINE_INTENT; +import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION; +import static fr.gouv.etalab.mastodon.helper.Helper.PREF_KEY_ID; +import static fr.gouv.etalab.mastodon.helper.Helper.canNotify; +import static fr.gouv.etalab.mastodon.helper.Helper.notify_user; + + +/** + * Created by Thomas on 20/05/2017. + * Notifications for home timeline job + */ + +public class HomeTimelineSyncJob extends Job implements OnRetrieveHomeTimelineServiceInterface{ + + static final String HOME_TIMELINE = "home_timeline"; + + @NonNull + @Override + protected Result onRunJob(Params params) { + callAsynchronousTask(); + return Result.SUCCESS; + } + + + public static int schedule(boolean updateCurrent){ + + Set jobRequests = JobManager.instance().getAllJobRequestsForTag(HOME_TIMELINE); + if (!jobRequests.isEmpty() && !updateCurrent) { + return jobRequests.iterator().next().getJobId(); + } + return new JobRequest.Builder(HomeTimelineSyncJob.HOME_TIMELINE) + .setPeriodic(TimeUnit.MINUTES.toMillis(Helper.MINUTES_BETWEEN_HOME_TIMELINE), TimeUnit.MINUTES.toMillis(5)) + .setPersisted(true) + .setUpdateCurrent(updateCurrent) + .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) + .setRequirementsEnforced(false) + .build() + .schedule(); + } + + + /** + * Task in background starts here. + */ + private void callAsynchronousTask() { + + if( !canNotify(getContext())) + return; + final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + boolean notif_hometimeline = sharedpreferences.getBoolean(Helper.SET_NOTIF_HOMETIMELINE, true); + //User disagree with home timeline refresh + if( !notif_hometimeline) + return; //Nothing is done + //No account connected, the service is stopped + if(!Helper.isLoggedIn(getContext())) + return; + SQLiteDatabase db = Sqlite.getInstance(getContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + //If an Internet connection and user agrees with notification refresh + //If WIFI only and on WIFI OR user defined any connections to use the service. + if(!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(getContext())) { + List accounts = new AccountDAO(getContext(),db).getAllAccount(); + //It means there is no user in DB. + if( accounts == null ) + return; + //Retrieve users in db that owner has. + for (Account account: accounts) { + String since_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + account.getId(), null); + new RetrieveHomeTimelineServiceAsyncTask(getContext(), account.getInstance(), account.getToken(), since_id, account.getAcct(), account.getId(), HomeTimelineSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + + } + } + } + + + @Override + public void onRetrieveHomeTimelineService(APIResponse apiResponse, String acct, String userId) { + List statuses = apiResponse.getStatuses(); + if( apiResponse.getError() != null || statuses == null || statuses.size() == 0) + return; + final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + + final String max_id = sharedpreferences.getString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, null); + if( max_id == null){ + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, apiResponse.getSince_id()); + editor.apply(); + return; + } + //No previous notifications in cache, so no notification will be sent + String message; + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, apiResponse.getSince_id()); + editor.apply(); + for(Status status: statuses){ + //The notification associated to max_id is discarded as it is supposed to have already been sent + //Also, if the toot comes from the owner, we will avoid to warn him/her... + if( (status.getId().equals(max_id)) || (acct != null && status.getAccount().getAcct().trim().equals(acct.trim()) )) + continue; + String notificationUrl = status.getAccount().getAvatar(); + + if(statuses.size() > 0 ) + message = getContext().getResources().getQuantityString(R.plurals.other_notif_hometimeline, statuses.size(), statuses.size()); + else + message = ""; + final Intent intent = new Intent(getContext(), MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK ); + intent.putExtra(INTENT_ACTION, HOME_TIMELINE_INTENT); + intent.putExtra(PREF_KEY_ID, userId); + long notif_id = Long.parseLong(userId); + final int notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2); + + if( notificationUrl != null){ + ImageLoader imageLoaderNoty = ImageLoader.getInstance(); + File cacheDir = new File(getContext().getCacheDir(), getContext().getString(R.string.app_name)); + ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getContext()) + .imageDownloader(new PatchBaseImageDownloader(getContext())) + .threadPoolSize(5) + .threadPriority(Thread.MIN_PRIORITY + 3) + .denyCacheImageMultipleSizesInMemory() + .diskCache(new UnlimitedDiskCache(cacheDir)) + .build(); + imageLoaderNoty.init(config); + DisplayImageOptions options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false) + .cacheOnDisk(true).resetViewBeforeLoading(true).build(); + final String finalMessage = message; + String title; + if( status.getAccount().getDisplay_name() != null && status.getAccount().getDisplay_name().length() > 0 ) + title = getContext().getResources().getString(R.string.notif_pouet, Helper.shortnameToUnicode(status.getAccount().getDisplay_name(), true)); + else + title = getContext().getResources().getString(R.string.notif_pouet, status.getAccount().getUsername()); + final String finalTitle = title; + + imageLoaderNoty.loadImage(notificationUrl, options, new SimpleImageLoadingListener(){ + @Override + public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { + super.onLoadingComplete(imageUri, view, loadedImage); + notify_user(getContext(), intent, notificationId, loadedImage, finalTitle, finalMessage); + } + @Override + public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason){ + notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(), + R.drawable.mastodonlogo), finalTitle, finalMessage); + }}); + + } + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java new file mode 100644 index 000000000..b2ece6425 --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/jobs/NotificationsSyncJob.java @@ -0,0 +1,271 @@ +package fr.gouv.etalab.mastodon.jobs; +/* Copyright 2017 Thomas Schneider + * + * This file is a part of Mastalab + * + * 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. + * + * Mastalab 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 Mastalab; if not, + * see . */ + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.sqlite.SQLiteDatabase; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.view.View; + +import com.evernote.android.job.Job; +import com.evernote.android.job.JobManager; +import com.evernote.android.job.JobRequest; +import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache; +import com.nostra13.universalimageloader.core.DisplayImageOptions; +import com.nostra13.universalimageloader.core.ImageLoader; +import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; +import com.nostra13.universalimageloader.core.assist.FailReason; +import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer; +import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; + +import java.io.File; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import fr.gouv.etalab.mastodon.activities.MainActivity; +import fr.gouv.etalab.mastodon.client.APIResponse; +import fr.gouv.etalab.mastodon.client.PatchBaseImageDownloader; +import fr.gouv.etalab.mastodon.helper.Helper; +import mastodon.etalab.gouv.fr.mastodon.R; +import fr.gouv.etalab.mastodon.asynctasks.RetrieveNotificationsAsyncTask; +import fr.gouv.etalab.mastodon.client.Entities.Account; +import fr.gouv.etalab.mastodon.client.Entities.Notification; +import fr.gouv.etalab.mastodon.interfaces.OnRetrieveNotificationsInterface; +import fr.gouv.etalab.mastodon.sqlite.AccountDAO; +import fr.gouv.etalab.mastodon.sqlite.Sqlite; + +import static fr.gouv.etalab.mastodon.helper.Helper.INTENT_ACTION; +import static fr.gouv.etalab.mastodon.helper.Helper.NOTIFICATION_INTENT; +import static fr.gouv.etalab.mastodon.helper.Helper.PREF_KEY_ID; +import static fr.gouv.etalab.mastodon.helper.Helper.canNotify; +import static fr.gouv.etalab.mastodon.helper.Helper.notify_user; + + +/** + * Created by Thomas on 29/04/2017. + * Notifications refresh job + */ + +public class NotificationsSyncJob extends Job implements OnRetrieveNotificationsInterface{ + + static final String NOTIFICATION_REFRESH = "job_notification"; + + @NonNull + @Override + protected Result onRunJob(Params params) { + //Code refresh here + callAsynchronousTask(); + return Result.SUCCESS; + } + + + public static int schedule(boolean updateCurrent){ + + Set jobRequests = JobManager.instance().getAllJobRequestsForTag(NOTIFICATION_REFRESH); + if (!jobRequests.isEmpty() && !updateCurrent) { + return jobRequests.iterator().next().getJobId(); + } + + return new JobRequest.Builder(NotificationsSyncJob.NOTIFICATION_REFRESH) + .setPeriodic(TimeUnit.MINUTES.toMillis(Helper.MINUTES_BETWEEN_NOTIFICATIONS_REFRESH), TimeUnit.MINUTES.toMillis(5)) + .setPersisted(true) + .setUpdateCurrent(updateCurrent) + .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) + .setRequirementsEnforced(false) + .build() + .schedule(); + } + + + + /** + * Task in background starts here. + */ + private void callAsynchronousTask() { + if( !canNotify(getContext())) + return; + SQLiteDatabase db = Sqlite.getInstance(getContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + //If an Internet connection and user agrees with notification refresh + final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + //Check which notifications the user wants to see + boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true); + boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true); + boolean notif_ask = sharedpreferences.getBoolean(Helper.SET_NOTIF_ASK, true); + boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true); + boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true); + //User disagree with all notifications + if( !notif_follow && !notif_add && !notif_ask && !notif_mention && !notif_share) + return; //Nothing is done + //No account connected, the service is stopped + if(!Helper.isLoggedIn(getContext())) + return; + //If WIFI only and on WIFI OR user defined any connections to use the service. + if(!sharedpreferences.getBoolean(Helper.SET_WIFI_ONLY, false) || Helper.isOnWIFI(getContext())) { + List accounts = new AccountDAO(getContext(),db).getAllAccount(); + //It means there is no user in DB. + if( accounts == null ) + return; + //Retrieve users in db that owner has. + for (Account account: accounts) { + String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + account.getId(), null); + new RetrieveNotificationsAsyncTask(getContext(), account.getInstance(), account.getToken(), max_id, account.getAcct(), account.getId(), NotificationsSyncJob.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + } + } + + + + @Override + public void onRetrieveNotifications(APIResponse apiResponse, String acct, String userId, boolean refreshData) { + List notifications = apiResponse.getNotifications(); + if( apiResponse.getError() != null || notifications == null || notifications.size() == 0) + return; + Bitmap icon_notification = null; + final SharedPreferences sharedpreferences = getContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); + boolean notif_follow = sharedpreferences.getBoolean(Helper.SET_NOTIF_FOLLOW, true); + boolean notif_add = sharedpreferences.getBoolean(Helper.SET_NOTIF_ADD, true); + boolean notif_mention = sharedpreferences.getBoolean(Helper.SET_NOTIF_MENTION, true); + boolean notif_share = sharedpreferences.getBoolean(Helper.SET_NOTIF_SHARE, true); + final String max_id = sharedpreferences.getString(Helper.LAST_NOTIFICATION_MAX_ID + userId, null); + if( max_id == null){ + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, apiResponse.getSince_id()); + editor.apply(); + return; + } + + //No previous notifications in cache, so no notification will be sent + int newFollows = 0; + int newAdds = 0; + int newAsks = 0; + int newMentions = 0; + int newShare = 0; + String notificationUrl = null; + String title = null; + final String message; + for(Notification notification: notifications){ + //The notification associated to max_id is discarded as it is supposed to have already been sent + if( max_id != null && notification.getId().equals(max_id)) + continue; + switch (notification.getType()){ + case "mention": + if(notif_mention){ + newMentions++; + if( notificationUrl == null){ + notificationUrl = notification.getAccount().getAvatar(); + if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 ) + title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getContext().getString(R.string.notif_mention)); + else + title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_mention)); + } + } + break; + case "reblog": + if(notif_share){ + newShare++; + if( notificationUrl == null){ + notificationUrl = notification.getAccount().getAvatar(); + if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 ) + title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getContext().getString(R.string.notif_reblog)); + else + title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_reblog)); + + } + } + break; + case "favourite": + if(notif_add){ + newAdds++; + if( notificationUrl == null){ + notificationUrl = notification.getAccount().getAvatar(); + if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 ) + title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getContext().getString(R.string.notif_favourite)); + else + title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_favourite)); + } + } + break; + case "follow": + if(notif_follow){ + newFollows++; + if( notificationUrl == null){ + notificationUrl = notification.getAccount().getAvatar(); + if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0 ) + title = String.format("@%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),getContext().getString(R.string.notif_follow)); + else + title = String.format("@%s %s", notification.getAccount().getUsername(),getContext().getString(R.string.notif_follow)); + } + } + break; + default: + } + } + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, apiResponse.getSince_id()); + editor.apply(); + int allNotifCount = newFollows + newAdds + newAsks + newMentions + newShare; + if( allNotifCount > 0){ + //Some others notification + int other = allNotifCount -1; + if(other > 0 ) + message = getContext().getResources().getQuantityString(R.plurals.other_notifications, other, other); + else + message = ""; + final Intent intent = new Intent(getContext(), MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK ); + intent.putExtra(INTENT_ACTION, NOTIFICATION_INTENT); + intent.putExtra(PREF_KEY_ID, userId); + long notif_id = Long.parseLong(userId); + final int notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1); + + if( notificationUrl != null && icon_notification == null){ + ImageLoader imageLoaderNoty = ImageLoader.getInstance(); + File cacheDir = new File(getContext().getCacheDir(), getContext().getString(R.string.app_name)); + ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getContext()) + .imageDownloader(new PatchBaseImageDownloader(getContext())) + .threadPoolSize(5) + .threadPriority(Thread.MIN_PRIORITY + 3) + .denyCacheImageMultipleSizesInMemory() + .diskCache(new UnlimitedDiskCache(cacheDir)) + .build(); + imageLoaderNoty.init(config); + DisplayImageOptions options = new DisplayImageOptions.Builder().displayer(new SimpleBitmapDisplayer()).cacheInMemory(false) + .cacheOnDisk(true).resetViewBeforeLoading(true).build(); + + final String finalTitle = title; + imageLoaderNoty.loadImage(notificationUrl, options, new SimpleImageLoadingListener(){ + @Override + public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { + super.onLoadingComplete(imageUri, view, loadedImage); + if( max_id != null) + notify_user(getContext(), intent, notificationId, loadedImage, finalTitle, message); + } + @Override + public void onLoadingFailed(java.lang.String imageUri, android.view.View view, FailReason failReason){ + if( max_id != null) + notify_user(getContext(), intent, notificationId, BitmapFactory.decodeResource(getContext().getResources(), + R.drawable.mastodonlogo), finalTitle, message); + }}); + } + + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/services/StreamingService.java b/app/src/main/java/fr/gouv/etalab/mastodon/services/StreamingService.java index b61c7bda8..df7aa76fd 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/services/StreamingService.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/services/StreamingService.java @@ -287,7 +287,9 @@ public class StreamingService extends Service implements OnRetrieveStreamingInte intent.putExtra(PREF_KEY_ID, userId); long notif_id = Long.parseLong(userId); notificationId = ((notif_id + 1) > 2147483647) ? (int) (2147483647 - notif_id - 1) : (int) (notif_id + 1); - + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putString(Helper.LAST_NOTIFICATION_MAX_ID + userId, notification.getId()); + editor.apply(); }else if(event == StreamingUserAsyncTask.EventStreaming.UPDATE ){ //lastePreviousContent contains the content of the last notification, if it was a mention it will avoid to push two notifications @@ -304,6 +306,9 @@ public class StreamingService extends Service implements OnRetrieveStreamingInte intent.putExtra(PREF_KEY_ID, userId); long notif_id = Long.parseLong(userId); notificationId = ((notif_id + 2) > 2147483647) ? (int) (2147483647 - notif_id - 2) : (int) (notif_id + 2); + SharedPreferences.Editor editor = sharedpreferences.edit(); + editor.putString(Helper.LAST_HOMETIMELINE_MAX_ID + userId, status.getId()); + editor.apply(); } } if( notify){