[英]NFC Tag start without asking the user what application to use
我的應用程序基本上只是獲取任何標簽的標簽ID
我希望應用程序在不詢問用戶使用哪個應用程序的情況下運行
直接來自同一應用
我在互聯網上找到了有關如何開發NFC作家和讀者的教程
但每次我點擊時,系統都會要求用戶選擇一個應用程序(即使我關閉了該應用程序)
因為我要為不同的實現創建不同的活動,所以通過使用相同的方法,Android系統會要求用戶選擇許多應用程序(它們都是我的應用程序活動)
這是我的代碼:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.nfc.test"
android:versionCode="1"
android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<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:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".TapToRegisterTag" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
<!-- Other Activities -->
</application>
</manifest>
TapToRegisterTag.java
package com.nfc.test;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class TapToRegisterTag extends Activity{
// Prepare NFC Tag variables
Tag myTag;
String tagID;
NfcAdapter mNfcAdapter;
public static final String MIME_TEXT_PLAIN = "text/plain";
public static final String TAG = "NfcDemo";
ImageView logo;
TextView txt;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.register_tag_layout);
logo = (ImageView)findViewById(R.id.imageView2);
txt = (TextView)findViewById(R.id.textView);
// prepare NFC
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mNfcAdapter.isEnabled()) {
Toast.makeText(this, "NFC is disabled.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "NFC is Enabled.", Toast.LENGTH_LONG).show();
}
handleIntent(getIntent());
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
/**
* It's important, that the activity is in the foreground (resumed). Otherwise
* an IllegalStateException is thrown.
*/
setupForegroundDispatch(this, mNfcAdapter);
try{
this.myTag = (Tag) getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
this.tagID = OnetapActivity.bytesToHex(myTag.getId());
Toast.makeText(this, "Tag ID: \n" + tagID, Toast.LENGTH_LONG).show();
}catch (Exception ex){
Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
protected void onPause() {
stopForegroundDispatch(this, mNfcAdapter);
super.onPause();
}
@Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
// TODO: handle Intent
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String type = intent.getType();
if (MIME_TEXT_PLAIN.equals(type)) {
//new NdefReaderTask().execute(tag);
try{
this.myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
this.tagID = OnetapActivity.bytesToHex(this.myTag.getId());
Toast.makeText(this, "Tag ID: \n" + tagID, Toast.LENGTH_LONG).show();
}catch (Exception ex){
Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
}
} else {
Log.d(TAG, "Wrong mime type: " + type);
}
} else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
// In case we would still use the Tech Discovered Intent
this.myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = this.myTag.getTechList();
String searchedTech = Ndef.class.getName();
for (String tech : techList) {
if (searchedTech.equals(tech)) {
//new NdefReaderTask().execute(tag);
try{
myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
//this.myTag = (Tag) getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
this.tagID = OnetapActivity.bytesToHex(myTag.getId());
Toast.makeText(this, "Tag ID: \n" + tagID, Toast.LENGTH_LONG).show();
}catch (Exception ex){
Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
}
break;
}
}
}
}
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);
IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{};
// Notice that this is the same filter as in our manifest.
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
try {
filters[0].addDataType(MIME_TEXT_PLAIN);
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("Check your mime type.");
}
adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
}
public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
adapter.disableForegroundDispatch(activity);
}
}
@ xml / 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>
<!-- class name -->
</tech-list>
</resources>
<!--
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.NfcF</tech>
<tech>android.nfc.tech.NfcV</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
<tech>android.nfc.tech.MifareClassic</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
-->
到目前為止,我唯一了解的是AAR(Android應用程序記錄)的實現。 這些是標記中的NDEF消息,僅會啟動AAR中給定的應用程序。 效果很好。 但是,您必須實現NDEF縮進。 您可以嘗試在Android市場上找到一些AAR作家。
其實我對我的朋友找到了解決方案
這是他的答案:
也許您應該將“過濾器”和“技術列表”更改為null
您的代碼:
adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
改成
adapter.enableForegroundDispatch(activity, pendingIntent, null, null);
參考:
如果為此方法提供了任何IntentFilter,它們將用於匹配ACTION_NDEF_DISCOVERED和ACTION_TAG_DISCOVERED的調度Intent。 由於ACTION_TECH_DISCOVERED依賴於IntentFilter匹配之外的元數據,因此該調度的Intent是通過分別傳入技術列表來處理的。 技術列表中的每個第一級條目代表一系列必須全部存在才能匹配的技術。 如果任何一個第一級別集匹配,則調度將通過給定的PendingIntent進行路由。 換句話說,第二級進行“與”運算,而第一級條目進行“與”運算。
如果為充當通配符的filter和techLists參數都傳遞null,則將導致前台活動通過ACTION_TAG_DISCOVERED意向接收所有標簽。
資源:
我反編譯谷歌播放apk並編寫以下代碼:
public static void resume(Context con, Activity _activity) {
NfcAdapter _nfcAdapter = NfcAdapter.getDefaultAdapter(con);
if (!_isReceiveIntentEnabled) {
if (_nfcAdapter != null) {
_nfcAdapter.setNdefPushMessage(null, _activity, new Activity[0]);
NfcAdapter localNfcAdapter = _nfcAdapter;
Activity localActivity = _activity;
int flag = PendingIntent.FLAG_NO_CREATE; // 536870912;
Intent intent = new Intent(_activity, _activity.getClass()).addFlags(flag);
PendingIntent localPendingIntent = PendingIntent.getActivity(_activity, 0, intent, 0);
IntentFilter[] arrayOfIntentFilter = new IntentFilter[] { new IntentFilter("android.nfc.action.TECH_DISCOVERED") };
String[][] techArr = new String[][] { new String[] { IsoDep.class.getName() } };
localNfcAdapter.enableForegroundDispatch(localActivity, localPendingIntent, arrayOfIntentFilter, techArr);
}
_isReceiveIntentEnabled = true;
}
}
public static void pause(Context con, Activity _activity) {
NfcAdapter _nfcAdapter = NfcAdapter.getDefaultAdapter(con);
if (_isReceiveIntentEnabled) {
if (_nfcAdapter != null) {
_nfcAdapter.disableForegroundDispatch(_activity);
}
_isReceiveIntentEnabled = false;
}
}
不要忘記添加權限:
<uses-permission android:name="android.permission.NFC" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.