1、打开音乐库
<span style="font-size:18px;">Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI); //打开音乐库 startActivityForResult(intent, 0);</span>2、得到手机中音乐信息
<span style="font-size:14px;">private void get_list() { ContentResolver musicResolver = this.getContentResolver(); Cursor musicCursor = musicResolver.query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null); while (musicCursor.moveToNext()) { long id = musicCursor.getLong(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns._ID)); String path = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA));//文件的路径 String display_name = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns.DISPLAY_NAME));//文件的名字 int size = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns.SIZE));//文件的长度 String album = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM));//音乐的专辑 String artist = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST));//歌手的名字 String title = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE));//歌曲的名字 int duration = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION));//歌曲的时长 String mime_type = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.AudioColumns.MIME_TYPE));//歌曲的类型 System.out.println("id:" + id + "\n path:" + path + "\n display_name:" + display_name + "\n size:" + size + "\n album:" + album + "\n artist:" + artist + "\n title:" + title + "\n duration:" + duration + "\n mimeType:" + mime_type); } }</span>
根据id来播放指定的音乐
long id = /* retrieve it from somewhere */; Uri contentUri = ContentUris.withAppendedId( android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id); mMediaPlayer = new MediaPlayer(); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.setDataSource(getApplicationContext(), contentUri); // ...prepare and start...
创建MediaPlayer
方式一
// Load an audio resource from a package resource. MediaPlayer resourcePlayer = MediaPlayer.create(this, R.raw.my_audio); // Load an audio resource from a local file. MediaPlayer filePlayer = MediaPlayer.create(this, Uri.parse(“file:///sdcard/localfile.mp3”)); // Load an audio resource from an online resource. MediaPlayer urlPlayer = MediaPlayer.create(this, Uri.parse(“http://site.com/audio/audio.mp3”)); // Load an audio resource from a Content Provider. MediaPlayer contentPlayer = MediaPlayer.create(this, Settings.System.DEFAULT_RINGTONE_URI);
//加载raw的资源文件 AssetFileDescriptor assetFileDescriptor = getResources().openRawResourceFd(R.raw.tfboys); mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(),assetFileDescriptor.getStartOffset(),assetFileDescriptor.getLength()); //加载asset的资源文件 AssetFileDescriptor assetFileDescriptor = getAssets().openFd("tfboys.mp3"); mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(),assetFileDescriptor.getStartOffset(),assetFileDescriptor.getLength()); //加载sd卡的文件 mediaPlayer.setDataSource(path); //加载网络音频 mediaPlayer.setDataSource(url);
播放音频
Uri myUri = ....; // initialize Uri here MediaPlayer mediaPlayer = new MediaPlayer(); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(getApplicationContext(), myUri); mediaPlayer.prepare(); mediaPlayer.start();*mediaPlayer.prepare()和MediaPlayer.prepareAnsy()的区别:
mediaPlayer.prepare()方法在UI线程中执行,MediaPlayer.prepareAnsy()是开启另一个线程用于MediaPlayer的准备工作
其它的操作:
public void stop() { if (mediaPlayer != null){ mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; } } public void replay() { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.seekTo(0); } else { play(); } } public void pause() { if (mediaPlayer != null) mediaPlayer.pause(); }MediaPlayer的准备监听:
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { } });MediaPlayer的错误监听:
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { return false; } });
优化完善播放音频
根据电话状态来改变MediaPlayer的状态:TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); telephonyManager.listen(new PhoneStateListener(){ @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state){ case TelephonyManager.CALL_STATE_RINGING://正在拨打电话 break; case TelephonyManager.CALL_STATE_IDLE://挂断 break; } } },PhoneStateListener.LISTEN_CALL_STATE);
监听音频焦点的改变
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); audioManager.requestAudioFocus(new AudioManager.OnAudioFocusChangeListener() { @Override public void onAudioFocusChange(int focusChange) { switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: System.out.println("得到焦点"); // 得到焦点 if (mediaPlayer == null) play(); else if (!mediaPlayer.isPlaying()) mediaPlayer.start(); mediaPlayer.setVolume(1.0f, 1.0f); break; case AudioManager.AUDIOFOCUS_LOSS: System.out.println("将MediaPlayer进行释放"); // 失去焦点很长时间,应该将MediaPlayer进行释放 if (mediaPlayer.isPlaying()) mediaPlayer.stop(); mediaPlayer.release(); mediaPlayer = null; break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: System.out.println("停止播放,不去释放MediaPlayer"); //失去焦点很短时间,但是我们不得不停止播放,我们不去释放MediaPlayer,因为还有可能被唤醒 if (mediaPlayer.isPlaying()) mediaPlayer.pause(); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: System.out.println("失去焦点很短时间,但是一直保持播放"); // 失去焦点很短时间,但是他一直保持播放 if (mediaPlayer.isPlaying()) mediaPlayer.setVolume(0.1f, 0.1f); break; } } },AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN);有可能处理噪音,例如用户先用耳机听音乐然后将耳机拔下的情况:
<receiver android:name=".MusicIntentReceiver"> <intent-filter> <action android:name="android.media.AUDIO_BECOMING_NOISY" /> </intent-filter> </receiver>
public class MusicIntentReceiver extends android.content.BroadcastReceiver { @Override public void onReceive(Context ctx, Intent intent) { if (intent.getAction().equals( android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) { // signal your service to stop playback // (via an Intent, for instance) } } }
同理播放视频也是一样的
视频是由图像和声音组成,图像则由SurfaceView来显示
sv = (SurfaceView) findViewById(R.id.sv); /* 下面设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前 API11以下使用*/ sv.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); sv.getHolder().addCallback(this);为了避免SurfaceView销毁在创建图像变成黑屏,则实现SurfaceHolder.CallBack接口方法:
@Override public void surfaceCreated(SurfaceHolder holder) { if(position != 0){ play(); mediaPlayer.seekTo(position); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { System.out.println("执行了surfaceChanged方法"); } @Override public void surfaceDestroyed(SurfaceHolder holder) { if(mediaPlayer != null && mediaPlayer.isPlaying()){ position = mediaPlayer.getCurrentPosition(); mediaPlayer.stop(); } }
图像和声音绑定
mediaPlayer.setDisplay(sv.getHolder());