播放MP3的小应用(边写边学Android 一)

"在信息时代,客观障碍已不复存在,所谓障碍都是主观上的。如果你想研发什么新的技术,你不需要几百万美元的资金,你只需要在冰箱里放满比萨和可乐,再有一 台便宜的计算机,和与之献身的决心,你即可拥有任何你想拥有的编程境界!- John Carmack

实现非常简单
1、用ContentResolver查询到话机中的MP3歌曲信息
2、用ListView展示出来
3、用一个Service中的MediaPlayer播放歌曲
4、用触摸手势,向右,向左滑动来播放,停止歌曲

下面是代码,我写了很详细的注释,希望大家看了后有什么优化意见,和改进建议都可以告诉我,欢迎讨论。

K_musicActivity.java 用来呈现和控制

Java代码 复制代码
  1. package com.kennan.k_music;   
  2.   
  3. import android.app.Activity;   
  4. import android.content.Intent;   
  5. import android.database.Cursor;   
  6. import android.graphics.Color;   
  7. import android.os.Bundle;   
  8. import android.provider.MediaStore;   
  9. import android.view.GestureDetector;   
  10. import android.view.MotionEvent;   
  11. import android.view.View;   
  12. import android.view.GestureDetector.OnGestureListener;   
  13. import android.view.View.OnTouchListener;   
  14. import android.widget.AdapterView;   
  15. import android.widget.LinearLayout;   
  16. import android.widget.ListAdapter;   
  17. import android.widget.ListView;   
  18. import android.widget.SimpleCursorAdapter;   
  19.   
  20. public class K_musicActivity extends Activity implements OnTouchListener,   
  21.         OnGestureListener {   
  22.   
  23.     private LinearLayout m_LinearLayout;   
  24.     private ListView m_ListView;   
  25.     private Intent i;   
  26.     private Cursor cur;   
  27.     private GestureDetector mGestureDetector;   
  28.     private static final int FLING_MIN_DISTANCE = 50;   
  29.     private static final int FLING_MIN_VELOCITY = 100;   
  30.   
  31.     /** Called when the activity is first created. */  
  32.     @Override  
  33.     public void onCreate(Bundle savedInstanceState) {   
  34.         super.onCreate(savedInstanceState);   
  35.            
  36.         // UI最底层的LinearLayout   
  37.         m_LinearLayout = new LinearLayout(this);   
  38.         // 设置内部元素排列方式   
  39.         m_LinearLayout.setOrientation(LinearLayout.VERTICAL);   
  40.         // 背景颜色   
  41.         m_LinearLayout.setBackgroundColor(Color.GREEN);   
  42.            
  43.         // listView,用来存放歌曲列表   
  44.         m_ListView = new ListView(this);   
  45.            
  46.         // 设置listView元素layout参数   
  47.         LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(   
  48.                 LinearLayout.LayoutParams.FILL_PARENT,   
  49.                 LinearLayout.LayoutParams.WRAP_CONTENT);   
  50.         m_ListView.setBackgroundColor(Color.BLUE);   
  51.         m_LinearLayout.addView(m_ListView, param);   
  52.            
  53.         // 将此activity的ContentView设置为m_LinearLayout   
  54.         this.setContentView(m_LinearLayout);   
  55.            
  56.         // 查询媒体信息   
  57.         cur = this.getContentResolver().query(   
  58.                 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, nullnullnull,   
  59.                 MediaStore.Audio.Media.DEFAULT_SORT_ORDER);   
  60.   
  61.         this.startManagingCursor(cur);   
  62.            
  63.         // 用listAdapter将歌曲信息添加至ListView   
  64.         ListAdapter adapter = new SimpleCursorAdapter(this,   
  65.                 android.R.layout.simple_expandable_list_item_2, cur,   
  66.                 new String[] { MediaStore.Audio.Media.TITLE,   
  67.                         MediaStore.Audio.Media.ARTIST }, new int[] {   
  68.                         android.R.id.text1, android.R.id.text2 });   
  69.         m_ListView.setAdapter(adapter);   
  70.            
  71.         // 播放歌曲的Service,这是一个Action路径   
  72.         i = new Intent("com.kennan.music");   
  73.            
  74.         // 添加点击单条歌曲监听,用于选择播放歌曲   
  75.         m_ListView.setOnItemClickListener(clictlistener);   
  76.            
  77.         // 手势探测器,用于捕捉手势实现,播放,停止播放   
  78.         mGestureDetector = new GestureDetector(this);   
  79.            
  80.         // 添加触摸监听,实现手势功能   
  81.         m_LinearLayout.setLongClickable(true);   
  82.         m_LinearLayout.setOnTouchListener(this);   
  83.         m_ListView.setLongClickable(true);   
  84.         m_ListView.setOnTouchListener(this);   
  85.   
  86.     }   
  87.        
  88.     /**  
  89.      * 点击单条歌曲监听,选择播放歌曲  
  90.      */  
  91.     private AdapterView.OnItemClickListener clictlistener = new AdapterView.OnItemClickListener() {   
  92.   
  93.         @Override  
  94.         public void onItemClick(AdapterView<?> arg0, View arg1, int position,   
  95.                 long arg3) {   
  96.                
  97.             // 将歌曲信息游标移动到被单击处歌曲   
  98.             cur.moveToPosition(position);   
  99.             // 得到歌曲的URI   
  100.             String data = cur.getString(cur   
  101.                     .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));   
  102.             // 将歌曲URI传说到播放歌曲的Service   
  103.             i.putExtra("data", data);   
  104.   
  105.         }   
  106.     };   
  107.        
  108.     @Override  
  109.     public boolean onTouch(View v, MotionEvent event) {   
  110.         // OnGestureListener will analyzes the given motion event   
  111.         return mGestureDetector.onTouchEvent(event);   
  112.     }   
  113.        
  114.     /**  
  115.      * 滑动事件,向右活动开始播放歌曲,向左播放停止播放歌曲  
  116.      */  
  117.     @Override  
  118.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,   
  119.             float velocityY) {   
  120.         // 参数解释:   
  121.         // e1:第1个ACTION_DOWN MotionEvent   
  122.         // e2:最后一个ACTION_MOVE MotionEvent   
  123.         // velocityX:X轴上的移动速度,像素/秒   
  124.         // velocityY:Y轴上的移动速度,像素/秒   
  125.   
  126.         // 触发条件 :   
  127.         // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒   
  128.   
  129.         if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE   
  130.                 && Math.abs(velocityX) > FLING_MIN_VELOCITY) {   
  131.             // Fling left   
  132.   
  133.             K_musicActivity.this.stopService(i);   
  134.         } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE   
  135.                 && Math.abs(velocityX) > FLING_MIN_VELOCITY) {   
  136.             // Fling right   
  137.                
  138.             // 先关闭正在播放的service,避免多个service同时播放   
  139.             K_musicActivity.this.stopService(i);   
  140.             K_musicActivity.this.startService(i);   
  141.         }   
  142.   
  143.         return false;   
  144.     }   
  145.        
  146.        
  147.     // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发   
  148.     @Override  
  149.     public boolean onDown(MotionEvent e) {   
  150.   
  151.         return false;   
  152.     }   
  153.   
  154.     // 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发   
  155.     // 注意和onDown()的区别,强调的是没有松开或者拖动的状态   
  156.     @Override  
  157.     public void onShowPress(MotionEvent e) {   
  158.         // TODO Auto-generated method stub   
  159.     }   
  160.   
  161.     // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发   
  162.     @Override  
  163.     public boolean onSingleTapUp(MotionEvent e) {   
  164.         // TODO Auto-generated method stub   
  165.         return false;   
  166.     }   
  167.   
  168.     // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发   
  169.     @Override  
  170.     public void onLongPress(MotionEvent e) {   
  171.         // TODO Auto-generated method stub   
  172.   
  173.     }   
  174.   
  175.     // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发   
  176.     @Override  
  177.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,   
  178.             float distanceY) {   
  179.         // TODO Auto-generated method stub   
  180.         return false;   
  181.     }   
  182.   
  183. }  
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 用来播放歌曲

Java代码 复制代码
  1. package com.kennan.k_music;   
  2.   
  3. import java.io.IOException;   
  4.   
  5. import android.app.Service;   
  6. import android.content.Intent;   
  7. import android.media.MediaPlayer;   
  8. import android.os.IBinder;   
  9.   
  10. public class KMusicService extends Service {   
  11.   
  12.     private MediaPlayer player;   
  13.   
  14.     public IBinder onBind(Intent arg0) {   
  15.         return null;   
  16.     }   
  17.   
  18.     public void onStart(Intent intent, int startId) {   
  19.         super.onStart(intent, startId);   
  20.            
  21.         // 得到从activity传来的歌曲URI   
  22.         String uri = intent.getStringExtra("data");   
  23.            
  24.         player = new MediaPlayer();   
  25.         try {   
  26.             player.setDataSource(uri);   
  27.             player.prepare();   
  28.         } catch (IllegalArgumentException e) {   
  29.             // TODO Auto-generated catch block   
  30.             e.printStackTrace();   
  31.         } catch (IllegalStateException e) {   
  32.             // TODO Auto-generated catch block   
  33.             e.printStackTrace();   
  34.         } catch (IOException e) {   
  35.             // TODO Auto-generated catch block   
  36.             e.printStackTrace();   
  37.         }   
  38.            
  39.         player.start();   
  40.     }   
  41.        
  42.     public Service getService(){   
  43.         return this;   
  44.     }   
  45.        
  46.     public void onDestroy() {   
  47.   
  48.         player.stop();   
  49.         super.onDestroy();   
  50.     }   
  51. }  
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代码 复制代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.kennan.k_music"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  7.         <activity android:name=".K_musicActivity"  
  8.                   android:label="@string/app_name">  
  9.             <intent-filter>  
  10.                 <action android:name="android.intent.action.MAIN" />  
  11.                 <category android:name="android.intent.category.LAUNCHER" />  
  12.             </intent-filter>  
  13.         </activity>  
  14.   
  15.     <service android:name="KMusicService">  
  16.         <intent-filter>  
  17.                 <action android:name="com.kennan.music" />  
  18.                 <category android:name="android.intent.category.DEFAULT" />  
  19.         </intent-filter>  
  20.     </service>  
  21. </application>  
  22.     <uses-sdk android:minSdkVersion="7" />  
  23.   
  24.   
  25. </manifest>   



另外讲一下如何将MP3添加到模拟器中。
打开Eclipse中的DDMS
里面有个FileExplorer
里面有个sdcard就是手机的SD卡
在FileExplorer的右上角有图标,可以将MP3 push入手机模拟器
添加完后,进入模拟器,
进入Dev Tools,里面有个Media Scanner.运行一下。

ok现在进入应用就能看到歌曲列表了,试试吧。

转自:http://woshizn.javaeye.com/blog/605197

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值