音乐播放器
音乐播放器,这个作品已经花了很多心思上面,包括实现播放,获取歌词,专辑等,网络部分采用断点下载方式获取方法,这个播放器大家都懂的。
准备工具:Eclipse,ADT,SDK
实现需求:能够正常播放音乐,专辑和歌词,网络部分下载
本地音乐实现方法:一个本地音乐列表,另一个播放界面
对自己以前做过的小项目/应用来个总结吧,首先是音乐播放器,这个作品已经花了很多心思上面,包括实现播放,获取歌词,专辑等,网络部分采用断点下载方式获取方法,这个播放器大家都懂的。
准备工具:Eclipse,ADT,SDK
实现需求:本地能够正常播放音乐,显示专辑图片和歌词
网络部分下载
思路:就做两个activity, 一个本地音乐列表,另一个播放界面,列表里把音乐信息传递给播放界面去,进度条通过广播的形式,UI上我参照了类似网易新闻客户端, 也就是TabHost+RadioButton底部来做,界面总归好看点吧。我们做的底部也本地和网络两种而已。本地音乐的顶部是单独写xml,中间是列表如要那么整齐显示那就要BaseAdapter喽。分别用Cursor游标遍历,本地音乐Actvitiy显示建立一个方法,关键代码如下:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
/**
* 显示音乐列表
*/
private
void
ShowMp3List() {
Cursor cursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, media_info,
null
,
null
, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
if
(
null
!= cursor && cursor.getCount() >
0
) {
cursor.moveToFirst();
// 将游标移动到初始位置
_ids =
new
int
[cursor.getCount()];
// 返回INT的一个列
_artists =
new
String[cursor.getCount()];
// 返回String的一个列
_titles =
new
String[cursor.getCount()];
// 返回String的一个列
for
(
int
i =
0
; i < cursor.getCount(); i++) {
_ids<I> = cursor.getInt(
3
);
_titles<I> = cursor.getString(
0
);
_artists<I> = cursor.getString(
2
);
cursor.moveToNext();
// 将游标移到下一行
}
listview.setAdapter(
new
LocalMusicListAdapter(
this
, cursor));
// 用setAdapter装载数据
|
我们可以看到使用游标把媒体信息用getContentResolver方法查找出来,然后要作出判断游标获取的列数是否大于0,否则即使没有音乐也会扔异常。我们定义了三个临时数组,id,title,artist分别是id,标题,艺术家这些统统实例化参数是返回行数最后用个循环遍历出来并用moveToNext移至下一行。然后用setAdapter把信息装载适配器里,这样本地列表基本做完了。如果在UI花点功夫上那就更漂亮了,效果图:(此图应该看过) 。
![main.png main.png](http://www.eoeandroid.com/data/attachment/forum/201207/15/174319reo3nq6bqnmq6zzo.png)
昨天 17:43 上传
下载附件 (585.23 KB)
播放音乐
![playmusic.png playmusic.png](http://www.eoeandroid.com/data/attachment/forum/201207/15/174224pavphzcpftvuvvaj.png)
昨天 17:42 上传
下载附件 (521.4 KB)
这部分代码了。主要分为显示歌名,歌手,专辑,歌词。如果要正确显示歌名需要传递数据。那么在列表里用PutExtra这个方法来传递数据,播放这里用Bundle接收数据。列表和播放界面都要用建立临时变量。播放音乐的方法全部交给Service了。具体看代码。然后进度条是通过发送广播给服务。在activity界面里要静态反注册掉,反之会抛出异常,顺便建立一个几个Action用IntentFilter最后一个要registerReceiver即可。歌词部分需要用IO部分实现还有就是歌词路径问题,这个问题还是靠自己解决了。专辑图片效果图:
网络音乐部分:
实现方法有自己搭建Tomcat,但要自己开启服务器,而且ip地址每天在换。虽然可以实现但不推荐。另一个方法就是我们采用 点我查看断点续传,其实就是一些下载工具的技术,我们借助于断点下载来达到下载歌曲扫描出现在本地音乐列表里。如果第一次下载未完成或者意外情况退出了。下次可以根据上次断开的地方重新下载,如要记录第一次下载数据,那么肯定要数据库了。
最后别忘记加SD卡权限以及Internnet
源码: MusicOne1.zip
航空订票
航空订票正确方法是用webservice连上去得到xml并下载然后解析,但没有条件用webservice,只能用本地的开始解析,也就是在assets这里建立一个xml解析。解析上自己定义根名吧。然后布局方面我们采用tabhost显示单程和返程的UI。显示查询结果用Listview显示出来了。界面参照代码下载那帖吧。
我们首要任务就是怎么弄过用户输入信息而正确显示呢。我们来看单程查询,可以看到都是文本和Spinner,那么肯定加上相应的监听事件喽。日期方面自行参考其他资料。直接看查询代码:
- //查询按钮事件
- selectbtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(CheckAirportTabActivity.this,
- SingleListActivity.class);
- leaveCity = gospinner.getSelectedItem().toString();//获取出发城市选择的选项并转换成文字
- arriveCity = setofffspinner.getSelectedItem().toString();//同理
- leavedate = leaveDateEdt.getText().toString();//同理
- Bundle bundle = new Bundle();//Bundle存取数据,如出发城市,到达城市。出发日期等
- bundle.putString("leaveCity", leaveCity);
- bundle.putString("arriveCity", arriveCity);
- bundle.putString("leavedate", leavedate);
- intent.putExtras(bundle);//向查询界面传送数据
- startActivity(intent);
- finish();
- }
- });
- private ListView lv;
- String leaveCity,arriveCity,leavedate;
- public List<Map<String, Object>> parse(String path) {
- //定义一个单程的数组
- List<Map<String, Object>> singles = new ArrayList<Map<String, Object>>();
- //单程的实体
- List<SingleBean> singlebean = null;
- //Sax解析工厂
- SAXParserFactory factroy = SAXParserFactory.newInstance();
- Intent intent = getIntent();
- Bundle bundle = intent.getExtras();
- leaveCity = bundle.getString("leaveCity");//获取出发的数据
- arriveCity = bundle.getString("arriveCity");//获取目的城市数据
- leavedate=bundle.getString("leavedate");//单程的日期
- try {
- SAXParser parser = factroy.newSAXParser();
- XMLReader xmlreader = parser.getXMLReader();
- SingleXML handler = new SingleXML();//解析单程XML
- xmlreader.setContentHandler(handler);
- xmlreader.parse(new InputSource(this.getAssets().open(path)));//解析assets下解析xml
- singlebean = handler.getSingles();//获取单程的是列
- //for加强循环遍历实体类
- for (SingleBean sp : singlebean) {
- //根据用户的查询的关键字来查询。所以要截取字符窜。
- <div class="quote"><blockquote>if (leaveCity.equals(sp.getLeaveCity().substring(0, 2)
- .toString())
- && arriveCity.equals(sp.getArriveCity().substring(0, 2)
- .toString()))
//然后Map的容器装入进去。
Map<String, Object> map = new HashMap<String, Object>();
map.put("listview1", sp.getValue());//获取Value
map.put("listview2", sp.getKey());//获取关键字
map.put("listview3", sp.getLeaveCity());//获取出发城市
map.put("listview4", sp.getArriveCity());//获取到达城市
map.put("listview5", sp.getLeavetime());//获取离开时间
map.put("listview6", sp.getEndtime());//获取目的时间
map.put("listview7", sp.getPrice());//获取价格
map.put("listview8", sp.getDisaccount());//获取折扣
singles.add(map);//添加进map对象里。
} else {
continue;
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return singles;
}SAX解析过程不多说,关键地方在这里,根据用户的查询的关键字来查询。所以我们要截取字符窜。否则会很乱的,之后用map容器把各个根目录装载进去了。OK。简单的查询任务完成了
if (leaveCity.equals(sp.getLeaveCity().substring(0, 2)
.toString())
&& arriveCity.equals(sp.getArriveCity().substring(0, 2)
.toString()))