我正在尝试创建一个将简单纯文本消息写入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编程的初学者!
答案 0 :(得分:0)
您必须使用enable forground dispatch:http://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc.html#foreground-dispatch
前台调度系统允许活动拦截 意图并声称优先于处理相同的其他活动 意图。
<强> UPDATE1 强>
很难写出所有类型的标签,其中一些标签已经封闭。您可以先撰写Ndef和NdefFormatable代码。
例如:
@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
}
}
}