Sadly ,Notification.setLatestEventInfo() is removed in API Level 23….

The base class Notification was introduced in API level 1, from the very beginning. Back then you would create your notifications by creating a new instance via the constructor and then set the various properties on it.

If you wanted to display further details on the notification you would call

setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent)

In API level 11 aka “Honeycomb” Android introduced the Notification.Builder API which completely encapsulates the configuration step of a notification.
setLatestEventInfo() was consequently deprecated in the process.

Using it was fine, until they dropped it completely in Android 6.0. So now you can’t set your notification’s event info this way anymore. And you can’t use the Builder API in 2.3 since it’s not available yet.

To make it a bit worse, the builder API introduced in 11 used the uncommon method name getNotification() to build the notification, this was later corrected in 16 to build() as it is in all other builder APIs.

This means that if you want to have notifications with custom detail views from Android 2.3 (or earlier) until 6.0 you now have two choices:

Option A. The easy but heavy

The easy way to resolve this is to use the support-v4 library which provides you with a back port of the Notification.Builder API. You then use this exclusively for all your notifications and let it take care of the version specific stuff under the hood. This is a viable option if:

  • your app already depends on the support-v4 library or
  • you don’t care that support-v4 is about one of the largest libraries to include.

If however you’re building something that should have absolutely no external dependencies to be as small as it can possibly be, like say… a crash reporting SDK which is included in millions of apps, you might look for something else:

Option B. The light but painful

This way you fall back to old Java tricks of trade so your code paths dependent on old functionality are only executed at runtime. Reflection is your friend.

This helper class combines all the necessary steps:

public class NotificationUtil {    public static Notification createNotification(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {        Notification notification;        if (isNotificationBuilderSupported()) {            notification = buildNotificationWithBuilder(context, pendingIntent, title, text, iconId);        } else {            notification = buildNotificationPreHoneycomb(context, pendingIntent, title, text, iconId);        }        return notification;    }    public static boolean isNotificationBuilderSupported() {        try {            return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) && Class.forName("android.app.Notification.Builder") != null;        } catch (ClassNotFoundException e) {            return false;        }    }    @SuppressWarnings("deprecation")    private static Notification buildNotificationPreHoneycomb(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {        Notification notification = new Notification(iconId, "", System.currentTimeMillis());        try {            // try to call "setLatestEventInfo" if available            Method m = notification.getClass().getMethod("setLatestEventInfo", Context.class, CharSequence.class, CharSequence.class, PendingIntent.class);            m.invoke(notification, context, title, text, pendingIntent);        } catch (Exception e) {            // do nothing        }        return notification;    }    @TargetApi(Build.VERSION_CODES.HONEYCOMB)    @SuppressWarnings("deprecation")    private static Notification buildNotificationWithBuilder(Context context, PendingIntent pendingIntent, String title, String text, int iconId) {        android.app.Notification.Builder builder = new android.app.Notification.Builder(context)            .setContentTitle(title)            .setContentText(text)            .setContentIntent(pendingIntent)            .setSmallIcon(iconId);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {            return builder.build();        } else {            return builder.getNotification();        }    }}
  • It checks whether you’re on 3.0 or later and also if the Notification.Builder class is available at runtime.
  • If the builder is available it will use that - it’ll call build() if you’re running later than Jelly Bean or getNotification() from 11 through 15. By addressing the builder class directly without an import this will run on pre 3.0 devices as well.
  • Pre 3.0 it will use the classic Notification API and call setLatestEventInfo() via Reflection.
  • The annotations are in place so the compiler won’t complain or bug you.

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. Android权限列表permission说明 [轉載]
  2. android 屏幕适配方案第二版
  3. 性能调优工具TraceView
  4. android仿知乎标题栏随ScrollView滚动变
  5. Android低功耗蓝牙应用开发获取的服务UUI
  6. Android(安卓)创建DBHelper类
  7. 为PhoneGap写一个android插件
  8. Android-工作遭遇-URLConnection原生请求
  9. Android与JNI(一)
  10. Google是怎样控制Android厂商的?