Установите таймер, чтобы знать, как быстро NF C Читать тег - PullRequest
0 голосов
/ 19 января 2020

Я новичок в android и получаю проект, который мне нужен, чтобы узнать, как быстро тег NF C с телефона считывает тег с таймером. Прошло 4 дня, и я все еще пытаюсь понять это.

Так вот как это работает в моей голове. TAG> Обнаружено (запуск по таймеру)> Информация из тега Show Up> Timer Stop.

Возможно ли это? Я знаю, что это займет около 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);

1 Ответ

2 голосов
/ 19 января 2020

При таком методе чтения вам не нужно время, сколько ваше приложение тратит на чтение тегов NF C, поскольку время всегда будет точно равно нулю.

Это потому, что Android ОС полностью прочитала данные из тега, прежде чем результат будет передан в ваше приложение.

Существуют способы на самом деле прочитать тег самостоятельно, если вы действительно хотите время чтения тега.

Обновление: Поскольку вы не сказали мне тип используемой вами карты, невозможно написать код для измерения желаемого времени.

Некоторые сведения:

Все операции с картой NF C на низком уровне будут выполнять от 1 до N числа операций transceive, при этом каждая операция transceive отправляет байтовый массив от 1 до N байтов и возвращает байтовый массив. от 0 до N байт.

В качестве необработанного времени чтения вы должны указать время, необходимое для выполнения правильного числа команды transeive для чтения данных.

Время выполнения операций более высокого уровня будет также укажите время, необходимое для разбора число N байтовых массивов в NdefMessage, а также transceive команды

код:

Так как я не знаю карту введите лучшее, что я могу сделать, это получить время, необходимое для подключения к карте, чтения данных и анализа их на NdefMessage

Это время любой операции, которая может вызвать радиочастотную активность и блокировать дальнейшее выполнение кода.

Код игнорирует тот факт, что операционная система 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));
        }

    }
}

Для краткости " Привет "NDEF запись простого текста на моем телефоне, она производит журнал: -

V / NF C: Время чтения в миллисекундах: 18

...