我是android的新手,并获得了我需要知道电话中NFC标签以多快的时间使用计时器读取该标签的项目。已经有4天了,我仍然设法弄清楚。
所以这就是我的想法。标记>已检测到(定时器启动)>来自标记的信息显示>定时器停止。
有可能吗?我知道它将获得约0.1毫秒的时间。当检测到标签时,我已经可以使计时器启动,但是它不会停止。
这里是Java代码:
public class Read extends Activity {
NfcAdapter mAdapter;
Tag mTag;
PendingIntent mPI;
IntentFilter mFilter[];
String userData,yo;
boolean writeMode;
Context context;
TextView tvNFCContent, Timer,Low;
Button start, pause, reset, lap ;
long MillisecondTime, StartTime, TimeBuff, UpdateTime = 0L ;
Handler handler;
int Seconds, Minutes, MilliSeconds ;
ListView listView ;
String[] ListElements = new String[] { };
List<String> ListElementsArrayList ;
ArrayAdapter<String> adapter ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.read);
tvNFCContent = (TextView) findViewById(R.id.data);
Timer = (TextView)findViewById(R.id.timer);
handler = new Handler() ;
mAdapter = NfcAdapter.getDefaultAdapter(this);
mPI = PendingIntent.getActivity(getApplicationContext(), 0,
new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0 );
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
IntentFilter filter2 = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
mFilter = new IntentFilter[]{tagDetected,filter2};
mAdapter = NfcAdapter.getDefaultAdapter(this);
if (mAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
finish();
}
readFromIntent(getIntent());
}
/******************************************************************************
**********************************Read From NFC Tag***************************
******************************************************************************/
private void readFromIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))
{
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
}
buildTagViews(msgs);
}
}
private void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) return;
String text = "";
// String tagId = new String(msgs[0].getRecords()[0].getType());
byte[] payload = msgs[0].getRecords()[0].getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; // Get the Text Encoding
int languageCodeLength = payload[0] & 0063; // Get the Language Code, e.g. "en"
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
try {
text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
TimeBuff += MillisecondTime;
handler.removeCallbacks(runnable);
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEncoding", e.toString());
}
tvNFCContent.setText("NFC Content: " + text);
}
NdefMessage[] getNdefMessage(Intent intent)
{
NdefMessage[] msgs = null;
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if(rawMsgs != null)
{
msgs = new NdefMessage[rawMsgs.length];
for(int i=0; i<rawMsgs.length; i++)
{
msgs[i] = (NdefMessage)rawMsgs[i];
}
}
return msgs;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
setIntent(intent);
readFromIntent(intent);
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
mTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
StartTime = SystemClock.uptimeMillis();
handler.postDelayed(runnable, 0);
}
super.onNewIntent(intent);
if(intent.getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED))
{
Toast.makeText(getApplicationContext(),"Ndefdiscovered",Toast.LENGTH_SHORT).show();
}else if(intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED))
{
mTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Toast.makeText(getApplicationContext(),"Smartcard detected",Toast.LENGTH_SHORT).show();
NdefMessage[] messages = getNdefMessage(intent);
if(messages == null)
{
Toast.makeText(getApplicationContext(),"There Is No Data",Toast.LENGTH_SHORT).show();
return;
}
byte[] payload = messages[0].getRecords()[0].getPayload();
userData = new String(payload);
}else
{
Toast.makeText(getApplicationContext(),"Undefined smartcard",Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mAdapter.disableForegroundDispatch(this);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mAdapter.enableForegroundDispatch(this, mPI, mFilter, null);
}
public Runnable runnable = new Runnable() {
public void run() {
MillisecondTime = SystemClock.uptimeMillis() - StartTime;
UpdateTime = TimeBuff + MillisecondTime;
Seconds = (int) (UpdateTime / 1000);
Minutes = Seconds / 60;
Seconds = Seconds % 60;
MilliSeconds = (int) (UpdateTime % 1000);
Timer.setText("" + Minutes + ":"
+ String.format("%02d", Seconds) + ":"
+ String.format("%03d", MilliSeconds));
handler.postDelayed(this, 0);
}
};
}
这里是停止计时器的代码,但是我不知道在哪里准时停止计时器:
TimeBuff += MillisecondTime;
handler.removeCallbacks(runnable);
使用这种读取方法,您无需花费时间,您的应用程序实际花费多少时间来读取NFC标签,因为时间总是完全为零。
这是因为Android操作系统已在将结果传递到您的应用之前完全从标记中读取了数据。
如果您真的想花点时间阅读标签,有几种方法可以自己实际阅读标签。
更新:由于您没有告诉我您使用的卡的类型,因此无法编写代码来测量所需的时间。
某些背景:
[所有低级别的NFC卡操作都会进行1到N个transceive
操作,每个transceive
操作都会发送1到N个字节的字节数组,并返回0到N个字节的字节数组。] >
对于原始读取时间,您将花时间运行正确数量的transeive
命令以读取数据。
高级操作的时间还包括将N个字节数组解析为NdefMessage
以及transceive
命令所花费的时间
代码:
所以,我不知道该卡的类型是我能做的最好的事情,这是花一些时间连接到该卡并读取数据并将其解析为NdefMessage
这是可能导致RF活动并阻止代码进一步执行的任何操作的时间。
该代码忽略了以下事实,即Android操作系统已经读取了卡并已将您的卡数据传递给您,而您的应用在读取卡上花费的时间为零,它会重新读取卡以获取计时。请注意,如果您将卡快速拿走,可能会产生异常,并且无法及时读取卡。
我本可以编写代码来使用enableReaderMode
,这在写入卡时尤其可靠,并且具有许多其他好处。但是我改为使用ForegroundDispatch
,因为示例代码使用的是ForegroundDispatch
,所以我也照做。
PS,我不建议您使用ForegroundDispatch
package com.test.foregrounddispatch; import androidx.appcompat.app.AppCompatActivity; import android.app.PendingIntent; import android.content.Intent; import android.content.IntentFilter; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.Ndef; import android.os.Bundle; import android.util.Log; public class MainActivity extends AppCompatActivity { NfcAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAdapter = NfcAdapter.getDefaultAdapter(this); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); mAdapter.disableForegroundDispatch(this); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndefDetected.addDataType("*/*"); } catch (IntentFilter.MalformedMimeTypeException e) {} IntentFilter techDetected = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); IntentFilter[] nfcIntentFilter = new IntentFilter[]{ndefDetected,techDetected,tagDetected}; PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); if(mAdapter!= null) mAdapter.enableForegroundDispatch(this, pendingIntent, nfcIntentFilter, null); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { // While with ForegroundDispatch the NDEF message has already been read // And passed to us in the intent and thus the time the App spends "read" the NFC card is Zero // We want to time time the read, so now we have been notified that a NDEF card is in range // Try and read from it // Get the Tag from the intent Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); long startTime = 0; long endTime = 0; try { // Create an NDEF tag object Ndef ndefTag = Ndef.get(tag); // This is the I/O operation to read the card and format the result to an NDEF message // Nothing is done with the result to not add any time to it, as we are timing this startTime = System.currentTimeMillis(); ndefTag.connect(); ndefTag.getNdefMessage(); endTime = System.currentTimeMillis(); ndefTag.close(); } catch (Exception e) { Log.e("NFC", e.toString()); } Log.v("NFC", "Time to read in milliseconds is: " + (endTime - startTime)); } } }
对于手机上的简短“ Hello”纯文本NDEF记录,它会生成日志:-
V / NFC:读取时间以毫秒为单位:18