我目前有一个应用程序,用户必须登录才能使用它。在不久的将来,我们可能会支持NFC芯片登录而无需输入用户名和密码。我完全不知道扫描NFC芯片的工作情况,所以我查了一些教程并找到了this one。
我复制了教程中的代码,我想我明白它是如何工作的。问题是它不适用于我必须测试的卡(没有调用onNewIntent方法,而不是教程告诉我的)。卡工作(其他应用程序捡起来很好),所以我想问题是它是一个不同于教程中使用的类型。所以我将教程中提到的xml更改为以下内容:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.Ndef</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.IsoDep</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcB</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcF</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcV</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.Ndef</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NdefFormatable</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.MifareClassic</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
这是我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="nl.boomerweb.nfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<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="nl.boomerweb.nfc.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<meta-data
android:name="android.nfc.action.NDEF_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
</application>
</manifest>
我认为这不仅可以扫描Ndef类型的芯片,还可以扫描其他所有芯片。但是当我把卡拿到手机上时,我的应用程序仍然没有响应。
这些是我使用NFC扫描仪应用程序检索的卡片详细信息:
RF技术:
A型(ISO / IEC 14443 TYPE A)
标记类型:
Mifare Classic 1K
ATQA:
0004
SAK:
08
目标技术类(Android):
android.nfc.tech.MifareClassic,
android.nfc.tech.NfcA,
android.nfc.tech.NdefFormatable
我正在使用Android 4.1.2在三星Galaxy SIII上进行测试。我在设备上启用了nfc和sBeam,另一个扫描nfc芯片的应用程序运行完美,所以问题必须在我的代码中。我创建了一个单独的项目来测试它,它只包含上面提到的教程的最后部分中看到的代码(所以只有MainActivity,manifest和nfc_tech_filter.xml)。
最好的解决方案是可以读取所有卡片,但是现在可以读取此卡片的内容会很好。如果有人能解释如何添加新型nfc芯片,我也会感激不尽。在这个工作之后,我们可能会支持多种类型。
答案 0 :(得分:2)
我找到了一个适合我的解决方案。本教程实际上有两个问题,一个是我的应用程序根本没有响应卡,另一个是在我解决了第一个问题之后,那个应用程序在它已经运行时重新打开了。这是我用来解决这两个问题的所有代码:
<强>的AndroidManifest.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.nfc"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<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="com.example.nfc.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<action android:name="android.nfc.action.TAG_DISCOVERED" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
<meta-data
android:name="android.nfc.action.NDEF_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
<meta-data
android:name="android.nfc.action.TAG_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
</application>
</manifest>
<强> nfc_tech_filter.xml 强>
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.Ndef</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.IsoDep</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcB</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcF</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcV</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.Ndef</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NdefFormatable</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.MifareClassic</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
<强> MainActivity.java 强>
package com.example.nfc;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.widget.Toast;
public class MainActivity extends Activity {
public static final String MIME_TEXT_PLAIN = "text/plain";
public static final String TAG = "NfcDemo";
private NfcAdapter mNfcAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "Dit apparaat ondersteund geen NFC.", Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mNfcAdapter.isEnabled()) {
Toast.makeText(this, "NFC staat niet aan", Toast.LENGTH_SHORT).show();
}
handleIntent(getIntent());
}
@Override
protected void onResume() {
super.onResume();
setupForegroundDispatch(this, mNfcAdapter);
}
@Override
protected void onPause() {
stopForegroundDispatch(this, mNfcAdapter);
super.onPause();
}
@Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (intent != null && intent.getAction().contains("android.nfc")) {
//if we are here, we captured an nfc event
}
}
public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
String[][] techList = new String[][]{};
adapter.enableForegroundDispatch(activity, pendingIntent, null, techList);
}
public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
adapter.disableForegroundDispatch(activity);
}
}
您可能会看到我已将所有可能的操作添加到清单中。为了确保前台调度工作,我从教程中删除了过滤器。当更多事件被触发时,这当然会产生问题,但我想我以后总能过滤它们。不是最优雅的解决方案,但它可以完成工作。