【问题标题】:sending a message from a service to different app using aidl使用aidl将消息从服​​务发送到不同的应用程序
【发布时间】:2015-04-12 22:09:25
【问题描述】:

我有两个应用,应用 A 和应用 B。

A 只是一个服务,它在 BOOT COMPLETE 启动,如果被破坏则重新启动。

A 不断接收消息(通过串行连接,但这无关紧要)。

如果收到消息但没有其他应用绑定到该服务,我不关心该消息,它可能会丢失。

但是,如果收到一些消息并且假设 B 绑定到它,我希望 B 接收该消息。

所以,我尝试使用 AIDL 将消息从 A 传递到 B,但我无法让它工作。我可能没有在此处做某事或未正确使用它,因此我将不胜感激。

我的服务代码:

public class ExtProtocolService extends Service {
static RS232Comm serialComm;
public static final int BAUDRATE = 19200;
public static final int COM = 1;
public static Handler handler;
private Message message;

@Override
public IBinder onBind(Intent intent) {
    return (new MessageBinder());
}

private static class MessageBinder extends IExtMessage.Stub {

    @Override
    public void receive(IExtMessageCallBack callback) {
        new ReceiveThread(callback).
    }
}

@Override
public void onCreate() {
    serialComm = new RS232Comm(COM, BAUDRATE, 0, this);

    handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            message=msg;
        }
    };


}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(getApplicationContext(), "Protocol Service Started",
            Toast.LENGTH_SHORT).show();

    return START_STICKY;
}

public static class ReceiveThread implements Runnable {
    int numCharsToRead = 2;
    IExtMessageCallBack cb = null;
    boolean ok;

    ReceiveThread(IExtMessageCallBack cb) {
        this.cb = cb;
    }

    @Override
    public void run() {
        try {
            serialComm.Open();
            ok = serialComm.Receive(numCharsToRead);
            if (ok) {
                cb.onSuccess();
            }

        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

}

RS232Comm serialComm 是我在其中接收消息的类,那里的主要代码:

                    Message message=Message.obtain();
                Bundle bundle=new Bundle();
                bundle.putInt("command", command);
                bundle.putInt("messageLength", messageLength);
                bundle.putString("wholeData", wholeData);
                message.setData(bundle);
                Toast.makeText(context.getApplicationContext(), "Valid", Toast.LENGTH_LONG).show();
                ExtProtocolService.handler.sendMessage(message);
                return true;

如您所见,我正在使用处理程序将消息传递回服务类。

我的 AIDL 文件是:

interface IExtMessage{
void receive(IExtMessageCallBack callback);
  }

和:

interface IExtMessageCallBack{

void onSuccess();
void onFailure(String msg);

}

现在,应用 B ,它只是测试我的消息是否通过的主要活动:

package com.tfl.testmyservice;



public class MainActivity extends Activity implements ServiceConnection {
    public static final String TAG = "YANIV";
    private IExtMessage binding;
    private Application appContext = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent implicit = new Intent(IExtMessage.class.getName());
        List<ResolveInfo> matches = getPackageManager().queryIntentServices(
                implicit, 0);

        if (matches.size() == 0) {
            Toast.makeText(getApplicationContext(),
                    "Cannot find a matching service!", Toast.LENGTH_LONG)
                    .show();
        } else if (matches.size() > 1) {
            Toast.makeText(getApplicationContext(),
                    "Found multiple matching services!", Toast.LENGTH_LONG)
                    .show();
        } else {
            Intent explicit = new Intent(implicit);
            ServiceInfo svcInfo = matches.get(0).serviceInfo;
            ComponentName cn = new ComponentName(
                    svcInfo.applicationInfo.packageName, svcInfo.name);
            explicit.setComponent(cn);
            bindService(explicit, this, Context.BIND_WAIVE_PRIORITY);
        }

    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder binder) {
        binding = IExtMessage.Stub.asInterface(binder);

    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        binding = null;

    }

    public void onEventMainTread(CallbackEvent event){
        if(event.succeeded){
            Toast.makeText(this, "Success", Toast.LENGTH_LONG).show();
        }
        else{
            Toast.makeText(this, event.msg, Toast.LENGTH_LONG).show();
        }
    }

    IExtMessageCallBack.Stub cb=new IExtMessageCallBack.Stub() {

        @Override
        public void onSuccess() throws RemoteException {
            new CallbackEvent(true, null);

        }

        @Override
        public void onFailure(String msg) throws RemoteException {
            new CallbackEvent(false, msg);

        }
    };


    static class CallbackEvent{
        boolean succeeded=false;
        String msg=null;

        public CallbackEvent(boolean succeeded,String msg) {
            this.succeeded=succeeded;
            this.msg=msg;
        }

    }


}

应用 B 中也有相同的 AIDL。

我得到的输出是“找不到匹配的服务!”

只想指出该服务本身运行良好。就在我尝试使用 AIDL 的 IPC 时,事情变得有点混乱。

【问题讨论】:

    标签: android ipc aidl


    【解决方案1】:

    您在 MainActivity 中对服务的操作字符串似乎不正常。

    您正在使用IExtMessage 的类名作为服务操作字符串。

    Intent implicit = new Intent(IExtMessage.class.getName());
    List<ResolveInfo> matches = getPackageManager().queryIntentServices(implicit, 0);
    

    但通常与服务本身相关的字符串用于操作字符串,与IPC类无关。

    您最好仔细检查应用 A 的 android 清单文件中服务 ExtProtocolService 的意图过滤器中的操作字符串。您应该使用与查询意图相同的字符串。

    并检查服务是否在清单文件中“导出”。

    【讨论】:

      猜你喜欢
      • 2019-01-16
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 2016-05-14
      • 1970-01-01
      • 2018-12-20
      • 1970-01-01
      相关资源
      最近更新 更多