简体   繁体   中英

Full screen notification intent won't work from service

Here's my notification manager class:

class DefaultNotificationManager @Inject constructor(
private val context: Context,
private val notificationManager: AndroidNotificationManager,
private val notificationIntent: Intent): NotificationManager {

companion object {
    const val DEFAULT_REQUEST_ID = 0
    const val CHANNEL_ID = "0"
    const val CLEVER_TAP_CHANNEL_ID = "1"
    const val CHANNEL_NAME = "Notification"
    const val CLEVER_TAP_CHANNEL_NAME = "Announcements"
}

init {
    setupNotificationChannels(NotificationType.values())
}

override fun show(messageTitle: String, messageBody: String) {
    showType(messageTitle, messageBody, NotificationType.DEFAULT.type)
}

override fun showType(messageTitle: String, messageBody: String, notificationType: String) {
    val notification = getNotification(messageTitle, messageBody, notificationType)
    notificationManager.notify(UUID.randomUUID().toString(), NotificationID.id, notification) notification)
}

override fun getNotification(messageTitle: String, messageBody: String, notificationType:String): Notification {
    val defaultSoundUri: Uri = getSoundUri(notificationType)
    val notificationBuilder: NotificationCompat.Builder =
        NotificationCompat.Builder(context, notificationType)
            .setSmallIcon(R.drawable.ct_ic_arrow_back_white_24dp)
            .setContentTitle(messageTitle)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setVibrate(longArrayOf(0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100))

    if (notificationType == NotificationType.NEW_TRIP_REQUEST.type) {
        notificationBuilder.setFullScreenIntent(createNotificationPendingIntent(), true)
    } else {
        notificationBuilder.setContentIntent(createNotificationPendingIntent())
    }

    return notificationBuilder.build()
}

private fun setupNotificationChannels(notificationTypes: Array<NotificationType>) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        notificationTypes.forEach {
            val channel = NotificationChannel(
                it.type,
                CHANNEL_NAME,
                AndroidNotificationManager.IMPORTANCE_HIGH
            ).apply { setSound(getSoundUri(it.type),
                    Notification.AUDIO_ATTRIBUTES_DEFAULT)
                enableVibration(true)
            vibrationPattern = longArrayOf(0, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100)}
            notificationManager.createNotificationChannel(channel)
        }

        val cleverTapChannel = NotificationChannel(
            CLEVER_TAP_CHANNEL_ID,
            CLEVER_TAP_CHANNEL_NAME,
            AndroidNotificationManager.IMPORTANCE_HIGH
        )
        notificationManager.createNotificationChannel(cleverTapChannel)
    }
}

private fun getSoundUri(type: String): Uri {
    return when (type) {
        NotificationType.NEW_TRIP_REQUEST.type -> Uri.parse("${ContentResolver.SCHEME_ANDROID_RESOURCE}://${context.packageName}/${R.raw.tune2}")
        else -> RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
    }
}

enum class NotificationType(val type: String){
    NEW_TRIP_REQUEST("new_trip"),
    DEFAULT("default"),
    FOREGROUND("foreground")
}

private fun createNotificationPendingIntent(): PendingIntent? {
    notificationIntent.addFlags(
        Intent.FLAG_ACTIVITY_CLEAR_TOP or
                Intent.FLAG_ACTIVITY_SINGLE_TOP
                or
                Intent.FLAG_ACTIVITY_NEW_TASK
    )
    return getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}

object NotificationID {
    private val c: AtomicInteger = AtomicInteger(0)
    val id: Int
        get() = c.incrementAndGet()
}

And here's the manifest configuration:

        <activity android:name=".presentation.splash.ui.SplashActivity"
            android:screenOrientation="portrait">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <activity
            android:name=".presentation.auth.base.activities.AuthActivity"
            android:launchMode="singleTask"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustPan"/>

        <activity
            android:name=".presentation.main.activities.MainActivity"
            android:screenOrientation="portrait"
            android:launchMode="singleTask"
            android:showOnLockScreen="true" />


        <service
            android:name="com.data.services.PushMessagesService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

Running this onCreate of the MainActivity:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setShowWhenLocked(true)
            setTurnScreenOn(true)
        } else {
            window.addFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
            )
        }

        with(getSystemService(KEYGUARD_SERVICE) as KeyguardManager) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                requestDismissKeyguard(this@turnScreenOnAndKeyguardOff, null)
            }
        }
    }

Now the issue is, If I create a notification from a fragment using the same notification manager class, the notification works as expected: it shows full screen and wakes up the device even when the device is asleep, and if I click on the notification, it resumes the app.

But if I create the notification from the com.google.firebase.MESSAGING_EVENT onMessageReceived, full screen intent doesn't work and the screen won't turn on. Also, on click will recreate the activity.

Thanks

From Doc

Only for use with extremely high-priority notifications demanding the user's immediate attention, such as an incoming phone call or alarm clock that the user has explicitly set to a particular time.

I suppose you need to add a category to your notification. eg

.setCategory(NotificationCompat.CATEGORY_CALL)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM