制作一个类似与下图的简易音乐播放器
1.创建一个布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="horizontal"
android:weightSum="5"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="56dp">
<TextView
android:textSize="20sp"
android:textStyle="bold"
android:id="@+id/musicTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:textSize="18sp"
android:layout_marginTop="3dp"
android:text="artist"
android:id="@+id/musicArtist"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
<ImageView
android:src="@drawable/ic_media_play"
android:id="@+id/musicPlay"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="56dp"/>
<ImageView
android:src="@drawable/ic_media_next"
android:id="@+id/musicNext"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="56dp"/>
</LinearLayout>
布局很简单,两个TextView和两个ImageView。
2.实现AppWidgetProvider
实现一个appWidget一般需要两步,第一步实现实现一个AppWidgetProvider中的onUpdate()方法,有点类似Activity中的onCreate()方法。第二步,在AndroidManifest中声明。
public class MusicWidgetProvider extends AppWidgetProvider{
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
//开启一个服务
context.startService(new Intent(context,MusicService.class));
super.onUpdate(context,appWidgetManager,appWidgetIds);
}
@Override
public void onDisabled(Context context) {
//关闭服务
context.stopService(new Intent(context, MusicService.class));
super.onDisabled(context);
}
}
在MusicWidgetProvider 中只是简单的开启和关闭一个服务,因为在MusicWidgetProvider 中不能很好的实现音乐的播放,将音乐的播放逻辑放在服务中实现。
3.声明appWidget
<receiver android:name=".MusicWidgetProvider">
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/music_provider_info"
/>
</receiver>
还需一个xml文件
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dp"
android:minHeight="56dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/music_provider">
4.在服务中实现音乐播放
在实现音乐播放前,需要创建一个类用于存放音乐信息
public class SongInfo {
private String title;//歌曲名
private String artist;//歌手
private String data;//歌曲所在路径
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
还需要一个方法去获取手机中的音乐文件
public class MusicManager {
/**
* 获取手机内的所有歌曲信息
* @param context
* @return
*/
public static List<SongInfo> getSongList(Context context)
{
List<SongInfo> songList=new ArrayList<>();
ContentResolver contentResolver=context.getContentResolver();
//从对应的数据库中获取对应列的歌曲信息
Cursor cursor=contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DATA
},null,null,MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
cursor.moveToFirst();
for (int i = 0; i < cursor.getCount(); i++) {
SongInfo song=new SongInfo();
song.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)));
song.setArtist(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
song.setData(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
songList.add(song);
cursor.moveToNext();
}
cursor.close();
return songList;
}
}
存放歌曲信息的数据库中还存放了其他信息,如DURATION(歌曲长度),SIZE(大小)。。。在本例中只需要歌曲名,歌手,路径即可。
准备工作完成,开始实现音乐播放。
public class MusicService extends Service{
private static final String TAG = "MusicService";
private static final String MUSIC_PLAY_ACTION="appwidget.action.musicplay";
private static final String MUSIC_NEXT_ACTION="appwidget.action.musicnext";
private List<SongInfo> songList;//存放歌曲信息
private int currentSong=0;//当前播放歌曲的位置
private MediaPlayer mediaPlayer;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
songList=MusicManager.getSongList(this);
//注册广播
IntentFilter filter=new IntentFilter(MUSIC_PLAY_ACTION);
filter.addAction(MUSIC_NEXT_ACTION);
registerReceiver(new MusicReceiver(), filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//更新appWidget
updateAppWidget();
return super.onStartCommand(intent, flags, startId);
}
/**
* 更新appWidget
*/
public void updateAppWidget()
{
AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(this);
RemoteViews remoteViews=new RemoteViews(this.getPackageName(),R.layout.music_provider);
//设置歌曲名和歌手
remoteViews.setTextViewText(R.id.musicTitle,getCurrentSongTitle());
remoteViews.setTextViewText(R.id.musicArtist, getCurrentSongArtist());
Intent playIntent=new Intent(MUSIC_PLAY_ACTION);
if (mediaPlayer!=null)
{
//根据音乐是否播放,更改imageView的图片
remoteViews.setImageViewResource(R.id.musicPlay, mediaPlayer.isPlaying() ?
R.drawable.ic_media_pause : R.drawable.ic_media_play);
}
//点击开启广播
PendingIntent playBroad=PendingIntent.getBroadcast(this,0,playIntent,0);
remoteViews.setOnClickPendingIntent(R.id.musicPlay, playBroad);
Intent nextIntent=new Intent(MUSIC_NEXT_ACTION);
PendingIntent nextBroad=PendingIntent.getBroadcast(this,0,nextIntent,0);
remoteViews.setOnClickPendingIntent(R.id.musicNext, nextBroad);
ComponentName componentName=new ComponentName(this,MusicWidgetProvider.class);
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
/**
* 获取当前歌曲名
* @return
*/
public String getCurrentSongTitle()
{
return songList==null?"暂无歌曲":songList.get(currentSong).getTitle();
}
/**
* 获取当前歌手
* @return
*/
public String getCurrentSongArtist()
{
return songList==null?"未知歌手":songList.get(currentSong).getArtist();
}
public void play()
{
try {
mediaPlayer=new MediaPlayer();
mediaPlayer.setDataSource(songList.get(currentSong).getData());
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//准备完成后,播放音乐并更新appwidget
mediaPlayer.start();
updateAppWidget();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//播放结束,播放下一首
playNext();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 播放下一首
*/
public void playNext()
{
if(mediaPlayer!=null)
{
Stop();
}
//指向下一首,这里需要对是否是最后一首进行判断
currentSong++;
play();
}
/**
* 暂停播放,更新appWidget
*/
public void pause()
{
mediaPlayer.pause();
updateAppWidget();
}
/**
* 播放,更新appWidget
*/
public void start()
{
mediaPlayer.start();
updateAppWidget();
}
/**
* 音乐停止
*/
public void Stop()
{
if (mediaPlayer!=null)
{
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
}
}
@Override
public void onDestroy() {
super.onDestroy();
Stop();
}
/**
* 接收广播,处理对应请求
*/
public class MusicReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MUSIC_PLAY_ACTION))
{
//当mediaPlayer为null时,表示当前未播放音乐
if (mediaPlayer==null)
{
play();
}else {
//当音乐正在播放时,暂停播放
if (mediaPlayer.isPlaying())
{
pause();
}else {
start();
}
}
}else if (intent.getAction().equals(MUSIC_NEXT_ACTION))
{
playNext();
}
}
}
}
5.运行
作者:qq_31244409 发表于2016/10/3 14:26:40 原文链接
阅读:118 评论:0 查看评论