我正在使用NFC,目前正在尝试为Android 9.0中内置的Open Mobile API编写代码,但不了解在SEService中传递Executor参数的方式。

public class MainActivity extends Activity implements SEService.OnConnectedListener {

    final String LOG_TAG = "NfcTest";

    private SEService seService;

    private Button button;


    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        LinearLayout layout = new LinearLayout(this);
        layout.setLayoutParams(new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT));

        button = new Button(this);
        button.setLayoutParams(new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT));

        button.setText("Click Me");
        button.setEnabled(false);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                try {

                    Reader[] readers = seService.getReaders();
                    if (readers.length < 1)
                        return;


                    Session session = readers[0].openSession();



                    Channel channel = session.openLogicalChannel(new byte[]{
                            (byte) 0xF0, 0x51, (byte) 0xBC, 0x53, 0x54, 0x69, 0x64,
                            (byte) 0x4D, 0x6F, 0x62, 0x69, (byte) 0x6C,
                            (byte) 0x65, 0x2D, (byte) 0x49, 0x44});


                    byte[] respApdu = channel.transmit(new byte[]{
                            (byte) 0x90, 0x10, 0x00, 0x00, 0x00});

                    channel.close();

                    // Parse response APDU and show text but remove SW1 SW2 first
                    byte[] helloStr = new byte[respApdu.length - 2];
                    System.arraycopy(respApdu, 0, helloStr, 0, respApdu.length - 2);
                    Toast.makeText(MainActivity.this, new String(helloStr), Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    Log.i(LOG_TAG, "Message: " + e.getClass().getCanonicalName());
                    if(e.getClass().isInstance(new NoSuchElementException()))
                        Toast.makeText(MainActivity.this, "NFC sim", Toast.LENGTH_LONG).show();
                    else if (e.getClass().isInstance(new IOException())){
                        Toast.makeText(MainActivity.this, "No sim found", Toast.LENGTH_LONG).show();
                    }
                    else{
                        Toast.makeText(MainActivity.this, "Normal sim", Toast.LENGTH_LONG).show();
                    }
                }
            }
        });

        layout.addView(button);
        setContentView(layout);


        try {

            seService = new SEService(this, this,this);
        } catch (SecurityException e) {
            Log.e(LOG_TAG, "Binding not allowed, uses-permission org.simalliance.openmobileapi.SMARTCARD?");
        } catch (Exception e) {
            Log.e(LOG_TAG, "Exception: " + e.getMessage());
        }
    }

    @Override
    protected void onDestroy() {
        if (seService != null && seService.isConnected()) {
            seService.shutdown();
        }
        super.onDestroy();
    }

    public void serviceConnected(SEService service) {
        Log.i(LOG_TAG, "seviceConnected()");
        button.setEnabled(true);
    }

    @Override
    public void onConnected() {

    }
}


问题发生在:

seService = new SEService(this, this,this);


接受的第一个和最后一个参数中间一个执行程序出现错误!


  java.util.concurrent.Executor这个


如何通过?

最佳答案

您会收到此错误,因为构造函数SEService的第二个参数必须是java.util.concurrent.Executor。您的MainActivity(this对象)没有实现执行程序。

SEService使用此执行程序来调用回调方法。因此,您必须自己创建一个这样的执行器,才能将其传递给SEService。例如,您可以只用一个工作线程创建一个ExecutorService来处理回调:

ExecutorService pool = Executors.newSingleThreadExecutor();
seService = new SEService(this, pool, this);


但是请注意,这些回调将在工作线程(而不是应用程序的主线程)上执行。因此,如果您想在回调中执行任何UI操作,则需要在UI线程上显式运行它们,例如

runOnUiThread(new Runnable() {
    void run() {
        button.setEnabled(true); // ... or some other UI modifications
    }
});

10-08 09:33