我的主要活动中有此代码。在此活动中,我将数据写入NFC标签。这项工作非常完美:
public class MainActivity extends Activity implements OnClickListener {
private NfcAdapter mAdapter;
private boolean mInWriteMode;
private Button mWriteTagButton;
private TextView mTextView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// grab our NFC Adapter
mAdapter = NfcAdapter.getDefaultAdapter(this);
// button that starts the tag-write procedure
mWriteTagButton = (Button)findViewById(R.id.write_tag_button);
mWriteTagButton.setOnClickListener(this);
// TextView that we'll use to output messages to screen
mTextView = (TextView)findViewById(R.id.text_view);
}
public void onClick(View v) {
if(v.getId() == R.id.write_tag_button) {
displayMessage("Touch and hold tag against phone to write.");
enableWriteMode();
}
}
@Override
protected void onPause() {
super.onPause();
disableWriteMode();
}
/**
* Called when our blank tag is scanned executing the PendingIntent
*/
@Override
public void onNewIntent(Intent intent) {
if(mInWriteMode) {
mInWriteMode = false;
// write to newly scanned tag
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
writeTag(tag);
}
}
/**
* Force this Activity to get NFC events first
*/
private void enableWriteMode() {
mInWriteMode = true;
// set up a PendingIntent to open the app when a tag is scanned
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
IntentFilter[] filters = new IntentFilter[] { tagDetected };
mAdapter.enableForegroundDispatch(this, pendingIntent, filters, null);
}
private void disableWriteMode() {
mAdapter.disableForegroundDispatch(this);
}
/**
* Format a tag and write our NDEF message
*/
private boolean writeTag(Tag tag) {
// record to launch Play Store if app is not installed
NdefRecord appRecord = NdefRecord.createApplicationRecord(getPackageName());
// record that contains our custom "retro console" game data, using custom MIME_TYPE
byte[] payload = getRandomConsole().getBytes();
byte[] mimeBytes = MimeType.NFC_DEMO.getBytes(Charset.forName("US-ASCII"));
NdefRecord cardRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, mimeBytes,
new byte[0], payload);
NdefMessage message = new NdefMessage(new NdefRecord[] { cardRecord, appRecord});
try {
// see if tag is already NDEF formatted
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
if (!ndef.isWritable()) {
displayMessage("Read-only tag.");
return false;
}
// work out how much space we need for the data
int size = message.toByteArray().length;
if (ndef.getMaxSize() < size) {
displayMessage("Tag doesn't have enough free space.");
return false;
}
ndef.writeNdefMessage(message);
displayMessage("Tag written successfully.");
return true;
} else {
// attempt to format tag
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
try {
format.connect();
format.format(message);
displayMessage("Tag written successfully!\nClose this app and scan tag.");
return true;
} catch (IOException e) {
displayMessage("Unable to format tag to NDEF.");
return false;
}
} else {
displayMessage("Tag doesn't appear to support NDEF format.");
return false;
}
}
} catch (Exception e) {
displayMessage("Failed to write tag");
}
return false;
}
private String getRandomConsole() {
double rnd = Math.random();
if(rnd<0.25) return "Random-1";
else if(rnd<0.5) return "Random-2";
else if(rnd<0.75) return "Random-3";
else return "Random-4";
}
private void displayMessage(String message) {
mTextView.setText(message);
}
}
然后,这是我从NFC标签读取数据的活动。理论上,当发现NFC标签时,这是系统启动但系统启动先前活动的活动。这是代码:
public class CardActivity extends Activity {
private TextView mCardView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.card_activity);
// ImageView that we'll use to display cards
mCardView = (TextView)findViewById(R.id.card_view);
// see if app was started from a tag and show game console
Intent intent = getIntent();
if(intent.getType() != null && intent.getType().equals(MimeType.NFC_DEMO)) {
Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msg = (NdefMessage) rawMsgs[0];
NdefRecord cardRecord = msg.getRecords()[0];
String consoleName = new String(cardRecord.getPayload());
mCardView.setText(consoleName);
}
}
}
清单文件是这样的:
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".CardActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<data android:mimeType="application/vnd.daggothSoft.nfcdemo"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
MIME-Type的最后一个活动是:
public class MimeType {
public static final String NFC_DEMO = "application/vnd.daggothSoft.nfcdemo";
}
问题在于,当我扫描NFC标签时,根据清单,启动系统的活动不是应该的。始终启动主要活动。我不知道问题出在哪里,问题是什么......好吧,任何评论或帮助都会非常有用。
谢谢,真的,谢谢;)
答案 0 :(得分:0)
注意Android的用于intent过滤器的MIME类型匹配区分大小写 - 尽管MIME类型本身并非如此。因此,对于Android(以及几乎在任何地方使用它们),您应该坚持使用仅使用小写字母的MIME类型的约定。
特别是对于存储在NFC标签上的MIME类型记录,Android会自动将它们转换为全小写字母,以克服意图过滤器中区分大小写的问题。因此,在您的示例中,将意图过滤器中的类型名称更改为"application/vnd.daggothsoft.nfcdemo"
将起作用:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<data android:mimeType="application/vnd.daggothsoft.nfcdemo"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
然后,您还应确保仅使用小写字母编写MIME类型:
public static final String NFC_DEMO = "application/vnd.daggothsoft.nfcdemo";