简体   繁体   English

将纯文本写入NFC标签,意图问题

[英]Writing plain text to an NFC tag, problems with intents

I'm trying to make an application that writes a simple plain text message to an NFC tag. 我正在尝试制作一个将简单的纯文本消息写入NFC标签的应用程序。 The user writes a message in the EditText box, then on button press, the app writes the text onto a tag. 用户在EditText框中写一条消息,然后按一下按钮,应用程序将文本写到标签上。 I've been following this tutorial: http://www.framentos.com/it/android-tutorial/2012/07/31/write-hello-world-into-a-nfc-tag-with-a/ However, when i try to put the NFC tag up next to it, the phone opens up another app, instead of using mine that is already open. 我一直在关注本教程: http : //www.framentos.com/it/android-tutorial/2012/07/31/write-hello-world-into-a-nfc-tag-with-a/当我尝试在其旁边放置NFC标签时,手机会打开另一个应用程序,而不是使用已经打开的地雷。 I know the problem's with the intents, but i don't want to declare the intent filter in the manifest, because i don't want the app to open up when the tag is placed next to the phone, i want the app to be already open beforehand. 我知道问题与意图有关,但是我不想在清单中声明意图过滤器,因为我不希望将标签放在手机旁边时打开应用程序,所以我希望应用程序是已经事先打开。 Here's the code for the application: 这是该应用程序的代码:

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class MainActivity extends AppCompatActivity {

    NfcAdapter adapter;
    PendingIntent pendingIntent;
    IntentFilter writeTagFilters[];
    Tag mytag;
    Context ctx;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ctx=this;
        Button btnWrite = (Button) findViewById(R.id.button);
        final EditText message = (EditText)findViewById(R.id.edit_message);
        btnWrite.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v) {
                try {
                    if(mytag==null){
                        Toast.makeText(ctx, ctx.getString(R.string.error_detected), Toast.LENGTH_LONG).show();
                    }else{
                        write(message.getText().toString(),mytag);
                        Toast.makeText(ctx, ctx.getString(R.string.ok_writing), Toast.LENGTH_LONG ).show();
                    }
                } catch (IOException e) {
                    Toast.makeText(ctx, ctx.getString(R.string.error_writing), Toast.LENGTH_LONG ).show();
                    e.printStackTrace();
                } catch (FormatException e) {
                    Toast.makeText(ctx, ctx.getString(R.string.error_writing) , Toast.LENGTH_LONG ).show();
                    e.printStackTrace();
                }
            }
        });

        adapter = NfcAdapter.getDefaultAdapter(this);
        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
        writeTagFilters = new IntentFilter[] { tagDetected };
    }

    private NdefRecord createRecord(String text) throws UnsupportedEncodingException {

        //create the message in according with the standard
        String lang = "en";
        byte[] textBytes = text.getBytes();
        byte[] langBytes = lang.getBytes("US-ASCII");
        int langLength = langBytes.length;
        int textLength = textBytes.length;

        byte[] payload = new byte[1 + langLength + textLength];
        payload[0] = (byte) langLength;

        // copy langbytes and textbytes into payload
        System.arraycopy(langBytes, 0, payload, 1, langLength);
        System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength);

        NdefRecord recordNFC = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
        return recordNFC;
    }

    private void write(String text, Tag tag) throws IOException, FormatException {

        NdefRecord[] records = { createRecord(text) };
        NdefMessage message = new NdefMessage(records);
        Ndef ndef = Ndef.get(tag);
        ndef.connect();
        ndef.writeNdefMessage(message);
        ndef.close();
    }

    @Override
    protected void onNewIntent(Intent intent){
        if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())){
            mytag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            Toast.makeText(this, this.getString(R.string.ok_detection) + mytag.toString(), Toast.LENGTH_LONG ).show();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {


   return true;
    }

    return super.onOptionsItemSelected(item);
}

} }

Please help, i don't know what i'm doing wrong! 请帮助,我不知道我在做什么错! I'm just a beginner at NFC and Android programming! 我只是NFC和Android编程的初学者!

You have to use enable forground dispatch : http://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch 您必须使用启用地面调度: http : //developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch

The foreground dispatch system allows an activity to intercept an intent and claim priority over other activities that handle the same intent. 前台分派系统允许活动拦截意图并声明优先于其他处理相同意图的活动。

UPDATE1 更新1

It's difficult to write on all kind of tags, some of them have closed specifications. 很难在所有类型的标签上书写,其中一些标签具有封闭的规范。 You could start by writing on Ndef and NdefFormatable tags. 您可以从编写NdefNdefFormatable标签开始。

For instance: 例如:

@Override 
protected void onPause() {
    super.onPause();
    mAdapter.disableForegroundDispatch(this);
}

@Override 
protected void onResume(){
  super.onResume();
  PendingIntent pendingIntent=PendingIntent.getActivity(this,0,new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);
  IntentFilter ndef=new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
  try {
    ndef.addDataType("*/*");
  }
 catch (  MalformedMimeTypeException e) {
    Log.e(TAG,"Bad MIME type declared",e);
    return;
  }
  IntentFilter[] filters=new IntentFilter[]{ndef};
  String[][] techLists=new String[][]{new String[]{Ndef.class.getName()},new String[]{NdefFormatable.class.getName()}};
  mNfcAdapter.enableForegroundDispatch(this,pendingIntent,filters,techLists);
}

@Override 
protected void onNewIntent(Intent intent) {
    Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    String[] techList = tag.getTechList();
    for (String tech : techList) {
          if (tech.equals(Ndef.class.getName())) {
              //write NDEF msg
          } else if (tech.equals(NdefFormatable.class.getName())) {
              //format and write NDEF msg
          }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM