5

我最近一直在试验新的Bubbles API。无论我做什么,我希望以气泡形式出现的通知总是作为正常通知出现在系统托盘中。

我已经编写了自己的玩具应用程序,我将在此处添加。我还从我学习过的教程(此处此处)中删除了其他几个应用程序。在每种情况下,都没有气泡,只有系统托盘通知。

由于示例应用程序声称它们可以呈现气泡,因此我认为问题一定出在我的模拟器环境中。我正在运行一个使用Android API R. 我在开发者选项中启用了气泡:

在此处输入图像描述

这是我开发的应用程序的相关代码:

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.bubbles">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".BubbleActivity"
            android:allowEmbedded="true"
            android:documentLaunchMode="always"
            android:resizeableActivity="true" />
        <activity
            android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.kt

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider

class MainActivity : AppCompatActivity() {

    private lateinit var bubbleViewModel: BubbleViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        bubbleViewModel = ViewModelProvider(
            this, BubbleViewModelFactory(this.application))
            .get(BubbleViewModel::class.java)
    }

    fun blowBubble(view: View) {
        bubbleViewModel.showBubble()
    }
}

气泡视图模型.kt

class BubbleViewModel(application: Application): AndroidViewModel(application) {

    private val notificationHelper = NotificationHelper(getApplication())

    init {
        notificationHelper.createNotificationChannels()
    }

    fun showBubble() {
        viewModelScope.launch{
            withContext(Dispatchers.Main) {
                with (notificationHelper) {
                    if (canBubble())
                        showNotification()
                }
            }
        }
    }
}

NotificationHelper.kt

class NotificationHelper(private val context: Context) {

    private val notificationManager = context.getSystemService(NotificationManager::class.java)
    private lateinit var channel: NotificationChannel

    fun createNotificationChannels() {

        channel = NotificationChannel(
            CHANNEL_NEW_MESSAGES,
            context.getString(R.string.channel_name),
            NotificationManager.IMPORTANCE_HIGH)

        with(channel) {
            enableVibration(true)
            lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
            description = context.getString(R.string.channel_description)
            setAllowBubbles(true)
        }

        Log.d("bubble", "Can Bubble: $channel.canBubble()")
        notificationManager?.let {
            it.createNotificationChannel(channel)
        }
    }

    @WorkerThread
    fun showNotification() {

        val bubbleIntent = PendingIntent.getActivity(
            context,
            REQUEST_BUBBLE,
            Intent(context, BubbleActivity::class.java).setAction(Intent.ACTION_VIEW),
            PendingIntent.FLAG_UPDATE_CURRENT)

        val bubbleMetaData = Notification.BubbleMetadata.Builder()
            .setDesiredHeight(600)
            .createIntentBubble(bubbleIntent, Icon.createWithResource(context, R.drawable.baseball))
            .setAutoExpandBubble(false)
            .setSuppressNotification(false)
            .build()

        val person = Person.Builder()
            .setIcon(Icon.createWithResource(context, R.drawable.baseball))
            .setName("Bubbles...")
            .setImportant(true)
            .build()

        val style = Notification.MessagingStyle(person)
            .addMessage("...are the Best!", System.currentTimeMillis(), person)

        val builder = Notification.Builder(context, CHANNEL_NEW_MESSAGES)
            .setBubbleMetadata(bubbleMetaData)
            .setContentIntent(bubbleIntent)
//            .setContentTitle("Title")
//            .setContentText("Hello this is a notification")
            .setSmallIcon(R.drawable.baseball)
            .setShowWhen(true)
            .setAutoCancel(true)
            .setStyle(style)
//            .addPerson(person.uri)


        notificationManager?.notify(0, builder.build())
    }

    fun canBubble(): Boolean {
        notificationManager?.let {
            val channel = it.getNotificationChannel(CHANNEL_NEW_MESSAGES)
            return it.areBubblesAllowed() && channel.canBubble()
        }
        return false
    }

    companion object {
        private const val CHANNEL_NEW_MESSAGES = "new_messages"
        const val REQUEST_BUBBLE = 2
    }
}

最后,目标活动,我认为这并不重要,因为它只有在气泡可以点击时才会触发: BubbleActivity.kt

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class BubbleActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_bubble)
    }
}

这就是它的全部内容。但是当运行它并单击按钮以显示气泡时,我得到了这个结果:

在此处输入图像描述

4

2 回答 2

4

@AndroidDev 您的代码在 API 级别 29 中运行良好,并将通知显示为气泡,但在 Android R 中不起作用。我想您不必担心,因为它处于预览阶段并且绝对不稳定。

因此,如果您在 API 级别 29 的模拟器中运行代码,它应该可以正常工作。

此问题是 Android 10 的回归问题,并在此处报告

于 2020-03-13T17:00:46.383 回答
2

我在同样的问题上苦苦挣扎,但是当我运行 Google 的示例应用程序People时,它​​工作得很好。

来自https://developer.android.com/guide/topics/ui/bubbles

如果应用面向 Android 11 或更高版本,则通知不会显示为气泡,除非它满足对话要求。

这些要求提到了这部分,您看起来好像缺少:

只有具有关联快捷方式的通知才能冒泡。

如何设置快捷方式(以及其他所有内容)可以在他们提到的示例中看到:https ://github.com/android/user-interface-samples/blob/main/People/app/src/main/java/com /example/android/people/data/NotificationHelper.kt

于 2020-10-22T13:27:54.897 回答