详解Android应用开发--MP3音乐播放器代码实现(一)

所属分类: 软件编程 / Android 阅读数: 25
收藏 0 赞 0 分享

需求1:将内存卡中的MP3音乐读取出来并显示到列表当中

1.从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象

2.迭代List集合,把每一个Mp3Info对象的所有属性,保存到Map对象当中

3.定义一个List集合,把Map对象添加到List集合当中

4.通过定义一个SimpleAdpter,调用setAdpter方法,将数据显示到列表当中

/** 
* 用于从数据库中查询歌曲的信息,保存在List当中 
* 
* @return 
*/ 
public List<Mp3Info> getMp3Infos() { 
  Cursor cursor = getContentResolver().query( 
    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, 
    MediaStore.Audio.Media.DEFAULT_SORT_ORDER); 
  List<Mp3Info> mp3Infos = new ArrayList<Mp3Info>(); 
  for (int i = 0; i < cursor.getCount(); i++) { 
    Mp3Info mp3Info = new Mp3Info(); 
    cursor.moveToNext(); 
    long id = cursor.getLong(cursor 
      .getColumnIndex(MediaStore.Audio.Media._ID));  //音乐id 
    String title = cursor.getString((cursor  
      .getColumnIndex(MediaStore.Audio.Media.TITLE)));//音乐标题 
    String artist = cursor.getString(cursor 
      .getColumnIndex(MediaStore.Audio.Media.ARTIST));//艺术家 
    long duration = cursor.getLong(cursor 
      .getColumnIndex(MediaStore.Audio.Media.DURATION));//时长 
    long size = cursor.getLong(cursor 
      .getColumnIndex(MediaStore.Audio.Media.SIZE)); //文件大小 
    String url = cursor.getString(cursor 
      .getColumnIndex(MediaStore.Audio.Media.DATA));       //文件路径 
  int isMusic = cursor.getInt(cursor 
    .getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否为音乐 
  if (isMusic != 0) {   //只把音乐添加到集合当中 
    mp3Info.setId(id); 
    mp3Info.setTitle(title); 
    mp3Info.setArtist(artist); 
    mp3Info.setDuration(duration); 
    mp3Info.setSize(size); 
    mp3Info.setUrl(url); 
    mp3Infos.add(mp3Info); 
    } 
  } 
return mp3Infos; 
} 

/** 
   * 填充列表 
   * @param mp3Infos 
   */ 
  public void setListAdpter(List<Mp3Info> mp3Infos) { 
    List<HashMap<String, String>> mp3list = new ArrayList<HashMap<String, String>>(); 
    for (Iterator iterator = mp3Infos.iterator(); iterator.hasNext();) { 
      Mp3Info mp3Info = (Mp3Info) iterator.next(); 
      HashMap<String, String> map = new HashMap<String, String>(); 
      map.put("title", mp3Info.getTitle()); 
      map.put("Artist", mp3Info.getArtist()); 
      map.put("duration", String.valueOf(mp3Info.getDuration())); 
      map.put("size", String.valueOf(mp3Info.getSize())); 
      map.put("url", mp3Info.getUrl()); 
      mp3list.add(map); 
    } 
    mAdapter = new SimpleAdapter(this, mp3list, 
        R.layout.music_list_item_layout, new String[] { "title", "Artist", "duration" }, 
        new int[] { R.id.music_title, R.id.music_Artist, R.id.music_duration }); 
    mMusiclist.setAdapter(mAdapter);   
  } 

实现效果如图:

  

需求2:点击列表的每一项,启动一个服务来播放音乐

1.   注册条目点击监听器OnItemClickListener

2.   定义一个实现OnItemClickListener接口的内部类

3.   定义一个继承Service的服务类PlayerServie

1.   注册条目点击监听器OnItemClickListener

mMusiclist = (ListView) findViewById(R.id.music_list); 
    mMusiclist.setOnItemClickListener(new MusicListItemClickListener()); 
    mp3Infos = getMp3Infos(); 
    setListAdpter(getMp3Infos()); 

2.   定义一个实现OnItemClickListener接口的内部类

private class MusicListItemClickListener implements OnItemClickListener { 
  @Override 
  public void onItemClick(AdapterView<?> parent, View view, int position, 
      long id) { 
    if(mp3Infos != null) { 
      Mp3Info mp3Info = mp3Infos.get(position); 
      Log.d("mp3Info-->", mp3Info.toString()); 
      Intent intent = new Intent(); 
      intent.putExtra("url", mp3Info.getUrl());     
      intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG); 
      intent.setClass(MainActivity.this, PlayerService.class); 
      startService(intent);    //启动服务 
    } 
  } 
} 

3.   定义一个继承Service的服务类PlayerServie(未完善的Service类)

package com.wwj.sb.service; 
 
 
import android.annotation.SuppressLint; 
import android.app.Service; 
import android.content.Intent; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnPreparedListener; 
import android.os.IBinder; 
 
import com.wwj.sb.domain.AppConstant; 
 
@SuppressLint("NewApi") 
public class PlayerService extends Service { 
  private MediaPlayer mediaPlayer = new MediaPlayer();    //媒体播放器对象 
  private String path;            //音乐文件路径 
  private boolean isPause;          //暂停状态 
   
  @Override 
  public IBinder onBind(Intent arg0) { 
    return null; 
  } 
   
  @Override 
  public int onStartCommand(Intent intent, int flags, int startId) { 
    if(mediaPlayer.isPlaying()) { 
      stop(); 
    } 
    path = intent.getStringExtra("url");     
    int msg = intent.getIntExtra("MSG", 0); 
    if(msg == AppConstant.PlayerMsg.PLAY_MSG) { 
      play(0); 
    } else if(msg == AppConstant.PlayerMsg.PAUSE_MSG) { 
      pause(); 
    } else if(msg == AppConstant.PlayerMsg.STOP_MSG) { 
      stop(); 
    } 
    return super.onStartCommand(intent, flags, startId); 
  } 
   
 
  /** 
   * 播放音乐 
   * @param position 
   */ 
  private void play(int position) { 
    try { 
      mediaPlayer.reset();//把各项参数恢复到初始状态 
      mediaPlayer.setDataSource(path); 
      mediaPlayer.prepare(); //进行缓冲 
      mediaPlayer.setOnPreparedListener(new PreparedListener(position));//注册一个监听器 
    } 
    catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
   
  /** 
   * 暂停音乐 
   */ 
  private void pause() { 
    if (mediaPlayer != null && mediaPlayer.isPlaying()) { 
      mediaPlayer.pause(); 
      isPause = true; 
    } 
  } 
   
  /** 
   * 停止音乐 
   */ 
  private void stop(){ 
    if(mediaPlayer != null) { 
      mediaPlayer.stop(); 
      try { 
        mediaPlayer.prepare(); // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数 
      } catch (Exception e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
   
   
  @Override 
  public void onDestroy() { 
    if(mediaPlayer != null){ 
      mediaPlayer.stop(); 
      mediaPlayer.release(); 
    } 
  } 
  /** 
   * 
   * 实现一个OnPrepareLister接口,当音乐准备好的时候开始播放 
   * 
   */ 
  private final class PreparedListener implements OnPreparedListener { 
    private int positon; 
     
    public PreparedListener(int positon) { 
      this.positon = positon; 
    } 
     
    @Override 
    public void onPrepared(MediaPlayer mp) { 
      mediaPlayer.start();  //开始播放 
      if(positon > 0) {  //如果音乐不是从头播放 
        mediaPlayer.seekTo(positon); 
      } 
    } 
  } 
   
} 

以上代码实现了两个需求,显示音乐列表和实现列表点击事件启动Servic。下次会实现控制音乐播放的需求。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

老生常谈Android HapticFeedback(震动反馈)

下面小编就为大家带来一篇老生常谈Android HapticFeedback(震动反馈)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详谈OnTouchListener与OnGestureListener的区别

下面小编就为大家带来一篇详谈OnTouchListener与OnGestureListener的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android仿知乎悬浮功能按钮FloatingActionButton效果

前段时间在看属性动画,恰巧这个按钮的效果可以用属性动画实现,下面通过本文给大家分享adroid仿知乎悬浮功能按钮FloatingActionButton效果,需要的朋友参考下吧
收藏 0 赞 0 分享

解决Android V7后自定义Toolbar、ActionBar左侧有空白问题

这篇文章主要介绍的Android V7后自定义Toolbar、ActionBar左侧有空白问题的解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android常见控件使用详解

这篇文章主要为大家详细介绍了Android常见控件的使用方法,包括ProgressBar进度条控件、AlertDialog对话框控件等,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android实现简洁的APP更新dialog数字进度条

这篇文章主要为大家详细介绍了Android实现简洁的APP更新dialog数字进度条,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android 判断当前语言环境是否是中文环境

本文主要介绍了Android 判断当前语言环境是否是中文环境的方法。具有很好的参考价值。下面跟着小编一起来看下吧
收藏 0 赞 0 分享

详谈Android中Matrix的set、pre、post的区别

下面小编就为大家带来一篇详谈Android中Matrix的set、pre、post的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Android实现登录界面记住密码的存储

这篇文章主要为大家详细介绍了Android SharedPreferrences实现登录界面记住密码的存储,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android 使用SharedPreferrences储存密码登录界面记住密码功能

Android存储方式有很多种,在这里所用的存储方式是SharedPreferrences, 其采用了Map数据结构来存储数据,以键值的方式存储,可以简单的读取与写入,下面通过实例代码给大家讲解下,需要的朋友参考下吧
收藏 0 赞 0 分享
查看更多