问题 声音没有在android> icecream sandwich中播放


我正在使用以下代码播放声音。在ICS之前一切正常。但是在ICS和更高版本上没有听到声音。没有错误,但听不到声音。

编辑:注意,以下代码由广泛的接收器触发。 BroadCast接收器调用异步任务。在asycn任务的后处理方法中,调用以下方法。

错误可能是什么?

public static void playSound(final Context context, final int volume,
            Uri uri, final int stream, int maxTime, int tickTime) {
        //stopPlaying();
        /*
        if (stream < 0 || stream > 100) {
            throw new IllegalArgumentException(
                    "volume must be between 0 and 100 .Current volume "
                            + volume);
        }*/

        final AudioManager mAudioManager = (AudioManager) context
                .getSystemService(Context.AUDIO_SERVICE);

        int deviceLocalVolume = getDeviceVolume(volume,
                mAudioManager.getStreamMaxVolume(stream));

        Log.d(TAG,
                "device max volume = "
                        + mAudioManager.getStreamMaxVolume(stream)
                        + " for streamType " + stream);
        Log.d(TAG, "playing sound " + uri.toString()
                + " with device local volume " + deviceLocalVolume);

        final int oldVolume = mAudioManager.getStreamVolume(stream);

        // set the volume to what we want it to be. In this case it's max volume
        // for the alarm stream.
        Log.d(Constants.APP_TAG, "setting device local volume to " + deviceLocalVolume);
        mAudioManager.setStreamVolume(stream, deviceLocalVolume,
                AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);

         final MediaPlayer mediaPlayer = new MediaPlayer();
         golbalMMediaPlayer = mediaPlayer;

        try {
             final OnPreparedListener OnPreparedListener = new OnPreparedListener() {

                @Override
                public void onPrepared(final MediaPlayer mp) {
                    Log.d(TAG, "onMediaPlayercompletion listener");
                    mp.start();
                    countDownTimer.start();
                }
            };

            mediaPlayer.setDataSource(context.getApplicationContext(), uri);
            mediaPlayer.setAudioStreamType(stream);
            mediaPlayer.setLooping(false);
            mediaPlayer.setOnPreparedListener(OnPreparedListener);
            mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

                @Override
                public void onCompletion(MediaPlayer mp) {
                    Log.d(Constants.APP_TAG, "Entered onCompletion listener of mediaplayer");
                    mAudioManager.setStreamVolume(stream, oldVolume,
                            AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                    try{
                    if(mediaPlayer != null && mediaPlayer.isPlaying()){
                        mediaPlayer.release();
                    }
                    }catch(Exception ex){
                        Log.e(Constants.APP_TAG, "error on oncompletion listener" ,ex);
                    }
                }

            });

             CountDownTimer timer = new CountDownTimer(maxTime*1000, tickTime*1000) {

                @Override
                public void onTick(long millisUntilFinished) {
                    Log.d(TAG, "tick while playing sound ");
                }

                @Override
                public void onFinish() {
                    Log.d(TAG, "timer finished");
                    stopPlaying();
                }
            };

            countDownTimer = timer;

            mediaPlayer.prepareAsync();

        } catch (Exception e) {
            Log.e(TAG, "problem while playing sound", e);
        } finally {

        }
    }

日志:

:07-01 00:00:00.030: D/beephourly(9500): device max volume = 7 for streamType 5
07-01 00:00:00.030: D/beephourly(9500): playing sound content://media/internal/audio/media/166 with device local volume 7
07-01 00:00:00.030: D/beephourly(9500): setting device local volume to 7
07-01 00:00:00.080: D/beephourly(9500): vibrating with pattern = [J@428bae20
07-01 00:00:00.090: D/beephourly(9500): will show normal notification
07-01 00:00:00.100: D/beephourly(9500): notification is enabled
07-01 00:00:00.100: D/usersettings(9500): hr = 0
07-01 00:00:00.110: D/beephourly(9500): onMediaPlayercompletion listener
07-01 00:00:00.451: D/beephourly(9500): tick while playing sound 
07-01 00:00:20.460: D/beephourly(9500): timer finished
07-01 00:00:20.460: D/beephourly(9500): got request to stop playing
07-01 00:00:20.460: D/beephourly(9500): cancelling countdowntimer
07-01 00:00:20.460: D/beephourly(9500): releasing mediaplayer now

1113
2018-06-30 18:33


起源

您是否尝试过其他设备ICS +? - Pr38y
对setStreamVolume的调用看起来很可疑。您可以验证设备的音量设置,然后将呼叫删除 mAudioManager.setStreamVolume? - selbie
在跟随之前我也有问题 这个 它会对你有用。 - bhavesh kaila


答案:


尝试这个 :

播放声音

public class PlaySound extends Activity implements OnTouchListener {
  private SoundPool soundPool;
  private int soundID;
  boolean loaded = false;


/** Called when the activity is first created. */

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  View view = findViewById(R.id.textView1);
  view.setOnTouchListener(this);
  // Set the hardware buttons to control the music
  this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
  // Load the sound
  soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
  soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {

  @Override
  public void onLoadComplete(SoundPool soundPool, int sampleId,
      int status) {
     loaded = true;
  }
  });
  soundID = soundPool.load(this, R.raw.sound1, 1);

  }

 @Override
 public boolean onTouch(View v, MotionEvent event) {
  if (event.getAction() == MotionEvent.ACTION_DOWN) {
  // Getting the user sound settings
  AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
  float actualVolume = (float) audioManager
      .getStreamVolume(AudioManager.STREAM_MUSIC);
  float maxVolume = (float) audioManager
      .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
  float volume = actualVolume / maxVolume;
  // Is the sound loaded already?
  if (loaded) {
    soundPool.play(soundID, volume, volume, 1, 0, 1f);
    Log.e("Test", "Played sound");
  }
}
 return false;
}
} 

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="Click on the screen to start playing" >
</TextView>

</LinearLayout> 

来源链接: http://www.vogella.com/tutorials/AndroidMedia/article.html#sound


9
2017-07-09 06:26





有时MediaPlayer对象必须声明为公共变量,否则它们将被Dalvik Heap删除。

public final MediaPlayer mediaPlayer = new MediaPlayer();

1
2017-07-06 15:06



我假设 golbalMMediaPlayer 是一个静态参考。 - matiash


private MediaPlayer mPlayer;
....
SoundPool sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
    int iTmp = sp.load(getBaseContext(), R.raw.windows_8_notify, 1); 
    sp.play(iTmp, 1, 1, 0, 0, 1);
    mPlayer = MediaPlayer.create(getBaseContext(), R.raw.windows_8_notify);
    mPlayer.start();
    mPlayer.setLooping(true); }

首先,在你的所有私人所在的地方,在onCreate之前,放第一行,然后,在onCreate内部启动音乐,只需确保将“windows_8_notify”更改为你想要的歌曲的名称。


1
2017-07-06 15:12





我会在IllegalStateException中包装调用,通过调试器运行它,看看你得到了什么。

要尝试的事情

  1. 设置布尔值isPlaying = mp.isPlaying();并检查其价值。

  2. 在开始之前尝试mp.reset()并查看它是否有效。

  3. 实现MediaPlayer.OnErrorListener并使用媒体播放器注册该方法。

看看你得到了什么错误。 这个 可能会有所帮助。


1
2017-07-09 05:57





日志
  ... streamType 5

StreamType 5表示STREAM_NOTIFICATION。
(从通知中调用?)

它应该是STREAM_MUSIC(3)


要检查它不是ICS /设备特定问题,
  - 在res / raw /文件夹下放置声音文件(sound_01.ogg或sound_01.mp3)
  - 在main_layout中放置名为start_button和stop_button的按钮
试试这个。
(我已经使用API​​10和API19模拟器检查了此代码并播放了声音。)

import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity
// implements MediaPlayer.OnPreparedListener
{
    private MediaPlayer mediaPlayer;
    private boolean isPrepared;
    private boolean isPlaying;

    private View start_button;
    private View stop_button;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);
        Init();
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        Load();
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        Unload();
    }

    private void Init()
    {
        setVolumeControlStream(AudioManager.STREAM_MUSIC);

        start_button = findViewById(R.id.start_button);
        stop_button = findViewById(R.id.stop_button);

        start_button.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Play();
            }
        });
        stop_button.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Stop();
            }
        });
    }

    private void Load()
    {
        Unload();

        // load from resource (res/raw/xx.ogg or .mp3)
        // It's better to use thread
        mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sound_01); // On success, prepare() will already have been called
        // mediaPlayer.setOnPreparedListener(this); // cannot set this listener (MediaPlayer.create does not return before prepared)
        isPrepared = true;
    }

    private void Unload()
    {
        isPrepared = false;
        if (null != mediaPlayer)
        {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    // @Override
    // public void onPrepared(MediaPlayer mp)
    // {
    // isPrepared = true;
    // }

    private void Play()
    {
        // If you got "start called in state xx" error, no sound will be heard.
        // To reset this error, call reset(), setDataSource() and prepare()
        // (for resources: call release() and create())
        if (!isPrepared)
        {
            return;
        }
        mediaPlayer.start();
        isPlaying =  true;
    }

    private void Stop()
    {
        // Do not omit this check
        // or you will get "called in wrong state" errors
        // like "pause called in state 8"   
        // and error (-38, 0)
        if (!isPlaying)
        {
            return;
        }
        isPlaying = false;
        mediaPlayer.pause();
        mediaPlayer.seekTo(0);
    }
}

如果它是ICS /设备特定的,这些链接可能会有所帮助。 (有点老......)


1
2017-07-10 11:07



:感谢回复。以前我使用流类型3,现在使用5但仍面临同样的问题。备注:此代码由广播接收器触发。 BroadCast接收器调用异步任务。在asycn任务的后处理方法中调用playSound方法。这个问题很奇怪。请你帮忙 - user93796


如果您在程序中的其他任务中使用其他AsyncTasks或SerialExecutor,则可能会出现问题(如果您使用的是第三方SDK,则可能甚至不知道)。

看这里的帖子:

https://code.google.com/p/android/issues/detail?id=20941

我建议这样做,因为你的声音“滴答”也不起作用。因此,AudioPlayer必须执行不正确的设置并不是一个问题,而是一些其他任务似乎阻止它直到该任务停止,并且它可能是一个与您希望听到声音同时运行的任务。


0
2017-08-10 10:37