Подтвердить что ты не робот

Создание пользовательских больших уведомлений

Я хотел создать уведомление, включая некоторые элементы управления. Поскольку текст и элементы управления невелики с размером уведомления по умолчанию (64dp), я хотел бы иметь размер больше, чем размер по умолчанию.
Можно создавать большие уведомления, и я думаю, что возможно иметь собственный макет, но я не знаю, как это сделать.

Чтобы быть более конкретным, на следующем скриншоте показано уведомление от spotify (изображение взято из здесь): Spotify notification

Как вы можете видеть, размер больше, чем значение по умолчанию. Кроме того, у него есть какие-то ImageButtons без текста - если вы используете Notification.Builder.addAction(), вы можете предоставить значок, но также необходимо предоставить CharSequence в качестве описания - если вы оставите описание пустым, все равно будет зарезервировано место для текста, и если вы передадите значение null, он сработает.

Может ли кто-нибудь сказать мне, как создать большое уведомление с помощью настраиваемого макета?

Спасибо

4b9b3361

Ответ 1

Обновление из-за изменений API:

Из API 24 on Notification.Builder содержит метод setCustomBigContentView (RemoteViews). Также этот NotificationCompat.Builder (который является частью пакета support.v4) содержит этот метод.
Обратите внимание, что в документации для NotificationCompat.Builder.setCustomBigContentView указано:

Поставляйте настраиваемые RemoteViews вместо шаблона платформы в развернутой форме. Это переопределит расширенный макет, который в противном случае был бы сконструирован этим объектом Builder. No-op для версий до JELLY_BEAN.

Следовательно, это также будет работать только для API >= 16 (JELLY_BEAN).


Оригинальный ответ

Поэтому после чрезмерного использования google я нашел этот учебник, объясняющий, как использовать пользовательские большие макеты. Хитрость заключается не в том, чтобы использовать setStyle(), а вручную установить поле bigContentView Notification после его создания. Кажется немного взломанным, но это то, что я, наконец, придумал:

notification_layout_big.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp" <!-- This is where I manually define the height -->
    android:orientation="horizontal" >

    <!-- some more elements.. --> 
</LinearLayout>

Построение Notification в коде:

Notification foregroundNote;

RemoteViews bigView = new RemoteViews(getApplicationContext().getPackageName(),
    R.layout.notification_layout_big);

// bigView.setOnClickPendingIntent() etc..

Notification.Builder mNotifyBuilder = new Notification.Builder(this);
foregroundNote = mNotifyBuilder.setContentTitle("some string")
        .setContentText("Slide down on note to expand")
        .setSmallIcon(R.drawable.ic_stat_notify_white)
        .setLargeIcon(bigIcon)
        .build();

foregroundNote.bigContentView = bigView;

// now show notification..
NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotifyManager.notify(1, foregroundNote);

Edit
Как отмечалось в chx101, это работает только для API >= 16. Я не упоминал об этом в этом ответе, но он упоминался в данном связанном учебнике выше:

Расширенные уведомления были впервые представлены в Android 4.1 JellyBean [API 16].

Ответ 2

 dialog_custom_notification
        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="wrap_content"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/dp_10"
                android:background="@drawable/shape_bg_main_notification"
                android:gravity="center"
                android:orientation="horizontal"
                android:padding="@dimen/dp_10">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="top">

                    <ImageView
                        android:id="@+id/ivAppIcon"
                        android:layout_width="@dimen/dp_36"
                        android:layout_height="@dimen/dp_36"
                        android:layout_gravity="top"
                        android:background="@mipmap/ic_launcher" />
                </LinearLayout>

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="top"
                    android:layout_marginLeft="@dimen/dp_10"
                    android:layout_weight="1"
                    android:orientation="vertical">

                    <TextView
                        android:id="@+id/tvNotificationTitle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Notification Tile"
                        android:textStyle="bold" />

                    <TextView
                        android:id="@+id/tvNotificationDescription"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="@dimen/dp_5"
                        android:text="Notification Description" />

                </LinearLayout>

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="top">

                    <TextView
                        android:id="@+id/tvDateTime"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentRight="true"
                        android:layout_gravity="top"
                        android:text="09:50" />
                </LinearLayout>
            </LinearLayout>
        </LinearLayout>

shape_bg_main_notification
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/white" />

    <corners android:radius="@dimen/dp_6" />

</shape>



@SuppressLint("WrongConstant")
            fun showOfflineNotification(context: Context, title: String, description: String) {
                val NOTIFICATION_CHANNEL_ID = "com.myapp"
                val intent = Intent(context, HomeActivity::class.java)
                intent.putExtra("notification", 1)
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                if (intent != null) {
                    val pendingIntent = PendingIntent.getActivity(
                        context, getTwoDigitRandomNo(), intent,
                        PendingIntent.FLAG_ONE_SHOT
                    )
                    val defaultSoundUri =
                        RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)

                    val remoteCollapsedViews = RemoteViews(packageName, R.layout.dialog_custom_notification)
                    remoteCollapsedViews.setTextViewText(R.id.tvNotificationTitle, title)
                    remoteCollapsedViews.setTextViewText(R.id.tvNotificationDescription, description)
                    remoteCollapsedViews.setTextViewText(R.id.tvDateTime, getTime())

                    val notificationBuilder = NotificationCompat.Builder(context)
                    notificationBuilder.setCustomBigContentView(remoteCollapsedViews)
                    notificationBuilder.setSmallIcon(R.mipmap.ic_launcher_round)
                    notificationBuilder.setLargeIcon(
                        BitmapFactory.de

codeResource(
                                context.resources,
                                R.mipmap.ic_launcher
                            )
                        )
                        notificationBuilder.setBadgeIconType(R.mipmap.ic_launcher_round)
                        notificationBuilder.setContentTitle(title)
                        if (description != null) {
                            notificationBuilder.setContentText(description)
                            notificationBuilder.setStyle(
                                NotificationCompat.BigTextStyle().bigText(description)
                            )
                        }
                        notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH)
                        notificationBuilder.setAutoCancel(true)
                        notificationBuilder.setSound(defaultSoundUri)
                        notificationBuilder.setVibrate(longArrayOf(1000, 1000))
                        notificationBuilder.setContentIntent(pendingIntent)

                        val notificationManager =
                            context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            val importance = NotificationManager.IMPORTANCE_MAX
                            val notificationChannel = NotificationChannel(
                                NOTIFICATION_CHANNEL_ID,
                                "NOTIFICATION_CHANNEL_NAME",
                                importance
                            )
                            notificationChannel.enableLights(true)
                            notificationChannel.lightColor = Color.RED
                            notificationChannel.enableVibration(true)
                            notificationChannel.vibrationPattern = longArrayOf(1000, 1000)
                            assert(notificationManager != null)
                            notificationBuilder.setChannelId(NOTIFICATION_CHANNEL_ID)
                            notificationManager.createNotificationChannel(notificationChannel)
                        }
                        notificationManager.notify(
                            getTwoDigitRandomNo()/*Id of Notification*/,
                            notificationBuilder.build()
                        )
                    }
                }

                private fun getTime(): String {
                    val calendar = Calendar.getInstance()
                    val mdformat = SimpleDateFormat("HH:mm")
                    val strDate = mdformat.format(calendar.time)
                    return strDate
                }

                fun getTwoDigitRandomNo(): Int {
                    return Random().nextInt(90) + 10
                }