diff --git a/src/de/duenndns/ssl/MemorizingTrustManager.java b/src/de/duenndns/ssl/MemorizingTrustManager.java index 1d76750..50d152c 100644 --- a/src/de/duenndns/ssl/MemorizingTrustManager.java +++ b/src/de/duenndns/ssl/MemorizingTrustManager.java @@ -42,6 +42,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.security.cert.*; import java.security.KeyStore; import java.security.KeyStoreException; @@ -567,25 +569,70 @@ private String hostNameMessage(X509Certificate cert, String hostname) { return si.toString(); } - void startActivityNotification(Intent intent, int decisionId, String certName) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - LOGGER.warning("Can't fallback showing a notification. Android API level to low, requires at least 11 but was " - + Build.VERSION.SDK_INT); - return; + /** + * Reflectively call + * Notification.setLatestEventInfo(Context, CharSequence, CharSequence, PendingIntent) + * since it was remove in Android API level 23. + * + * @param notification + * @param context + * @param mtmNotification + * @param certName + * @param call + */ + private static void setLatestEventInfoReflective(Notification notification, + Context context, CharSequence mtmNotification, + CharSequence certName, PendingIntent call) { + Method setLatestEventInfo; + try { + setLatestEventInfo = notification.getClass().getMethod( + "setLatestEventInfo", Context.class, CharSequence.class, + CharSequence.class, PendingIntent.class); + } catch (NoSuchMethodException e) { + throw new IllegalStateException(e); } - PendingIntent call = PendingIntent.getActivity(master, 0, intent, 0); - final Notification n = new Notification.Builder(master) - .setContentTitle(master.getString(R.string.mtm_notification)) + try { + setLatestEventInfo.invoke(notification, context, mtmNotification, + certName, call); + } catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + throw new IllegalStateException(e); + } + } + + void startActivityNotification(Intent intent, int decisionId, String certName) { + Notification notification; + final PendingIntent call = PendingIntent.getActivity(master, 0, intent, + 0); + final String mtmNotification = master.getString(R.string.mtm_notification); + final long currentMillis = System.currentTimeMillis(); + final Context context = master.getApplicationContext(); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + @SuppressWarnings("deprecation") + // Use an extra identifier for the legacy build notification, so + // that we suppress the deprecation warning. We will latter assign + // this to the correct identifier. + Notification n = new Notification(android.R.drawable.ic_lock_lock, + mtmNotification, + currentMillis); + setLatestEventInfoReflective(n, context, mtmNotification, certName, call); + n.flags |= Notification.FLAG_AUTO_CANCEL; + notification = n; + } else { + notification = new Notification.Builder(master) + .setContentTitle(mtmNotification) .setContentText(certName) .setTicker(certName) .setSmallIcon(android.R.drawable.ic_lock_lock) - .setWhen(System.currentTimeMillis()) + .setWhen(currentMillis) .setContentIntent(call) .setAutoCancel(true) .build(); + } - notificationManager.notify(NOTIFICATION_ID + decisionId, n); + notificationManager.notify(NOTIFICATION_ID + decisionId, notification); } /**