GVKun编程网logo

Android MediaPlayer.reset()正在调用onCompletion(正在启动android)

15

本文将为您提供关于AndroidMediaPlayer.reset()正在调用onCompletion的详细介绍,我们还将为您解释正在启动android的相关知识,同时,我们还将为您提供关于(Andr

本文将为您提供关于Android MediaPlayer.reset()正在调用onCompletion的详细介绍,我们还将为您解释正在启动android的相关知识,同时,我们还将为您提供关于(Android MediaPlayer)如果MediaPlayer.create()隐式调用prepare(),我应该如何调用setAudioStreamType()?、Android MediaPlaye.getDuration()获取音视频时长的方式、Android Mediaplayer MediaController超时、android MediaPlayer NullPointerException的实用信息。

本文目录一览:

Android MediaPlayer.reset()正在调用onCompletion(正在启动android)

Android MediaPlayer.reset()正在调用onCompletion(正在启动android)

我遇到以下代码的问题.我在MediaController上调用了setPrevNextListener,并为Prev和Next定义了两个onClickListener.当我单击下一个按钮而不是前进一个轨道时,我前进两个轨道.这似乎是由于onCompletion被某种方式调用的事实. MediaPlayer.reset()是否会调用onCompletion?我已经包含了logcat输出和我的代码.如果我做错了,请告诉我.提前致谢.

logcat的:

02-24 00:36:34.826: D/MP(6675): Next Button Clicked,index was: 0
02-24 00:36:34.837: D/MP(6675): About to call Reset()
02-24 00:36:34.906: D/MP(6675): Inside setUpPlayer
02-24 00:36:34.917: D/MP(6675): Called setDataSource with index: 1
02-24 00:36:34.917: D/MP(6675): Leaving setUpPlayer
02-24 00:36:34.917: D/MP(6675): About to call prepareAsync()
02-24 00:36:34.937: D/MP(6675): Leaving next button
02-24 00:36:35.226: E/MediaPlayer(6675): Attempt to call getDuration without a valid mediaplayer
02-24 00:36:35.226: E/MediaPlayer(6675): error (-38,0)
02-24 00:36:35.276: E/MediaPlayer(6675): Error (-38,0)
02-24 00:36:35.287: D/MP(6675): Inside onCompletion
02-24 00:36:35.337: D/MP(6675): About to call Reset()
02-24 00:36:35.347: D/MP(6675): Inside setUpPlayer
02-24 00:36:35.356: D/MP(6675): Called setDataSource with index: 2
02-24 00:36:35.356: D/MP(6675): Leaving setUpPlayer
02-24 00:36:35.356: D/MP(6675): About to call prepareAsync()
02-24 00:36:35.377: D/MP(6675): Leaving onCompletion
02-24 00:36:36.517: D/MP(6675): Inside onPrepared,index is: 2
02-24 00:36:36.577: D/MP(6675): Leaving onPrepared

码:

public class MusicPlayerActivity extends Activity implements OnPreparedListener,OnCompletionListener,MediaController.MediaPlayerControl {

    private MediaPlayer mp;
    private MediaController mc;
    private SonarDatabase db;
    private SubsonicAPIConnector sonic;
    ArrayList<String> songs;
    int index = 0;
    private Handler handler = new Handler();

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

        // Get params from intent
        Intent i = getIntent();
        String albumId = i.getStringExtra("albumId");
        String artistId = i.getStringExtra("artistId");
        String albumName = i.getStringExtra("albumName");
        String songName = i.getStringExtra("songName");
        String songId = i.getStringExtra("songId");
        String coverArt = "al-"+albumId+".jpeg";
        String duration = i.getStringExtra("duration");
        Log.d("MP","results: albumName:" + albumName + ",songName: " + songName + ",songId: " 
                + songId + ",duration: " + duration + ",coverArt: " + coverArt + ",artistId: "
                + artistId + ",albumId: " + albumId);
        db = new SonarDatabase(getApplicationContext());
        sonic = new SubsonicAPIConnector(db.getURL(),db.getUsername(),db.getpassword());
        String artistName = db.getArtistNameById(artistId);
        setTitle("Now Playing");
        songs = db.getSongListForAlbum(albumId);
        index = songs.indexOf(songId); 
        Log.d("MP","songid: " + songId + ",index: " + index);
        // Update text views with song information
        TextView txtArtist = (TextView) findViewById(R.id.txtArtistName);
        txtArtist.setText(artistName);
        TextView txtAlbum = (TextView) findViewById(R.id.txtAlbumName);
        txtAlbum.setText(albumName);
        TextView txtSong = (TextView) findViewById(R.id.txtSongName);
        txtSong.setText(songName);

        // Show the album art
        File img = new File(this.getFilesDir()+"/covers/"+coverArt);
        if(img.exists()) {
            Log.d("MP","Found image at: " + img.toString());
            ImageView imgView = (ImageView) findViewById(R.id.cover_art);
            imgView.se@R_301_5026@Bitmap(BitmapFactory.decodeFile(img.getPath()));
        } else {
            Log.d("MP","Couldn't find image: " + img.toString());
        }


        // Create the media player and controller
        mp = new MediaPlayer();
        mp.setonPreparedListener(this);
        mp.setonCompletionListener(this);
        mc = new NonHidingMediaController(this);
        mc.setPrevNextListeners(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // next button clicked
                Log.d("MP","Next Button Clicked,index was: " + index);
                playNextTrack();
                Log.d("MP","Leaving next button");
            }
        },new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // prevIoUs button clicked
                Log.d("MP","PrevIoUs button clicked,index was: " + index);
                if(mp.isPlaying() && mp.getCurrentPosition() < 2000 && index != 0) {
                    Log.d("MP","Start the prior song.");
                    playPrevIoUsTrack();
                } else {
                    Log.d("MP","Restart this song.");
                    restartCurrentTrack();
                }   
                Log.d("MP","Leaving prevIoUs button");
            }
        });
        mc.setMediaPlayer(this);
        setUpPlayer();
        Log.d("MP","About to call prepareAsync()");
        mp.prepareAsync();
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        Log.d("MP","Inside onCompletion");
        //Todo add code for scrobbling here.
        playNextTrack();
        Log.d("MP","Leaving onCompletion");
    }


    private void playNextTrack() {
        index++;
        TextView txtSong = (TextView) findViewById(R.id.txtSongName);
        txtSong.setText(db.getSongNameById(songs.get(index)));
        Log.d("MP","About to call Reset()");
        mp.reset();
        setUpPlayer();
        Log.d("MP","About to call prepareAsync()");
        mp.prepareAsync();
    }

    private void playPrevIoUsTrack() {
        index--;
        TextView txtSong = (TextView) findViewById(R.id.txtSongName);
        txtSong.setText(db.getSongNameById(songs.get(index)));
        Log.d("MP","About to call prepareAsync()");
        mp.prepareAsync();

    }

    private void restartCurrentTrack() {
        mp.seekTo(0);
    }

    public void onPrepared(MediaPlayer mp) {
        Log.d("MP","Inside onPrepared,index is: " + index);
        mc.setMediaPlayer(this);
        mc.setAnchorView(findViewById(R.id.music_player_view));
        mp.start();
        handler.post(new Runnable() {
            public void run() {
                mc.setEnabled(true);
                mc.show();
            }
        });
        Log.d("MP","Leaving onPrepared");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_music_player,menu);
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d("MP","OnTouchEvent called");
        mc.show();
        return false;
    }

    private void setUpPlayer() {
        Log.d("MP","Inside setUpPlayer");
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            mp.setDataSource(sonic.streamString("&id=" + songs.get(index)));
            Log.d("MP","Called setDataSource with index: " + index);
        } catch (IllegalArgumentException e) {
            // Todo Auto-generated catch block
            e.printstacktrace();
        } catch (SecurityException e) {
            // Todo Auto-generated catch block
            e.printstacktrace();
        } catch (IllegalStateException e) {
            // Todo Auto-generated catch block
            e.printstacktrace();
        } catch (IOException e) {
            // Todo Auto-generated catch block
            e.printstacktrace();
        }
        Log.d("MP","Leaving setUpPlayer");
    }

    @Override
    protected void onStop() {
        super.onStop();
        mc.hide();
        mp.stop();
        mp.release();
    }

    public void start() {
        mp.start();
    }

    public void pause() {
        mp.pause();
    }

    public int getDuration() {
        return mp.getDuration();
    }

    public int getCurrentPosition() {
        return mp.getCurrentPosition();
    }

    public void seekTo(int i) {
        mp.seekTo(i);
    }

    public boolean isPlaying() {
        return mp.isPlaying();
    }

    public int getBufferPercentage() {
        return 0;
    }

    public boolean canPause() {
        return true;
    }

    public boolean canSeekBackward() {
        return true;
    }

    public boolean canSeekForward() {
        return true;
    }

    public class NonHidingMediaController extends MediaController {
        public NonHidingMediaController(Context context,AttributeSet attrs) {
            super(context,attrs);
        }

        public NonHidingMediaController(Context context,boolean useFastForward) {
            super(context,useFastForward);
        }

        public NonHidingMediaController(Context context) {
            super(context);
        }

        @Override
        public void show(int timeout) {
            super.show(0);
        }

    }


}

解决方法

我对android源码进行了一些挖掘,发现任何未处理的错误都会导致MediaPlayer调用onCompletion处理程序.在这种情况下,您似乎在空闲,初始化或错误状态下调用getDuration.可以从媒体控制器内部进行.我建议在调用getDuration的任何地方之前添加一些Log.d(),以查看导致问题的调用的位置.

(Android MediaPlayer)如果MediaPlayer.create()隐式调用prepare(),我应该如何调用setAudioStreamType()?

(Android MediaPlayer)如果MediaPlayer.create()隐式调用prepare(),我应该如何调用setAudioStreamType()?

我正在编写一个使用服务的 Android闹钟应用程序来播放闹钟.目前,我可以获得播放的音频,但播放的形式可以通过关闭设备的音量进行静音.因此,我试图添加一个调用setAudioStreamType(AudioManager.STREAM_ALARM);以防止这种情况.

我为我的onStartCommand()函数提供以下服务:

MediaPlayer mMP;    
@Override
    public int onStartCommand(Intent intent,int flags,int startId)
    {
        try
        {
            mMP = MediaPlayer.create(this,R.raw.alarm);
            mMP.setAudioStreamType(AudioManager.STREAM_ALARM);
            mMP.setLooping(true);
            //mMP.prepare(); commented out since prepare() is called in create
        }
        catch (Exception e)
        {
            e.printstacktrace();
        }
        if (mMP != null) mMP.start();

        return START_STICKY;
    }

我的问题是,通过调用setAudioStreamType(),MediaPlayer从不播放音频.如果我评论该行,音频播放.

有了行,我得到以下运行时错误:

04-10 19:32:03.115: E/MediaPlayer(3411): setAudioStream called in state 8

04-10 19:32:03.115: E/MediaPlayer(3411): error (-38,0)

04-10 19:32:03.115: E/MediaPlayer(3411): start called in state 0

04-10 19:32:03.115: E/MediaPlayer(3411): error (-38,0)

04-10 19:32:03.115: E/MediaPlayer(3411): Error (-38,0)

有些研究(现在我找不到链接)告诉我,在调用prepare()之后,setAudioStreamType()不能被调用,而create()隐含地调用prepare().

在任何方面,我应该如何设置AudioStreamType()没有这样的错误?

解决方法

您可以调用mp.reset(),然后设置流类型,数据源,然后准备.或者,只需使用默认构造函数并自己处理初始化.

编辑:

Resources res = getResources();
AssetFileDescriptor afd = res.openRawResourceFd(R.raw.alarm);

mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_ALARM);
mp.setLooping(true);
mp.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
mp.prepare();
mp.start();

Android MediaPlaye.getDuration()获取音视频时长的方式

Android MediaPlaye.getDuration()获取音视频时长的方式

android MediaPlaye.getDuration()获取不到在线音乐时长,看看mediaPlayer.getDuration()的源码,里面明确地说了,不支持在线内容,所以,根本原因就是它(不过我本地资源也获取不到)

 /**
     * Gets the duration of the file.
     *
     * @return the duration in milliseconds,if no duration is available
     *         (for example,if streaming live content),-1 is returned.
     */
    public native int getDuration();

解决办法:使用MediaMetadataRetriever获取音视频总时长。

try {
	//1,创建MediaMetadataRetriever对象
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    //2.设置音视频资源路径
    retriever.setDataSource(path);
    //3.获取音视频资源总时长
    String time = retriever.extractMetadata(MediaMetadataRetriever.MetaDATA_KEY_DURATION);
    
}catch (Exception e){
    e.printstacktrace();
}

遇到的问题:
报错:java.lang.RuntimeException: setDataSource Failed: status = 0x80000000
解决办法:
1.加网络权限

<uses-permission android:name=@H_301_115@"android.permission.INTERNET" />

2.替换下setDataSource的参数形式

FileInputStream inputStream = null;
   try {
       	inputStream = new FileInputStream(new File(currentAudioPath).getAbsolutePath());
       	retriever.setDataSource(inputStream.getFD());
       } catch (Exception e) {
        e.printstacktrace();
   }
String time = retriever.extractMetadata(MediaMetadataRetriever.MetaDATA_KEY_DURATION);

3.场景:使用MediaRecorder录制短视频,结束录后,马上通过path获取短视频的时长。这样也会导致报错;

原因:在MediaRecorder.release() 之前调用了获取时长的方法。
解释:MediaRecorder.release()没有调用前,视频文件还属于不完整状态。
解决方案:在MediaRecorder.release()结束后在调用获取时长的方法。

但是,通过这种方法获取的duration可能不准确,对于VBR格式的mp3,duration可能远远比真实的长度小。对于这个问题,可以用比特率和文件大小来计算:

下面是我采用的方式

  MediaMetadataRetriever retriever = new MediaMetadataRetriever();
  long fileSize = new File(currentAudioPath).length();
  retriever.setDataSource(new File(currentAudioPath).getAbsolutePath());
  long bitRate = Long.parseLong(retriever.extractMetadata(MediaMetadataRetriever.MetaDATA_KEY_BITRATE));
  long duration = (fileSize*8) /(bitRate);//单位秒
  retriever.release();//务必release

Android Mediaplayer MediaController超时

Android Mediaplayer MediaController超时

香港专业教育学院实现了流媒体的MP3 URL的mediaplayer和mediacontroller.但是,我在TMobile网络上的设备无法获得很好的3G信号,因此可以在EDGE上运行.我假设媒体播放器因流太慢或不完整而崩溃,是否可以设置超时?

解决方法:

MediaPlayer中没有超时方法,但是您可以自己实现-有多种方法可以执行.
我建议其中之一,我用了自己,对我有用-broadcastReceiver
代码如下所示:

public class ConnectivityCheckingReceiver extends WakefulbroadcastReceiver
{
  private AlarmManager alarmManager;
  private PendingIntent pendingIntent;

  @Override
  public void onReceive(Context context, Intent intent)
  {
    if (MusicService.mediaPlayer != null)
    {
        if (!MusicService.mediaPlayer.isPlaying())
            Log.v("Music", "Music is NOT playing"); 
            //stop service and notify user
        else
            Log.v("Music", "Music is playing");
    }
    else
    {
        Log.v("Music", "User stopped player");
    }
  }
  public void setAlarm (Context context, int hour, int minute, int second)
  {
    alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, ConnectivityCheckingReceiver.class);
    pendingIntent = PendingIntent.getbroadcast(context, 0, intent, 0);
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, hour);
    calendar.set(Calendar.MINUTE, minute);
    calendar.set(Calendar.SECOND, second);
    alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);      
  }
}

在活动/服务/片段中添加以下行:

ConnectivityCheckingReceiver conCheck = new ConnectivityCheckingReceiver();
conCheck.setAlarm(context, hour, min, second);

您将需要自己实现小时/分钟/秒检查逻辑,但是使用Joda Time之类的库就可以轻松实现.
并且不要忘记添加到清单中:

<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name=".receivers.ConnectivityCheckingReceiver" />

附言:我的解决方案不是完美的,但是我没有看到关于此问题的任何好答案,因此,如果找到一个,请分享.

android MediaPlayer NullPointerException

android MediaPlayer NullPointerException

我有点难以对此进行故障排除,因为我是通过其他人的 Android设备的崩溃报告得到的,我无法向他们提问,而且我从未在自己的Android设备上看到它.

崩溃报告说它是Android 4.1.2,堆栈跟踪是:

java.lang.NullPointerException
at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2102)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
at dalvik.system.NativeStart.main(Native Method)

不幸的是,grepcode.com上的android源代码似乎与这些行号不匹配,所以我不确定哪个是null.

当发生这种情况时,我不知道用户正在做什么,所以我不知道这是在音乐或声音效果正在播放时发生,还是在发生破坏时发生了什么.我有点怀疑它可能在毁灭期间发生.我在activity的onDestroy方法中有以下代码:

public void onDestroy() {
    synchronized(curPlayers) {
        for(List<MediaP> ms : curPlayers.values()) {
            synchronized(ms) {
                for(MediaP m : ms) {
                    synchronized(m) {
                        m.m.stop();
                        m.m.release();
                    }
                }
            }
        }
        curPlayers.clear();
    }
}

private static class MediaP {
    private MediaP(MediaPlayer m) {
        this.m = m;
    }

    private MediaPlayer m;
    private boolean wasplaying = false;
}

那里有什么我应该做的吗?

解决方法

在release()之前删除对MediaPlayer.stop()的调用.我们在Nexus 4,5,7,10和Moto X上看到过很多类似的崩溃.你可以在这里阅读更多内容 NullPointerException in MediaPlayer$EventHandler.handleMessage

据我所知,有一次他们切换到从stop()发送消息,如果你不够运气,你的release()会在检查到它不为空并尝试调用其方法后立即使对象无效.

关于Android MediaPlayer.reset()正在调用onCompletion正在启动android的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于(Android MediaPlayer)如果MediaPlayer.create()隐式调用prepare(),我应该如何调用setAudioStreamType()?、Android MediaPlaye.getDuration()获取音视频时长的方式、Android Mediaplayer MediaController超时、android MediaPlayer NullPointerException等相关知识的信息别忘了在本站进行查找喔。

本文标签: