Android(java)学习笔记177: 服务(service)之音乐播放器
1.我们播放音乐,希望在后台长期运行,不希望因为内存不足等等原因,从而导致被gc回收,音乐播放终止,所以我们这里使用服务Service创建一个音乐播放器。
2.创建一个音乐播放器项目(使用服务)
(1)首先新建一个Android项目,命名为"Mp3音乐播放器",如下:
(2)创建服务MusicService,如下:
1 package com.himi.Mp3player; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.media.AudioManager; 6 import android.media.MediaPlayer; 7 import android.os.Binder; 8 import android.os.IBinder; 9 10 public class MusicService extends Service { 11 /** 12 * 要播放的音乐文件的路径 13 */ 14 private String path; 15 private MediaPlayer mediaPlayer; 16 /** 17 * 音乐播放的状态 18 */ 19 private int PLAYING_STATUS; 20 private int STOP = 0; 21 private int PLAYING = 1; 22 private int PAUSE = 2; 23 24 @Override 25 public IBinder onBind(Intent intent) { 26 return new MyBinder(); 27 } 28 29 private class MyBinder extends Binder implements IMusicService { 30 public MusicService callGetMusicService() { 31 return getMusicService(); 32 } 33 } 34 35 /** 36 * 返回服务的对象 37 * 38 * @return 39 */ 40 public MusicService getMusicService() { 41 return this; 42 } 43 44 @Override 45 public void onCreate() { 46 System.out.println("服务被创建了。"); 47 super.onCreate(); 48 } 49 50 @Override 51 public void onDestroy() { 52 System.out.println("服务被销毁了。"); 53 super.onDestroy(); 54 } 55 56 /** 57 * 设置要播放的音乐 58 * 59 * @param path 60 * 音乐文件的路径 61 */ 62 public void setMusic(String path) { 63 this.path = path; 64 } 65 66 /** 67 * 播放音乐,播放之前请设置音乐的路径 68 */ 69 public boolean play() { 70 if (mediaPlayer != null && mediaPlayer.isPlaying()) { 71 mediaPlayer.stop(); 72 mediaPlayer.release(); 73 mediaPlayer = null; 74 } 75 try { 76 if (path == null) { 77 return false; 78 } 79 mediaPlayer = new MediaPlayer(); 80 mediaPlayer.reset(); 81 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 82 mediaPlayer.setDataSource(path); 83 mediaPlayer.prepare(); 84 mediaPlayer.start(); 85 PLAYING_STATUS = PLAYING; 86 return true; 87 } catch (Exception e) { 88 e.printStackTrace(); 89 return false; 90 } 91 } 92 93 /** 94 * 暂停音乐 95 */ 96 public void pause() { 97 if (mediaPlayer != null && mediaPlayer.isPlaying()) { 98 mediaPlayer.pause(); 99 PLAYING_STATUS = PAUSE; 100 } 101 } 102 103 /** 104 * 继续开始 105 */ 106 public void resume() { 107 if (mediaPlayer != null && PLAYING_STATUS == PAUSE) { 108 mediaPlayer.start(); 109 PLAYING_STATUS = PLAYING; 110 } 111 } 112 113 public void stop() { 114 if (mediaPlayer != null && mediaPlayer.isPlaying()) { 115 mediaPlayer.stop(); 116 mediaPlayer.release(); 117 mediaPlayer = null; 118 PLAYING_STATUS = STOP; 119 } 120 } 121 }
使用到的接口为IMusicService,如下:
这里服务(service)方法比较多,所以我们最好调用方法获取服务的引用,如下:
1 package com.himi.Mp3player; 2 3 public interface IMusicService { 4 //调用获取服务的引用 5 public MusicService callGetMusicService(); 6 7 }
(3)布局文件activity_main.xml,如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context="com.himi.Mp3player.MainActivity" > 7 8 <EditText 9 android:id="@+id/et_path" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:hint="请输入音乐的路径" /> 13 14 <LinearLayout 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:orientation="horizontal" > 18 19 <Button 20 android:layout_width="0dip" 21 android:layout_height="wrap_content" 22 android:layout_weight="1" 23 android:onClick="play" 24 android:text="播放" /> 25 26 <Button 27 android:layout_width="0dip" 28 android:layout_height="wrap_content" 29 android:layout_weight="1" 30 android:onClick="pause" 31 android:text="暂停" /> 32 33 <Button 34 android:layout_width="0dip" 35 android:layout_height="wrap_content" 36 android:layout_weight="1" 37 android:onClick="resume" 38 android:text="继续" /> 39 40 <Button 41 android:layout_width="0dip" 42 android:layout_height="wrap_content" 43 android:layout_weight="1" 44 android:onClick="stop" 45 android:text="停止" /> 46 </LinearLayout> 47 48 </LinearLayout>
布局效果如下:
(4)使用到服务要在AndroidMainfest.xml文件中注册服务,如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.himi.Mp3player" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="15" 9 android:targetSdkVersion="17" /> 10 11 <application 12 android:allowBackup="true" 13 android:icon="@drawable/ic_launcher" 14 android:label="@string/app_name" 15 android:theme="@style/AppTheme" > 16 <activity 17 android:name=".MainActivity" 18 android:label="@string/app_name" > 19 <intent-filter> 20 <action android:name="android.intent.action.MAIN" /> 21 22 <category android:name="android.intent.category.LAUNCHER" /> 23 </intent-filter> 24 </activity> 25 <service android:name="com.himi.Mp3player.MusicService"></service> 26 </application> 27 28 </manifest>
(5)此处的MainActivity,如下:
1 package com.himi.Mp3player; 2 3 import android.app.Activity; 4 import android.content.ComponentName; 5 import android.content.Intent; 6 import android.content.ServiceConnection; 7 import android.os.Bundle; 8 import android.os.IBinder; 9 import android.text.TextUtils; 10 import android.view.View; 11 import android.widget.EditText; 12 import android.widget.Toast; 13 14 public class MainActivity extends Activity { 15 16 private MyConn conn; 17 private IMusicService iMusicService; 18 private MusicService musicService; 19 private EditText et_path; 20 21 @Override 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.activity_main); 25 26 et_path = (EditText) findViewById(R.id.et_path); 27 // 保证服务长期后台运行 28 Intent intent = new Intent(this, MusicService.class); 29 startService(intent); 30 // 调用服务的方法 31 conn = new MyConn(); 32 bindService(intent, new MyConn(), BIND_AUTO_CREATE); 33 } 34 35 private class MyConn implements ServiceConnection { 36 37 public void onServiceConnected(ComponentName name, IBinder service) { 38 iMusicService = (IMusicService) service; 39 musicService = iMusicService.callGetMusicService(); 40 } 41 42 public void onServiceDisconnected(ComponentName name) { 43 // TODO 自动生成的方法存根 44 45 } 46 47 } 48 49 public void play(View view) { 50 String path = et_path.getContext().toString().trim(); 51 if (TextUtils.isEmpty(path)) { 52 Toast.makeText(this, "路径不合法", 0).show(); 53 return; 54 } 55 musicService.setMusic(path); 56 boolean result = musicService.play(); 57 if (!result) { 58 Toast.makeText(this, "播放失败,请检查路径,或者音乐文件是否合法", 0).show(); 59 } 60 } 61 62 public void pause(View view) { 63 musicService.pause(); 64 } 65 66 public void resume(View view) { 67 musicService.resume(); 68 69 } 70 71 public void stop(View view) { 72 musicService.stop(); 73 } 74 75 @Override 76 protected void onDestroy() { 77 // 解绑服务 78 unbindService(conn); 79 super.onDestroy(); 80 } 81 82 }