【问题标题】:NFC app based on Titanium is not triggered by tag基于 Titanium 的 NFC 应用程序不会被标签触发
【发布时间】:2016-05-27 23:13:33
【问题描述】:

我对 Appcelerator Titanium 的 ti.nfc module 有疑问。

我添加了模块并遵循了本指南:

http://vizteck.com/test/blog/nfc-data-communication-android-using-titanium

我还关注了 Appcelerator 的官方文档。

index.js

var nfc = require("ti.nfc");
var nfcAdapter;

// This creates an NFC adapter associated with the current activity. 
// Each activity should have only ONE NFC adapter.
nfcAdapter = nfc.createNfcAdapter({
     onNdefDiscovered: handleNDEFDiscovery,
     onTagDiscovered: handleTagDiscovery,
     onTechDiscovered: handleTechDiscovery
});


function handleNDEFDiscovery(data){
    // alert('NDEF DISCOVERED:: ' + data.messages[0].records[0].getPayload());
    // Our required payload fits in the first record of the first Ndef msg
    var payload = data.messages[0].records[0].getPayload();
    // First byte of payload is control byte
    // Bits 5 to 0 of the control bytes contain 
    // length of language code succeeding the control byte
    var langCodeLength = payload[0] & 0077;
    // Received NFC text data starts after textOffset bytes in payload
    var textOffset = langCodeLength + 1;
    // Payload contains byte array which needs to be converted to a string
    // nfc_text contains the exact text string sent by the sending NFC device
    var nfc_text = payload.toString().substring(textOffset);
    /* process nfc_text as required by application logic here */
}

function handleTagDiscovery(data){
    alert('TAG DISCOVERED:: ' + data.messages[0].records[0].getPayload());
}

function handleTechDiscovery(data){
    alert('TECH DISCOVERED:: ' + data.messages[0].records[0].getPayload());
}

    // Check for NFC support on device
    if (!nfcAdapter.isEnabled()) {
        alert('NFC is not enabled on this device!');
    }else{        
        // Tag scans are received by the current activity as new intents. We
        // need to pass scan intents to the nfc adapter for processing.
        var act = Ti.Android.currentActivity;
        act.addEventListener('newintent', function(e) {
            nfcAdapter.onNewIntent(e.intent);
        });

        // Since we want the app to only use NFC while active in the foreground
        // We disable and enable foreground dispatch on app pause and resume respectively
        act.addEventListener('resume', function(e) {
            nfcAdapter.enableForegroundDispatch(dispatchFilter);
        });
        act.addEventListener('pause', function(e) {
            nfcAdapter.disableForegroundDispatch();
        });

        // The foreground dispatch filter specifies the types of NFC 
        // messages the app wants to receive and handle. The only entry in our case
        // specifies type ‘text/plain’ since we want to send and receive plain text
        dispatchFilter = nfc.createNfcForegroundDispatchFilter({
            intentFilters: [
                { action: nfc.ACTION_NDEF_DISCOVERED, mimeType: 'text/plain' },
            ],
            techLists: [
                [ "android.nfc.tech.NfcF" ],
                [ "android.nfc.tech.Ndef" ],
                [ "android.nfc.tech.MifareClassic" ],
                [ "android.nfc.tech.NfcA" ]
            ]
        });
        // This enables foreground dispatch for the first time
        nfcAdapter.enableForegroundDispatch(dispatchFilter);
    }

Android tiapp.xml

<android xmlns:android="http://schemas.android.com/apk/res/android">
    <manifest>
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-sdk android:minSdkVersion="14" />
        <application>
            <activity
             android:label="TagViewer" android:theme="@style/Theme.Titanium"
             android:configChanges="keyboardHidden|orientation"
             android:launchMode="singleTask">
                <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>
                <intent-filter>
                    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
                    <category android:name="android.intent.category.DEFAULT"/>
                    <data android:scheme="http"/>
                </intent-filter>
            </activity>
        </application>
    </manifest>
</android>

当我启动应用程序时,nfcAdapter 已启用,我看到以下 4 个警报:

[INFO] :   ALERT: (KrollRuntimeThread) [322,322] org.appcelerator.titanium.proxy.ActivityProxy@1a252dad
[INFO] :   ALERT: (KrollRuntimeThread) [0,322] org.appcelerator.kroll.runtime.v8.V8Function@368d58e2
[INFO] :   ALERT: (KrollRuntimeThread) [0,322] org.appcelerator.kroll.runtime.v8.V8Function@2c0fe473
[INFO] :   ALERT: (KrollRuntimeThread) [1,323] org.appcelerator.kroll.runtime.v8.V8Function@3e517f30

每次我拿着一个标签(卡片靠在手机背面时,我都会在 appcelerator 的控制台中看到类似这样的内容:

[INFO] :   Timeline: Timeline: Activity_idle id: android.os.BinderProxy@30a1f176 time:23801469
[INFO] :   Timeline: Timeline: Activity_idle id: android.os.BinderProxy@30a1f176 time:23802093
etc...

我使用了在 Play 商店中找到的另一个应用程序(NFC 阅读器)。我的 Tag 包含的数据有:Tag ID (hex)、Tag ID (dec)、ID (reversed)。我使用的标签具有以下特点:

  • 标签类型:ISO 15693

  • 技术:NfcV、NdefFormatable

  • 序列号:a2:3b:6b:1e:50:01:04:e0

Output from NFC Reader 问题是什么?为什么它不能很好地解释标签/卡片? 我希望你能帮助我。

非常感谢;)

【问题讨论】:

  • 您的标签包含哪些数据?
  • 我使用了在 Play 商店中找到的另一个应用程序(NFC 阅读器)。数据为:标签 ID(十六进制)、标签 ID(十进制)、ID(反转)。我需要我的应用程序的标签 ID(十六进制)(序列号)。

标签: javascript android nfc intentfilter appcelerator-titanium


【解决方案1】:

鉴于 NFC 阅读器的输出,您的标签不包含 NDEF 消息(因为它显示“NdefFormatable”而不是“Ndef”标签技术)。但是,您将 NFC 意图过滤器(在清单和前台调度中)注册为仅对包含文本记录(或 MIME 类型“text/plain”)或“http://”的 NFC 标签敏感" URL(仅在清单中注册):

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain"/>
</intent-filter>
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="http"/>
</intent-filter>
nfc.createNfcForegroundDispatchFilter({
        intentFilters: [
            { action: nfc.ACTION_NDEF_DISCOVERED, mimeType: 'text/plain' },
        ],
        ...

因此,您的应用将不会拾取标签。

你能做些什么呢?

您可以使用应用所期望的数据类型对标签进行编程(因此,您将文本记录写入标签),或者您更改应用的意图过滤器以正确发现该标签类型。

对于前台调度,您可以使用以下代码实现:

dispatchFilter = nfc.createNfcForegroundDispatchFilter({
    intentFilters: [
        { action: nfc.ACTION_TECH_DISCOVERED },
    ],
    techLists: [
        [ "android.nfc.tech.NfcV" ]
    ]
}); 

然后您将在onTechDiscovered 回调中收到标签发现事件:

function handleTechDiscovery(data) {
    // do something
}

然后您可以根据需要处理标签。例如。如果要读取标签 UID/防碰撞标识符,可以从data 参数中获取NfcTag 对象:

    var tag = data.tag;

并通过查询getId()方法获取UID:

    alert('Tag ID: ' + tag.getId());

【讨论】:

  • 感谢您现在标签调用回调句柄TechDiscovery(数据),我可以在控制台中看到:INFO] : TECH DISCOVERED:: [object Object]。我该怎么做才能正确读取 [object Object] ?
  • 问题解决了!非常非常感谢你!如果我能为你做点什么没问题。
  • 我还有一个小问题,如果我把index.js中的js代码放到另一个js页面,就不行了。你知道为什么吗?
  • @Gianluca 不,我没有。
【解决方案2】:

谢谢迈克尔! 我用你的替换了我的“dispatchFilter”,并修改了函数“handleTechDiscovery”,将“data.messages[0].records[0].getPayload()”更改为“data”。

现在,当我将标签卡靠在手机背面时,我在 appcelerator 的控制台中看到如下内容:

[INFO] : I/Nfc Module: android.nfc.action.TECH_DISCOVERED intent 收到但没有消息

[信息]:NFC 已启用

[INFO] : TECH DISCOVERED:: [object Object]

我该怎么做才能正确读取该 [object Object] ?

如果标签/卡包含数据,为什么“收到 android.nfc.action.TECH_DISCOVERED 意图但没有消息”?

再次感谢您的回复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多