2
0
mirror of https://github.com/KDE/kdeconnect-android synced 2025-08-30 21:55:10 +00:00

Added Notification icons

Some additional fields are transferred in a network package. This includes
the payloads MD5 checksum (which determines where the image file is stored)
and the notifications title and text (which allows more flexibility in the
desktop app, ticker is still transferred for compatibility)

REVIEW: 130033
This commit is contained in:
Nicolas Fella
2017-04-13 21:26:26 +02:00
committed by Albert Vaca
parent dbf069cf85
commit 2cdf743bba

View File

@@ -26,6 +26,7 @@ import android.app.AlertDialog;
import android.app.Notification; import android.app.Notification;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
@@ -39,15 +40,19 @@ import org.kde.kdeconnect.UserInterface.MaterialActivity;
import org.kde.kdeconnect.UserInterface.SettingsActivity; import org.kde.kdeconnect.UserInterface.SettingsActivity;
import org.kde.kdeconnect_tp.R; import org.kde.kdeconnect_tp.R;
import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NotificationsPlugin extends Plugin implements NotificationReceiver.NotificationListener { public class NotificationsPlugin extends Plugin implements NotificationReceiver.NotificationListener {
public final static String PACKAGE_TYPE_NOTIFICATION = "kdeconnect.notification"; public final static String PACKAGE_TYPE_NOTIFICATION = "kdeconnect.notification";
public final static String PACKAGE_TYPE_NOTIFICATION_REQUEST = "kdeconnect.notification.request"; public final static String PACKAGE_TYPE_NOTIFICATION_REQUEST = "kdeconnect.notification.request";
/*
private boolean sendIcons = false; private boolean sendIcons = true;
*/
@Override @Override
public String getDisplayName() { public String getDisplayName() {
@@ -155,6 +160,8 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
String packageName = statusBarNotification.getPackageName(); String packageName = statusBarNotification.getPackageName();
String appName = AppsHelper.appNameLookup(context, packageName); String appName = AppsHelper.appNameLookup(context, packageName);
if ("com.facebook.orca".equals(packageName) && if ("com.facebook.orca".equals(packageName) &&
(statusBarNotification.getId() == 10012) && (statusBarNotification.getId() == 10012) &&
"Messenger".equals(appName) && "Messenger".equals(appName) &&
@@ -178,28 +185,35 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
np.set("silent", true); np.set("silent", true);
np.set("requestAnswer", true); //For compatibility with old desktop versions of KDE Connect that don't support "silent" np.set("requestAnswer", true); //For compatibility with old desktop versions of KDE Connect that don't support "silent"
} }
/*
if (sendIcons) { if (sendIcons) {
try { try {
Drawable drawableAppIcon = AppsHelper.appIconLookup(context, packageName); Bitmap appIcon = notification.largeIcon;
Bitmap appIcon = ImagesHelper.drawableToBitmap(drawableAppIcon);
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); if (appIcon != null) {
if (appIcon.getWidth() > 128) { ByteArrayOutputStream outStream = new ByteArrayOutputStream();
appIcon = Bitmap.createScaledBitmap(appIcon, 96, 96, true); if (appIcon.getWidth() > 128) {
appIcon = Bitmap.createScaledBitmap(appIcon, 96, 96, true);
}
appIcon.compress(Bitmap.CompressFormat.PNG, 90, outStream);
byte[] bitmapData = outStream.toByteArray();
np.setPayload(bitmapData);
np.set("payloadHash", getChecksum(bitmapData));
} }
appIcon.compress(Bitmap.CompressFormat.PNG, 90, outStream); } catch(Exception e){
byte[] bitmapData = outStream.toByteArray();
np.setPayload(bitmapData);
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Log.e("NotificationsPlugin", "Error retrieving icon"); Log.e("NotificationsPlugin", "Error retrieving icon");
} }
} }
*/
np.set("id", key); np.set("id", key);
np.set("appName", appName == null? packageName : appName); np.set("appName", appName == null? packageName : appName);
np.set("isClearable", statusBarNotification.isClearable()); np.set("isClearable", statusBarNotification.isClearable());
np.set("ticker", getTickerText(notification)); np.set("ticker", getTickerText(notification));
np.set("title", getNotificationTitle(notification));
np.set("text", getNotificationText(notification));
np.set("time", Long.toString(statusBarNotification.getPostTime())); np.set("time", Long.toString(statusBarNotification.getPostTime()));
if (requestAnswer) { if (requestAnswer) {
np.set("requestAnswer", true); np.set("requestAnswer", true);
@@ -209,6 +223,50 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
device.sendPackage(np); device.sendPackage(np);
} }
private String getNotificationTitle(Notification notification) {
final String TITLE_KEY = "android.title";
final String TEXT_KEY = "android.text";
String title = "";
if(notification != null) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
Bundle extras = notification.extras;
title = extras.getCharSequence(TITLE_KEY).toString();
} catch(Exception e) {
Log.w("NotificationPlugin","problem parsing notification extras for " + notification.tickerText);
e.printStackTrace();
}
}
}
//TODO Add compat for under Kitkat devices
return title;
}
private String getNotificationText(Notification notification) {
final String TEXT_KEY = "android.text";
String text = "";
if(notification != null) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
Bundle extras = notification.extras;
Object extraTextExtra = extras.get(TEXT_KEY);
if (extraTextExtra != null) text = extraTextExtra.toString();
} catch(Exception e) {
Log.w("NotificationPlugin","problem parsing notification extras for " + notification.tickerText);
e.printStackTrace();
}
}
}
//TODO Add compat for under Kitkat devices
return text;
}
/** /**
* Returns the ticker text of the notification. * Returns the ticker text of the notification.
@@ -230,7 +288,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
if (extraTextExtra != null) extraText = extraTextExtra.toString(); if (extraTextExtra != null) extraText = extraTextExtra.toString();
if (extraTitle != null && extraText != null && !extraText.isEmpty()) { if (extraTitle != null && extraText != null && !extraText.isEmpty()) {
ticker = extraTitle + " " + extraText; ticker = extraTitle + ": " + extraText;
} else if (extraTitle != null) { } else if (extraTitle != null) {
ticker = extraTitle; ticker = extraTitle;
} else if (extraText != null) { } else if (extraText != null) {
@@ -398,4 +456,29 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
} }
return result; return result;
} }
public String getChecksum(byte[] data){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data);
return bytesToHex(md.digest());
} catch (NoSuchAlgorithmException e) {
Log.e("KDEConenct", "Error while generating checksum", e);
}
return null;
}
public static String bytesToHex(byte[] bytes) {
char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars).toLowerCase();
}
} }