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

时间:2019-04-04 23:59:54

标签: android android-mediaplayer android-8.0-oreo

我有一个可以为用户播放音乐的应用,当我在运行API 25或更高版本的设备上进行测试时,此代码在运行Android且设备达到API 25的设备上可以正常运行,音乐也不会播放并且不会显示错误消息,是使用API​​ 28设备时的日志。

我尝试过的事情:

  • MediaPlayer.setAudioStreamType(int streamtype)已弃用,因此我为26以上的API实现了AudioAttributes
  • 不同类型的mp3文件,但它们在api 25及以下版本中都发挥相同的作用,当我尝试使用API​​ 26在设备或仿真器上进行任何操作
  • 在文档和示例中进行搜索,但是看起来都一样,我的代码也没什么不同

    private void playMusic() {
    try {
        mMediaPlayer.reset();
    
        // For Android API 26 (Android 8 Oreo) and newer, specify AudioAttributes.
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            Log.d("Record", "setAudioAttributes()");
            AudioAttributes.Builder builder = new AudioAttributes.Builder();
            builder.setUsage(AudioAttributes.USAGE_MEDIA);
            builder.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC);
            AudioAttributes attributes = builder.build();
            mMediaPlayer.setAudioAttributes(attributes);
    
        } else {
            Log.d("Record", "setAudioStreamType()");
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        }
    
        mMediaPlayer.setDataSource(String.format("http://www.server.com/mp3/%s.mp3", mp3File));
        mMediaPlayer.prepareAsync();
        mMediaPlayer.start();
    
    } catch (IOException e) {
        Log.d("Record", "error playing mp3");
        e.printStackTrace();
    }
    }
    

日志

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

3 个答案:

答案 0 :(得分:5)

You need to define a res/xml/network_security_config.xml and permit HTTP for that host:

<?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>

That network_security_config.xml also needs to be referenced in the Manifest.xml:

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

The SDK documentation explains it all in detail - and this applies to all network traffic an app creates.

Instead of lowering the security standards, upgrading the connection to HTTPS should be preferred.


And concerning that one deprecated method .setAudioStreamType(), use .setAudioAttributes() instead - as your code already does. It does not seem to be the "main problem" here; verified that.

答案 1 :(得分:0)

Please use this code.

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();

                }

            });

答案 2 :(得分:0)

只需在application标签中添加一行

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