【问题标题】:MediaPlayer start()/stop() mUri is nullMediaPlayer start()/stop() mUri 为空
【发布时间】:2013-04-30 22:12:51
【问题描述】:

我有一个看起来像这样的活动,

public class TestActivity extends Activity {

    private SensorManager      mSensorManager;
        private ShakeEventListener mSensorListener;
    private MediaPlayer        mPlayer;

    private boolean            mIsPlaying; 

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE); 

        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.testsound);

        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensorListener = new ShakeEventListener();   
        mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() {

          @Override 
          public void onShake() {
            toggleSound();
          }
        });  
    }

    @Override
    protected void onResume() {
      super.onResume();
      mSensorManager.registerListener(mSensorListener,
          mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
          SensorManager.SENSOR_DELAY_UI);
    }

    @Override
    protected void onPause() {
      super.onPause();
      mSensorManager.unregisterListener(mSensorListener);
      stopSound();
    }    

    protected void toggleSound() {
        if (!mIsPlaying) {
          startSound();
        } else {
          stopSound();  
        }
    }


    protected void startSound() {

        if (mPlayer == null)
          {
            mPlayer = MediaPlayer.create(TestActivity.this, R.raw.test);
            mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 

            mPlayer.setLooping(true);
            mPlayer.start();  

            mPlayer.setOnCompletionListener(new OnCompletionListener() {

                 @Override
                public void onCompletion(MediaPlayer mp) {
                  stopSound();
                }
            }); 

            mIsPlaying = true;
          }
    }


    protected void stopSound() {
        if (mPlayer != null) {
              if (mPlayer.isPlaying())
              {
                  mPlayer.stop();
              }
              mPlayer.release();
              mPlayer = null;
        }

        mIsPlaying = false;
    }

}

我知道这可能不是最好的方法,但我只是从一些随机测试开始。我没有包含 ShakeEventListener,但这几乎只是检测到一个抖动事件,在该事件上循环播放一个样本声音(是的,这很烦人!)直到下一次抖动。

这实际上工作得很好,除了我得到带有标签 MediaPlayer 的 LogCat 条目,在执行启动和停止命令时显示 start() mUri is nullstop() mUri is null。这让我相信我做错了什么,但当我在谷歌上搜索了一下时,我无法找出它是什么,这显然也不是一个流行的错误。

有人知道这意味着什么吗?对不起,如果我太厚了——我还是有点困惑。

更新(来自 cmets):我做的一件事是给它一个实际的 Uri(从路径构建),然后它带有一个类似的警告,现在说 start() mUri is android.resource://com.joris.soundtest/2130968576(D 级),这次之前是一个 E -level Uri is android.resource//...(点给出相同的 uri)。这些 LogCat 条目是否可能只是“信息性”,用于调试? E级的听起来不像..

谢谢! -乔里斯。

【问题讨论】:

  • 尝试将上下文传递给 startSound 方法,如图所示here
  • 不幸的是,这并没有改变 LogCat 的输出。我做的一件事是给它一个实际的 Uri(从路径构建),然后它带有一个类似的警告,现在说 start() mUri is android.resource://com.joris.soundtest/2130968576(D 级),这次之前是 E 级 Uri is android.resource//...(点给出相同乌里)。那些 LogCat 条目是否可能只是“提供信息”,用于调试?

标签: java android uri android-mediaplayer


【解决方案1】:

更改以下内容,因为 mediaplayer.release() 方法不会使 mediaplayer 对象为 null ...

package com.pranav.listviewdemo;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

public class MainActivity extends Activity {

    private SensorManager      mSensorManager;
    private ShakeEventListener mSensorListener;
    private MediaPlayer        mPlayer;
    static int i=1;

    private boolean            mIsPlaying=false; 

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE); 

        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);

        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensorListener = new ShakeEventListener(this,null);   
        mPlayer = MediaPlayer.create(this, R.raw.test);
        mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 

        mPlayer.setLooping(true);

        mPlayer.setOnCompletionListener(new OnCompletionListener() {

             @Override
            public void onCompletion(MediaPlayer mp) {
              stopSound();
            }
        }); 
        mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() {

          @Override 
          public void onShake() {
            toggleSound();
            Toast.makeText(getBaseContext(), "DETECTED"+i, Toast.LENGTH_SHORT).show();
            i++;
          }
        });  
    }

    @Override
    protected void onResume() {
      super.onResume();
      mSensorManager.registerListener(mSensorListener,
          mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
          SensorManager.SENSOR_DELAY_UI);
    }

    @Override
    protected void onPause() {
      super.onPause();
      mSensorManager.unregisterListener(mSensorListener);
      stopSound();
    }    

    protected void toggleSound() {
        if (!mIsPlaying) {
          startSound();
        } else {
          stopSound();  
        }
    }


    protected void startSound() {

        if (mPlayer != null)
          {
            mPlayer.seekTo(0);
            mPlayer.start();  
            mIsPlaying = true;
          }
    }


    protected void stopSound() {
        if (mPlayer != null) {
              if (mPlayer.isPlaying())
              {
                  mPlayer.pause();
                  mIsPlaying = false;
              }

        }


    }

}

【讨论】:

  • 我自己在 stopSound() 中,在 release() 之后将其设置为 NULL。这实际上似乎有效。我已经尝试在我的 OnCreate 方法中执行 mPlayer.create(..) 事情,然后只在 startSound 和 stopSound 中启动和停止,在 OnPause 中使用 release()。从长远来看,这会是更优雅的事情吗?目前它在任何情况下都会给我各种致命异常(在非法状态下调用等),但我可以尝试解决它们,如果它是对持续使用 create() 和 release() + 的改进空。
  • 哦,太棒了,感谢您的努力 - 我今晚会试一试。但是,通过快速检查,看起来 mPlayer 永远不会为 NULL(这可能会导致它永远不会在 startSound() 中启动声音?),并且没有任何版本(从我在线阅读的内容来看) ,出于资源目的,这是非常强制性的)。我很可能遗漏了一些东西。我通常只有在尝试过之后才能正确理解代码。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 1970-01-01
  • 2013-01-23
相关资源
最近更新 更多