package com.jay.msgapp2; import android.app.Service; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; public class BService extends Service { //记录下客户端发过来的 Messenger Messenger clientMessenger; //接受客户端发过来的消息 Messenger messenger = new Messenger(new Handler(Looper.myLooper()) { @Override public void handleMessage(Message msg) { //客户端发送来的数据 msg 中还有齐他参数,客户端发送过来都可以拿到 String clientData = msg.getData().getString("data"); //客户端的 Messenger 对象 clientMessenger = msg.replyTo; //发送数据返回给客户端 sendMsgToClient(); super.handleMessage(msg); } }); //服务端绑定器 @Override public IBinder onBind(Intent intent) { //绑定成功 return messenger.getBinder(); } //发送数据返回给客户端 private void sendMsgToClient(){ Message message = Message.obtain(); Bundle bundle = new Bundle(); bundle.putString("data","成功返回给客户端数据..."); message.setData(bundle); try { clientMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } }
服务端AndroidManifest.xml在application节点下,把上面的服务配置一下:<service android:name=".BService" android:enabled="true" android:exported="true"></service>
服务端的MainActivity中启动服务
package com.jay.msgapp2; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent1 = new Intent(this, BService.class); startService(intent1); } }
客户端
package com.jay.myapplication; import androidx.appcompat.app.AppCompatActivity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { public TextView mtxtMsg; public Messenger sendMessenger; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mtxtMsg = findViewById(R.id.txtMsg); //一个按钮来发消息 Button btnPlay = (Button) findViewById(R.id.btn1); try { connectService();//建立连接,构建 sendMessenger } catch (Exception ex) { mtxtMsg.setText("连接异常:" + ex.getMessage()); } btnPlay.setOnClickListener(view -> { try { Message message = Message.obtain(null, 1); //把自己的Messenger带进去 服务端拿到之后 可以直接通过这个对象发数据过来 //就是服务端的 clientMessenger message.replyTo = replyMessenger; Bundle bundle = new Bundle(); bundle.putString("data", "服务器你好");//key和服务端的一致 message.setData(bundle); //发送消息的方法 sendMessenger.send(message); } catch (RemoteException ex) { mtxtMsg.setText("远程异常:" + ex.getMessage()); } catch (Exception exception) { mtxtMsg.setText("发送异常:" + exception.getMessage()); } }); } /** * 和服务器建立连接 连接成功之后 sendMessenger 就是发消息的对象。 **/ private void connectService() throws Exception { ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { sendMessenger = new Messenger(service);//连接成功 } @Override public void onServiceDisconnected(ComponentName name) { // Log.e("kk", "链接断开!"); } }; Intent intent = new Intent(); //需要在AndroidManifest.xml中配置包名的可见性com.jay.msgapp2 intent.setComponent(new ComponentName("com.jay.msgapp2", "com.jay.msgapp2.BService")); boolean res = getApplicationContext().bindService(intent, serviceConnection, BIND_AUTO_CREATE); if (!res) { throw new Exception("连接失败"); } } //客户端的Messenger Messenger replyMessenger = new Messenger(new Handler(Looper.myLooper()) { @Override public void handleMessage(Message msg) { String data = msg.getData().getString("data");//服务端返回的数据 mtxtMsg.setText("返回:" + data); super.handleMessage(msg); } }); }
客户端连接服务端的时候调用bindService方法,要加上 getApplicationContext().bindService(intent, serviceConnection, BIND_AUTO_CREATE);
build.gradle中要配置 compileSdk 31 minSdk 31 targetSdk 31,至少30,因为我的手机是Android12,所以我配置的是31。AndroidManifest.xml中配置<application tools:targetApi="31"...
客户端的AndroidManifest.xml中配置包可见性,或者配置权限可发现所有包<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<queries> <package android:name="com.jay.msgapp2" /> </queries>
总的来说和网上大部分文章差不多,只是很多文章没有写 服务端的版本配置,启动服务。客户端的软件包可见性配置,连接服务使用getApplicationContext().bindService()
另外,gradle插件的版本也不能太低,具体是多少我也没试,看别人说不能太低,我的 Android Gradle Plugin Version 7.3.0 / Gradle Version 7.4。
参考文章:
https://blog.csdn.net/qq379454816/article/details/52573476
https://www.jb51.net/article/76470.htm
https://www.jb51.net/article/76474.htm
https://www.jianshu.com/p/b2c86d4aa366
软件包可见性 https://blog.csdn.net/yang_study_first/article/details/119787421