天天看點

RemoteServiceException:Bad notification posted:Couldn't expand RemoteViews for:StatusBarNotification

使用自定義的 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);