http://blog.csdn.net/android_tutor/article/details/5743183

大家好今天我将为大家分享基于Service与ContentProvider的音乐播放实例,对于接触Android有一些时日的人来说,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布局文件(我这里增加了四个按钮,上一首,播放,下一首,暂停)代码如下:

[java] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <TextView
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:text="WelcometoMrWei'sblog."
  11. />
  12. <LinearLayout
  13. android:orientation="horizontal"
  14. android:layout_width="fill_parent"
  15. android:layout_height="wrap_content"
  16. >
  17. <Button
  18. android:id="@+id/previous"
  19. android:layout_height="fill_parent"
  20. android:layout_width="wrap_content"
  21. android:layout_weight="1"
  22. android:text="上一首"
  23. />
  24. <Button
  25. android:id="@+id/play"
  26. android:layout_height="fill_parent"
  27. android:layout_width="wrap_content"
  28. android:layout_weight="1"
  29. android:text="播放"
  30. />
  31. <Button
  32. android:id="@+id/next"
  33. android:layout_height="fill_parent"
  34. android:layout_width="wrap_content"
  35. android:layout_weight="1"
  36. android:text="下一首"
  37. />
  38. <Button
  39. android:id="@+id/pause"
  40. android:layout_height="fill_parent"
  41. android:layout_width="wrap_content"
  42. android:layout_weight="1"
  43. android:text="暂停"
  44. />
  45. </LinearLayout>
  46. </LinearLayout>

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

[java] view plain copy
  1. packagecom.tutor.music;
  2. importjava.io.IOException;
  3. importandroid.app.Service;
  4. importandroid.content.Intent;
  5. importandroid.database.Cursor;
  6. importandroid.media.MediaPlayer;
  7. importandroid.net.Uri;
  8. importandroid.os.IBinder;
  9. importandroid.provider.MediaStore;
  10. importandroid.widget.Toast;
  11. publicclassMusicServiceextendsService{
  12. String[]mCursorCols=newString[]{
  13. "audio._idAS_id",//indexmustmatchIDCOLIDXbelow
  14. MediaStore.Audio.Media.ARTIST,MediaStore.Audio.Media.ALBUM,
  15. MediaStore.Audio.Media.TITLE,MediaStore.Audio.Media.DATA,
  16. MediaStore.Audio.Media.MIME_TYPE,MediaStore.Audio.Media.ALBUM_ID,
  17. MediaStore.Audio.Media.ARTIST_ID,MediaStore.Audio.Media.DURATION
  18. };
  19. privateMediaPlayermMediaPlayer;
  20. privateCursormCursor;
  21. privateintmPlayPosition=0;
  22. publicstaticfinalStringPLAY_ACTION="com.tutor.music.PLAY_ACTION";
  23. publicstaticfinalStringPAUSE_ACTION="com.tutor.music.PAUSE_ACTION";
  24. publicstaticfinalStringNEXT_ACTION="com.tutor.music.NEXT_ACTION";
  25. publicstaticfinalStringPREVIOUS_ACTION="com.tutor.music.PREVIOUS_ACTION";
  26. @Override
  27. publicIBinderonBind(Intentarg0){
  28. //TODOAuto-generatedmethodstub
  29. returnnull;
  30. }
  31. @Override
  32. publicvoidonCreate(){
  33. super.onCreate();
  34. mMediaPlayer=newMediaPlayer();
  35. //通过一个URI可以获取所有音频文件
  36. UriMUSIC_URL=MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
  37. //这里我过滤了一下,因为我机里有些音频文件是游戏音频,很短
  38. //播放不到一秒钟,我这里作了处理,默认大于10秒的可以看作是歌
  39. mCursor=getContentResolver().query(MUSIC_URL,mCursorCols,"duration>10000",null,null);
  40. }
  41. @Override
  42. publicvoidonStart(Intentintent,intstartId){
  43. super.onStart(intent,startId);
  44. Stringaction=intent.getAction();
  45. if(action.equals(PLAY_ACTION)){
  46. play();
  47. }elseif(action.equals(PAUSE_ACTION)){
  48. pause();
  49. }elseif(action.equals(NEXT_ACTION)){
  50. next();
  51. }elseif(action.equals(PREVIOUS_ACTION)){
  52. previous();
  53. }
  54. }
  55. //playthemusic
  56. publicvoidplay(){
  57. inite();
  58. }
  59. //暂停时,结束服务
  60. publicvoidpause(){
  61. stopSelf();
  62. }
  63. //上一首
  64. publicvoidprevious(){
  65. if(mPlayPosition==0){
  66. mPlayPosition=mCursor.getCount()-1;
  67. }else{
  68. mPlayPosition--;
  69. }
  70. inite();
  71. }
  72. publicvoidnext(){
  73. if(mPlayPosition==mCursor.getCount()-1){
  74. mPlayPosition=0;
  75. }else{
  76. mPlayPosition++;
  77. }
  78. inite();
  79. }
  80. publicvoidinite(){
  81. mMediaPlayer.reset();
  82. StringdataSource=getDateByPosition(mCursor,mPlayPosition);
  83. Stringinfo=getInfoByPosition(mCursor,mPlayPosition);
  84. //用Toast显示歌曲信息
  85. Toast.makeText(getApplicationContext(),info,Toast.LENGTH_SHORT).show();
  86. try{
  87. mMediaPlayer.setDataSource(dataSource);
  88. mMediaPlayer.prepare();
  89. mMediaPlayer.start();
  90. }catch(IllegalArgumentExceptione1){
  91. e1.printStackTrace();
  92. }catch(IllegalStateExceptione1){
  93. e1.printStackTrace();
  94. }catch(IOExceptione1){
  95. e1.printStackTrace();
  96. }
  97. }
  98. //根据位置来获取歌曲位置
  99. publicStringgetDateByPosition(Cursorc,intposition){
  100. c.moveToPosition(position);
  101. intdataColumn=c.getColumnIndex(MediaStore.Audio.Media.DATA);
  102. Stringdata=c.getString(dataColumn);
  103. returndata;
  104. }
  105. //获取当前播放歌曲演唱者及歌名
  106. publicStringgetInfoByPosition(Cursorc,intposition){
  107. c.moveToPosition(position);
  108. inttitleColumn=c.getColumnIndex(MediaStore.Audio.Media.TITLE);
  109. intartistColumn=c.getColumnIndex(MediaStore.Audio.Media.ARTIST);
  110. Stringinfo=c.getString(artistColumn)+""+c.getString(titleColumn);
  111. returninfo;
  112. }
  113. //服务结束时要释放MediaPlayer
  114. publicvoidonDestroy(){
  115. super.onDestroy();
  116. mMediaPlayer.release();
  117. }
  118. }

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

[java] view plain copy
  1. packagecom.tutor.music;
  2. importandroid.app.Activity;
  3. importandroid.content.ComponentName;
  4. importandroid.content.Intent;
  5. importandroid.os.Bundle;
  6. importandroid.view.View;
  7. importandroid.view.View.OnClickListener;
  8. importandroid.widget.Button;
  9. publicclassMusicDemoextendsActivityimplementsOnClickListener{
  10. privateButtonmPrevious,mPlay,mNext,mPause;
  11. privateComponentNamecomponent;
  12. publicvoidonCreate(BundlesavedInstanceState){
  13. super.onCreate(savedInstanceState);
  14. setContentView(R.layout.main);
  15. //oncreate里代码一如既往的少
  16. setupViews();
  17. }
  18. //初始化一些工作
  19. publicvoidsetupViews(){
  20. component=newComponentName(this,
  21. MusicService.class);
  22. mPrevious=(Button)findViewById(R.id.previous);
  23. mPlay=(Button)findViewById(R.id.play);
  24. mNext=(Button)findViewById(R.id.next);
  25. mPause=(Button)findViewById(R.id.pause);
  26. mPrevious.setOnClickListener(this);
  27. mPlay.setOnClickListener(this);
  28. mNext.setOnClickListener(this);
  29. mPause.setOnClickListener(this);
  30. }
  31. //按钮点击事件响应
  32. publicvoidonClick(Viewv){
  33. if(v==mPrevious){
  34. IntentmIntent=newIntent(MusicService.PREVIOUS_ACTION);
  35. mIntent.setComponent(component);
  36. startService(mIntent);
  37. }elseif(v==mPlay){
  38. IntentmIntent=newIntent(MusicService.PLAY_ACTION);
  39. mIntent.setComponent(component);
  40. startService(mIntent);
  41. }elseif(v==mNext){
  42. IntentmIntent=newIntent(MusicService.NEXT_ACTION);
  43. mIntent.setComponent(component);
  44. startService(mIntent);
  45. }else{
  46. IntentmIntent=newIntent(MusicService.PAUSE_ACTION);
  47. mIntent.setComponent(component);
  48. startService(mIntent);
  49. }
  50. }
  51. }

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

[java] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.tutor.music"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  7. <activityandroid:name=".MusicDemo"
  8. android:label="@string/app_name">
  9. <intent-filter>
  10. <actionandroid:name="android.intent.action.MAIN"/>
  11. <categoryandroid:name="android.intent.category.LAUNCHER"/>
  12. </intent-filter>
  13. </activity>
  14. <serviceandroid:name=".MusicService"android:exported="true"/>
  15. </application>
  16. <uses-sdkandroid:minSdkVersion="7"/>
  17. </manifest>

第六步:运行上述Android工程,效果如下图所示:

效果1:首界面:

效果2:点击播发按钮开始播放音乐:

效果3:我们可以在设置(Settings)->应用(Applications)->正在运行的服务(Running Services)查看我们启动了一个新的Service:



更多相关文章

  1. android 透明效果
  2. Android(安卓)Edittext设置负数以及小数
  3. Android多媒体--利用Service实现背景音乐的播放
  4. 几款好用的Android(安卓)Studio插件
  5. TextView添加ClickableSpan和LinkMovementMethod之间的关系
  6. android中的提示信息显示方法(toast应用)
  7. Android实现widget定时更新
  8. Android(安卓)中使用OpenGL ES进行2D开发(GLSurfaceView)
  9. 系出名门Android(7) - 控件(View)之ZoomControls, Include...

随机推荐

  1. MySQL 的启动和连接方式实例分析
  2. MySQL 主从复制原理与实践详解
  3. docker下mysql 8.0.20 安装配置方法图文
  4. mysql 8.0.20 winx64安装配置方法图文教
  5. Win10下mysql 8.0.20 安装配置方法图文教
  6. mysql 8.0.20 winx64.zip压缩版安装配置
  7. MySQL数据库主从同步实战过程详解
  8. MySQL数据库基础入门之常用命令小结
  9. MySQL数据库入门之备份数据库操作详解
  10. MySQL数据库入门之多实例配置方法详解