Android多媒体——播放音频
来源:互联网 发布:如何成为英雄知乎 编辑:程序博客网 时间:2024/05/16 20:30
在Android中播放音频文件一般使用MediaPlayer类来实现,它对多种格式的音频文件提供了非常全面的控制方法,从而使得播放音乐的工作变得简单
setDataSource():设置要播放的音频文件的位置
prepare():在开始播放之前调用这个方法完成准备工作
start():开始或继续播放
pause():暂停播放
reset():将MediaPlayer对象重置到刚刚创建的状态
seekTo():从指定位置开始播放
stop():停止播放音频,调用之后MediaPlayer对象无法再播放音频
release():释放掉与MediaPlayer对象相关的资源
isPlaying():判断当前MediaPlayer是否正在播放
getDuration():获取载入的音频文件的时长
播放
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Button mButton; private MediaPlayer player=new MediaPlayer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton= (Button) findViewById(R.id.button_musicplay); mButton.setOnClickListener(this); mButtonPause= (Button) findViewById(R.id.button_musicpause); mButtonPause.setOnClickListener(this); player.reset(); File path= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); File[]files=path.listFiles(); try { player.setDataSource(files[0].getAbsolutePath()); player.prepare(); player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }); } catch (IOException e) { e.printStackTrace(); } }}
但是要实现一个功能比较齐全的仅仅靠在主活动上加点击事件是不可能的,因为还要实现音乐可以后台播放,并可以将播放过程用进度条显示在主活动上,通过拖拉进度条可以是音乐从所拖动的位置继续播放。要实现这么些功能,就需要用到Android中的服务和广播接收器。
首先搭建一个音乐播放器的主界面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context=".MainActivity"> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"> </ListView> <SeekBar android:id="@+id/seekBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/textview_currenttime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="当前时间"/> <TextView android:id="@+id/textview_alltime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="总时间"/> </RelativeLayout> <Button android:id="@+id/button_musicpause" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="暂停/播放"/></LinearLayout>
ListView中的布局为
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageview" android:layout_width="50dp" android:layout_height="50dp" android:src="@mipmap/ic_launcher"/> <TextView android:id="@+id/textview_artist" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="艺术家"/> <TextView android:id="@+id/textview_line" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="——"/> <TextView android:id="@+id/textview_musicname" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="歌曲名"/></LinearLayout>
在主活动中添加三个点击事件,分别是ListView、开始暂停按钮、SeekBar进度条,还有一个广播接收器,用来接收广播并对UI上的空间进行处理。
package com.example.administrator.mymediaplayer;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.media.MediaPlayer;import android.os.Environment;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.AdapterView;import android.widget.Button;import android.widget.ListView;import android.widget.SeekBar;import android.widget.TextView;import com.example.administrator.mymediaplayer.adapter.MusicAdapter;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.logging.SimpleFormatter;public class MainActivity extends AppCompatActivity{ private Button mButton; private Button mButtonPause; private ListView mListView; private TextView mTextviewAll; private TextView mTextviewCurrent; private SeekBar mSeekBar; private File[]musics; private MediaPlayer player=new MediaPlayer(); private MusicReceiver musicReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextviewAll= (TextView) findViewById(R.id.textview_alltime); mTextviewCurrent= (TextView) findViewById(R.id.textview_currenttime); //开始暂停按钮的点击事件 mButtonPause= (Button) findViewById(R.id.button_musicpause); mButtonPause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent(getApplicationContext(),MusicService.class); intent.putExtra("type",Config.STOP_MUSIC); startService(intent); } }); //SeekBar的点击事件,将进度信息传送给后台服务 mSeekBar= (SeekBar) findViewById(R.id.seekBar); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { Intent intent=new Intent(getApplicationContext(),MusicService.class); intent.putExtra("type",Config.START_SEEK_TO); intent.putExtra("progress",seekBar.getProgress()); startService(intent); } }); //找到sdCard File sdCard=Environment.getExternalStorageDirectory(); //找到sdCard下的存放音乐的文件夹 File musicFiles = new File(sdCard,"Music"); //得到音乐文件夹下的所有歌曲 musics=musicFiles.listFiles(); //通过点击放置歌曲的ListView中的某一条信息使得音乐可以在后台播放 mListView= (ListView) findViewById(R.id.listview); mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent intent=new Intent(getApplicationContext(),MusicService.class); intent.putExtra("type",Config.START_MUSIC); //把某一首歌的路径传送给服务类 intent.putExtra("musicname",musics[position].getAbsolutePath()); //启动服务 startService(intent); } }); //定义ListView的适配器 MusicAdapter adapter=new MusicAdapter(getLayoutInflater(),musics); //将适配器加载到ListView中 mListView.setAdapter(adapter); //广播接收器的注册 musicReceiver=new MusicReceiver(); IntentFilter filter=new IntentFilter("com.music"); registerReceiver(musicReceiver,filter); } //广播接收器的取消注册 @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(musicReceiver); } //广播接收器类 class MusicReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //接收到的广播的格式,通过不同的格式执行不同的操作 int type=intent.getIntExtra("type", Config.ALL_TIME); //定义显示歌曲播放和总时间的格式 SimpleDateFormat format=new SimpleDateFormat("mm:ss"); switch (type){ //得到歌曲的总时间,并设置进度条总的长度,作为给播放时间进度条的位置的参考 case Config.ALL_TIME: int alltime=intent.getIntExtra("alltime",Config.ALL_TIME); mSeekBar.setMax(alltime); String timeall=format.format(alltime); mTextviewAll.setText(timeall); break; //得到当前播放时间,并将其设置在进度条上 case Config.CURRENT_TIME: int time=intent.getIntExtra("time",Config.CURRENT_TIME); mSeekBar.setProgress(time); String timecurrent=format.format(time); mTextviewCurrent.setText(timecurrent); break; default: break; } } }}
然后既然有ListView,就需要一个Adapter类
package com.example.administrator.mymediaplayer.adapter;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.media.MediaMetadata;import android.media.MediaMetadataRetriever;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import com.example.administrator.mymediaplayer.R;import java.io.File;/** * Created by Administrator on 2015/9/10. */public class MusicAdapter extends BaseAdapter { private LayoutInflater mInflater; private File[]musics; public MusicAdapter(LayoutInflater mInflater, File[] musics) { this.mInflater = mInflater; this.musics = musics; } @Override public int getCount() { return musics.length; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder=null; if (convertView==null){ convertView=mInflater.inflate(R.layout.activity_music,null); viewHolder=new ViewHolder(); viewHolder.textView= (TextView) convertView.findViewById(R.id.textview_musicname); viewHolder.textViewArtist= (TextView) convertView.findViewById(R.id.textview_artist); viewHolder.textViewLine= (TextView) convertView.findViewById(R.id.textview_line); viewHolder.imageView= (ImageView) convertView.findViewById(R.id.imageview); convertView.setTag(viewHolder); }else { viewHolder= (ViewHolder) convertView.getTag(); } MediaMetadataRetriever metadata=new MediaMetadataRetriever(); metadata.setDataSource(musics[position].getAbsolutePath()); String artist=metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST); if (artist==null){ viewHolder.textViewArtist.setText("UnKnow"); }else { viewHolder.textViewArtist.setText(artist); } byte[]image=metadata.getEmbeddedPicture(); if (image==null){ viewHolder.imageView.setImageResource(R.mipmap.ic_launcher); }else { Bitmap bitmap= BitmapFactory.decodeByteArray(image,0,image.length); viewHolder.imageView.setImageBitmap(bitmap); } viewHolder.textView.setText(musics[position].getName()); return convertView; } class ViewHolder{ TextView textView; TextView textViewArtist; TextView textViewLine; ImageView imageView; }}
中间获取歌曲的作者和图片的代码其实放在这里不是很合适,但是比较简单,不需要来回传递信息。
然后就需要一个后台服务类来进行后台操作,在后台中对活动中传回来的信息做相应的后台服务
package com.example.administrator.mymediaplayer;import android.app.Service;import android.content.Intent;import android.media.MediaPlayer;import android.os.IBinder;import android.support.annotation.Nullable;import android.util.Log;import java.io.IOException;/** * Created by Administrator on 2015/9/10. */public class MusicService extends Service { private MediaPlayer player; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { int type=intent.getIntExtra("type",Config.START_MUSIC); switch (type){ case Config.START_MUSIC: startMusic(intent); break; case Config.START_SEEK_TO: int progress=intent.getIntExtra("progress",0); player.seekTo(progress); break; case Config.STOP_MUSIC: if (player.isPlaying()){ player.pause(); }else{ player.start(); } new MusicPlayThread().start(); default: break; } return super.onStartCommand(intent, flags, startId); } private void startMusic(Intent intent) { String musicpath=intent.getStringExtra("musicname"); if (player==null){ player=new MediaPlayer(); } player.reset(); try { player.setDataSource(musicpath); player.prepare(); player.start(); } catch (IOException e) { e.printStackTrace(); } int time=player.getDuration(); Intent intent2=new Intent("com.music"); intent2.putExtra("type",Config.ALL_TIME); intent2.putExtra("alltime",time); sendBroadcast(intent2); new MusicPlayThread().start(); } //用来发送当前广播信息的线程 class MusicPlayThread extends Thread{ @Override public void run() { while (player.isPlaying()){ int currenttime=player.getCurrentPosition(); Intent intent=new Intent("com.music"); intent.putExtra("type",Config.CURRENT_TIME); intent.putExtra("time",currenttime); sendBroadcast(intent); //由于Android对时间是一毫秒计算,所以需要休眠一段时间,降低发送频率,不至于广播积压 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
0 0
- Android—多媒体(音频播放)
- Android多媒体——播放音频
- Android 多媒体——音频播放录制、视频播放、相机
- Android 多媒体应用——MediaPlayer音频播放
- Android 多媒体应用——SoundPool音频播放
- 【Android】多媒体编程——MediaPlayer音频播放
- Android多媒体—音频技术
- Android多媒体——音乐播放器(播放内存音频)
- Android中的多媒体音频和视频播放
- Android --- 多媒体应用(SoundPool播放音频)
- iOS 多媒体(1)——音频的播放
- Android多媒体音频—MediaRecoder&MediaPlayer
- Android多媒体音频—AudioRecord&AudioTrack
- android之播放多媒体文件一(播放音频)
- Android多媒体——(MidiaRecorder音频录制/视频播放surface/Soundpool提示音/调用系统摄像头camera)
- android 多媒体——音乐播放器
- Android—多媒体(视频播放、拍照)
- 多媒体之播放音频(二)——SoundPool(播放简短提示音)
- 高手详解SQL性能优化十条经验
- Android四大组件---Service
- nyoj 284 坦克大战 【bfs(简单题)】
- mvn 小的知识点
- 快速排序的优化
- Android多媒体——播放音频
- 递归之经典:汉诺塔
- CocoaPods安装教程
- 实现绝对定位元素的水平垂直居中
- 统计学习方法~笔记1
- leetcode:Basic Calculator II
- 怎么判断一个ResultSet为空 ,有没有内容
- unity实现简单的摄像机切换
- operator new 函数、operator delete 函数 和 定位 new