如何在android中的通知中添加按钮?

Posted

技术标签:

【中文标题】如何在android中的通知中添加按钮?【英文标题】:How to add button to notifications in android? 【发布时间】:2013-04-18 05:29:48 【问题描述】:

我的应用播放音乐,当用户通过从屏幕顶部(或通常从平板电脑屏幕的右下角)滑动打开通知屏幕时,我想向他们展示一个按钮来停止当前播放的音乐并开始如果他们愿意,可以再做一次。

我不打算将小部件放在用户的主屏幕上,而只是放在通知中。我该怎么做?

【问题讨论】:

我认为这是一个有效的问题 这不是一个有效的问题吗? 有些人只是对有意义的问题投反对票,但为什么 这是我的谷歌搜索结果,没有答案... 这是一个完全有效的问题,我对所有投票结束此问题的人的理解为零。 【参考方案1】:

您可以为动作创建一个意图(在这种情况下停止播放),然后将其作为动作按钮添加到您的通知中。

Intent snoozeIntent = new Intent(this, MyBroadcastReceiver.class);
snoozeIntent.setAction(ACTION_SNOOZE);
snoozeIntent.putExtra(EXTRA_NOTIFICATION_ID, 0);
PendingIntent snoozePendingIntent =
        PendingIntent.getBroadcast(this, 0, snoozeIntent, 0);

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setContentIntent(pendingIntent)
        .addAction(R.drawable.ic_snooze, getString(R.string.snooze),
                snoozePendingIntent);

请参考the android documentation。

【讨论】:

为了改进您的答案,您将添加不带图标的“文本”。请参考创建意图的方法,在通知区域添加图标按钮并加入两者,然后如何接收意图。 什么是 ACTION_SNOOZE?【参考方案2】:

我将尝试提供我使用过的解决方案,并且大多数音乐播放器也使用相同的技术在通知栏中显示播放器控件。

我正在运行一项用于管理媒体播放器及其所有控件的服务。 Activity 用户控件通过向服务发送 Intent 与服务交互,例如

 Intent i = new Intent(MainActivity.this, MyRadioservice.class);
        i.setAction(Constants.Player.ACTION_PAUSE);

        startService(i);

为了在 Service 类中接收意图并执行操作,我在 Service 的 onStartCommand 方法中使用以下代码

 @Override
public int onStartCommand(Intent intent, int flags, int startId) 


    if (intent.getAction().equals(Constants.Player.ACTION_PAUSE)) 
        if(mediaPlayer.isPlaying()) 
            pauseAudio();
        
    

现在要准确回答您的问题,以显示带有播放控件的通知。您可以调用以下方法来显示带有控件的通知。

   //    showNotification
private void startAppInForeground() 
//  Start Service in Foreground

    // Using RemoteViews to bind custom layouts into Notification
    RemoteViews views = new RemoteViews(getPackageName(),
            R.layout.notification_status_bar);

// Define play control intent 
   Intent playIntent = new Intent(this, MyRadioService.class);
    playIntent.setAction(Constants.Player.ACTION_PLAY);

// Use the above play intent to set into PendingIntent
    PendingIntent pplayIntent = PendingIntent.getService(this, 0,
            playIntent, 0);

// binding play button from layout to pending play intent defined above 
views.setOnClickPendingIntent(R.id.status_bar_play, pplayIntent);
views.setImageViewResource(R.id.status_bar_play,
            R.drawable.status_bg);

Notification status = null;
 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) 
        status = new Notification.Builder(this).build();
    

  status.flags = Notification.FLAG_ONGOING_EVENT;
    status.icon = R.mipmap.ic_launcher;
    status.contentIntent = pendingIntent;
    startForeground(Constants.FOREGROUND_SERVICE, status);

希望这真的对你有帮助。你将能够实现你想要的。有一个快乐的编码:)

【讨论】:

我没试过。但对于用户案例,fit 似乎是唯一的 complete 答案。 此代码将在任何 android bellow Jelly Bean 中抛出 nullpointerexception【参考方案3】:
    // It shows buttons on lock screen (notification).

Notification notification = new Notification.Builder(context)
    .setVisibility(Notification.VISIBILITY_PUBLIC)
    .setSmallIcon(R.drawable.NotIcon)
    .addAction(R.drawable.ic_prev, "button1",ButtonOneScreen) 
    .addAction(R.drawable.ic_pause, "button2", ButtonTwoScreen)  
   .....
    .setStyle(new Notification.MediaStyle()
    .setShowActionsInCompactView(1)
    .setMediaSession(mMediaSession.getSessionToken())
    .setContentTitle("your choice")
    .setContentText("Again your choice")
    .setLargeIcon(buttonIcon)
    .build();

更多详情请参考Click here

【讨论】:

【参考方案4】:

使用 android Pie 测试、工作的代码。这些都在同一个服务类中。

显示通知:

public void setNotification() 

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    
    NotificationChannel channel = new NotificationChannel("a", "status", NotificationManager.IMPORTANCE_DEFAULT);
    channel.setDescription("notifications");
    notificationManager = getSystemService(NotificationManager.class);
    notificationManager.createNotificationChannel(channel);

    
else
    notificationManager =  (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


Receiver.service = this;
Notification.MediaStyle style = new Notification.MediaStyle();

notification = new Notification.Builder(this)
        .setSmallIcon(R.mipmap.ic_launcher)
        .setContentTitle("Notification")
        .addAction(R.drawable.close_icon,  "quit_action", makePendingIntent("quit_action"))
        .setStyle(style);

style.setShowActionsInCompactView(0);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    
    notification.setChannelId("a");
    

// notificationManager.notify(123 , notification.build()); // pre-oreo
startForeground(126, notification.getNotification());

辅助函数:

public PendingIntent makePendingIntent(String name)
    
    Intent intent = new Intent(this, FloatingViewService.Receiver.class);
    intent.setAction(name);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
    return pendingIntent;
    

处理动作:

static public class Receiver extends BroadcastReceiver 
static FloatingViewService service;

@Override
public void onReceive(Context context, Intent intent)
    

    String whichAction = intent.getAction();

    switch (whichAction)
        

        case "quit_action":
            service.stopForeground(true);
            service.stopSelf();
            return;

        

    

您还需要更新清单:

<receiver android:name=".FloatingViewService$Receiver">
        <intent-filter>
            <action android:name="quit_action" />
        </intent-filter>
    </receiver>

【讨论】:

【参考方案5】:

我认为除了Ankit Gupta 答案,你可以使用MediaSession (API > 21) 添加原生mediaController 视图:

notificationBuilder
        .setStyle(new Notification.MediaStyle()
            .setShowActionsInCompactView(new int[]playPauseButtonPosition)  // show only play/pause in compact view
            .setMediaSession(mSessionToken))
        .setColor(mNotificationColor)
        .setSmallIcon(R.drawable.ic_notification)
        .setVisibility(Notification.VISIBILITY_PUBLIC)
        .setUsesChronometer(true)
        .setContentIntent(createContentIntent(description)) // Create an intent that would open the UI when user clicks the notification
        .setContentTitle(description.getTitle())
        .setContentText(description.getSubtitle())
        .setLargeIcon(art);

来源:tutorial

您也可以创建自定义视图并将其显示在通知区域中,第一个答案here 很棒。

【讨论】:

【参考方案6】:

您可以添加如下按钮,并且可以对该按钮执行操作,我也为我完成了如下操作,请检查。

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                        .setSmallIcon(R.drawable.ic_logo)
                        .setAutoCancel(true)
                        .setContentTitle(name)
                        .setContentText(body)
                        .setGroupSummary(true)
                        .addAction(android.R.drawable.ic_menu_directions, "Mark as read", morePendingIntent);

//morePendingIntent(做你的事情)

  PendingIntent morePendingIntent = PendingIntent.getBroadcast(
                        this,
                        REQUEST_CODE_MORE,
                        new Intent(this, NotificationReceiver.class)
                                .putExtra(KEY_INTENT_MORE, REQUEST_CODE_MORE)
                                .putExtra("bundle", object.toString()),
                        PendingIntent.FLAG_UPDATE_CURRENT
                );

【讨论】:

【参考方案7】:

我不知道这是否正确,但它确实有效。

    创建一个BroadCastReceiver 类以在按下按钮时接收数据。
public class MyBroadCastReceiver extends BroadcastReceiver 
    @Override
    public void onReceive(Context context, Intent intent) 
        
        String log = "URI: " + intent.toUri(Intent.URI_INTENT_SCHEME);
        Log.d("my", "LOG:::::::" + log);
    

    现在在您要创建通知的任何活动中 -
 Intent intent = new Intent();
        intent.setAction("unique_id");
        intent.putExtra("key", "any data you want to send when button is pressed");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, 0);
    现在在创建通知时使用此挂起的 Intent,最后您需要注册此广播以便在 MyBroadCastReceiver 类中接收它。
BroadcastReceiver br = new MyBroadCastReceiver();
        IntentFilter filter = new IntentFilter("unique_id");
        registerReceiver(br, filter);

现在,如果您想在按下按钮时执行某些操作,您可以在 MyBroadCastReceiver 类的 onReceive() 方法中执行此操作。

【讨论】:

以上是关于如何在android中的通知中添加按钮?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 react-native-firebase 在 iOS 设备的推送通知中添加按钮?

Flutter:如何向本地通知添加按钮

按下大视图通知按钮后如何敬酒

如何在类似按钮单击android时通知其他屏幕

如何根据 Firebase 数据库中的条目向我的 android 应用发送通知? [关闭]

在 Android 中执行点击操作后,如何从通知中发送 Toast?