`
chengfengyang
  • 浏览: 20967 次
社区版块
存档分类
最新评论

基于Service与ContentProvider的音乐播放实例

阅读更多
Android的核心也就是Activity,Service,ContentProvider,BroadCastReceiver,以及串联它们的Intent五大模块,Activity我就不用多说了,而我将就这个例子来说一下Service,以及ContentProvider.

Service:

Android中的服务,它与Activity不同,它是不能与用户交互的,运行在后台的程序,如果我们退出应用时,没有结束进程,它仍然在后台运行,那我们什么时候会用到Service呢?比如我们播放音乐的时候,有可能想边听音乐边干些其他事情,当我们退出播放音乐的应用,如果不用Service,我们就听不到歌了,所以这时候就得用到Service了,又比如当我们一个应用的数据是通过网络获取的,不同时间(一段时间)的数据是不同的这时候我们可以用Service在后台定时更新,而不用每打开应用的时候在去获取。

CotentProvider:

Android中的内容提供者,它让我们可以通过一个URL跨应用获取数据(通常是SQLite数据库),我觉得Android这个还是机制还是非常不错的,特别是我们想获取Sdcard里一些数据时,比如我们想获取所有Sdcard里的音频,视频,图片等,我们只要通过一个URL就可以轻松搞定,其实我们在开机或者插入Sdcard时,Android会做一些事情,就是它自动建库,将我们卡里所有音频,视频,图片等信息存在相应的表中,我们可以用DDMS打开看一下如下图(data/data目录下),红线是我手机当前卡建立的数据库(不同卡会建立不同的数据库)





然后我们可以将这个数据库导出,用可以打开.db的工具打开浏览数据库的相关信息如下图所示(我这里打开了音频的数据表,可以看到我手机里所有音频文件,当然还有数据表字段):





本来这个应用是我用来写播放音乐Widget的代码,但是布局有点多,我就简单化了,做了一个比较 简单的Demo,老规矩Step by Step.



第一步:新建一个Android工程命名为MusicDemo.

第二步:候改main.xml布局文件(我这里增加了四个按钮,上一首,播放,下一首,暂停)代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
	<TextView  
	    android:layout_width="fill_parent" 
	    android:layout_height="wrap_content" 
	    android:text="Welcome to Mr Wei's blog."
	    />
	<LinearLayout
	  	android:orientation="horizontal"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	>
		<Button
			android:id="@+id/previous"
			android:layout_height="fill_parent"
			android:layout_width="wrap_content"
			android:layout_weight="1"
			android:text="上一首"
		/>
		<Button
			android:id="@+id/play"
			android:layout_height="fill_parent"
			android:layout_width="wrap_content"
			android:layout_weight="1"
			android:text="播放"
		/>
		<Button
			android:id="@+id/next"
			android:layout_height="fill_parent"
			android:layout_width="wrap_content"
			android:layout_weight="1"
			android:text="下一首"
		/>
		<Button
			android:id="@+id/pause"
			android:layout_height="fill_parent"
			android:layout_width="wrap_content"
			android:layout_weight="1"
			android:text="暂停"
		/>
	</LinearLayout>
</LinearLayout>


第三步:新建一个MusicService.java类,播放音乐都是在这个类里进行的哦,代码如下:

package com.tutor.music;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.provider.MediaStore;
import android.widget.Toast;
public class MusicService extends Service {
	
	String[] mCursorCols = new String[] {
			"audio._id AS _id", // index must match IDCOLIDX below
			MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM,
			MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA,
			MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Media.ALBUM_ID,
			MediaStore.Audio.Media.ARTIST_ID, MediaStore.Audio.Media.DURATION
	};
	private MediaPlayer mMediaPlayer;
	private Cursor mCursor;
	private int mPlayPosition = 0;
	
	public static final String PLAY_ACTION = "com.tutor.music.PLAY_ACTION";
	public static final String PAUSE_ACTION = "com.tutor.music.PAUSE_ACTION";
	public static final String NEXT_ACTION = "com.tutor.music.NEXT_ACTION";
	public static final String PREVIOUS_ACTION = "com.tutor.music.PREVIOUS_ACTION";
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public void onCreate() {
		super.onCreate();
		mMediaPlayer = new MediaPlayer();
		//通过一个URI可以获取所有音频文件
		Uri MUSIC_URL = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
		//这里我过滤了一下,因为我机里有些音频文件是游戏音频,很短
		//播放不到一秒钟,我这里作了处理,默认大于10秒的可以看作是歌
		mCursor = getContentResolver().query(MUSIC_URL, mCursorCols, "duration > 10000", null, null);
	}
	
	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
		
		String action = intent.getAction();
		if(action.equals(PLAY_ACTION)){
			play();
		}else if(action.equals(PAUSE_ACTION)){
			pause();
		}else if(action.equals(NEXT_ACTION)){
			next();
		}else if(action.equals(PREVIOUS_ACTION)){
			previous();
		}
	}
	
	//play the music
	public void play() {	
		inite();
	}
	
	//暂停时,结束服务
	public void pause() {
		stopSelf();
	}
	//上一首
	public void previous() {
		if (mPlayPosition == 0) {
			mPlayPosition = mCursor.getCount() - 1;
		} else {
			mPlayPosition--;
		}
		inite();
	}
	public void next() {
		if (mPlayPosition == mCursor.getCount() - 1) {
			mPlayPosition = 0;
		} else {
			mPlayPosition++;
		}
		inite();
	}
	public void inite() {
		mMediaPlayer.reset();
		String dataSource = getDateByPosition(mCursor, mPlayPosition);
		String info = getInfoByPosition(mCursor, mPlayPosition);
		//用Toast显示歌曲信息
		Toast.makeText(getApplicationContext(), info, Toast.LENGTH_SHORT).show();
		try {
			mMediaPlayer.setDataSource(dataSource);
			mMediaPlayer.prepare();
			mMediaPlayer.start();
		} catch (IllegalArgumentException e1) {
			e1.printStackTrace();
		} catch (IllegalStateException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
	//根据位置来获取歌曲位置
	public String getDateByPosition(Cursor c,int position){
		c.moveToPosition(position);
		int dataColumn = c.getColumnIndex(MediaStore.Audio.Media.DATA);		
		String data = c.getString(dataColumn);
		return data;
	}
	//获取当前播放歌曲演唱者及歌名
	public String getInfoByPosition(Cursor c,int position){
		c.moveToPosition(position);
		int titleColumn = c.getColumnIndex(MediaStore.Audio.Media.TITLE);
		int artistColumn = c.getColumnIndex(MediaStore.Audio.Media.ARTIST);
		String info = c.getString(artistColumn)+" " + c.getString(titleColumn);
		return info;
		
	}
	//服务结束时要释放MediaPlayer
	public void onDestroy() {
		super.onDestroy();
		mMediaPlayer.release();
	}
}

第四步:修改Musicdemo.java代码如下(代码比较简洁易懂):

package com.tutor.music;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MusicDemo extends Activity implements OnClickListener {
    
	private Button mPrevious,mPlay,mNext,mPause;
	private ComponentName component;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //oncreate里代码一如既往的少
        setupViews();
    }
    //初始化一些工作
    public void setupViews(){
    	component = new ComponentName(this,
				MusicService.class);
    	
    	mPrevious = (Button)findViewById(R.id.previous);
    	mPlay = (Button)findViewById(R.id.play);
    	mNext = (Button)findViewById(R.id.next);
    	mPause = (Button)findViewById(R.id.pause);
    	
    	mPrevious.setOnClickListener(this);
    	mPlay.setOnClickListener(this);
    	mNext.setOnClickListener(this);
    	mPause.setOnClickListener(this);
    }
    //按钮点击事件响应
	public void onClick(View v) {
		if(v == mPrevious){
			Intent mIntent = new Intent(MusicService.PREVIOUS_ACTION);
			mIntent.setComponent(component);
			startService(mIntent);
		}else if(v == mPlay){
			Intent mIntent = new Intent(MusicService.PLAY_ACTION);
			mIntent.setComponent(component);
			startService(mIntent);
		}else if(v == mNext){
			Intent mIntent = new Intent(MusicService.NEXT_ACTION);
			mIntent.setComponent(component);
			startService(mIntent);
		}else{
			Intent mIntent = new Intent(MusicService.PAUSE_ACTION);
			mIntent.setComponent(component);
			startService(mIntent);
		}
		
	}
}

第五步:修改AndroidManifest.xml,这里只是把我们的MusicService申明进去,不然会报错(第14行代码),代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.tutor.music"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MusicDemo"
                  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=".MusicService" android:exported="true" />
    </application>
    <uses-sdk android:minSdkVersion="7" />
</manifest> 

分享到:
评论

相关推荐

    Android实例代码

    第10章、Service与BroadcastReceiver 10.1、Service:Service的创建、配置、启动、停止、绑定和通信; Service的生命周期; 10.2、跨进程调用Service(AIDL服务):创建AIDL文件; 将接口暴露给客户端; 客户端访问AIDL...

    Android入门到精通源代码.

    8.4 应用实例详解:播放背景音乐 8.4.1 实例分析 8.4.2 实例实现 第9章 Android中的数据存储 9.1 使用Preferences存储数据 9.1.1 访问Preferences的API 9.1.2 使用XML存储Preferences数据 9.2 使用文件存储数据 ...

    android开发入门与实战(下)

    7.5 Android应用的灵魂——Intent和Activity介绍与实例 7.5.1 实例操作演示 7.5.2 实例编程实现 7.6 用好列表,做好程序——列表(ListView)介绍与实例 7.6.1 实例程序演示 7.6.2 实例编程实现 7.7 友好地互动交流...

    android开发入门与实战(上)

    7.5 Android应用的灵魂——Intent和Activity介绍与实例 7.5.1 实例操作演示 7.5.2 实例编程实现 7.6 用好列表,做好程序——列表(ListView)介绍与实例 7.6.1 实例程序演示 7.6.2 实例编程实现 7.7 友好地互动交流...

    Google.Android开发入门与实战

    从技术实现上,讲解了5个Android平台下的完整综合实例及源代码分析,分别是RSS阅读器、基于Google Map的个人GPS、豆瓣网(Web 2.0)客户端、在线音乐播放器、手机信息查看助手。《Android开发入门与实战》注重对实际...

    《Google Android开发入门与实战》.pdf

    从技术实现上,讲解了5个android平台下的完整综合实例及源代码分析,分别是rss阅读器、基于google map的个人gps、豆瓣网(web 2.0)客户端、在线音乐播放器、手机信息查看助手。本书注重对实际动手能力的指导,在遵循...

    Google Android开发入门与实战的代码

    7.5 Android应用的灵魂——Intent和Activity介绍与实例 106 7.5.1 实例操作演示 106 7.5.2 实例编程实现 106 7.6 用好列表,做好程序——列表(ListView)介绍与实例 111 7.6.1 实例程序演示 111 7.6.2...

    Android应用开发从入门到精通 android studio code 11-17章

     Android UI、常见控件和自定义控件、碎片、四大组件(Activity、Service、Broadcast和ContentProvider)、二维绘制、Canvas和Paint、多媒体开发等;  还讲解了Android开发的高级技术:  Camera、地图、GPS、...

    Android应用开发从入门到精通 android studio code 1-10章

     Android UI、常见控件和自定义控件、碎片、四大组件(Activity、Service、Broadcast和ContentProvider)、二维绘制、Canvas和Paint、多媒体开发等;  还讲解了Android开发的高级技术:  Camera、地图、GPS、...

    Android应用开发从入门到精通 code 1-12章

     Android UI、常见控件和自定义控件、碎片、四大组件(Activity、Service、Broadcast和ContentProvider)、二维绘制、Canvas和Paint、多媒体开发等;  还讲解了Android开发的高级技术:  Camera、地图、GPS、...

    Android应用开发从入门到精通样章

     Android UI、常见控件和自定义控件、碎片、四大组件(Activity、Service、Broadcast和ContentProvider)、二维绘制、Canvas和Paint、多媒体开发等;  还讲解了Android开发的高级技术:  Camera、地图、GPS、...

    Android应用开发从入门到精通 code 13-17章

     Android UI、常见控件和自定义控件、碎片、四大组件(Activity、Service、Broadcast和ContentProvider)、二维绘制、Canvas和Paint、多媒体开发等;  还讲解了Android开发的高级技术:  Camera、地图、GPS、...

    疯狂Android讲义源码

     10.1.3 绑定本地Service并与之  通信 377  10.1.4 Service的生命周期 381  10.2 跨进程调用Service  (AIDL服务) 382  10.2.1 AIDL服务简介 382  10.2.2 创建AIDL文件 383  10.2.3 将接口暴露给客户端 383...

    xmljava系统源码-PluginLoader:基于PluginFramwork的插件加载器,支持APK动态加载

    xml java系统源码 #Tamic Plugin-Framework ...也可交由系统管理,但是不支持多实例,因此插件service仍然通过代理方式实现。) 6、支持插件引用宿主程序的依赖库、插件资源、宿主资源。 7、支持插件使用

    新版Android开发教程.rar

    开放手机联盟, Open Handset Alliance :是美国 Google 公司与 2007 年 11 月 5 日宣布组建的一个全球性的联 盟组织。这一联盟将会支持 Google 发布的 Android 手机操作系统或者应用软件,共同开发名为 Android 的 ...

Global site tag (gtag.js) - Google Analytics