先看一下包的结构:
1.com.mp3player包下的类:
(1.)MainActivity类
package com.mp3player;
import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TabHost;
public class MainActivity extends TabActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaa");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 得到他tabhost对象,对TabActivity的 操作通常都有这个这个对象完成
TabHost tabHost = getTabHost();
// 生成一个Intent对象,该对象指向另一个Activity
Intent remoteIntent = new Intent();
remoteIntent.setClass(this, Mp3Player01Activity.class);
// 生成一个TabSpec对象,代表了一个页
TabHost.TabSpec remoteSpc = tabHost.newTabSpec("Remote");
Resources res = getResources();
// 设置该页的Indiacator
remoteSpc.setIndicator("Remote", res
.getDrawable(android.R.drawable.stat_sys_download));
remoteSpc.setContent(remoteIntent);
// 将设置好的TabSpec对象添加到TabHost中
tabHost.addTab(remoteSpc);
Intent localIntent = new Intent();
localIntent.setClass(this, LocalMp3ListActivity.class);
TabHost.TabSpec localSpec = tabHost.newTabSpec("Local");
localSpec.setIndicator("Local", res
.getDrawable(android.R.drawable.stat_sys_download));
localSpec.setContent(localIntent);
tabHost.addTab(localSpec);
}
}
(2.)Mp3Player01Activity类
package com.mp3player;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import com.download.HttpDownloader;
import com.model.Mp3Info;
import com.mp3player.service.DownloadService;
import com.xml.Mp3ListContenHandler;
public class Mp3Player01Activity extends ListActivity {
private static final int UPDATE = 1;
private static final int ABOUT = 2;
private List<Mp3Info> mp3Infos = null;
/** Called when the activity is first created. */
/**
* 当点击menu按钮时会调用相应的方法
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(0, UPDATE, 1, R.string.mp3list_update);
menu.add(0, ABOUT, 2, R.string.mp3list_about);
return super.onCreateOptionsMenu(menu);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_mp3_list);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == UPDATE) {
updateListView();
} else if (item.getItemId() == ABOUT) {
// 用户点击了关于按钮
}
return super.onOptionsItemSelected(item);
}
//为列表准备数据
private SimpleAdapter buildSimpleAdapter(List<Mp3Info> mp3Infos){
// 生成一个List对象,并按照SimpleAdapter的标准,将mp3Infos当中的数据添加到List当中去
List<HashMap<String, String>> list = 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("mp3_name", mp3Info.getMp3Name());
map.put("mp3_size", mp3Info.getMp3Size());
list.add(map);
}
// 创建一个SimpleAdapter对象
SimpleAdapter simpleAdapter = new SimpleAdapter(this, list,
R.layout.mp3info_item, new String[] { "mp3_name", "mp3_size" },
new int[] { R.id.mp3_name, R.id.mp3_size });
// 将这个SimpleAdapter对象设置到ListActivity当中
return simpleAdapter;
}
private void updateListView() {
// 用户点击了更新列表按钮
// 下载包含所有Mp3基本信息的xml文件
String xml = downloadXML("http://192.168.1.100:8080/ServletForAndroid/resources.xml");
// 对xml文件进行解析,并将解析的结果放置到Mp3Info对象当中,最后将这些Mp3Info对象放置到List当中
mp3Infos = parse(xml);
SimpleAdapter simpleAdapter = buildSimpleAdapter(mp3Infos);
setListAdapter(simpleAdapter);
}
private String downloadXML(String urlStr){
HttpDownloader httpDownloader=new HttpDownloader();
String result=httpDownloader.download(urlStr);
return result;
}
//xml文件解析
private List<Mp3Info> parse(String xmlStr) {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
List<Mp3Info> infos = new ArrayList<Mp3Info>();
try {
XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();
Mp3ListContenHandler mp3ListContentHandler = new Mp3ListContenHandler(infos);
xmlReader.setContentHandler(mp3ListContentHandler);
xmlReader.parse(new InputSource(new StringReader(xmlStr)));
for (Iterator iterator = infos.iterator(); iterator.hasNext();) {
Mp3Info mp3Info = (Mp3Info) iterator.next();
System.out.println(mp3Info);
}
} catch (Exception e) {
e.printStackTrace();
}
return infos;
}
protected void onListItemClick(ListView l, View v, int position, long id) {
//根据用户点击列表当中的位置获得条目位置
System.out.println(position);
Mp3Info mp3Info = mp3Infos.get(position);
System.out.println(mp3Info);
//Mp3Info类已经复写了toString方法,故可以将所有元素都打印出来
Intent intent = new Intent();
intent.putExtra("mp3Info", mp3Info);
//跳转到DownloadService
intent.setClass(this, DownloadService.class);
//启动service
startService(intent);
super.onListItemClick(l, v, position, id);
}
}
(3.)LocalMp3ListActivity类
package com.mp3player;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import com.model.Mp3Info;
import com.util.FileUtils;
public class LocalMp3ListActivity extends ListActivity{
private List<Mp3Info> mp3Infos=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.local_mp3_list);
}
@Override
protected void onResume() {
FileUtils fileUtils=new FileUtils();
mp3Infos=fileUtils.getMp3Files("mp3/");
List<HashMap<String, String>> list=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("mp3_name", mp3Info.getMp3Name());
map.put("mp3_size", mp3Info.getMp3Size());
list.add(map);
}
SimpleAdapter simpleAdapter=new SimpleAdapter(this, list, R.layout.mp3info_item, new String[] {"mp3_name","mp3_size"}, new int[] {R.id.mp3_name,R.id.mp3_size});
setListAdapter(simpleAdapter);
super.onResume();
}
//条目的回调函数
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
if(mp3Infos!=null){
Mp3Info mp3Info=mp3Infos.get(position);
Intent intent=new Intent();
intent.putExtra("mp3Info", mp3Info);
intent.setClass(this, PlayerActivity.class);
startActivity(intent);
}
super.onListItemClick(l, v, position, id);
}
}
(4.)PlayerActivity类
package com.mp3player;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Queue;
import com.krc.KrcProcessor;
import com.model.Mp3Info;
import com.mp3player.service.PlayerService;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;
public class PlayerActivity extends Activity {
ImageButton beginButton = null;
ImageButton pauseButton = null;
ImageButton stopButton = null;
MediaPlayer mediaPlayer = null ;
private TextView lrcTextView = null;
ArrayList<Queue> queues = null;
private boolean isPlaying = false;
private Handler handler = new Handler();
// private UpdateTimeCallback updateTimeCallback = null;
private long begin = 0;
private long currentTimeMill = 0;
private long nextTimeMill = 0;
private long pauseTimeMills = 0;
private String message = null;
private Mp3Info mp3Info = null ;
private IntentFilter intentFilter = null;
private BroadcastReceiver receiver = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.player);
Intent intent = getIntent();
mp3Info = (Mp3Info)intent.getSerializableExtra("mp3Info");
beginButton = (ImageButton)findViewById(R.id.begin);
pauseButton = (ImageButton)findViewById(R.id.pause);
stopButton = (ImageButton)findViewById(R.id.stop);
lrcTextView = (TextView)findViewById(R.id.lrcText);
beginButton.setOnClickListener(new BeginButton());
pauseButton.setOnClickListener(new PauseButton());
stopButton.setOnClickListener(new StopButton());
}
/**
* 根据歌词文件的名字来读取歌词信息
* @param lrcName
*/
/*private void prepareLrc(String lrcName){
try{
InputStream inputStream = new FileInputStream(Environment.getExternalStorageDirectory().getAbsoluteFile()
+ File.separator + "mp3/" + mp3Info.getLrcName());
LrcProcessor lrcProcessor = new LrcProcessor();
queues = lrcProcessor.process(inputStream);
//创建一个UpdateTimeCallback对象
updateTimeCallback = new UpdateTimeCallback(queues);
begin = 0;
currentTimeMill = 0;
nextTimeMill = 0;
}catch(FileNotFoundException e){
e.printStackTrace();
}
}*/
class BeginButton implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//创建一个Intent对象,用于Service开始播放mp3
Intent intent = new Intent();
intent.setClass(PlayerActivity.this, PlayerService.class);
intent.putExtra("mp3Info", mp3Info);
intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG);
//读取LRC文件
System.out.println("mp3 lrc-->" + mp3Info.getKrcName());
// prepareLrc(mp3Info.getLrcName());
startService(intent);
//将begin的值置为当前毫秒数
// begin = System.currentTimeMillis();
// //延后5毫秒执行UpdateTimeCallback
// handler.postDelayed(updateTimeCallback, 5);
// isPlaying = true;
}
}
class PauseButton implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//创建一个Intent对象,用于Service暂停播放mp3
Intent intent = new Intent();
intent.setClass(PlayerActivity.this, PlayerService.class);
intent.putExtra("mp3Info", mp3Info);
intent.putExtra("MSG", AppConstant.PlayerMsg.PAUSE_MSG);
startService(intent);
// if(isPlaying){
// handler.removeCallbacks(updateTimeCallback);
// //暂停时取得当前时间
// pauseTimeMills = System.currentTimeMillis() ;
// }else{
// //再次播放
// handler.postDelayed(updateTimeCallback, 5);
// //得到再次开始播放的时间
// begin = System.currentTimeMillis() - pauseTimeMills + begin;
// }
// //如果当前状态时暂停的话,点击后状态改为播放;如果是播放的话,点击后改为暂停
// isPlaying = isPlaying?false : true;
}
}
class StopButton implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(PlayerActivity.this, PlayerService.class);
intent.putExtra("mp3Info", mp3Info);
intent.putExtra("MSG", AppConstant.PlayerMsg.STOP_MSG);
startService(intent);
//移出updateTimeCallback,不再进行歌词更新
// handler.removeCallbacks(updateTimeCallback);
}
}
/*class UpdateTimeCallback implements Runnable{
Queue times = null;
Queue messages = null;
public UpdateTimeCallback(ArrayList<Queue> queues){
//从ArrayList当中取出相应的对象
times = queues.get(0);
messages = queues.get(1);
}
@Override
public void run() {
// TODO Auto-generated method stub
//计算偏移量,也即是从mp3播放开始到现在,共消耗了多少时间,单位毫秒
long offset = System.currentTimeMillis() - begin;
//第一次播放
if(currentTimeMill == 0){
//从times取出下一次要更新歌词的时间点
nextTimeMill = (Long)times.poll();
//下一个时间点对应的歌词
message = (String)messages.poll();
}
//已经播放的时间大于等于下一次要更新歌词的时间
if(offset >= nextTimeMill){
//将相应的歌词放到lrcTextView中
lrcTextView.setText(message);
//再次从队列里取出message
message = (String)messages.poll();
//再次从队列里取出时间点
nextTimeMill = (Long)times.poll();
}
currentTimeMill = currentTimeMill + 10;
//10毫秒后再次用handler执行updateTimeCallback
handler.postDelayed(updateTimeCallback, 10);
}
}*/
/**
* 广播接收器,主要作用接收service所发送的广播,并且更新UI,也就是放置歌词的TextView
* @author Administrator
*
*/
class LrcMessageBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
//从intent中取出歌词信息,更新TextView
String lrcMessage = intent.getStringExtra("lrcMessage");
lrcTextView.setText(lrcMessage);
}
}
private IntentFilter getIntentFilter(){
if(intentFilter == null){
intentFilter = new IntentFilter();
intentFilter.addAction(AppConstant.LRC_MESSAGE_ACTION);
}
return intentFilter;
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
unregisterReceiver(receiver);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
receiver = new LrcMessageBroadcastReceiver();
registerReceiver(receiver, getIntentFilter());
}
}
(5.)AppConstant类,此类为了实现歌词同步,现在还没实现此功能
package com.mp3player;
public interface AppConstant {
public class PlayerMsg{
public static final int PLAY_MSG = 1;
public static final int PAUSE_MSG = 2;
public static final int STOP_MSG = 3;
}
public class URL{
public static final String BASE_URL = "http://192.168.1.100:8080/ServletForAndroid/MP3/";
}
public static final String LRC_MESSAGE_ACTION = "mars.mp3player.lrcmessage.action";
}
因为代码太多,所以在下一博中继续