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

时间:2015-08-13 13:46:02

标签: java android android-intent nfc

我正在尝试创建一个将简单纯文本消息写入NFC标记的应用程序。用户在EditText框中写入消息,然后在按下按钮时,应用程序将文本写入标签。 我一直在关注本教程:http://www.framentos.com/it/android-tutorial/2012/07/31/write-hello-world-into-a-nfc-tag-with-a/ 但是,当我尝试将NFC标签放在它旁边时,手机会打开另一个应用程序,而不是使用已经打开的应用程序。我知道问题与意图有关,但我不想在清单中声明意图过滤器,因为我不希望应用程序在标签放在手机旁边时打开,我希望应用程序是已事先打开。 这是应用程序的代码:

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);
}

}

请帮助,我不知道我做错了什么! 我只是NFC和Android编程的初学者!

1 个答案:

答案 0 :(得分:0)

您必须使用enable forground dispatch:http://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch

  

前台调度系统允许活动拦截   意图并声称优先于处理相同的其他活动   意图。

<强> UPDATE1

很难写出所有类型的标签,其中一些标签已经封闭。您可以先撰写NdefNdefFormatable代码。

例如:

@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
          }
    }
}