如何在不启动Activity的情况下使用通知中的操作

31

我正在开发一个简单的音乐播放器。正如其名称所示,该音乐播放器可以播放歌曲、暂停播放、跳转到下一首歌曲、返回上一首歌曲并完全停止播放。当您播放歌曲时,将显示一个通知,其中包含艺术家姓名和歌曲名称;此通知还有三个按钮 (操作): 停止、暂停和下一首。

我的问题在于确保单击任何操作时,与操作相关的播放控件会触发,但我实在不知道应该如何做到这一点。我查看了 Android Notification :http://developer.android.com/guide/topics/ui/notifiers/notifications.html ,但它并未澄清或专门说明通知操作的相关信息。

例如,以下是一个简单操作(应与通知中“下一个”按钮的单击关联):注意:以下所有代码均写在以下包下: com.deadpixels.light.player,活动名为:PlayerActivity

public void nextSong() {
    if (position == songs.size() -1) {
        Toast.makeText(this, "No more songs on queue", Toast.LENGTH_SHORT).show();
        if(mPlayer.isPlaying()) {
            return;
        }
        else {
            buttonPlay.setImageResource(R.drawable.button_play);
        }
        return;
    }
    else {
        position++;
        playSong(songs.get(position));
    }
}

以下是我尝试做的:

Intent nextIntent = new Intent(KEY_NEXT);
PendingIntent nextPendingIntent = createPendingResult(0, nextIntent, 0);

下一个意图(NextIntent)的操作位置为:

public static final String KEY_NEXT = "com.deadpixels.light.player.PlayerActivity.nextSong";

然后我通过addAction()将其添加到通知中:
mBuilder.addAction(R.drawable.not_action_next, "Next", nextPendingIntent);

你们知道我还能尝试什么吗?使用我上面解释的东西根本没有任何作用,通知显示出来了,并且有三个操作按钮,但是点击它们对我来说毫无作用。
一度我以为如果我添加了具有操作名称的意图过滤器可能会有所帮助,但是后来我想,它们都在同一个命名空间中,我为什么要这样做呢?
1个回答

45

我使用广播来解决了这个问题。例如,要发送一个广播以跳到下一首歌曲,您可以使用以下内容:

Intent nextIntent = new Intent(KEY_NEXT);
PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this, 0, nextIntent, 0);

然后,在你的 Activity 中注册一个 BroadcastReceiver

IntentFilter filter = new IntentFilter();
filter.addAction(KEY_NEXT);
// Add other actions as needed

receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(KEY_NEXT)) {
            nextSong();
        } else if (...) {
            ...
        }
        ...
    }
}

registerReceiver(receiver, filter);

如果您正在使用服务来管理后台播放,则应该在服务中注册 BroadcastReceiver 而不是活动。一定要将 receiver 实例存储在某个地方,以便在活动或服务关闭时可以取消注册。


1
请确保存储接收器实例.. 存储在哪里? - gursahib.singh.sahni
@anonymous 在您的活动或服务中保留对它的引用。 - acj
1
为什么不在清单中注册BroadcastReceiver并将其作为单独的类呢? - streamride
@streamride 你可以这样做。但有时候,对于它们的生命周期进行细粒度控制是很有用的。例如,在这个问题的背景下,你可能只想在特定的活动被使用时才监听广播。 - acj
unregisterReceiver(broadcastReceiver); 对于懒人 :P - jobbert
如何在通知中更改专辑封面和歌曲标题? - Bhanu Prakash Pasupula

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接