android一个很简单很简单的音乐播放器

来源:互联网 发布:mac老是弹出垃圾网站 编辑:程序博客网 时间:2024/05/18 00:34

这是一个乱七八糟的主界面

偷懒直接把所有操作都也在了MainActivity上面,主要是学习是怎么运行的,之后满满完善吧。这里的操作包括上下曲,播放暂停,随机开关,列表跳转播放。UI十分十分简单。

public class MainActivity extends Activity implements OnClickListener {private MediaPlayer mediaPlayer;private MusicInfo musicInfo;private Button mButton, mPre, mPlay, mNext, mRandom;private SeekBar mSeekBar;private boolean Random = false;private TextView mName, mCurtime, mAllTime, mCount;private int location = 0;MusicAdapater adapater;Cursor mCursor;int musicCount;int curplaytime;String title;int id;private boolean isPause = true;Handler handler = new Handler() {};Runnable runnable = new Runnable() {    @Override    public void run() {        if (mediaPlayer != null) {            title = musicInfo.getTitle();            mName.setText(title);            if (title != null) {                if (Random == false) {                    mRandom.setText(getResources().getString(                            R.string.randomon));                } else if (Random == true) {                    mRandom.setText(getResources().getString(                            R.string.randomoff));                }                int time = new Long(musicInfo.getTime()).intValue();                mAllTime.setText(MusicAdapater.Format(musicInfo.getTime()));                mSeekBar.setMax(time);                mSeekBar.setProgress(mediaPlayer.getCurrentPosition());                mCurtime.setText(MusicAdapater.Format(mediaPlayer                        .getCurrentPosition()));                mCount.setText(musicInfo.getId() + "/" + musicCount);            }        }        handler.postDelayed(this, 1000);    }};protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    Log.i(TAG, "onCreate()");    requestWindowFeature(Window.FEATURE_NO_TITLE);    initView();    musicCount = MusicList.getMusicInfos(this).size();    handler.postDelayed(runnable, 1000);}private void initView() {    setContentView(R.layout.main_activity);    mediaPlayer = new MediaPlayer(); //初始化MediaPlayer    musicInfo = new MusicInfo();    // 自动播放下一首    mediaPlayer.setOnCompletionListener(new OnCompletionListener() {        @Override        public void onCompletion(MediaPlayer mp) {            // TODO Auto-generated method stub            if (mediaPlayer != null) {                if (Random) { //因为我定义的Random=false,即随机关                    location = location + 1;                    songplay(location);                } else if (!Random) { //随机开                    location = getRandomNumber();                    songplay(location);                }            }        }    });    mName = (TextView) findViewById(R.id.name);    mButton = (Button) findViewById(R.id.btn_list);    mPre = (Button) findViewById(R.id.pre);    mPlay = (Button) findViewById(R.id.play);    mNext = (Button) findViewById(R.id.next);    mRandom = (Button) findViewById(R.id.btn_random);    mSeekBar = (SeekBar) findViewById(R.id.time_seekbar);    mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {        @Override        public void onStopTrackingTouch(SeekBar seekBar) {            // TODO Auto-generated method stub            mediaPlayer.getCurrentPosition();        }        @Override        public void onStartTrackingTouch(SeekBar seekBar) {            // TODO Auto-generated method stub        }        @Override        public void onProgressChanged(SeekBar seekBar, int progress,                boolean fromUser) {            // TODO Auto-generated method stub            if (fromUser) { // 判断是否为用户自己操作                 mediaPlayer.seekTo(progress); // 设置音乐进度 就是拖动进度条也就是所谓的快进,后退            }            curplaytime = progress; //记录当前播放时间        }    });    mCurtime = (TextView) findViewById(R.id.tv_curtime);    mAllTime = (TextView) findViewById(R.id.tv_alltime);    mCount = (TextView) findViewById(R.id.music_count);    mAllTime.setText("00:00");    mCurtime.setText("00:00");    mCount.setText("0/0");    mButton.setOnClickListener(this);    mNext.setOnClickListener(this);    mPre.setOnClickListener(this);    mPlay.setOnClickListener(this);    mRandom.setOnClickListener(this);}@Overridepublic void onClick(View v) {    // TODO Auto-generated method stub    switch (v.getId()) {    case R.id.btn_list:        Intent intent = new Intent(MainActivity.this, MusicList.class);        startActivityForResult(intent, 1); //因为要从MusicList返回一个值,所以要用startActivityForResult        break;    case R.id.pre:        if (Random) {            if (location > 0 && location <= musicCount - 1) {                location = location - 1;                songplay(location);            } else if (location == 0) {                songplay(musicCount - 1);                location = musicCount - 1;            }        } else if (!Random) {            location = getRandomNumber();            songplay(location);        }        break;    case R.id.play:        if (mediaPlayer != null && mediaPlayer.isPlaying()) {            mediaPlayer.pause();        } else {            if (curplaytime != 0) { //如果播放时间不为0,就继续上次时间播放                songplay(location);                mediaPlayer.seekTo(curplaytime);            } else {                songplay(location);            }        }        break;    case R.id.next:        nextsong();        break;    case R.id.btn_random:        if (Random == false) {            Random = true;        } else if (Random == true) {            Random = false;        }    default:        break;    }}private void nextsong() {    if (Random) {        if (location >= 0 && location < musicCount - 1) {            location = location + 1;            songplay(location);        } else {            songplay(0);            location = 0;        }    } else if (!Random) {        location = getRandomNumber();        songplay(location);    }}public void onDestroy() {    if (mediaPlayer.isPlaying()) {        mediaPlayer.stop();    }    mediaPlayer.release();    super.onDestroy();}public void songplay(int location) {    musicInfo = MusicList.getMusicInfos(getApplicationContext()).get(            location);    String url = musicInfo.getUrl();    try {        mediaPlayer.reset();        mediaPlayer.setDataSource(url);        mediaPlayer.prepare();        mediaPlayer.start();    } catch (IllegalArgumentException e) {        e.printStackTrace();    } catch (SecurityException e) {        e.printStackTrace();    } catch (IllegalStateException e) {        e.printStackTrace();    } catch (IOException e) {        e.printStackTrace();    }}/** * 返回值从[0,musicCount] *  * @return location */public int getRandomNumber() {    Random random = new Random();    int location = random.nextInt(musicCount);    return location;}//接收从listview传过来的id,由于id索引从1开始,而location索引从0开始,所以要减1.protected void onActivityResult(int requestCode, int resultCode, Intent data) {    if (1 == requestCode) {        if (1 == resultCode) {            Bundle bundle = data.getExtras();            id = bundle.getInt("id");            location = id - 1;            songplay(location);        }    }    super.onActivityResult(requestCode, resultCode, data);}protected void onRestart() {    super.onRestart();}

}

MusicInfo.java

public class MusicInfo {private int id; // 歌曲ID private String title; // 歌曲名称 private String singer; // 歌手名称 private long time;private String url;public MusicInfo(){}public MusicInfo(int id, String title, String singer, long time, String url){    super();    this.id=id;    this.title = title;    this.singer = singer;    this.time = time;    this.url = url;}public String getUrl(){    return url;}public void setUrl(String url) {    this.url = url;}public int getId() {    return id;}public void setId(int ld){    this.id=ld;}public String getTitle(){    return title;}public void setTitle(String title){    this.title = title;}public String getSinger(){    return singer;}public void setSinger(String singer){    this.singer = singer; }public Long getTime(){    return time;}public void setTime(long time){    this.time = time;}

}

一个不咋滴的适配器

public class MusicAdapater extends BaseAdapter {private Context mContext;private List<MusicInfo> musicInfos;private MusicInfo musicInfo;int mPosition;public MusicAdapater(Context context,List<MusicInfo> musicInfos){    this.mContext = context;    this.musicInfos = musicInfos;}public int getPosition(){    return mPosition;}public void setPosition(int mPosition){    this.mPosition = mPosition;}@Overridepublic int getCount() {    // 决定listview有多少个item    return musicInfos.size();}@Overridepublic Object getItem(int position) {    return position;}@Overridepublic long getItemId(int position) {    return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {    // TODO Auto-generated method stub    View view;    ViewHolder holder;    if (convertView == null) {        holder = new ViewHolder();        convertView = LayoutInflater.from(mContext).inflate(R.layout.music_title, null);        holder.title = (TextView)convertView.findViewById(R.id.music_title);        holder.singer = (TextView)convertView.findViewById(R.id.music_singer);        holder.time = (TextView)convertView.findViewById(R.id.music_time);        convertView.setTag(holder);    } else {        holder = (ViewHolder)convertView.getTag();    }    musicInfo =musicInfos.get(position);    holder.title.setText(musicInfo.getTitle());    holder.singer.setText(musicInfo.getSinger());    holder.time.setText(Format(musicInfo.getTime()));    return convertView;}class ViewHolder {    public TextView title; //音乐名    public TextView singer; // 歌手名    public TextView time; //时间}/** * 时间转化 把音乐时间的long型数据转化为“分:秒” * @param time * @return String hms */public static String Format(long time) {    SimpleDateFormat format = new SimpleDateFormat("mm:ss");    String hms = format.format(time);    return hms;}       

}

音乐列表界面

public class MusicList extends Activity {private ListView mListView;MusicInfo musicInfo;MusicAdapater adapater;protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    requestWindowFeature(Window.FEATURE_NO_TITLE);    setContentView(R.layout.music_list_activity);    initView(this);}void initView(Context context) {    mListView = (ListView) findViewById(R.id.listview);    mListView.setOnItemClickListener(new MusicItemCLickListener());    musicInfo = new MusicInfo();    adapater = new MusicAdapater(context, getMusicInfos(context));     mListView.setAdapter(adapater);}public static List<MusicInfo> getMusicInfos(Context context) {    Cursor mCursor = context.getContentResolver().query(            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,            MediaStore.Audio.Media.DEFAULT_SORT_ORDER);    List<MusicInfo> musicInfos = new ArrayList<MusicInfo>();    for (int i = 0; i < mCursor.getCount(); i++) {        MusicInfo musicInfo = new MusicInfo();        mCursor.moveToNext();        int id = i + 1; //这是自定义音乐id,从1开始,方便之后使用,有规律        // long id = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Audio.Media._ID));  // 音乐id,好像无规律        String title = mCursor.getString((mCursor.getColumnIndex(MediaStore.Audio.Media.TITLE)));// 音乐标题        String artist = mCursor.getString(mCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));// 艺术家        long duration = mCursor.getLong(mCursor.getColumnIndex(MediaStore.Audio.Media.DURATION));// 时长        int isMusic = mCursor.getInt(mCursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));// 是否为音乐        String url = mCursor.getString(mCursor.getColumnIndex(MediaStore.Audio.Media.DATA)); //路径        if (isMusic != 0) {            musicInfo.setId(id);            musicInfo.setTitle(title);            musicInfo.setSinger(artist);            musicInfo.setTime(duration);            musicInfo.setUrl(url);            musicInfos.add(musicInfo);        }    }    return musicInfos;}/* * 这是listview item 的点击事件 点击后抛出音乐id给MainActivity,在MainActivity中根据id来播放相应的音乐 */private class MusicItemCLickListener implements OnItemClickListener {    @Override    public void onItemClick(AdapterView<?> parent, View view, int position,            long id) {        // TODO Auto-generated method stub        if (getMusicInfos(getApplicationContext()) != null) {            MusicInfo musicInfo = getMusicInfos(getApplicationContext()).get(position);            int id2 = musicInfo.getId();            Intent intent = new Intent(MusicList.this, MainActivity.class);            Bundle bundle = new Bundle();            bundle.putInt("id", id2);            intent.putExtras(bundle);            setResult(1, intent);            MusicList.this.finish();        }    }}

}

因为mediaplay是在MainActiviy中实例化的,为了防止MainActiviy活动重复创建,修改 AndroidManifest 当然记得加权限##

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><application    android:allowBackup="true"    android:icon="@drawable/ic_launcher"    android:label="@string/app_name"    android:theme="@style/AppTheme" >    <activity        android:name=".MainActivity"        android:launchMode="singleTask" //这个是防止重复创建栈顶活动的问题直接从返回栈中检查是否存在该活动的实例,存在就直接使用,不存在就新建        android:label="@string/app_name" >        <intent-filter>            <action android:name="android.intent.action.MAIN" />            <category android:name="android.intent.category.LAUNCHER" />        </intent-filter>    </activity>    <activity android:name=".MusicList"></activity></application>

下面是布局文件 main_activity.xml

布局文件就没什么好说的了。随便扔了几个控件在上面

<?xml version="1.0" encoding="utf-8"?>      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" ><TextView    android:id="@+id/name"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_gravity="center"    android:textColor="@android:color/black"    android:textSize="24sp" /><LinearLayout    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:gravity="center" >    <TextView        android:id="@+id/tv_curtime"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textColor="@android:color/black"        android:textSize="24sp" />    <SeekBar        android:id="@+id/time_seekbar"        android:layout_width="600dp"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:maxHeight="10dp"        android:minWidth="10dp" />    <TextView        android:id="@+id/tv_alltime"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textColor="@android:color/black"        android:textSize="24sp" /></LinearLayout><TextView    android:id="@+id/music_count"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_gravity="center"    android:textColor="@android:color/black"    android:textSize="24sp" /><LinearLayout    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_gravity="center"    android:layout_marginTop="30dp"    android:gravity="center"    android:orientation="horizontal" >    <Button        android:id="@+id/btn_list"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/list"        android:textSize="32sp" />    <Button        android:id="@+id/pre"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/pre"        android:textSize="32sp" />    <Button        android:id="@+id/play"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/play"        android:textSize="32sp" />    <Button        android:id="@+id/next"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/next"        android:textSize="32sp" />    <Button        android:id="@+id/btn_random"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/randomon"        android:textSize="32sp" /></LinearLayout>

第二个布局文件 music_list_activity.xml

<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:orientation="vertical" ><ListView    android:id="@+id/listview"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:divider="#000" >        </ListView>    

第三个布局文件music_title.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextView    android:id="@+id/music_title"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:textSize="24sp" /><LinearLayout    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:orientation="horizontal" >    <TextView        android:id="@+id/music_singer"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="24sp" />    <TextView        android:id="@+id/music_time"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textSize="24sp"        android:layout_marginLeft="20dp" /></LinearLayout><LinearLayout    android:layout_width="match_parent"    android:layout_height="20dp" ></LinearLayout>


至于那些资源values就没写了

这是一个自动的跑马灯自定义控件

有些字段太长了TextView大小又有限怎么办?那就让它自己动起来。
创建一个类继承自TextView

public class MarqueeTextView extends TextView{public MarqueeTextView(Context context, AttributeSet attrs){    super(context, attrs);}@Overrideprotected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect)   {    // TODO Auto-generated method stub    if(focused) super.onFocusChanged(focused, direction, previouslyFocusedRect);}@Overridepublic void onWindowFocusChanged(boolean hasWindowFocus){    // TODO Auto-generated method stub    if(hasWindowFocus) super.onWindowFocusChanged(hasWindowFocus);}@Overridepublic boolean isFocused(){    return true;}}

然后是自定义控件的使用,记得给layout_width设定一个比较具体的大小,不然跑步起来哦

    <com.android.auto.autohome.MarqueeTextView                    android:id="@+id/music_name"                    android:layout_width="match_parent"                    android:layout_height="wrap_content"                    android:layout_marginTop="10dp"                    android:ellipsize="marquee"                    android:singleLine="true"                    android:text="@string/unknow"                    android:textColor="@color/white"                    android:textSize="20sp" />