Android MediaPlayer 无法在 API 26+ 上播放音乐

Android MediaPlayer won't play music on API 26+

我有一个为用户流式传输音乐的应用程序,当我在设备 运行 API 26 或更高版本音乐无法播放,也不会显示错误消息,附件是我使用 API 28 设备时的日志。

我尝试过的:

日志

2019-04-04 17:51:38.911 2947-24864/com.roneskinder.karaoke 
V/MediaPlayer: resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
2019-04-04 17:51:38.911 2947-24864/com.roneskinder.karaoke V/MediaPlayer: cleanDrmObj: mDrmObj=null mDrmSessionId=null
2019-04-04 17:51:38.913 2947-3054/com.roneskinder.karaoke D/EGL_emulation: eglMakeCurrent: 0xe830ce20: ver 3 0 (tinfo 0xe8315bd0)
2019-04-04 17:51:38.915 2947-24864/com.roneskinder.karaoke V/MediaHTTPService: MediaHTTPService(android.media.MediaHTTPService@aa03fa3): Cookies: null
2019-04-04 17:51:38.920 2947-4147/com.roneskinder.karaoke V/MediaHTTPService: makeHTTPConnection: CookieHandler (java.net.CookieManager@ead45b3) exists.
2019-04-04 17:51:38.920 2947-4147/com.roneskinder.karaoke V/MediaHTTPService: makeHTTPConnection(android.media.MediaHTTPService@aa03fa3): cookieHandler: java.net.CookieManager@ead45b3 Cookies: null

请使用此代码。

MediaPlayer player = new MediaPlayer();

player.setDataSource("http://www.server.com/mp3/%s.mp3");
player.setLooping(false);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.prepareAsync();

player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

                @Override
                public void onPrepared(MediaPlayer player) {
                    player.start();

                }

            });

您需要为该主机定义 res/xml/network_security_config.xml 并允许 HTTP

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">server.com</domain>
    </domain-config>
</network-security-config>

那个network_security_config.xml也需要在Manifest.xml中引用:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    ...>
    <application
        android:networkSecurityConfig="@xml/network_security_config"
        ...>
            ...
    </application>
</manifest>

SDK documentation 对此进行了详细解释 - 这适用于应用创建的所有网络流量。

与其降低安全标准,不如将连接升级到 HTTPS


关于那个已弃用的方法 .setAudioStreamType(),请改用 .setAudioAttributes() - 正如您的代码已经做的那样。这里好像不是"main problem";验证了。

只需在 application 标签中添加一行

<application
        .......
        android:usesCleartextTraffic="true"
        .......>
        .......
    </application>