"在信息时代,客观障碍已不复存在,所谓障碍都是主观上的。如果你想研发什么新的技术,你不需要几百万美元的资金,你只需要在冰箱里放满比萨和可乐,再有一 台便宜的计算机,和与之献身的决心,你即可拥有任何你想拥有的编程境界!- John Carmack
实现非常简单
1、用ContentResolver查询到话机中的MP3歌曲信息
2、用ListView展示出来
3、用一个Service中的MediaPlayer播放歌曲
4、用触摸手势,向右,向左滑动来播放,停止歌曲
下面是代码,我写了很详细的注释,希望大家看了后有什么优化意见,和改进建议都可以告诉我,欢迎讨论。
K_musicActivity.java 用来呈现和控制
- package com.kennan.k_music;
- import android.app.Activity;
- import android.content.Intent;
- import android.database.Cursor;
- import android.graphics.Color;
- import android.os.Bundle;
- import android.provider.MediaStore;
- import android.view.GestureDetector;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.GestureDetector.OnGestureListener;
- import android.view.View.OnTouchListener;
- import android.widget.AdapterView;
- import android.widget.LinearLayout;
- import android.widget.ListAdapter;
- import android.widget.ListView;
- import android.widget.SimpleCursorAdapter;
- public class K_musicActivity extends Activity implements OnTouchListener,
- OnGestureListener {
- private LinearLayout m_LinearLayout;
- private ListView m_ListView;
- private Intent i;
- private Cursor cur;
- private GestureDetector mGestureDetector;
- private static final int FLING_MIN_DISTANCE = 50;
- private static final int FLING_MIN_VELOCITY = 100;
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // UI最底层的LinearLayout
- m_LinearLayout = new LinearLayout(this);
- // 设置内部元素排列方式
- m_LinearLayout.setOrientation(LinearLayout.VERTICAL);
- // 背景颜色
- m_LinearLayout.setBackgroundColor(Color.GREEN);
- // listView,用来存放歌曲列表
- m_ListView = new ListView(this);
- // 设置listView元素layout参数
- LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.FILL_PARENT,
- LinearLayout.LayoutParams.WRAP_CONTENT);
- m_ListView.setBackgroundColor(Color.BLUE);
- m_LinearLayout.addView(m_ListView, param);
- // 将此activity的ContentView设置为m_LinearLayout
- this.setContentView(m_LinearLayout);
- // 查询媒体信息
- cur = this.getContentResolver().query(
- MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
- MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
- this.startManagingCursor(cur);
- // 用listAdapter将歌曲信息添加至ListView
- ListAdapter adapter = new SimpleCursorAdapter(this,
- android.R.layout.simple_expandable_list_item_2, cur,
- new String[] { MediaStore.Audio.Media.TITLE,
- MediaStore.Audio.Media.ARTIST }, new int[] {
- android.R.id.text1, android.R.id.text2 });
- m_ListView.setAdapter(adapter);
- // 播放歌曲的Service,这是一个Action路径
- i = new Intent("com.kennan.music");
- // 添加点击单条歌曲监听,用于选择播放歌曲
- m_ListView.setOnItemClickListener(clictlistener);
- // 手势探测器,用于捕捉手势实现,播放,停止播放
- mGestureDetector = new GestureDetector(this);
- // 添加触摸监听,实现手势功能
- m_LinearLayout.setLongClickable(true);
- m_LinearLayout.setOnTouchListener(this);
- m_ListView.setLongClickable(true);
- m_ListView.setOnTouchListener(this);
- }
- /**
- * 点击单条歌曲监听,选择播放歌曲
- */
- private AdapterView.OnItemClickListener clictlistener = new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int position,
- long arg3) {
- // 将歌曲信息游标移动到被单击处歌曲
- cur.moveToPosition(position);
- // 得到歌曲的URI
- String data = cur.getString(cur
- .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
- // 将歌曲URI传说到播放歌曲的Service
- i.putExtra("data", data);
- }
- };
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- // OnGestureListener will analyzes the given motion event
- return mGestureDetector.onTouchEvent(event);
- }
- /**
- * 滑动事件,向右活动开始播放歌曲,向左播放停止播放歌曲
- */
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- // 参数解释:
- // e1:第1个ACTION_DOWN MotionEvent
- // e2:最后一个ACTION_MOVE MotionEvent
- // velocityX:X轴上的移动速度,像素/秒
- // velocityY:Y轴上的移动速度,像素/秒
- // 触发条件 :
- // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒
- if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- // Fling left
- K_musicActivity.this.stopService(i);
- } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- // Fling right
- // 先关闭正在播放的service,避免多个service同时播放
- K_musicActivity.this.stopService(i);
- K_musicActivity.this.startService(i);
- }
- return false;
- }
- // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发
- @Override
- public boolean onDown(MotionEvent e) {
- return false;
- }
- // 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发
- // 注意和onDown()的区别,强调的是没有松开或者拖动的状态
- @Override
- public void onShowPress(MotionEvent e) {
- // TODO Auto-generated method stub
- }
- // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- // TODO Auto-generated method stub
- return false;
- }
- // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发
- @Override
- public void onLongPress(MotionEvent e) {
- // TODO Auto-generated method stub
- }
- // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
- float distanceY) {
- // TODO Auto-generated method stub
- return false;
- }
- }
package com.kennan.k_music;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class K_musicActivity extends Activity implements OnTouchListener,
OnGestureListener {
private LinearLayout m_LinearLayout;
private ListView m_ListView;
private Intent i;
private Cursor cur;
private GestureDetector mGestureDetector;
private static final int FLING_MIN_DISTANCE = 50;
private static final int FLING_MIN_VELOCITY = 100;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// UI最底层的LinearLayout
m_LinearLayout = new LinearLayout(this);
// 设置内部元素排列方式
m_LinearLayout.setOrientation(LinearLayout.VERTICAL);
// 背景颜色
m_LinearLayout.setBackgroundColor(Color.GREEN);
// listView,用来存放歌曲列表
m_ListView = new ListView(this);
// 设置listView元素layout参数
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
m_ListView.setBackgroundColor(Color.BLUE);
m_LinearLayout.addView(m_ListView, param);
// 将此activity的ContentView设置为m_LinearLayout
this.setContentView(m_LinearLayout);
// 查询媒体信息
cur = this.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
this.startManagingCursor(cur);
// 用listAdapter将歌曲信息添加至ListView
ListAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_expandable_list_item_2, cur,
new String[] { MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST }, new int[] {
android.R.id.text1, android.R.id.text2 });
m_ListView.setAdapter(adapter);
// 播放歌曲的Service,这是一个Action路径
i = new Intent("com.kennan.music");
// 添加点击单条歌曲监听,用于选择播放歌曲
m_ListView.setOnItemClickListener(clictlistener);
// 手势探测器,用于捕捉手势实现,播放,停止播放
mGestureDetector = new GestureDetector(this);
// 添加触摸监听,实现手势功能
m_LinearLayout.setLongClickable(true);
m_LinearLayout.setOnTouchListener(this);
m_ListView.setLongClickable(true);
m_ListView.setOnTouchListener(this);
}
/**
* 点击单条歌曲监听,选择播放歌曲
*/
private AdapterView.OnItemClickListener clictlistener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// 将歌曲信息游标移动到被单击处歌曲
cur.moveToPosition(position);
// 得到歌曲的URI
String data = cur.getString(cur
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
// 将歌曲URI传说到播放歌曲的Service
i.putExtra("data", data);
}
};
@Override
public boolean onTouch(View v, MotionEvent event) {
// OnGestureListener will analyzes the given motion event
return mGestureDetector.onTouchEvent(event);
}
/**
* 滑动事件,向右活动开始播放歌曲,向左播放停止播放歌曲
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// 参数解释:
// e1:第1个ACTION_DOWN MotionEvent
// e2:最后一个ACTION_MOVE MotionEvent
// velocityX:X轴上的移动速度,像素/秒
// velocityY:Y轴上的移动速度,像素/秒
// 触发条件 :
// X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒
if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
// Fling left
K_musicActivity.this.stopService(i);
} else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
// Fling right
// 先关闭正在播放的service,避免多个service同时播放
K_musicActivity.this.stopService(i);
K_musicActivity.this.startService(i);
}
return false;
}
// 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发
@Override
public boolean onDown(MotionEvent e) {
return false;
}
// 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发
// 注意和onDown()的区别,强调的是没有松开或者拖动的状态
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
// 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}
// 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
}
// 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
}
}
KMusicService 用来播放歌曲
- package com.kennan.k_music;
- import java.io.IOException;
- import android.app.Service;
- import android.content.Intent;
- import android.media.MediaPlayer;
- import android.os.IBinder;
- public class KMusicService extends Service {
- private MediaPlayer player;
- public IBinder onBind(Intent arg0) {
- return null;
- }
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- // 得到从activity传来的歌曲URI
- String uri = intent.getStringExtra("data");
- player = new MediaPlayer();
- try {
- player.setDataSource(uri);
- player.prepare();
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalStateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- player.start();
- }
- public Service getService(){
- return this;
- }
- public void onDestroy() {
- player.stop();
- super.onDestroy();
- }
- }
package com.kennan.k_music;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
public class KMusicService extends Service {
private MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// 得到从activity传来的歌曲URI
String uri = intent.getStringExtra("data");
player = new MediaPlayer();
try {
player.setDataSource(uri);
player.prepare();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
player.start();
}
public Service getService(){
return this;
}
public void onDestroy() {
player.stop();
super.onDestroy();
}
}
AndroidManifest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.kennan.k_music"
- android:versionCode="1"
- android:versionName="1.0">
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".K_musicActivity"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <service android:name="KMusicService">
- <intent-filter>
- <action android:name="com.kennan.music" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </service>
- </application>
- <uses-sdk android:minSdkVersion="7" />
- </manifest>
另外讲一下如何将MP3添加到模拟器中。
打开Eclipse中的DDMS
里面有个FileExplorer
里面有个sdcard就是手机的SD卡
在FileExplorer的右上角有图标,可以将MP3 push入手机模拟器
添加完后,进入模拟器,
进入Dev Tools,里面有个Media Scanner.运行一下。
ok现在进入应用就能看到歌曲列表了,试试吧。