0

I have a background service that is started on BOOT COMPLETE with a broadcast receiver.

what I wanted to do is to create another application that will bind to that service using AIDL interface.

the app simply asks the user to enter ip number and port , and when he clicks the button the service should receive these data. my problem is that when I enter the data and click "submit" the app crashes with a nullPointerException. and when I debug the app I see that the OnServiceConnected isn't being called at all.

I think I defined the AIDL files well, I can't figure out what's wrong here.

the AIDL file (aidl is within the same package name at the service and at the client) :

interface ISetIpPort{
    void getIpPort(String ip,int port);
}

My service (the relevant methods) :

@Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return (new IpPortBinder(getApplicationContext()));
    }

    private static class IpPortBinder extends ISetIpPort.Stub{
        Context context;
        public IpPortBinder(Context context) {
            this.context=context;
        }

        @Override
        public void getIpPort(String ip, int port) throws RemoteException {
            Toast.makeText(context, "Received ip " +ip+" And port "+port, Toast.LENGTH_LONG);

        }

    }

My application :

public class MainActivity extends Activity implements OnClickListener,ServiceConnection {
    private Button submitButton,cancelButton;
    private EditText ipText,portText;
    private ISetIpPort binding=null;
    String ip;
    String port;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        submitButton=(Button) findViewById(R.id.okButton);
        submitButton.setOnClickListener(this);
        cancelButton=(Button) findViewById(R.id.cancelButton);
        cancelButton.setOnClickListener(this);
        ipText=(EditText) findViewById(R.id.ip);
        portText=(EditText) findViewById(R.id.port);
    }

    @Override
    public void onClick(View v) {

        if(v==findViewById(R.id.okButton)){
            ip=ipText.getText().toString();
            port=portText.getText().toString();
            int portInteger=Integer.parseInt(port);
            try {
                binding.getIpPort(ip, portInteger);
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                Log.e(getClass().getSimpleName(),"Exception requesting to set ip and port",e);
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }

        if(v==findViewById(R.id.cancelButton)){
            finish();
            System.exit(0);
        }
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        Intent implicit=new Intent(ISetIpPort.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{
            Toast.makeText(getApplicationContext(), "service attached!", Toast.LENGTH_LONG).show();
            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 service) {
        binding=ISetIpPort.Stub.asInterface(service);
        submitButton.setEnabled(true);

    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        binding=null;
        submitButton.setEnabled(false);

    }

}

Don't worry about me not validating ip or port insertion. I just want to first test this IPC .

1 Answers1

0

OK my problem is here :

bindService(explicit, this, Context.BIND_WAIVE_PRIORITY);

should be

bindService(explicit, this, Context.BIND_AUTO_CREATE);