设置计时器以了解NFC读取标签的速度

问题描述 投票:0回答:1

我是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);

android timer nfc
1个回答
2
投票

使用这种读取方法,您无需花费时间,您的应用程序实际花费多少时间来读取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

© www.soinside.com 2019 - 2024. All rights reserved.