使用自定义的 notification时,遇到这个错误:
android.app.RemoteServiceException: Bad notification posted: Couldn't expand RemoteViews for: StatusBarNotification
查了资料,发现原因不外乎是因为布局里有不支持的布局或控件:
RemoteViews并不是支持全部的布局和控件,在RemoteViews中,只能使用以下几种界面组件,自定义的控件也不行:
布局Layout: FrameLayout, LinearLayout, RelativeLayout。
控件Component:
AnalogClock, Button, Chronometer, ImageButton, ImageView, ProgressBar, TextView, ViewFlipper, ListView, GridView, StackView, AdapterViewFlipper。
我查看了下我用的布局和控件,根布局用的是LinearLayout,然后嵌套了一个LinearLayout,剩下的就是ImageView和TextView了,都符合这个啊。
后来又试,发现根布局使用layout_marginLeft这样的属性就会报上面的异常,或者根布局内使用了嵌套的LinearLayout也会报这个异常,所以就把layout_marginLeft放到了控件里,并且把嵌套的LinearLayout去掉了,把根布局改成了RelativeLayout,然后问题就解决了。
最终的布局是view_notification.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="@drawable/ic_noti"
android:layout_marginLeft="@dimen/normal_padding"
android:layout_marginTop="@dimen/normal_padding"/>
<TextView
android:id="@+id/tv_appname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/normal_match"
android:layout_toRightOf="@+id/iv_icon"
android:layout_marginTop="@dimen/normal_padding"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_icon"
android:textColor="@color/black"
android:layout_marginLeft="@dimen/normal_padding"/>
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="@+id/tv_title"
android:layout_marginBottom="@dimen/normal_match"
android:layout_marginLeft="@dimen/normal_padding"/>
</RelativeLayout>
自定义的notification为:
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder notification = new Notification.Builder(this);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.view_notification);
remoteViews.setTextViewText(R.id.tv_appname, getString(R.string.app_name));
remoteViews.setTextViewText(R.id.tv_title, title);
remoteViews.setImageViewResource(R.id.iv_icon, R.drawable.ic_noti);
remoteViews.setTextViewText(R.id.tv_content, content);
notification = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_noti)
// .setContentTitle(title)
// .setContentText(content)
.setTicker(title)
.setNumber(1)
.setTicker(title)//收到信息后状态栏显示的文字信息.setAutoCancel(true)//用户点击Notification点击面板后是否让通知取消(默认不取消)
.setVibrate(new long[]{0, 1000, 1000, 1000})//设置震动
.setDefaults(Notification.DEFAULT_LIGHTS)
// .setSound(Uri.fromFile(new File("/system/media/audio/ui/VideoRecord.ogg")))//设置声音
.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "5"))//设置声音
.setLights(Color.RED, 1000, 1000)//设置前置LED灯进行闪烁, 第一个为颜色值 第二个为亮的时长 第三个为暗的时长
.setContentIntent(pendingIntent);
Notification build = notification.build();
build.contentView = remoteViews;
build.flags = Notification.DEFAULT_VIBRATE | Notification.FLAG_SHOW_LIGHTS;//震动、
notificationManager.notify(0, build);