控制安卓或其他音乐播放器的默认播放器

22

如何控制Android的默认音乐播放器或其他任何播放器? 控制指暂停,播放,下一曲等。我需要绑定服务吗? 我尝试使用IMediaPlaybackService,但它无法正常工作。肯定有出路,因为我在Android市场上看到了可以控制音乐播放器的应用程序。 有什么想法吗?

7个回答

25
AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

if(mAudioManager.isMusicActive()) {
    Intent i = new Intent(SERVICECMD);
    i.putExtra(CMDNAME , CMDSTOP );
    YourApplicationClass.this.sendBroadcast(i);
}

你可以通过获取音频管理器并向其发送命令来实现。

以下是这些命令。

 public static final String CMDTOGGLEPAUSE = "togglepause";
 public static final String CMDPAUSE = "pause";
 public static final String CMDPREVIOUS = "previous";
 public static final String CMDNEXT = "next";
 public static final String SERVICECMD = "com.android.music.musicservicecommand";
 public static final String CMDNAME = "command";
 public static final String CMDSTOP = "stop";

1
请问您如何播放音乐?其他命令都可以正常使用,但是我不知道如何播放音乐。谢谢 :) - Abdellah Benhammou
2
请问您如何查找所有音乐播放器的SERVICECMD? - Vinay
谢谢。它运行良好。使用相同的命令是否可以使用默认相机应用程序拍照? - Jame
@AbdellahBenhammou 你知道如何在Google Play音乐中设置随机播放和重复模式吗? - Pratik Tank
非常感谢 @Ahmed Ekri。你节省了我很多时间 :) - user9140980

12

发送广播接收器的Intent存在问题,因为用户至少要打开一次音乐播放器,而且它不能用于许多第三方音乐播放器。

下面给出的代码适用于所有音乐播放器。

long eventtime = SystemClock.uptimeMillis();

Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0);
downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent);
sendOrderedBroadcast(downIntent, null);

Intent upIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
KeyEvent upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0);
upIntent.putExtra(Intent.EXTRA_KEY_EVENT, upEvent);
sendOrderedBroadcast(upIntent, null);

/*NEXT*/
Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN,   KeyEvent.KEYCODE_MEDIA_NEXT, 0);
downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent);
sendOrderedBroadcast(downIntent, null);

/*PREVIOUS*/
Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0);
downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent);
sendOrderedBroadcast(downIntent, null);

我已经在索尼、HTC和三星设备上测试了这段代码。

这段代码模拟了耳机上的播放/暂停按钮操作。


我猜它只能播放/暂停音乐。那么像下一首、上一首这样的功能该怎么实现呢? - Naddy
你能告诉我如何获取正在播放的歌曲的详细信息吗?我是否可以在广播接收器中获得回调以获取歌曲详情? - Pirate
嗨,我在安卓7上运行了这段代码,它可以正常工作。我的设备是华为GR5 2017。但是,在生产应用中我能依赖它吗?有人使用过吗?它在大多数安卓设备和版本上都能正常工作吗? - Md. Tahmid Mozaffar

7
如果您想控制音乐播放器(当前播放器),有一种方法可以向其发送KeyEvents:
if (mAudioManager == null) mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);

KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY);
mAudioManager.dispatchMediaKeyEvent(event);

这是一种更安全的方法,因为通常广播keyEvent可能会导致同时播放多个播放器。

注意:需要有minSdk 19或更高版本。


1
这里只需要再加一个补充:对于一些音乐应用(例如 Spotify),你甚至需要发送“KeyEvent.ACTION_UP”事件才能正常工作。 - Arsalan Mehmood

4

最新的SDK似乎无法使用引用的KeyEvent方法。对于我来说,使用AudioManager的dispatchMediaKeyEvent()方法和定义的KeyEvent有效。

参见:这里

代码示例:

this.mAudioManager = (AudioManager) this.context.getSystemService(Context.AUDIO_SERVICE);

long eventtime = SystemClock.uptimeMillis();

KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_NEXT, 0);
mAudioManager.dispatchMediaKeyEvent(downEvent);

KeyEvent upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_NEXT, 0);
mAudioManager.dispatchMediaKeyEvent(upEvent);

downIntentupIntent不需要,而且在upIntent行中有一个拼写错误,但这个程序完美运行!谢谢! - TheWanderer
谢谢@mpkasp!你知道我们是否可以获取当前播放歌曲的信息吗?干杯 - usernotnull
1
@RJFares 嗯,设置一个广播接收器并监听音乐播放器的变化。mMusicReceiver = new BroadcastReceiver(this); mIntentFilter = new IntentFilter(); mIntentFilter.addAction("com.apple.android.music.metachanged"); mIntentFilter.addAction("com.apple.android.music.playstatechanged"); 你可以通过 this.track = intent.getStringExtra("track"); 等方式获取曲目、专辑等信息。 - mpkasp

2

在最新的Android系统中,KeyEvent无法正常工作,也不支持像Spotify这样的应用程序。最好的解决方案是使用MediaController。对于当前正在播放且您想要控制的每个应用程序,您都需要创建不同的MediaController。它需要Context和MediaSession.Token。Token“标识”播放音乐的进程。例如,如果您正在播放Google Play音乐,现在又在播放Spotify,则可以为两者创建MediaControllers。如何检索令牌?有两种方法:

  • MediaSessionManager获取列表。您可以在Google示例项目中找到它。
  • 从通知中获取-如果您可以访问通知(NotificationListenerService),则可以搜索来自音乐应用程序的通知并获取其当前令牌。

您可以从MediaController中检查会话的当前状态:

getPlaybackState().getState() //e.g. PlaybackStateCompat.STATE_PLAYING

使用传输控制来控制应用程序,例如:

getTransportControls().skipToNext()

根据您使用的minSDK版本,可以使用Compat或非Compat版本。您可以使用以下方法将MediaSession.Token转换为MediaSessionCompat.Token:

MediaSessionCompat.Token.fromToken(token)

我喜欢这个仍然在一年半后保持相关性。它把一个两行命令变成了整个架构。我只是想跳过背景音乐,但 KeyEvent 方法不可靠,特别是一旦你断开与设备的连接,比如从 Google Cast 播放。 - Gary

1

Android 4.4中有一种名为RemoteController的新方法,但它很麻烦,我无法使其正常工作。它还要求您将用户引导至全局安全设置,并允许您的应用程序访问其所有通知!!!我不确定Google在想什么。

无论如何,我按照所有说明进行操作,但registerRemoteController()仍然返回false,所以我几乎无能为力(显然Google从未听说过错误代码)。

鉴于user2572182的方法似乎在Android 4.4上无法使用,因此这似乎是不可能的。

编辑:我在XDA上找到了一个使用RemoteController的示例应用程序(谁知道那里有有用的内容?)。它可以在我的手机上运行,但您仍然需要告诉用户去更改一些晦涩的安全设置,因此并不理想:

http://forum.xda-developers.com/showthread.php?p=51535568

编辑2:Google在Android“L”中再次更改了此项功能。我想他们意识到RemoteControlClient太过复杂。


你的第二个链接重定向到了7.0版本的“新特性”页面。 - Rosenpin

1
所有最新和旧版本的解决方案(从kitkat以下到Android 10)
/*global variable for audiomanager*/
 AudioManager mAudioManager;
/*initalize audiomanager in oncreate or onCreateView if using fragment*/
 mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
/*trigger keyEvent to play system music */
KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                        mAudioManager.dispatchMediaKeyEvent(event);
                    }
                    else
                    {
                        Intent i = new Intent(SERVICECMD);
                        i.putExtra(CMDNAME , CMDPLAY );
                        sendBroadcast(i);
                    }
/*you can use same code for stop system music but you need to change MEDIA_PLAY to MEDIA_STOP*/

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