Project catalog:
app-MainActivity
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private String otherPackage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button:
otherPackage="com.example.app1";
break;
case R.id.button2:
otherPackage="com.example.app2";
break;
case R.id.button3:
otherPackage="com.example.app3";
break;
}
Intent intent=getPackageManager().getLaunchIntentForPackage(otherPackage);
if(intent==null){
Toast.makeText(this, "not this app", Toast.LENGTH_SHORT).show();
}else{
startActivity(intent);
}
}
}
app1-MainActivity
package com.example.app1;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent;
switch (v.getId()){
case R.id.button:
Toast.makeText(this, "play music", Toast.LENGTH_SHORT).show();
intent=new Intent(MainActivity.this,MyService.class);
startService(intent);
findViewById(R.id.button).setEnabled(false);
findViewById(R.id.button2).setEnabled(true);
break;
case R.id.button2:
Toast.makeText(this, "stop music", Toast.LENGTH_SHORT).show();
intent=new Intent(MainActivity.this,MyService.class);
stopService(intent);
findViewById(R.id.button).setEnabled(true);
findViewById(R.id.button2).setEnabled(false);
break;
}
}
}
MyService
package com.example.app1;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
public class MyService extends Service {
MediaPlayer mp;
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
mp=MediaPlayer.create(getApplicationContext(),R.raw.cc);
mp.start();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
super.onDestroy();
mp.stop();
}
}
app2-MainActivity
package com.example.app2;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent;
switch (v.getId()){
case R.id.button:
Toast.makeText(this, "play music", Toast.LENGTH_SHORT).show();
/*intent=new Intent(MainActivity.this,MyService.class);*/
intent=new Intent("com.zlm.MAS");
intent.setPackage("com.example.app2");
startService(intent);
findViewById(R.id.button).setEnabled(false);
findViewById(R.id.button2).setEnabled(true);
break;
case R.id.button2:
Toast.makeText(this, "stop music", Toast.LENGTH_SHORT).show();
/*intent=new Intent(MainActivity.this,MyService.class);*/
intent=new Intent("com.zlm.MAS");
intent.setPackage("com.example.app2");
stopService(intent);
findViewById(R.id.button).setEnabled(true);
findViewById(R.id.button2).setEnabled(false);
break;
}
}
}
MyService
package com.example.app2;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
public class MyService extends Service {
MediaPlayer mp;
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
mp=MediaPlayer.create(getApplicationContext(),R.raw.cc);
mp.start();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
super.onDestroy();
mp.stop();
}
}
Manifestos
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="com.zlm.MAS"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
</application>
</manifest>
app3-MainActivity
package com.example.app3;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyService.PlayBinder playBinder= (MyService.PlayBinder) service;
playBinder.MyMethod();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
Intent intent=new Intent("com.zlm.MPS");
intent.setPackage("com.example.app3");
bindService(intent,conn,BIND_AUTO_CREATE);
}
}
MyService
package com.example.app3;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
public class MyService extends Service {
private MediaPlayer mp;
public class PlayBinder extends Binder {
public void MyMethod(){
mp=MediaPlayer.create(getApplicationContext(),R.raw.cc);
mp.start();
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
//throw new UnsupportedOperationException("Not yet implemented");
return new PlayBinder();
}
@Override
public void onDestroy(){
if(mp!=null){
mp.stop();
mp.release();
}
super.onDestroy();
}
}
Manifestos
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app3">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.zlm.MPS"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
app4_1-Manifestos
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app4_1">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name=".MusicPlayService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.zlm.MusicService"/>
</intent-filter>
</service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MusicPlayService
package com.example.app4_1;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
public class MusicPlayService extends Service {
private MediaPlayer mPlayer;
IBinder iBinder = new IRemoteService.Stub() {
@Override
public void play() throws RemoteException {
if(!mPlayer.isPlaying()){
mPlayer.start();
}
}
@Override
public void stop() throws RemoteException {
if(mPlayer.isPlaying()){
mPlayer.stop();
try{
mPlayer.prepare();
}catch (IOException e){
e.printStackTrace();
}
mPlayer.seekTo(0);
}
}
};
@Override
public void onCreate() {
super.onCreate();
if(mPlayer==null){
mPlayer = MediaPlayer.create(this, R.raw.cc);
mPlayer.setLooping(true);
}
}
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(this, "服务已绑定!", Toast.LENGTH_SHORT).show();
return iBinder;
}
@Override
public boolean onUnbind(Intent intent) {
if (mPlayer!=null){
mPlayer.stop();
mPlayer.release();
}
return super.onUnbind(intent);
}
}
IRemoteService.aidl
// IRemoteService.aidl
package com.example.app4_1;
// Declare any non-default types here with import statements
interface IRemoteService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
/*void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);*/
void play();
void stop();
}
app4_2-Manifestos
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app4_2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity
package com.example.app4_2;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.widget.Button;
import com.example.app4_1.IRemoteService;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Button btn1;
Button btn2;
//服务端项目包名,需要查看服务端项目清单文件
public static final String PACKAGE="com.example.app4_1";
//服务端项目里定义的意图动作名,需要查看服务端项目清单文件
public static final String ACTION = "com.zlm.MusicService";
private boolean isBinded=false;
private IRemoteService mServer;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//建立服务连接时的远程服务代理对象
mServer = IRemoteService.Stub.asInterface(service);
isBinded=true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBinded=false;
mServer=null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1=findViewById(R.id.btn1);btn1.setOnClickListener(this);
btn2=findViewById(R.id.btn2);btn2.setOnClickListener(this);
Intent intent = new Intent(ACTION);
intent.setPackage(PACKAGE); //隐式调用需要指定服务端项目的包名
bindService(intent,conn,BIND_AUTO_CREATE);
}
@Override
public void onClick(View v) { //监听器接口方法
int id = v.getId();
switch (id){
case R.id.btn1:
try {
mServer.play(); //调用服务接口方法
btn1.setEnabled(false);btn2.setEnabled(true);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn2:
try {
mServer.stop(); //调用服务接口方法
btn2.setEnabled(false);btn1.setEnabled(true);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
protected void onDestroy() {
if(isBinded){
unbindService(conn); //取消绑定
mServer = null;
isBinded=false;
}
super.onDestroy();
}
}
IRemoteService.aidl
// IRemoteService.aidl
package com.example.app4_1;
// Declare any non-default types here with import statements
interface IRemoteService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
/*void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);*/
void play();
void stop();
}