Show appicon in notifications

This commit is contained in:
fn
2020-06-18 18:03:57 +02:00
committed by GitHub
parent 91dfd881e1
commit 85c255e462
4 changed files with 131 additions and 40 deletions

View File

@@ -43,7 +43,6 @@ import com.github.gotify.Settings;
import com.github.gotify.Utils; import com.github.gotify.Utils;
import com.github.gotify.api.Api; import com.github.gotify.api.Api;
import com.github.gotify.api.ApiException; import com.github.gotify.api.ApiException;
import com.github.gotify.api.CertUtils;
import com.github.gotify.api.ClientFactory; import com.github.gotify.api.ClientFactory;
import com.github.gotify.client.ApiClient; import com.github.gotify.client.ApiClient;
import com.github.gotify.client.api.ClientApi; import com.github.gotify.client.api.ClientApi;
@@ -60,22 +59,17 @@ import com.github.gotify.messages.provider.MessageDeletion;
import com.github.gotify.messages.provider.MessageFacade; import com.github.gotify.messages.provider.MessageFacade;
import com.github.gotify.messages.provider.MessageState; import com.github.gotify.messages.provider.MessageState;
import com.github.gotify.messages.provider.MessageWithImage; import com.github.gotify.messages.provider.MessageWithImage;
import com.github.gotify.picasso.PicassoDataRequestHandler; import com.github.gotify.picasso.PicassoHandler;
import com.github.gotify.service.WebSocketService; import com.github.gotify.service.WebSocketService;
import com.github.gotify.settings.SettingsActivity; import com.github.gotify.settings.SettingsActivity;
import com.google.android.material.navigation.NavigationView; import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.BaseTransientBottomBar; import com.google.android.material.snackbar.BaseTransientBottomBar;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import com.squareup.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.Target; import com.squareup.picasso.Target;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
@@ -123,9 +117,7 @@ public class MessagesActivity extends AppCompatActivity
private boolean isLoadMore = false; private boolean isLoadMore = false;
private Integer selectAppIdOnDrawerClose = null; private Integer selectAppIdOnDrawerClose = null;
int PICASSO_CACHE_SIZE = 50 * 1024 * 1024; // 50 MB private PicassoHandler picassoHandler;
private Cache picassoCache;
private Picasso picasso;
// we need to keep the target references otherwise they get gc'ed before they can be called. // we need to keep the target references otherwise they get gc'ed before they can be called.
@SuppressWarnings("MismatchedQueryAndUpdateOfCollection") @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
@@ -139,8 +131,7 @@ public class MessagesActivity extends AppCompatActivity
Log.i("Entering " + getClass().getSimpleName()); Log.i("Entering " + getClass().getSimpleName());
settings = new Settings(this); settings = new Settings(this);
picassoCache = new Cache(new File(getCacheDir(), "picasso-cache"), PICASSO_CACHE_SIZE); picassoHandler = new PicassoHandler(this, settings);
picasso = makePicasso();
client = client =
ClientFactory.clientToken(settings.url(), settings.sslSettings(), settings.token()); ClientFactory.clientToken(settings.url(), settings.sslSettings(), settings.token());
@@ -157,7 +148,7 @@ public class MessagesActivity extends AppCompatActivity
messagesView.getContext(), layoutManager.getOrientation()); messagesView.getContext(), layoutManager.getOrientation());
ListMessageAdapter adapter = ListMessageAdapter adapter =
new ListMessageAdapter( new ListMessageAdapter(
this, settings, picasso, emptyList(), this::scheduleDeletion); this, settings, picassoHandler.get(), emptyList(), this::scheduleDeletion);
messagesView.addItemDecoration(dividerItemDecoration); messagesView.addItemDecoration(dividerItemDecoration);
messagesView.setHasFixedSize(true); messagesView.setHasFixedSize(true);
@@ -200,7 +191,7 @@ public class MessagesActivity extends AppCompatActivity
public void onRefreshAll(View view) { public void onRefreshAll(View view) {
try { try {
picassoCache.evictAll(); picassoHandler.evict();
} catch (IOException e) { } catch (IOException e) {
Log.e("Problem evicting Picasso cache", e); Log.e("Problem evicting Picasso cache", e);
} }
@@ -234,7 +225,9 @@ public class MessagesActivity extends AppCompatActivity
item.setCheckable(true); item.setCheckable(true);
Target t = Utils.toDrawable(getResources(), item::setIcon); Target t = Utils.toDrawable(getResources(), item::setIcon);
targetReferences.add(t); targetReferences.add(t);
picasso.load(Utils.resolveAbsoluteUrl(settings.url() + "/", app.getImage())) picassoHandler
.get()
.load(Utils.resolveAbsoluteUrl(settings.url() + "/", app.getImage()))
.error(R.drawable.ic_alarm) .error(R.drawable.ic_alarm)
.placeholder(R.drawable.ic_placeholder) .placeholder(R.drawable.ic_placeholder)
.resize(100, 100) .resize(100, 100)
@@ -242,20 +235,6 @@ public class MessagesActivity extends AppCompatActivity
} }
} }
private Picasso makePicasso() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.cache(picassoCache);
CertUtils.applySslSettings(builder, settings.sslSettings());
OkHttp3Downloader downloader = new OkHttp3Downloader(builder.build());
return new Picasso.Builder(this)
.addRequestHandler(new PicassoDataRequestHandler())
.downloader(downloader)
.build();
}
private void initDrawer() { private void initDrawer() {
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
navigationView.setItemIconTintList(null); navigationView.setItemIconTintList(null);
@@ -370,7 +349,7 @@ public class MessagesActivity extends AppCompatActivity
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
picasso.shutdown(); picassoHandler.get().shutdown();
} }
private void scheduleDeletion(int position, Message message, boolean listAnimation) { private void scheduleDeletion(int position, Message message, boolean listAnimation) {

View File

@@ -3,11 +3,11 @@ package com.github.gotify.messages.provider;
import com.github.gotify.client.model.Application; import com.github.gotify.client.model.Application;
import com.github.gotify.client.model.Message; import com.github.gotify.client.model.Message;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
class MessageImageCombiner { public class MessageImageCombiner {
List<MessageWithImage> combine(List<Message> messages, List<Application> applications) { List<MessageWithImage> combine(List<Message> messages, List<Application> applications) {
Map<Integer, String> appIdToImage = appIdToImage(applications); Map<Integer, String> appIdToImage = appIdToImage(applications);
@@ -26,8 +26,8 @@ class MessageImageCombiner {
return result; return result;
} }
private Map<Integer, String> appIdToImage(List<Application> applications) { public static Map<Integer, String> appIdToImage(List<Application> applications) {
Map<Integer, String> map = new HashMap<>(); Map<Integer, String> map = new ConcurrentHashMap<>();
for (Application app : applications) { for (Application app : applications) {
map.put(app.getId(), app.getImage()); map.put(app.getId(), app.getImage());
} }

View File

@@ -0,0 +1,94 @@
package com.github.gotify.picasso;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import com.github.gotify.R;
import com.github.gotify.Settings;
import com.github.gotify.Utils;
import com.github.gotify.api.Callback;
import com.github.gotify.api.CertUtils;
import com.github.gotify.api.ClientFactory;
import com.github.gotify.client.api.ApplicationApi;
import com.github.gotify.log.Log;
import com.github.gotify.messages.provider.MessageImageCombiner;
import com.squareup.picasso.OkHttp3Downloader;
import com.squareup.picasso.Picasso;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
public class PicassoHandler {
private static final int PICASSO_CACHE_SIZE = 50 * 1024 * 1024; // 50 MB
private static final String PICASSO_CACHE_SUBFOLDER = "picasso-cache";
private Context context;
private Settings settings;
private Cache picassoCache;
private Picasso picasso;
private Map<Integer, String> appIdToAppImage = new ConcurrentHashMap<>();
public PicassoHandler(Context context, Settings settings) {
this.context = context;
this.settings = settings;
picassoCache =
new Cache(
new File(context.getCacheDir(), PICASSO_CACHE_SUBFOLDER),
PICASSO_CACHE_SIZE);
picasso = makePicasso();
}
private Picasso makePicasso() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.cache(picassoCache);
CertUtils.applySslSettings(builder, settings.sslSettings());
OkHttp3Downloader downloader = new OkHttp3Downloader(builder.build());
return new Picasso.Builder(context).downloader(downloader).build();
}
public Bitmap getIcon(Integer appId) {
if (appId == -1) {
return BitmapFactory.decodeResource(context.getResources(), R.drawable.gotify);
}
try {
return picasso.load(
Utils.resolveAbsoluteUrl(
settings.url() + "/", appIdToAppImage.get(appId)))
.get();
} catch (IOException e) {
Log.e("Could not load image for notification", e);
}
return BitmapFactory.decodeResource(context.getResources(), R.drawable.gotify);
}
public void updateAppIds() {
ClientFactory.clientToken(settings.url(), settings.sslSettings(), settings.token())
.createService(ApplicationApi.class)
.getApps()
.enqueue(
Callback.call(
(apps) -> {
appIdToAppImage.clear();
appIdToAppImage.putAll(MessageImageCombiner.appIdToImage(apps));
},
(t) -> {
appIdToAppImage.clear();
}));
}
public Picasso get() {
return picasso;
}
public void evict() throws IOException {
picassoCache.evictAll();
}
}

View File

@@ -23,12 +23,14 @@ import com.github.gotify.R;
import com.github.gotify.Settings; import com.github.gotify.Settings;
import com.github.gotify.Utils; import com.github.gotify.Utils;
import com.github.gotify.api.ClientFactory; import com.github.gotify.api.ClientFactory;
import com.github.gotify.client.ApiClient;
import com.github.gotify.client.api.MessageApi; import com.github.gotify.client.api.MessageApi;
import com.github.gotify.client.model.Message; import com.github.gotify.client.model.Message;
import com.github.gotify.log.Log; import com.github.gotify.log.Log;
import com.github.gotify.log.UncaughtExceptionHandler; import com.github.gotify.log.UncaughtExceptionHandler;
import com.github.gotify.messages.Extras; import com.github.gotify.messages.Extras;
import com.github.gotify.messages.MessagesActivity; import com.github.gotify.messages.MessagesActivity;
import com.github.gotify.picasso.PicassoHandler;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@@ -46,16 +48,17 @@ public class WebSocketService extends Service {
private AtomicInteger lastReceivedMessage = new AtomicInteger(NOT_LOADED); private AtomicInteger lastReceivedMessage = new AtomicInteger(NOT_LOADED);
private MissedMessageUtil missingMessageUtil; private MissedMessageUtil missingMessageUtil;
private PicassoHandler picassoHandler;
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
settings = new Settings(this); settings = new Settings(this);
missingMessageUtil = ApiClient client =
new MissedMessageUtil( ClientFactory.clientToken(settings.url(), settings.sslSettings(), settings.token());
ClientFactory.clientToken( missingMessageUtil = new MissedMessageUtil(client.createService(MessageApi.class));
settings.url(), settings.sslSettings(), settings.token())
.createService(MessageApi.class));
Log.i("Create " + getClass().getSimpleName()); Log.i("Create " + getClass().getSimpleName());
picassoHandler = new PicassoHandler(this, settings);
} }
@Override @Override
@@ -115,6 +118,8 @@ public class WebSocketService extends Service {
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
ReconnectListener receiver = new ReconnectListener(this::doReconnect); ReconnectListener receiver = new ReconnectListener(this::doReconnect);
registerReceiver(receiver, intentFilter); registerReceiver(receiver, intentFilter);
picassoHandler.updateAppIds();
} }
private void onDisconnect() { private void onDisconnect() {
@@ -176,13 +181,15 @@ public class WebSocketService extends Service {
if (lastReceivedMessage.get() < message.getId()) { if (lastReceivedMessage.get() < message.getId()) {
lastReceivedMessage.set(message.getId()); lastReceivedMessage.set(message.getId());
} }
broadcast(message); broadcast(message);
showNotification( showNotification(
message.getId(), message.getId(),
message.getTitle(), message.getTitle(),
message.getMessage(), message.getMessage(),
message.getPriority(), message.getPriority(),
message.getExtras()); message.getExtras(),
message.getAppid());
} }
private void broadcast(Message message) { private void broadcast(Message message) {
@@ -224,6 +231,16 @@ public class WebSocketService extends Service {
private void showNotification( private void showNotification(
int id, String title, String message, long priority, Map<String, Object> extras) { int id, String title, String message, long priority, Map<String, Object> extras) {
showNotification(id, title, message, priority, extras, -1);
}
private void showNotification(
int id,
String title,
String message,
long priority,
Map<String, Object> extras,
Integer appid) {
Intent intent; Intent intent;
@@ -263,6 +280,7 @@ public class WebSocketService extends Service {
.setDefaults(Notification.DEFAULT_ALL) .setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis()) .setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_gotify) .setSmallIcon(R.drawable.ic_gotify)
.setLargeIcon(picassoHandler.getIcon(appid))
.setTicker(getString(R.string.app_name) + " - " + title) .setTicker(getString(R.string.app_name) + " - " + title)
.setGroup(NotificationSupport.Group.MESSAGES) .setGroup(NotificationSupport.Group.MESSAGES)
.setContentTitle(title) .setContentTitle(title)