首页 > 解决方案 > 在媒体播放期间更新 RemoteView 的视图

问题描述

我正在使用以下代码生成 mediaPlayer 通知:

package com.app1.notificationtemplate;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.widget.RemoteViews;

import androidx.core.app.NotificationCompat;

public class NotificationGenerator {
    public static final int  NOTIFICATION_ID_OPEN_ACTIVITY = 9;

    public static final String NOTIFY_PREVIOUS = "com.a.b.previous";
    public static final String NOTIFY_DELETE = "com.a.b.delete";
    public static final String NOTIFY_PAUSE = "com.a.b.pause";
    public static final String NOTIFY_PLAY = "com.a.b.play";
    public static final String NOTIFY_NEXT = "com.a.b.next";

    public static void openActivityNotificaton(Context context) {
        NotificationCompat.Builder nc = new NotificationCompat.Builder(context,
                                                        MainActivity.channelID);
        NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        Intent notifyIntent = new Intent(context, MainActivity.class);
        notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        nc.setContentIntent(pendingIntent);
        nc.setSmallIcon(R.mipmap.ic_launcher);
        nc.setAutoCancel(true);
        nc.setContentTitle("Notification Demo");
        nc.setContentText("Click please");

        nm.notify(NOTIFICATION_ID_OPEN_ACTIVITY, nc.build());


    }

    public static void customBigNotification(Context context){
        final RemoteViews expandedView = new RemoteViews(context.getPackageName(), R.layout.big_notification);
        NotificationCompat.Builder nc = new NotificationCompat.Builder(context, MainActivity.channelID);
        NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        Intent notifyIntent = new Intent(context, MainActivity.class);
        notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        nc.setContentIntent(pendingIntent);
        nc.setSmallIcon(R.drawable.play);
        nc.setAutoCancel(true);
        nc.setCustomBigContentView(expandedView);
        nc.setContentTitle("MusicPlayer");
        nc.setPriority(NotificationCompat.PRIORITY_MAX);
        nc.setContentText("Control AUdio");
        //expandedView.setTextViewText(R.id.text_song_name,"Adele");
        setListeners(expandedView, context);
        Notification notification = nc.build();
        notification.flags = NotificationCompat.FLAG_ONGOING_EVENT|NotificationCompat.FLAG_FOREGROUND_SERVICE
                            | NotificationCompat.FLAG_NO_CLEAR|NotificationCompat.FLAG_BUBBLE ;
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        nm.notify("newNotif", 1, nc.build());
    }

    public  static void setListeners(RemoteViews view, Context context){
        Intent previous = new Intent(NOTIFY_PREVIOUS);
        Intent delete = new Intent(NOTIFY_DELETE);
        Intent pause = new Intent(NOTIFY_PAUSE);
        Intent next = new Intent(NOTIFY_NEXT);
        Intent play = new Intent(NOTIFY_PLAY);

        PendingIntent pPrevious = PendingIntent.getBroadcast(context, 0,
                                                        previous, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.btnPrevious, pPrevious);

        PendingIntent pDelete = PendingIntent.getBroadcast(context, 0,
                                                        delete, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.btnDelete, pDelete);

        PendingIntent pPause = PendingIntent.getBroadcast(context, 0,
                                                        pause, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.btnPause, pPause);

        PendingIntent pPlay = PendingIntent.getBroadcast(context, 0,
                                                        play, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.btnPlay, pPlay);

        PendingIntent pNext = PendingIntent.getBroadcast(context, 0,
                                                        next, PendingIntent.FLAG_UPDATE_CURRENT);
        view.setOnClickPendingIntent(R.id.btnNext, pNext);

    }
}    

我也RemoteViews为通知设置了自定义通知视图 ( )。

但是,当我单击播放时,我不确定如何将播放视图更新为暂停视图。目前,我只是将播放按钮的可见性设置为gone. 但是,打开和关闭能见度是唯一的选择吗?无论如何我该怎么做(我遵循的教程并没有真正展示这一点)。但是,我认为如果我们可以替换按钮中的图像会更好,以避免可能的闪烁或闪烁。我还必须更新远程视图的艺术家和歌曲名称,但不知道这样做。请告诉我如何根据用户交互views进行更新RemoteView

另外,从通知到通信Service是使用Broadcasts唯一的选项吗?我还有什么其他选择?

标签: javaandroidnotifications

解决方案


您需要使用更新的数据创建一个新通知并使用NotificationManager它来更新它。无需重新启动服务。您有一个正在运行的前台服务,您所要做的就是通过notify.

因此,在您的广播接收器中openActivityNotificaton(),根据在通知中单击的视图,使用更新的数据调用您的函数。您可以为每个视图单击设置一个具有唯一操作的接收器,并相应地更新通知。我测试了,它不会导致闪烁,通知更新很顺利。

您的 Receiver 的代码将是这样的:

const val NOTIFICATION_TITLE_INTENT_ACTION = "notification_title_intent_action"
const val NOTIFICATION_ARROW_INTENT_ACTION = "notification_arrow_intent_action"

class NotificationInteractionReceiver : BroadcastReceiver() {

private lateinit var notificationsFactory: NotificationFactory

override fun onReceive(context: Context, intent: Intent) {
    notificationsFactory = NotificationFactory(context)

    // Update title according to what button was clicked
    val newTitle = when (intent.action) {
        NOTIFICATION_TITLE_INTENT_ACTION -> "title clicked"
        else -> "arrow clicked"
    }

    // Pass new title to class responsible for showing notification
    notificationsFactory.showNotification(context, s)
}

companion object {
    fun getIntent(context: Context, action: String): Intent {
        val intent = Intent(context, NotificationInteractionReceiver::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }

        intent.action = action

        return intent
    }
}
}

推荐阅读