项目概述:该项目模拟实现音乐APP控制端通过服务调用音乐APP服务端达到播放音乐和停止音乐的功能(只是模拟,不能实现播放)
一、服务端
1.布局文件activity_main.xml中
<Button
android:id="@+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/btnStop"
android:layout_marginTop="26dp"
android:onClick="start"
android:text="开启服务" />
<Button
android:id="@+id/btnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/btnStart"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
android:onClick="stop"
android:text="关闭服务" />
<Button
android:id="@+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/btnStop"
android:layout_below="@+id/btnStop"
android:layout_marginTop="14dp"
android:text="播放音乐"
android:onClick="play"/>
2.在自定义的服务类MyService.java中,需要继承服务Service
package com.t20.music.service;
import com.t20.music.service.function.MusicFunction.Stub;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MyBinder();
}
/**
* 内部类,实现MusicFunction.aidl接口中的播放方法
*
* @author Administrator
*
*/
class MyBinder extends Stub {
@Override
public void Play(String name) throws RemoteException {
// 播放音乐
play(name);
}
}
/**
* 创建服务
*/
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.w("服务消息:", "服务开启");
}
/**
* 销毁服务
*/
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.w("服务消息:", "服务关闭");
}
/**
* 播放音乐方法
*
* @param name
*/
private void play(String name) {
Log.e("播放信息:", "播放了名字为:" + name + ",的音乐!");
};
}
3.自定义播放音乐接口MusicFunction.aidl(将后缀名改为aidl,并将public去掉)
package com.t20.music.service.function;
interface MusicFunction {
void Play(String name);
}
4.在清单文件AndroidManifest.xml中注册服务
<!-- 注册服务 -->
<service android:name="com.t20.music.service.MyService" >
<intent-filter>
<action android:name="com.music.kugou" />
</intent-filter>
</service>
5.在MainActivity.java文件中完成开启、停止服务等操作
package com.t20.music;
import com.t20.music.service.MyService;
import com.t20.music.service.function.MusicFunction;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.widget.Toast;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
public class MainActivity extends Activity {
private Myconn myconn;// 活动与服务连接对象
MusicFunction mf;// 播放接口对象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 开启服务
*
* @param v
*/
public void start(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, MyService.class);
// 开启服务
startService(intent);
myconn = new Myconn();
// 绑定服务与活动,BIND_AUTO_CREATE在服务创建的时候自动绑定
bindService(intent, myconn, BIND_AUTO_CREATE);
}
/**
* 关闭服务,关闭服务之前,需要解绑服务
*
* @param v
*/
public void stop(View v) {
if (myconn != null) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, MyService.class);
// 解绑服务
unbindService(myconn);
mf = null;
myconn = null;
// 停止服务
stopService(intent);
}
}
/**
* 活动与服务连接内部类
*
* @author Administrator
*
*/
class Myconn implements ServiceConnection {
/**
* 服务在连接中 service是MyService.java服务中onBind()方法的返回值
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
mf = (MusicFunction) service;
}
/**
* 服务断开连接
*/
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
/**
* 播放音乐
*
* @param v
*/
public void play(View v) {
String name = "xxx";
if (mf != null) {
try {
mf.Play(name);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "请先开启服务", Toast.LENGTH_SHORT)
.show();
}
}
}
二、控制端
1.布局文件activity_main.xml中 <TextView
android:id="@+id/tvHead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="播放音乐"
android:textSize="20dp" />
<Button
android:id="@+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/tvHead"
android:layout_below="@+id/tvHead"
android:layout_marginTop="22dp"
android:onClick="play"
android:text="播放" />
<EditText
android:id="@+id/etName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/btnPlay"
android:layout_alignBottom="@+id/btnPlay"
android:layout_toLeftOf="@+id/btnPlay"
android:ems="10" />
2.自定义播放接口MusicFunction.aidl(将后缀名改为aidl,并将public去掉,同时该接口路径必须和服务端MusicFunction.aidl接口的路径一致)
package com.t20.music.service.function;
interface MusicFunction {
void Play(String address);
}
3.在MainActivity.java中实现播放控制
package com.t20.kugou;
import com.t20.music.service.function.MusicFunction;
import com.t20.music.service.function.MusicFunction.Stub;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
public class MainActivity extends Activity {
private MusicFunction mf;
private Intent intent;
private MyConn myConn;
private EditText etName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 音乐名字
etName = (EditText) findViewById(R.id.etName);
// 准备意图
intent = new Intent();
//必须和服务端在清单文件中注册的服务动作同名
intent.setAction("com.music.kugou");
// 开启服务
startService(intent);
Log.e("服务信息:", "服务开启");
myConn = new MyConn();
// 绑定服务与活动
bindService(intent, myConn, 0);
}
/**
* 关闭服务
*/
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (myConn != null) {
// 解绑活动与服务
unbindService(myConn);
if (intent != null) {
// 停止服务
stopService(intent);
}
}
}
/**
* 服务与活动连接类
*
* @author Administrator
*
*/
class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
mf = Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
/**
* 播放音乐
*
* @param v
*/
public void play(View v) {
String name = etName.getText().toString();
try {
mf.Play(name);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}