使用Android Studio在标签上写入NFC数据 [英] Write NFC data on an tag with Android Studio

查看:1097
本文介绍了使用Android Studio在标签上写入NFC数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个应用程序,其中我必须编写从文件到NFC卡的一系列值,而我一直在阅读,而且我不知道从哪里真正开始,我有一个很少有疑问.

I'm creating an application in which I have to write a series of values that come to me from a file to an NFC card and I've been reading and I don't know where to really start, I have a few doubts.

首先,我了解理想的情况是创建一个处理NFC的类,尽管我认为这是可选的,并且可以在同一类中完成.问题是我看到的教程仅使用活动,并使用了onNewIntent方法.

First of all I understand that the ideal is to create a class that handles the NFC, although I suppose this is optional and can be done in the same class. The problem is that the tutorials I see are only using activities and make use of the onNewIntent method.

处于一个片段中,我无法调用此方法,因此这是丢失的第一步,并且我不知道此方法是否必要,因为据我了解,即使关闭该方法也要启动该应用程序如果是读者,请纠正我,如果我错了.如果您能对我的工作做些指导,我会很感激,因为经过大量的阅读,我有点发疯了.

Being in a fragment I can not call this method so it is the first step in which I lose, and I do not know if this method is necessary because as I understand this is to launch the application even if it is closed as if it were a reader, correct me if I'm wrong. I appreciate if you can guide me a little in what I should do because after so much reading I've gone a little crazy.

推荐答案

我首先要考虑的是如何存储数据.

The first place I would start is thinking about how to store the data.

数据是针对您的应用程序定制的,还是要与其他应用程序共享?

Is the data custom to your application or do you want to share it with other App's?

App是将数据写入一次还是对其进行更新(想要将数据追加到存储在卡上的现有数据中?

Will the App be just writing the data once or will it be updating it (wanting to Append Data to existing data stored on the card?

更新:从您对数据类型的评论中,您最好使用更高级别的NDEF格式来使用自定义mime类型存储数据.假设您选择的卡类型支持此功能. 请注意,我给出的示例是使用低级命令逐页读取/写入的示例.

Update: from your comments about the data type you are probably better using the higher level NDEF format to store your Data using a custom mime type. This is assuming your chosen card type supports this. Note the example I gave is reading/writing using low level commands read and writing page by page.

您要存储多少字节数据(影响卡技术)

How many bytes of data do you want to store (Influences the card technology)

您可能还想考虑要使用哪种NFC卡技术,这可能是NTAG 21x系列卡之一的不错选择.

You probably want to also think about what NFC card technology you want to use, probably a good choice of one of the NTAG 21x series of cards.

您要定位的最低Android版本是什么?

What is the minimum version of Android you want to target?

我不会使用newIntent方法,因为这对于写入数据非常不可靠,如果您要定位的Android版本足够高,我会使用enableReaderMode.

I would not use the newIntent method as this is very unreliable for writing data, I would use the enableReaderMode if you are targeting a high enough version of Android.

您需要考虑的一些答案将影响示例的某些细节.

Some of the answers to what you need to think about will affect some of the details of the example.

更新:基于评论:即使您使用的是片段,我仍然会将NFC处理的机制放在活动"中.

Update: based on comments Even though you are using Fragments I would still put the mechanics of NFC handling in the Activity.

这样做的原因是因为OS仍在处理标签发现,如果您不声明"每个Fragment中的NFC硬件,则OS可能会在屏幕上方显示屏幕,尤其是NDEF数据格式.如果用户在错误的时间出示卡片,则会给用户带来糟糕的用户体验.

The reason for this is because the OS is still handling tag discovery, if you don't "claim" the NFC hardware in every Fragment then it is possible especially with the NDEF data format, for the OS to display a screen over your App if the user present a card at the wrong time, giving a bad user experience.

在我的多活动应用程序中,即使其中许多活动不是发现标签上的东西,也不执行任何操作",因为它们不是NFC活动,我还是在每个活动中声明"了NFC硬件.

In my multi Activity App I "claim" the NFC hardware in every Activity even if a lot of them do "On Tag discovered, do nothing" because they are not the NFC Activity.

因此,除非您想在每个Fragment中编写相同的代码,否则最好从您的一个Activity中调用NFC内容,然后在onTagDiscovered中执行类似(伪代码)的操作:-

So unless you want to write the same code in every Fragment, it would be much better to call the NFC stuff from your one Activity and then in onTagDiscovered does something like (pseudo code):-

已更新:

if displaying the NFC user prompt Fragment.
get data to file.
write data to the card.
Notify user that it is done.
else
do nothing when other fragments are displayed.

或者您可以在打开应用程序的任何时间进行写卡(同样,最好在活动中不要出现任何碎片)

or you could have card writing at any time the App is open (again best done in activity not in any fragment)

If card is presented no matter what fragment is being display
get data from the file
write data to the card
Notify user that it is done.

抱歉,我无法在Kotlin中进行示例,但这是从我的应用程序中提取的Java示例的准系统(未经测试,因此可能存在复制和粘贴错误)

Sorry I cannot do an example in Kotlin but here is a barebone of a Java Example, extracted from my App (not tested, so there could be copy and pasted errors)


public class MainActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback{

private NfcAdapter mNfcAdapter;

@Override
    protected void onCreate(Bundle savedInstanceState) {
    // All normal onCreate Stuff

    // Listen to NFC setting changes
    this.registerReceiver(mReceiver, filter);
    }

    // Listen for NFC being turned on while in the App
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();

            if (action.equals(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED)) {
                final int state = intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE,
                        NfcAdapter.STATE_OFF);
                switch (state) {
                    case NfcAdapter.STATE_OFF:
                    // Tell the user to turn NFC on if App requires it
                        break;
                    case NfcAdapter.STATE_TURNING_OFF:
                        break;
                    case NfcAdapter.STATE_ON:
                        enableNfc();
                        break;
                    case NfcAdapter.STATE_TURNING_ON:
                        break;
                }
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();

        enableNfc();

    }

    @Override
    protected void onPause() {
        super.onPause();
        if(mNfcAdapter!= null)
            mNfcAdapter.disableReaderMode(this);
    }




    private void enableNfc(){
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);

        if(mNfcAdapter!= null && mNfcAdapter.isEnabled()) {

            // Work around some buggy hardware that checks for cards too fast
            Bundle options = new Bundle();
            options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 1000);


            // Listen for all types of card when this App is in the foreground
            // Turn platform sounds off as they misdirect users when writing to the card
            // Turn of the platform decoding any NDEF data
            mNfcAdapter.enableReaderMode(this,
                    this,
                    NfcAdapter.FLAG_READER_NFC_A |
                            NfcAdapter.FLAG_READER_NFC_B |
                            NfcAdapter.FLAG_READER_NFC_F |
                            NfcAdapter.FLAG_READER_NFC_V |
                            NfcAdapter.FLAG_READER_NFC_BARCODE |
                            NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK |
                            NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,
                    options);
        } else {
            // Tell the user to turn NFC on if App requires it
        }
    }

    public void onTagDiscovered(Tag tag) {

        // This is run in a separate Thread to UI

        StringBuilder Uid = new StringBuilder();

        boolean successUid = getUID(tag, Uid);
        if (!successUid){
            // Not a successful read
            return;
        } else {
            // Feedback to user about successful read

            Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
            v.vibrate(500);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Update the UI / notify user  
                }
            });
            // Finish Task
            try {
                Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
                r.play();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public boolean getUID(Tag tag, StringBuilder Uid){
        NfcA mNfcA = NfcA.get(tag);

        if (mNfcA != null) {
            // The tag is NfcA capable
            try {
                mNfcA.connect();
                // Do a Read operation at page 0 an 1
                byte[] result = mNfcA.transceive(new byte[] {
                        (byte)0x3A,  // FAST_READ
                        (byte)(0 & 0x0ff),
                        (byte)(1 & 0x0ff),
                });

                if (result == null) {
                    // either communication to the tag was lost or a NACK was received
                    // Log and return
                    return false;
                } else if ((result.length == 1) && ((result[0] & 0x00A) != 0x00A)) {
                    // NACK response according to Digital Protocol/T2TOP
                    // Log and return
                    return false;
                } else {
                    // success: response contains ACK or actual data
                    for (int i = 0; i < result.length; i++) {
                        // byte 4 is a check byte
                        if (i == 3) continue;
                        Uid.append(String.format("%02X ", result[i]));
                    }

                    // Close and return
                    try {
                        mNfcA.close();
                    } catch (IOException e) {
                    }
                    return true;
                }

            } catch (TagLostException e) {
                // Log and return
                return false;
            } catch (IOException e){
                // Log and return
                return false;
            } finally {
                try {
                    mNfcA.close();
                } catch (IOException e) {
                }
            }
        } else {
            // Log error
            return false;
        }
    }

}

这篇关于使用Android Studio在标签上写入NFC数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆