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

Get details of app playing audio(获取应用程序播放音频的详细信息)
本文介绍了获取应用程序播放音频的详细信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序,该应用程序需要在设备重新启动后恢复音频播放。

我发现,简单地发送媒体播放按钮可能无法启动用户正在使用的同一个应用程序。(我正在运行Spotify,但在重启后发送播放按钮可打开Google Music)

是否有方法获取有关应用播放媒体的详细信息(重新启动前)?

我需要类似应用程序名称/活动名称/包名称等内容。 (这样我就可以在发送播放按钮之前启动相同的应用程序)

推荐答案

更新2:使用queryBroadcastReceivers接口,可能受package visibility filtering on Android 11 and higher影响。这意味着您必须声明QUERY_ALL_PACKAGES权限,并且在发布到Play Store时必须证明其使用的合理性。Android T似乎deprecate this API in favor of a slightly different one,但当前调用应该仍然有效。

更新:以下方法要求您实现AccessibilityService,Google Play现在对此有严格的要求和单独的审查流程,应用程序必须证明使用它的合理性。如果你实现以下内容,你的应用很可能会因为滥用此API而被Play Store拒绝。


虽然不完美,但我找到了一种方法来识别正在播放音乐的应用程序。

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

从技术上讲,遵循Android约定的音乐应用程序必须至少为CATEGORY_MUSIC_APP(或不推荐的MediaStore.INTENT_ACTION_MUSIC_PLAYER)设置意图过滤器,但我注意到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活动之前,您不会收到播放开始的通知。)
  • 谷歌音乐在启动后立即发布通知,可能没有播放音乐(另一款应用可能正在播放音乐。可能导致误报。)
  • iHeartRadio导致连续更改多个通知。

还可以从事件中获取Notification,并列出actions。如果任何Actiontitle"Play",则该应用程序不会播放音乐,而只是像上面解释的谷歌音乐那样发布通知。

(可以选择开始‘播放’意味着它现在不在播放。)此外,Play字符串不是标准字符串,可能会因应用程序和/或语言而异。假设字符串对大多数应用程序相同或相似,以支持可访问性等。并确保检查actions是否为空。如果通知使用自定义布局(例如:Spotify),则为空。(这也可能意味着盲人用户无法使用Spotify,因为辅助功能服务无法使用通知操作对其进行控制。)


更新: 如果您不想将其内置到您自己的应用程序中,也可以使用Automate这样的应用程序来处理此问题。

这篇关于获取应用程序播放音频的详细信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

How to target newer versions in .gitlab-ci.yml using auto devops (java 11 instead of 8 and Android 31 instead of 29)(如何在.gitlab-ci.yml中使用自动开发工具(Java 11而不是8,Android 31而不是29)瞄准较新的版本)
Android + coreLibraryDesugaring: which Java 11 APIs can I expect to work?(Android+core LibraryDesugering:我可以期待哪些Java 11API能够工作?)
How to render something in an if statement React Native(如何在If语句中呈现某些内容Reaction Native)
How can I sync two flatList scroll position in react native(如何在本机Reaction中同步两个平面列表滚动位置)
Using Firebase Firestore in offline only mode(在仅脱机模式下使用Firebase FiRestore)
Crash on Google Play Pre-Launch Report: java.lang.NoSuchMethodError(Google Play发布前崩溃报告:java.lang.NoSuchMethodError)