当前位置: 首页 > 知识库问答 >
问题:

从标签获取NDEF消息冻结Android应用

羊煜
2023-03-14

有人知道为什么会这样吗?

package com.example.infcdemo;

import java.io.IOException;
import java.util.Timer;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.nfc.tech.NfcA;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;

public class MainActivity extends Activity
{
    protected NfcAdapter mAdapter;
    protected PendingIntent mPendingIntent;
    protected IntentFilter mIntentfilter;
    protected String[][] mTechLists;
    protected IntentFilter[] mFilters;
    protected NfcA nfca = null;
    protected Intent mIntent = null;
    protected Tag mTag;
    private boolean nfc_initialized = false;

    Tag myTag = null;
    Ndef _ndef = null;

    Timer _incomingMessageTimer;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (nfc_initialized == false) 
        {
            // Initialize NFC Specific
            mAdapter = NfcAdapter.getDefaultAdapter(this);
            mPendingIntent = PendingIntent.getActivity(this, 0,
                    new Intent(this, getClass())
                            .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 1);
            IntentFilter ndef = new IntentFilter(
                    NfcAdapter.ACTION_TAG_DISCOVERED);
            mTechLists = new String[][] { new String[] { NfcA.class.getName(), Ndef.class.getName(),
                    NdefFormatable.class.getName() } };
            mFilters = new IntentFilter[] { ndef, };
            nfc_initialized = true;
        }
    }

    public void updateIncomingMessage(String msg)
    {
        TextView txtView = (TextView) findViewById(R.id.txtReceive);
        txtView.setText(msg);
    }

    @Override
    protected void onStart()
    {
        super.onStart();

        _incomingMessageTimer = new Timer();
        _incomingMessageTimer.schedule(new MessageReceiveTimer(new Handler(), this),0,900);
    }

    @Override
    protected void onStop()
    {
        super.onStop();

        _incomingMessageTimer.cancel();
        _incomingMessageTimer.purge();

    }

    @Override
    public void onNewIntent(Intent intent) 
    {
        mIntent = intent;

        String action = intent.getAction();
        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) 
        {
            myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

            if(_ndef != null)
            {
                try 
                {
                    _ndef.close();
                    _ndef = null;
                } 
                catch (IOException e) 
                {
                    e.printStackTrace();
                }
            }

            if(_ndef == null)
            {
                _ndef = Ndef.get(myTag);

                try 
                {
                    _ndef.connect();
                } 
                catch (IOException e) 
                {
                    e.printStackTrace();
                }
            }
        } 
    }
    @Override
    public void onPause()
    {
        super.onPause();
        mAdapter.disableForegroundDispatch(this);
    }

    @Override
    public void onResume() 
    {
        super.onResume();
        mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters,
            mTechLists);
    }
}

//TimerTask类

package com.example.infcdemo;
import java.util.TimerTask;

import android.nfc.NdefMessage;
import android.os.Handler;

public class MessageReceiveTimer extends TimerTask
{
    Handler _handler;
    MainActivity _mainActivity;

    MessageReceiveTimer(Handler handler, MainActivity mainActivity)
    {
        super();
        _handler = handler;
        _mainActivity = mainActivity;
    }

    @Override
    public void run() 
    {
        _handler.post(new Runnable() 
        {
            @Override
            public void run() 
            {
                try 
                {
                    if(_mainActivity._ndef != null)
                    {
                        NdefMessage ndefMsg = null;

                        if(_mainActivity._ndef.isConnected())
                            ndefMsg = _mainActivity._ndef.getNdefMessage();
                        else
                            ndefMsg = null;

                        byte[] ndefRecord = ndefMsg.getRecords()[0].getPayload();
                        String strMsg = new String(ndefRecord, "US-ASCII"); 
                        _mainActivity.updateIncomingMessage(strMsg);
                    }
                } 
                catch (Exception e)
                {
                    return;
                }
            }
        });
    }
}

共有1个答案

汝跃
2023-03-14

当您移除标记时,应用程序阻塞的原因是您在应用程序的主线程(UI线程)中对标记执行IO操作。

您首先创建一个计时器,该计时器在一个单独的线程中处理其计划任务

_incomingMessageTimer = new Timer();
                        ^^^^^^^^^^^
_incomingMessageTimer.schedule(new MessageReceiveTimer(new Handler(), this), 0, 900);
                      ^^^^^^^^

但是,当TimerTask执行时(在Timer线程上)

public class MessageReceiveTimer extends TimerTask {
    @Override
    public void run() {
        // code excecution happens in the Timer thread
    }
}
_handler.post(new Runnable() {
    @Override
    public void run() {
        // code execution happens in the Handler's thread
    }
});
_incomingMessageTimer.schedule(new MessageReceiveTimer(new Handler(), this),0,900);
                                                       ^^^^^^^^^^^^^
 类似资料:
  • 类似的问题 - 如何在Android中读取检测到的NFC标签(NDEF内容)详细信息? 我希望我的android应用程序能够读取和解析检测到的NDEF消息。 我已经编辑了AndroidManifest.xml来检测nfc标签,并添加了意图过滤器,如下所示 我相信这很好,因为当我使用SDK附带的NFCDemo示例应用程序创建MockNDEF标签时,当我可以选择处理这些生成的标签的应用程序列表出现时,

  • 我正在做一个NFC应用程序。为了启动我的应用程序,我使用了一个NDEF标签,里面有一条AAR NDEF记录。 这很好。但是现在我想直接用应用程序读取标签内容。我该怎么做? (当我从手机上取下标签并再次触摸它时,它已经起作用了,但我想取消这一步。) 舱单: 我只想让NDEF_发现我的意图。但我总是有行动。主要/类别。我的调试器的启动意图。 任何帮助都将不胜感激。我是基于这个做我的工作的: Andro

  • 我有一个应用程序可以读取一个NDEF标签,没什么大不了的:-) 我找到了这个链接:如何发现NFC标签是否还在Android的范围内?什么是一个开始,但我不知道如何更新标签。 我很挣扎,我甚至不知道我尝试做的事情在技术上是否可行。 有没有人知道怎么做的?干杯 对不起,我试着看了一些教程和例子,但我还是不明白。 这是我的全部密码。读取标签需要长得多的时间,有时并不需要。我不知道如何和在哪里更新标签,以

  • 我正在尝试创建一个 NFC 标签,该标签将触发两个单独的操作: 打开蓝牙连接 启动应用程序(或前往游戏商店) 我使用 nfc-eclipse-plugin 创建了一个包含两个合适记录的消息,但是,当写入标签时,它总是只触发第一个操作。两者都单独工作,但第二个总是被忽略。 我知道一个NFC标签上的2个NDEF消息/记录的答案-Android说你不能在一个标签上有两条独立的消息,只有一条消息中的多条记

  • 我正在开发一个Android应用程序,它使用NFC来注册设备间的触摸。我正在使用两个Nexus 7进行测试。 理想的用例是让应用程序在一个设备上处于活动状态,而不是在另一个设备上处于活动状态。主动设备推送一个包含一些数据的记录的NDefMessage,供被动设备应用处理。被动设备将包含一些数据的记录传回主动应用。 我在清单中设置了以下意图过滤器: 在我的主要活动中,我在onCreate中设置了以下