当应用程序处于后台/已终止或手机锁定状态时,如何获取FullScreenNotification?

问题描述

我创建了一个显示来电的活动,其中包括接听按钮和挂断按钮。当我收到FCM的通知时,将启动此活动。当应用程序处于前台状态时,当推送通知时,它就可以正常工作。

但是当我将应用程序置于后台(未终止),并且推送通知时,活动未启动。我只会在系统任务栏中看到带有标签,图标和文本的通知

尽管应用程序处于后台状态,但我想打开活动。为此,我使用了.setFullScreenIntent(pendingIntent,true)来引用https://developer.android.com/reference/android/app/Notification.Builder#setFullScreenIntent(android.app.PendingIntent,%20boolean)本文档。

仍然无法正常工作。

也引用了此链接FullScreen Notification

和这个https://developer.android.com/training/notify-user/custom-notification

请让我知道该怎么做?

这是我的清单

<uses-permission android:name="android.permission.disABLE_KEyguard" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUdio" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUdio_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUetoOTH" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BIND_JOB_SERVICE"
    tools:ignore="ProtectedPermissions" />

<uses-permission
    android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
    tools:ignore="ProtectedPermissions" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppThemeNoActionBar">
    <activity android:name=".LauncherActivity">

    </activity>
    <activity
        android:name=".NotificationActivity"
        android:launchMode="singletop"
        android:screenorientation="portrait"
        android:theme="@style/AppThemeNoActionBar">
        <intent-filter>
            <!-- Note: these actions are notification actions -->
            <action android:name="VIDEO_CALLING" />
            <category android:name="android.intent.category.DEFAULT" />
            <action android:name="OPEN_NEW_ACTIVITY" />
            <category android:name="android.intent.category.DEFAULT" />

        </intent-filter>

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

    </activity>

    <service
        android:name=".MyFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <!--        <service
        android:name=".AppFirebaseMessagingService"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    &lt;!&ndash;-->

    <Meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/ic_launcher" />
    <Meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id" />


    <Meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/colorAccent" />
    <Meta-data
        android:name="firebase_messaging_auto_init_enabled"
        android:value="false" />
    <Meta-data
        android:name="firebase_analytics_collection_enabled"
        android:value="false" />


    <receiver android:name=".FirebaseDataReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

    <service
        android:name=".MyJobIntentService"
        android:permission="android.permission.BIND_JOB_SERVICE" />


    <service android:name="com.google.android.gms.measurement.AppMeasurementService"
        android:enabled="true"
        android:exported="false"/>

    <receiver android:name="com.google.android.gms.measurement.AppMeasurementReceiver"
        android:enabled="true">
        <intent-filter>
            <action android:name="com.google.android.gms.measurement.UPLOAD" />
        </intent-filter>
    </receiver>
</application>

这是我的FirebaseMessagingService

    package com.example.agoraapp

import android.app.NotificationChannel
import android.app.notificationmanager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.media.ringtoneManager
import android.os.Build
import android.util.Log
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import com.example.agoraapp.MyWorker
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage


class MyFirebaseMessagingService : FirebaseMessagingService() {

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    // [START receive_message]
    private var mRemoteMessage: Map<String,String>? = null

    override fun onMessageReceived(remoteMessage: RemoteMessage) {


        // Check if message contains a data payload.
        if (!remoteMessage.data.equals("")) {
            Log.d(TAG,"Message data payload: " + remoteMessage.getData());
        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG,"Message Notification Body: " + remoteMessage.getNotification()!!.getBody());
            remoteMessage.data.get("notification_data")?.let { sendNotification(it) };

            val broadcast = Intent();
            broadcast.setAction("OPEN_NEW_ACTIVITY")
            sendbroadcast(broadcast)
        }

    }
    // [END receive_message]

    // [START on_new_token]
    /**
     * Called if the FCM registration token is updated. This may occur if the security of
     * the prevIoUs token had been compromised. Note that this is called when the
     * FCM registration token is initially generated so this is where you would retrieve the token.
     */
    override fun onNewToken(token: String) {
        Log.d(TAG,"Refreshed token: $token")

        // If you want to send messages to this application instance or
        // manage this apps subscriptions on the server side,send the
        // FCM registration token to your app server.
        sendRegistrationToServer(token)
    }
    // [END on_new_token]

    /**
     * Schedule async work using WorkManager.
     */
    private fun scheduleJob() {
        // [START dispatch_job]
        val work = OneTimeWorkRequest.Builder(MyWorker::class.java).build()
        WorkManager.getInstance().beginWith(work).enqueue()
        // [END dispatch_job]
    }

    /**
     * Handle time allotted to broadcastReceivers.
     */
    private fun handleNow() {
        Log.d(TAG,"Short lived task is done.")
        mRemoteMessage?.get("body")?.let { sendNotification(it) }

    }

    /**
     * Persist token to third-party servers.
     *
     * Modify this method to associate the user's FCM registration token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    private fun sendRegistrationToServer(token: String?) {
        // Todo: Implement this method to send token to your app server.
        Log.d(TAG,"sendRegistrationTokenToServer($token)")
    }

    /**
     * Create and show a simple notification containing the received FCM message.
     *
     * @param messageBody FCM message body received.
     */
    private fun sendNotification(messageBody: String) {
        val intent = Intent(this,NotificationActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(
            this,intent,PendingIntent.FLAG_ONE_SHOT
        )

        val channelId = getString(R.string.default_notification_channel_id)
        val defaultSoundUri = ringtoneManager.getDefaultUri(ringtoneManager.TYPE_NOTIFICATION)
        val notificationLayoutExpanded = RemoteViews(packageName,R.layout.activity_notify)

        val notificationBuilder = NotificationCompat.Builder(this,channelId)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(getString(R.string.fcm_message))
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent)
            .setFullScreenIntent(pendingIntent,true)
            .setCustomBigContentView(notificationLayoutExpanded)


        val notificationmanager = getSystemService(Context.NOTIFICATION_SERVICE)
                as notificationmanager

        // Since android Oreo notification channel is needed.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                channelId,"Channel human readable title",notificationmanager.IMPORTANCE_HIGH
            )
            notificationmanager.createNotificationChannel(channel)
        }

        notificationmanager.notify(0,notificationBuilder.build())




     /*   val builder = NotificationCompat.Builder(this)
        builder.setSmallIcon(android.R.drawable.btn_star)
        builder.setContentTitle("This is title of notification")
        builder.setContentText("This is a notification Text")
        builder.setLargeIcon(BitmapFactory.decodeResource(resources,R.mipmap.ic_launcher))
        builder.setStyle()
        builder.setPriority((int)NotificationPriority.Max)


        val intent = Intent(this,NotificationActivity::class.java)
        val pendingIntent =
            PendingIntent.getActivity(this,113,PendingIntent.FLAG_UPDATE_CURRENT)

        builder.setContentIntent(pendingIntent)
        builder.setAutoCancel(true)

        builder.setFullScreenIntent(pendingIntent,true)


        val manager = getSystemService(NOTIFICATION_SERVICE) as notificationmanager
        manager.notify(115,builder.build())
*/
    }

    companion object {

        private const val TAG = "MyFirebaseMsgService"
    }
}

这是我的呼叫活动布局,需要在收到通知后立即启动

   <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="@color/colorPrimaryDark">


    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/calling"
        android:textColor="@android:color/white"
        android:textSize="28sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/hangup"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/hangup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hang up"
        android:textColor="@android:color/white"
        android:background="@android:color/holo_red_dark"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/answer"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginBottom="100dp"/>

    <Button
        android:id="@+id/answer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Answer"
        android:textColor="@android:color/white"
        android:background="@android:color/holo_green_dark"
        app:layout_constraintBaseline_toBaselineOf="@+id/hangup"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/hangup" />

</androidx.constraintlayout.widget.ConstraintLayout>

这是活动课

class NotificationActivity : AppCompatActivity() {



    @SuppressLint("InvalidWakeLockTag")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_notify)
        // These flags ensure that the activity can be launched when the screen is locked.
        val window: Window = window
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setShowWhenLocked(true)
            setTurnScreenOn(true)
            val keyguardManager = getSystemService(Context.KEyguard_SERVICE) as KeyguardManager
            keyguardManager.requestdismissKeyguard(this,null)
        } else {
            window.addFlags(
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                        or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                        or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
            )
        }

        // to wake up screen
        val pm = applicationContext.getSystemService(POWER_SERVICE) as PowerManager
        val wakeLock = pm.newWakeLock(
            PowerManager.SCREEN_BRIGHT_WAKE_LOCK or
                    PowerManager.FULL_WAKE_LOCK or
                    PowerManager.ACQUIRE_CAUSES_WAKEUP,"TAG"
        )
        wakeLock.acquire()

        // to release screen lock
        val keyguardManager =
            applicationContext.getSystemService(KEyguard_SERVICE) as KeyguardManager
        val keyguardLock = keyguardManager.newKeyguardLock("TAG")
        keyguardLock.disableKeyguard()

        answer.setonClickListener {
            Toast.makeText(this,"Answer button",Toast.LENGTH_SHORT).show();

            val intent = Intent(this@NotificationActivity,MainActivity::class.java)
            startActivity(intent)
            finish()

        }
        hangup.setonClickListener {

            finish()
            Toast.makeText(this,"Hangup button",Toast.LENGTH_SHORT).show();
        }

    }

    companion object {
        fun start(context: Context,call: Call) {
            val intent = Intent(context,NotificationActivity::class.java)
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK

            context.startActivity(intent)
        }
    }
}

我还尝试使用广播接收器来接收通知,但仍然无法正常工作。在接收器活动中注册接收者

class MainActivity  : AppCompatActivity() {

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

        FirebaseApp.initializeApp(this)
        val token = FirebaseMessaging.getInstance().getToken() as? String


        FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
            if (!task.isSuccessful) {
                Log.w("TAG","Fetching FCM registration token Failed",task.exception)
                return@OnCompleteListener
            }

            // Get new FCM registration token
            val token = task.result

            // Log and toast
            val msg = getString(R.string.msg_token_fmt,token)
            Log.d("TAG",msg)
            Toast.makeText(baseContext,msg,Toast.LENGTH_SHORT).show()
        })
   

            mReceiver = object : broadcastReceiver() {
            override fun onReceive(context: Context?,intent: Intent?) {
                val myNewActivity = Intent(this@MainActivity,NotificationActivity::class.java)
                startActivity(myNewActivity)
            }
        }
        mIntentFilter = IntentFilter("OPEN_NEW_ACTIVITY");

        val notificationLayoutExpanded = RemoteViews(packageName,R.layout.activity_notify)
        val channelId = getString(R.string.default_notification_channel_id)
        val channelName = getString(R.string.default_notification_channel_name)
        val defaultSoundUri = ringtoneManager.getDefaultUri(ringtoneManager.TYPE_NOTIFICATION)
        val notificationBuilder = NotificationCompat.Builder(this,channelId)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle(getString(R.string.fcm_message))
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setCustomBigContentView(notificationLayoutExpanded)


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Create channel to show notifications.

            val notificationmanager = getSystemService(notificationmanager::class.java)
            notificationmanager?.createNotificationChannel(
                NotificationChannel(channelId,channelName,notificationmanager.IMPORTANCE_HIGH)
            )

            notificationmanager.notify(0,notificationBuilder.build())
        }

        
        // [START handle_data_extras]
        intent.extras?.let {
            for (key in it.keySet()) {
                val value = intent.extras?.get(key)
                Log.d("TAG","Key: $key Value: $value")
            }
        }
        // [END handle_data_extras]
    }
    override fun onResume() {
        super.onResume()
        registerReceiver(mReceiver,mIntentFilter);
    }

    override fun onPause() {
        super.onPause()
        if(mReceiver != null)
          //  unregisterReceiver(mReceiver);
        mReceiver = null;
    }

    companion object {

        private val LOG_TAG = MainActivity::class.java.simpleName

        private const val PERMISSION_REQ_ID_RECORD_AUdio = 22
        private const val PERMISSION_REQ_ID_CAMERA = PERMISSION_REQ_ID_RECORD_AUdio + 1
    }
}

FirebaseMessagingService的onMessageRecieved函数中的指定接收者

// Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG,"Message Notification Body: " + remoteMessage.getNotification()!!.getBody());
        remoteMessage.data.get("notification_data")?.let { sendNotification(it) };

        val broadcast = Intent();
        broadcast.setAction("OPEN_NEW_ACTIVITY")
        sendbroadcast(broadcast)
    }

请帮助。严重卡住...

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)