How can I send message from HostApduService to an

2019-02-25 06:29发布

问题:

I would like to pass a string to an Activity easily. Something like callback would be needed because when the string has to be passed then the Activity has to do something.

public class MyHostApduService extends HostApduService {
    @Override
    public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
        if (selectAidApdu(apdu)) {
            Log.i("HCEDEMO", "Application selected");
            return getWelcomeMessage();
        }
        else {
            if (exchangeDataApdu(apdu)) {
                Log.i("HCEDEMO", "Data exchanged");

                // int _len_ = apdu[4];
                String _data_ = new String(apdu).substring(5, apdu.length - 1);
                // TODO: Send _data_ to an activity...

                return new byte[] { (byte)0x90, (byte)0x00 };
            }
            else {
                Log.i("HCEDEMO", "Received: " + new String(apdu));
                return getNextMessage();
            }
        }
    }
}

回答1:

Your question is very broad and an answer depends on some design aspects of your application that you did not reveal to us:

You want to start the activity and pass some data to it

You can start the activity with an intent and pass the parameter as intent extra (also see this answer):

Intent intent = new Intent(this, YourActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("hcedata", _data_)
this.startActivity(intent);

You want to pass the data to a running instance of your activity

In that case, you could, for instance, register a BroadcastReceiver from your activity:

public class YourActivity extends Activity {
    final BroadcastReceiver hceNotificationsReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if () {
                String hcedata = intent.getStringExtra("hcedata");
                // TODO: do something with the received data
            }
        }
    });

    @Override
    protected void onStart() {
        super.onStart();

        final IntentFilter hceNotificationsFilter = new IntentFilter();
       hceNotificationsFilter.addAction("your.hce.app.action.NOTIFY_HCE_DATA");
        registerReceiver(hceNotificationsReceiver, hceNotificationsFilter);
    }

    @Override
    protected void onStop() {
        super.onStop();
        unregisterReceiver(hceNotificationsReceiver);
    }

In your service, you could then send an intent to that broadcast receiver (note that you might want to restrict the broadcast with a receiver permission in order to prevent your data from leaking to unauthorized receivers):

Intent intent = new Intent("your.hce.app.action.NOTIFY_HCE_DATA");
intent.putExtra("hcedata", _data_)
this.sendBroadcast(intent);

You want to pass data to an activity and receive a response back into your service

Similar as above, you could use the broadcast receiver in your service to get notified from your activity. Note that you cannot bind to your HCE service, so you cannot directly invoke methods on it from your activity.



回答2:

You have to use Intent mechanism.

If activity have to be started, in your service add:

Intent intent = new Intent(context, MyActivity.class);
intent.putExtra("extra_key", "values you want to pass");
startActivity(intent);

and in activity:

String value = getIntent().getStringExtra("extra_key");