我正在使用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
}
});