以下一段是弹系统通知
Notification notification = new Notification();
Intent intent = new Intent();
PendingIntent pendingIntent = PendingIntent.getBroadcast(NotifyActivity.this, 999, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.icon = android.R.drawable.sym_def_app_icon;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(NotifyActivity.this, "title", "this is a notification", pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int) System.currentTimeMillis(), notification);
通知的logo为app的默认icon,想要外部修改logo,用android自带的api是行不通了。
没关系,既然自定义layout可以达到修改logo的方法,那我们就从这里着手
查看android的源代码,不难发现,Notification的setLatestEventInfo方法主要代码如下:
public void setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.status_bar_latest_event_content);
if (this.icon != 0) {
contentView.setImageViewResource(R.id.icon, this.icon);
}
if (contentTitle != null) {
contentView.setTextViewText(R.id.title, contentTitle);
}
if (contentText != null) {
contentView.setTextViewText(R.id.text, contentText);
}
if (this.when != 0) {
contentView.setLong(R.id.time, "setTime", when);
}
this.contentView = contentView;
this.contentIntent = contentIntent;
}
不管你怎么封装,RemoteViews就摆在那,有这玩意儿,当然就看到修改logo的机会了,代码如下:
// 调用该方法之后,notification对象中的contentView就生成了,不过是根据系统内部的布局文件生成
notification.setLatestEventInfo(NotifyActivity.this, "title", "this is a notification", pendingIntent);
RemoteViews remoteViews = notification.contentView;
RemoteViews提供如下方法:
remoteViews.setImageViewBitmap(int viewId, Bitmap bitmap);
bitmap自然可以轻易生成,但RemoteViews是内部生成,viewId拿不到啊!
没事,万能的反射!!!!!
资源文件最后都会编译成为R$**类,**可以是layout,id等,通过源码可以看到内部的remoteView会编译到com.android.internal.R$id类中,
那样好办了,类名知道,变量名知道,获取变量值,so easy
Class<?> clazz = Class.forName("com.android.internal.R$id");
Field field = clazz.getField("icon");
field.setAccessible(true); //这句必须要,不然没有访问权限
int iconId = field.getInt(null);
remoteViews.setImageViewBitmap(iconId, logoBitmap);
大功告成,不信你试试!~~~~
真的吗?其实不是,上面法子只能解决部分手机问题,不信你在雷不群的大米手机,和小工匠的榔头手机上玩玩看,照样没戏。
Notification notification = new Notification();
Intent intent = new Intent();
PendingIntent pendingIntent = PendingIntent.getBroadcast(NotifyActivity.this, 999, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.icon = android.R.drawable.sym_def_app_icon;
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(NotifyActivity.this, "title", "this is a notification", pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int) System.currentTimeMillis(), notification);
通知的logo为app的默认icon,想要外部修改logo,用android自带的api是行不通了。
没关系,既然自定义layout可以达到修改logo的方法,那我们就从这里着手
查看android的源代码,不难发现,Notification的setLatestEventInfo方法主要代码如下:
public void setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.status_bar_latest_event_content);
if (this.icon != 0) {
contentView.setImageViewResource(R.id.icon, this.icon);
}
if (contentTitle != null) {
contentView.setTextViewText(R.id.title, contentTitle);
}
if (contentText != null) {
contentView.setTextViewText(R.id.text, contentText);
}
if (this.when != 0) {
contentView.setLong(R.id.time, "setTime", when);
}
this.contentView = contentView;
this.contentIntent = contentIntent;
}
不管你怎么封装,RemoteViews就摆在那,有这玩意儿,当然就看到修改logo的机会了,代码如下:
// 调用该方法之后,notification对象中的contentView就生成了,不过是根据系统内部的布局文件生成
notification.setLatestEventInfo(NotifyActivity.this, "title", "this is a notification", pendingIntent);
RemoteViews remoteViews = notification.contentView;
RemoteViews提供如下方法:
remoteViews.setImageViewBitmap(int viewId, Bitmap bitmap);
bitmap自然可以轻易生成,但RemoteViews是内部生成,viewId拿不到啊!
没事,万能的反射!!!!!
资源文件最后都会编译成为R$**类,**可以是layout,id等,通过源码可以看到内部的remoteView会编译到com.android.internal.R$id类中,
那样好办了,类名知道,变量名知道,获取变量值,so easy
Class<?> clazz = Class.forName("com.android.internal.R$id");
Field field = clazz.getField("icon");
field.setAccessible(true); //这句必须要,不然没有访问权限
int iconId = field.getInt(null);
remoteViews.setImageViewBitmap(iconId, logoBitmap);
大功告成,不信你试试!~~~~
真的吗?其实不是,上面法子只能解决部分手机问题,不信你在雷不群的大米手机,和小工匠的榔头手机上玩玩看,照样没戏。
只能慢慢研究了,如有进展,再来更新博客~~~
PS:传上自己写的小demo,点击通知即可展示效果。
下载地址:http://download.csdn.net/detail/vailenzhou/8351607