【问题标题】:Android MediaPlayer won't play music on API 26+Android MediaPlayer 不会在 API 26+ 上播放音乐
【发布时间】:2019-04-04 23:59:53
【问题描述】:

我有一个为用户流式传输音乐的应用程序,此代码在运行最高 API 25 的 Android 设备上运行良好,当我在运行 API 26 或更高版本的设备上测试时,音乐不会播放,也不会显示错误消息,附上我使用 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

【问题讨论】:

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


    【解决方案1】:

    您需要为该主机定义一个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() - 正如您的代码已经使用的那样。这似乎不是这里的“主要问题”;验证了。

    【讨论】:

    • 很好的答案,我在从运行在端口 9060 上的 laravel 服务器加载内容时遇到了类似的问题,我尝试添加一个像这样的新项目 111.222.333.444:9060 domain> 没有运气,文档说不允许使用 IP,那么在这种情况下我该如何继续?
    • @RonEskinder domain 配置需要一个主机名,没有端口。将注册域上的主机名发布到DNS 可能是绕过此限制的唯一方法。并不是说我会知道另一种可能性(除了使用任何公共DNS 服务器)。
    • 我更改了 network_security_config.xml 以允许所有连接,现在它工作正常&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;network-security-config&gt; &lt;base-config cleartextTrafficPermitted="true" /&gt; &lt;/network-security-config&gt;
    • @RonEskinder 这确实是我没有想到的一种可能性,因为反过来想,当谈到HTTPHTTPS 时(就简单地签署@987654337 @证书)。
    【解决方案2】:

    只需在application标签中添加一行

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

    【讨论】:

      【解决方案3】:

      请使用此代码。

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

      【讨论】:

      • setAudioStreamType() 对于 API 26+ 已弃用,这是我遇到的主要问题
      • @RonEskinder 主要问题是,您甚至不会加载文件。
      • 使用 setAudioAttributes(AudioAttributes) 代替 setAudioStreamType()。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-18
      相关资源
      最近更新 更多