获取应用播放音频的详细信息

时间:2016-09-02 10:19:56

标签: android audio media

我正在开发一款需要在设备重启后恢复音频播放的应用。

我发现只是发送媒体播放按钮可能无法启动用户使用的同一个应用程序。 (我已经发现运行,但在重新启动后发送播放按钮会打开Goog​​le音乐)

有没有办法获取应用播放媒体的详细信息(重启前)?

我需要类似app name / activity name / package name .etc。 (所以我可以在发送播放按钮之前启动相同的应用程序)

1 个答案:

答案 0 :(得分:3)

虽然不完美,但我发现了一种识别当前播放音乐的应用程序的方法。

我的方法是利用音乐播放器必须发布'正在进行的事实。通知,以防止被系统杀死,他们通常有一个Broadcast Receiver来处理媒体按钮。

技术上遵循android惯例的音乐应用程序必须为CATEGORY_MUSIC_APP(或已弃用的MediaStore.INTENT_ACTION_MUSIC_PLAYER)设置一个intent过滤器,用于其至少一项活动,但我注意到当前版本的iHeartRadio app决定不打扰。

所以这是我的方法

  • 注册Accessibility Service来监控Android通知
    • (音乐播放器必须发布'正在进行的'通知,以防止在CPU或内存压力下被Android杀死。)

辅助功能服务必须至少具备 android:accessibilityEventTypes="typeNotificationStateChanged"已由用户明确注册和启用。

服务必须按如下方式处理通知事件

@Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
        if (accessibilityEvent.getEventType() ==
           AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
            String packageName = accessibilityEvent.getPackageName().toString();

            AudioManager am = (AudioManager) getSystemService(AUDIO_SERVICE);
            boolean musicPlaying = am.isMusicActive();

            if (!musicPlaying) {
                Log.i("NOTIFICATION", "no one is playing music. (anymore...)");
               return; // clear saved package
            }

            PackageManager pm = getPackageManager();    
            Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);                
            i.setPackage(packageName);    

            List<ResolveInfo> a = pm.queryBroadcastReceivers(i, PackageManager.MATCH_ALL);

            if (a.size() > 0)
                Log.i("NOTIFICATION", "Music is played by: " + packageName);
                // save packageName to somewhere
            else
                Log.i("NOTIFICATION", "irrelevant notification from package: " + packageName);
        }
    }

稍后重启设备时,启动默认活动并按播放按钮。

Intent i = new Intent(Intent.ACTION_VIEW);
i.addCategory(Intent.CATEGORY_DEFAULT); 
i.setPackage(savedPackage);
startActivity(i);

AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

 am.dispatchMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY));
 am.dispatchMediaKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY));

 // may be fire another intent for home/launcher. so user doesn't have to

假设/警告

  • 音乐应用程序直接转到可以播放的活动(如果您还没有登录到该设备上的服务,iHeartRadio会要求登录)
  • 音乐应用保存上次播放状态。如果不是这种情况,则可以从曲目/播放列表的开头而不是用户离开的地方开始播放。
  • 准确度可能会有所不同
    • Spotify在用户离开活动或屏幕关闭时发布通知,并在播放状态发生变化时更新相同的通知(我们未通知现有通知更改。您不会收到通知播放开始,直到Spotify活动暂停。)
    • Google音乐会在通知发布后立即发布,并且可能无法播放音乐(其他应用可能正在播放音乐。可能会导致误报。)
    • iHeartRadio连续导致多个通知更改。

您还可以从活动中获取Notification,并列出actions。如果任何title的{​​{1}}为Action,则该应用不会播放音乐,只会发布上述Google音乐的通知。

(可以选择开始播放&#39;意味着它现在没有播放。)此外,字符串&#39; Play&#39;不是标准的,可能因应用和/或语言而异。假设大多数应用程序的字符串相同或相似,以支持可访问性.etc。并确保检查"Play"是否为空。如果通知使用自定义布局(例如:Spotify),则为null。 (可能还意味着盲人用户不能使用Spotify,因为Accessiblity Services无法使用通知操作来控制它。)

<强>更新 如果您不想将其构建到自己的应用中,也可以使用Automate等应用来处理此问题。