and*_*dev 11 android nfc android-beam nfc-p2p android-applicationrecord
我是NFC新手.我尝试连接到NFC并将文本数据从设备共享到另一台设备.
我在两台设备和一台设备上安装我的应用程序,打开我的应用程序,然后开始将设备点击到另一台设备,以便通过Beam传输数据.
在另一台设备上,由于Beam交互,我的应用程序打开.但是,活动是使用默认的MAIN意图操作启动的,而不是使用TAG_DISCOVERED(或类似的NFC意图)启动的.每次它做同样的事情.
此外,它没有调用该onNewIntent()方法.我试图打电话onNewIntent给onCreate,但在那种情况下,意图行动仍然是主要的.我希望能够获得Beam交互的NFC意图.那么请你告诉我哪里出错了?
在这段代码中,我没有共享数据.我首先需要标签.
表现:
<activity android:name="com.framentos.hellonfc.MainActivity"
android:clearTaskOnLaunch="true"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
Run Code Online (Sandbox Code Playgroud)
Java代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ctx = this;
// startHandler();
_handler = new Handler();
Button btnWrite = (Button) findViewById(R.id.button);
message = (TextView) findViewById(R.id.nfcwriteTag);
btnWrite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
adapter = NfcAdapter.getDefaultAdapter(this);
if (adapter == null) {
message.setText("NFC is not supported on this device.");
}
if (adapter.isEnabled()) {
message.setText("NFC is Enabled on this device.");
} else {
message.setText("Please enable NFC to communicate.");
}
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);
IntentFilter tagTech = new IntentFilter(
NfcAdapter.ACTION_TECH_DISCOVERED);
tagTech.addCategory(Intent.CATEGORY_DEFAULT);
IntentFilter tagDetect = new IntentFilter(
NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetect.addCategory(Intent.CATEGORY_DEFAULT);
writeTagFilters = new IntentFilter[] { tagDetected, tagTech ,tagDetect};
// handleIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.i(getPackageName(), "on New Intent is called...!");
handleIntent(getIntent());
}
public void onPause() {
super.onPause();
WriteModeOff();
}
@Override
public void onResume() {
super.onResume();
WriteModeOn();
}
private void WriteModeOn() {
writeMode = true;
adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters,
null);
}
private void WriteModeOff() {
writeMode = false;
adapter.disableForegroundDispatch(this);
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*and 28
从您在问题中发布的代码中,我假设您没有注册您的应用程序以发送特定的NDEF消息.在这种情况下,如果您的应用在一台设备上打开,Android会自动将包含您的应用的Play商店链接和Android应用记录(AAR)的URI记录的NDEF消息发送到另一台设备.
因此,您的第二个设备将收到以下NDEF消息:
+---------------------------------------------------------------------------------------+
| WKT:URI | http://play.google.com/store/apps/details?id=your.package.name&feature=beam |
+---------------------------------------------------------------------------------------+
| EXT:android:com:pkg | your.package.name |
+---------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
如果您的应用程序尚未在第二台设备上打开,现在会发生什么,即Android应用程序记录(第二条记录)将强制您的应用程序启动.但是,查看清单时,您没有与此NDEF消息的第一条记录(Play商店URL)匹配的intent过滤器.因此,Android认为您不期望NDEF消息并使用标准android.intent.action.MAIN(带有类别android.intent.category.LAUNCHER)来启动您的应用程序(或者更确切地说,您的应用程序的第一个活动具有针对MAIN类别操作的意图过滤器LAUNCHER).
为了在您的应用程序中接收NFC意图以及整个NDEF消息,您需要定义与上述NDEF消息中的第一条记录匹配的正确意图过滤器:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http"
android:host="play.google.com"
android:pathPrefix="/store/apps/details?id=your.package.name" />
</intent-filter>
Run Code Online (Sandbox Code Playgroud)
现在,Android将识别您的应用/活动已准备好接收NFC意图并将意图传递NDEF_DISCOVERED给您的活动.请注意,onNewIntent()如果您的应用尚未运行,您仍然无法获得该意图.相反,您可以使用activity的getIntent()方法获得启动活动的意图.例如在onCreate/ onStart/ onResume,你可以使用
Intent intent = getIntent();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
NdefMessage ndefMessage = null;
Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if ((rawMessages != null) && (rawMessages.length > 0)) {
ndefMessage = (NdefMessage)rawMessages[0];
}
// TODO: do something with the received NDEF message
}
Run Code Online (Sandbox Code Playgroud)
获取意图和NDEF消息.
关于清单中已有的意图过滤器:
NDEF_DISCOVERED:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Run Code Online (Sandbox Code Playgroud)
NDEF_DISCOVERED没有<data ... />标签的意图过滤器永远不会在许多NFC设备上触发.您应该始终定义您希望在启动NDEF记录中出现的具体数据.
TECH_DISCOVERED:
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
Run Code Online (Sandbox Code Playgroud)
如果您不想在检测到某种NFC标签技术时启动应用程序(您在nfc_tech_filter.xml文件中定义特定技术),则应该只使用此意图过滤器.对于您的Beam场景,您不会使用这样的意图过滤器.Btw .<category ...>标记不用于此intent过滤器.
TAG_DISCOVERED:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Run Code Online (Sandbox Code Playgroud)
通常不应在清单中使用此意图过滤器.它意味着如果没有其他应用程序可能处理检测到的NFC标记,则会触发回退.使用此功能可能会导致糟糕的用户体验(例如,您的应用程序正在为其无法或实际上无法处理的标记启动).它主要用于向后兼容API级别9(?).
如果您的活动已经开始,为了也捕获NFC意图,您可以注册这样的前台调度(在onResume方法中):
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
Run Code Online (Sandbox Code Playgroud)
这样,您将收到活动在您的活动onNewIntent方法中处于前台时发生的任何NFC发现事件.他们将通过ACTION_TAG_DISCOVERED意图发送.
| 归档时间: |
|
| 查看次数: |
7278 次 |
| 最近记录: |