如何onNewIntent执行之前拦截NFC标签 [英] how to intercept NFC tag before onNewIntent executes

查看:1292
本文介绍了如何onNewIntent执行之前拦截NFC标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有抓住NFC标签的应用程序。我曾在过去的问题是,用户将鼠标悬停在标签以不稳定的方式causeing的NFC适配器来触发两次。

我已经做了几件事情要对付这个。

清单:

 <活动
    机器人:名字=NfcActivity
    机器人:screenOrientation =画像
    机器人:launchMode =singleTask
    机器人:noHistory =真
    android:configChanges=\"mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation\">    &所述;意图滤光器>
        <作用机器人:名字=android.nfc.action.NDEF_DISCOVERED/>        <类机器人:名字=android.intent.category.DEFAULT/>        <数据机器人:mime类型=text / plain的/>
    &所述; /意图滤光器>
< /活性GT;

此设置了NFC捕获活动是在堆叠的唯一实例和那里是没有历史。我已经覆盖所有配置的变化,可以停止并重新启动这项活动,后者可以导致被交还到活动意图数据,使它看起来像一个重复扫描。

在活动本身我已经覆盖到onNewIntent做什么,但表现不好的扫描画面。我也明白,onNewIntent应该从功能角度看镜子的onCreate,但由于应用程序的previous版本已经发送2次扫描到下一个活动,我只想NFC捕捉code在一个地方的onCreate。

在我的onCreate做进一步的检查,以对抗对徘徊在一个标签,并造成不好的扫描。


  • 我检查的形式推出史上标志的意图。 Android版可以杀死一个应用程序时内存不足并重新启动后重新提供原意。这会导致什么似乎像一个重复扫描。

  • 在我的onCreate检查用户仍然有连接到标签的电话。这证明该用户没有悬停在与ndefTag.connect()的标签;

该应用程序似乎工作正常,但一个特定的手机(三星Galaxy年轻2),如果用户将手机上的标签的发言权几秒钟的NFC适配器似乎在一排火几次。

当发生这种情况的原扫描被取消。这样做的原因是在OnCreate处理的标签,但是当随后的扫描操作(通过将鼠标悬停,意外),在onPause - > onNewIntent运行。因此,活动跳出的onCreate,并停止处理标签。 onNewIntent显示故障扫描屏幕,并启动菜单屏幕。

为所发生的一切是用户必须重新扫描标签上面没有太大的问题。

我想发生的事情是:

在运行的onCreate,标签被处理,无论怎样,即使onNewintent执行。有没有一种方法,也许之前拦截的目的是达到onNewintent和的onPause?

也许有一个全球性的标志,我可以使用,可以先进行检查,以说的onCreate仍在运行和onNewIntent不应该,或者更重要的onPause不叫做的onCreate停止运行。

 进口的java.util.List;
进口java.util.concurrent.ExecutionException;进口org.ndeftools.Message;
进口org.ndeftools.Record;进口android.app.Activity;
进口android.app.PendingIntent;
进口android.app.ProgressDialog;
进口android.content.Context;
进口android.content.Intent;
进口android.content.IntentFilter;
进口android.nfc.NdefMessage;
进口android.nfc.NdefRecord;
进口android.nfc.NfcAdapter;
进口android.nfc.Tag;
进口android.nfc.tech.Ndef;
进口android.os.AsyncTask;
进口android.os.Build;
进口android.os.Bundle;
进口android.os.Handler;
进口android.os.Parcelable;
进口android.os.Vibrator;
进口android.util.Log;
进口android.widget.Toast;公共类NfcActivity延伸活动{    私有静态最后弦乐TAG = NfcActivity.class.getName();    保护NfcAdapter nfcAdapter;
    受保护的PendingIntent nfcPendingIntent;    处理程序处理程序;
    可运行的可运行;    处理器failHandler;
    可运行failRunnable;    Parcelable []消息;    我的意图;    标签标签;
    串TAGID;    布尔nfcConnected;    ProgressDialog progressDialog;    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.nfcactivitylayout);
        Log.e(TAG的OnCreate);
        nfcConnected = FALSE;        //初始化NFC
        nfcAdapter = NfcAdapter.getDefaultAdapter(本);
        nfcPendingIntent = PendingIntent.getActivity(此,0,新意图(本,this.getClass())addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),0);        标签= NULL;
        TAGID = NULL;        I = getIntent();        如果((i.getFlags()及!Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)= 0){            //检查是否Android有previously杀死了应用程序,并从历史中重新启动它
            //并交付原意。
            //如果有不处理,并启动菜单屏幕
                意图processPayloadIntent =新意图(NfcActivity.this,NfcscannerActivity.class);
                processPayloadIntent.setAction(QR code_ACTION);
                processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(processPayloadIntent);            }其他{        标签= i.getParcelableExtra(NfcAdapter.EXTRA_TAG);        TAGID = bytesToHexString(tag.getId());        Log.e(TAGTAGID =+ TAGID);        Log.e(TAG的OnCreate意图行动=+ i.getAction());
        //活动已捕获标签数据,证明该用户没有悬停在标签,并做了很好的扫描
        //盘旋可以触发两次适配器        AsyncNfcConnect ASNC =新AsyncNfcConnect();
        尝试{
            。asnc.execute()获得();
        }赶上(InterruptedException的E){
            // TODO自动生成catch块
            e.printStackTrace();
        }赶上(为ExecutionException E){
            // TODO自动生成catch块
            e.printStackTrace();
        }
        Log.e(TAGnfcConnected !!!!!!!!!!!!!!!!!!!!!!!!! =+ nfcConnected);        如果(nfcConnected ==真){
            INT buildVersionSdk = Build.VERSION.SDK_INT;
            INT buildVersion codeS = Build.VERSION_ codeS.GINGERBREAD;            Log.e(TAGbuildVersionSdk =+ buildVersionSdk
                    +buildVersion codeS =+ buildVersion codeS);            INT themeVersion;
            如果(Build.VERSION.SDK_INT> Build.VERSION_ codeS.GINGERBREAD){                themeVersion = 2;            }其他{                themeVersion = 1;
            }            尝试{            progressDialog =新ProgressDialog(这一点,themeVersion);
            progressDialog.setTitle(NFC标签扫描);
            progressDialog.setMessage(处理标记...);
            progressDialog.setIndeterminate(真);
            progressDialog.show();            }赶上(例外五){}
        如果(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(i.getAction())|| NfcAdapter.ACTION_TAG_DISCOVERED.equals(i.getAction())){            如果(NfcScannerApplication.isCanScanNfcTag()){            消息= i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            如果(短信!= NULL){
                //setContentView(R.layout.successfulnfc);                NfcScannerApplication.startNfcTimer();
                //Toast.makeText(this,NFC定时器设定,Toast.LENGTH_LONG).show();                Log.e(TAG,发现+ messages.length +NDEF消息); //几乎总是只有一个                颤动(); //信号找到的邮件:-)                initHandler();
                handler.postDelayed(可运行,2000年);      }其他{          Toast.makeText(这一点,在数据标签是不正确的,Toast.LENGTH_LONG).show();              尝试{                handler.removeCallbacks(可运行);
                Log.e(TAG,只是删除回调可运行读取NFC标签数据);                }赶上(例外五){                }
                initFailHandler();
                failHandler.postDelayed(failRunnable,1);      }            }其他{
                尝试{                    handler.removeCallbacks(可运行);
                    Log.e(TAG,只是删除回调可运行读取NFC标签数据);                    }赶上(例外五){                    }
                    initFailHandler();
                    failHandler.postDelayed(failRunnable,1);
            }        }其他{            Toast.makeText(这一点,标签无法正确识别,Toast.LENGTH_LONG).show();                尝试{                handler.removeCallbacks(可运行);
                Log.e(TAG,只是删除回调可运行读取NFC标签数据);                }赶上(例外五){                }
                initFailHandler();
                failHandler.postDelayed(failRunnable,1);        }
        }其他{
            尝试{                Toast.makeText(这一点,手机没有连接到TAG,Toast.LENGTH_LONG).show();                handler.removeCallbacks(可运行);
                Log.e(TAG,只是删除回调可运行读取NFC标签数据);                }赶上(例外五){                }
                initFailHandler();
                failHandler.postDelayed(failRunnable,1);        } // NFC的一端连接测试
        } //从历史的检验年底推出
    } //的onCreate结束    @覆盖
    保护无效调用onStart(){
        super.onStart();
        Log.e(TAG,在onStart);
    }    @覆盖
    保护无效的onStop(){
        super.onStop();
        Log.e(TAG的onStop);
    }    @覆盖
    公共无效onNewIntent(意向意图){
        Log.e(TAGonNewIntent);                            Toast.makeText(这一点,坏扫描!!!,Toast.LENGTH_LONG).show();                            initFailHandler();
                            failHandler.postDelayed(failRunnable,1);    } // onNewIntent结束
    公共无效enableForegroundMode(){
        Log.e(TAGenableForegroundMode);        IntentFilter的tagDetected =新的IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); //过滤所有
        IntentFilter的[] writeTagFilters =新的IntentFilter [] {} tagDetected;
        nfcAdapter.enableForegroundDispatch(这一点,nfcPendingIntent,writeTagFilters,NULL);
    }    公共无效disableForegroundMode(){
        Log.e(TAGdisableForegroundMode);        nfcAdapter.disableForegroundDispatch(本);
    }    @覆盖
    保护无效onResume(){
     super.onResume();
     Log.e(TAGonResume);        enableForegroundMode();
    }    @覆盖
    保护无效的onPause(){
        Log.e(TAG的onPause);        super.onPause();        disableForegroundMode();        如果(处理!= NULL){
            handler.removeCallbacks(可运行);
        }
    }    私人无效振动(){
        Log.e(TAG,震动);        振动器盛传=(振动器)getSystemService(Context.VIBRATOR_SERVICE);
        vibe.vibrate(500);
    }
    公共无效initHandler(){          处理器=新的处理程序();
          可运行=新的Runnable(){
                公共无效的run(){
                    processTag();                }                私人无效processTag(){
                    Log.e(TAG,即将过程变量);                    尝试{
                        progressDialog.dismiss();                    }赶上(例外五){                        //没做什么
                    }                    //解析记载
                    的for(int i = 0; I< messages.length;我++){
                        尝试{
                            清单<记录和GT;记录=新的消息((NdefMessage)消息[I]);                            Log.e(TAG,发现+ records.size()+的消息记录+ I);                            对于(INT K = 0; K< records.size(); K ++){
                                Log.e(TAG,记录#+ K +是阶级的+ records.get(K).getClass()getSimpleName());                                录制录制= records.get(K);                                NdefRecord n​​defRecord = record.getNdefRecord();                                字节[] = ARR ndefRecord.getPayload();                                字符串的有效载荷=新的String(ARR);
                                如果(payload.length()大于0){                                有效载荷= payload.substring(3,payload.length());                                Log.e(TAG,负载=+负载);                                串[] splitPayload = payload.split(,);                                串tagType = splitPayload [0];
                                串tagCompany = splitPayload [1];
                                串tagClientID = splitPayload [2];
                                串tagClientName = splitPayload [3];                                如果(tagClientID.equalsIgnoreCase(0)及!&放大器; tagClientID.length()大于0){                                    handler.post(新的Runnable(){
                                        公共无效的run(){                                            的setContentView(R.layout.successfulnfc);                                          }
                                        });
                                意图processPayloadIntent =新意图(NfcActivity.this,NfcscannerActivity.class);
                                processPayloadIntent.putExtra(有效载荷,有效载荷);
                                processPayloadIntent.putExtra(标签识别标签识别);
                                processPayloadIntent.setAction(NFC);
                                processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                //processPayloadIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
                                startActivity(processPayloadIntent);
                                完();
                                overridePendingTransition(0,R.anim.activity_animation_zoom_in);                                    }其他{
                                        Toast.makeText(NfcActivity.this标签数据的问题/扫描的问题。Toast.LENGTH_LONG).show();                                        initFailHandler();
                                        failHandler.postDelayed(failRunnable,1);
                                    }                                }其他{
                                    Toast.makeText(NfcActivity.this标签数据的问题/扫描的问题。Toast.LENGTH_LONG).show();                                    initFailHandler();
                                    failHandler.postDelayed(failRunnable,1);                                }                            }
                        }赶上(例外五){
                            Log.e(TAG,问题解析消息,E);
                        }                    }                }
            };        }    公共无效initFailHandler(){          failHandler =新的处理程序();
          failRunnable =新的Runnable(){
                公共无效的run(){                    returnToMainMenu();                }                私人无效returnToMainMenu(){
                    //Log.e(TAG,即将返回主菜单);                    尝试{
                        progressDialog.dismiss();                    }赶上(例外五){                        //没做什么
                    }                    Toast.makeText(NfcActivity.this,请检查您的扫描技术\\ n请勿标签或滑动鼠标悬停在......,Toast.LENGTH_LONG).show();                    failHandler.post(新的Runnable(){
                        公共无效的run(){                            的setContentView(R.layout.nfcfail);                          }
                        });
                    // onBack pressed();
                    意图processPayloadIntent =新意图(NfcActivity.this,NfcscannerActivity.class);
                    processPayloadIntent.setAction(QR code_ACTION);
                    processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(processPayloadIntent);
                    完();
                    // overridePendingTransition(0,R.anim.activity_animation_zoom_in);                }
            };        }
    私人字符串bytesToHexString(字节[] SRC){
        StringBuilder的StringBuilder的=新的StringBuilder(0X);
        如果(SRC == NULL || src.length< = 0){
            返回null;
        }        的char []缓冲区=新的char [2];
        的for(int i = 0; I< src.length;我++){
            缓冲器[0] = Character.forDigit((源[Ⅰ]≥>→4)及为0x0F,16);
            缓冲液[1] = Character.forDigit(源[1] - 放大器;为0x0F,16);
            的System.out.println(缓冲液);
            stringBuilder.append(缓冲液);
        }        返回stringBuilder.toString();
    }私有类AsyncNfcConnect扩展的AsyncTask<弦乐,太虚,字符串> {
        @覆盖
        保护字符串doInBackground(字符串... PARAMS){            NfcActivity.this.nfcConnected = FALSE;
            字符串结果;
            NDEF ndefTag = Ndef.get(标签);            尝试{
                Log.e(TAG,即将试连接()********* *******);
                ndefTag.connect(); //这个应该已经执行IO操作,如果没有标记,因此应该失败
                Log.e(TAGNdef.connect()连接!********** ********);
                NdefMessage ndefMsg = ndefTag.getNdefMessage(); //这读取来自标签的当前NDEF消息并因此导致一个IO操作                NfcActivity.this.nfcConnected = TRUE;
                结果=确定;
                返回结果;            }赶上(例外五){
                //没有下降标签或标签与通信
                Log.e(TAG,有使用Ndef.connect(连接到标签的问题);
                NfcActivity.this.nfcConnected = FALSE;
                结果=NOTOK;
                返回结果;
            } {最后
                尝试{
                    ndefTag.close();
                }赶上(例外五){
                }
            }
        }    } //异步结束
}


解决方案

您似乎坚持在 onNewIntent不处理NFC意图()。我建议的onCreate() onNewIntent()都调用一个普通的程序扫描标签。这样一来,无论是入口点会遵循相同的code路径。

您主张,即应用跳出的onCreate的可能是演讲的只是一个数字?会发生什么事是你的标签扫描 AsyncNfcConnect 上一个单独的线程作为后台任务运行(因为它应该)。这任务是在的onCreate()创建之后的onCreate继续运行()已完成(你可以添加添加<在的onCreate年底code>登录语句()检查)。当带有标签的连接莫名其妙地丢失,标签被重新发现, onNewIntent()叫,你观察到的。

在任何情况下,有没有办法prevent这种情况的发生,让您的应用程序必须能够处理它。为了检测这一点,并处理它,你可以设置一些标志您的活动里面表明您的后台任务正在运行或已运行。您也可以存储的信息是否发生异常,只是尝试重新扫描标签时,它被重新发现(这可能需要您实现我上面提出的建议)。如果你想使你的应用更加证明失败,您还可以存储最后扫描标签的ID时,你已经成功扫描后(或不)被重新发现积极再次识别它。异常时保持与相同的标记发生,则可能表明他的若干倍到用户后(例如,通过提示装置w.r.t.标记不同地定位)。

I have an app that captures NFC tags. The problem i have had in the past is that users hover over the tag in an unsteady manner causeing the NFC adapter to trigger twice.

I have done a few things to counter this.

manifest:

<activity
    android:name=".NfcActivity"
    android:screenOrientation="portrait"
    android:launchMode="singleTask" 
    android:noHistory="true"
    android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation">

    <intent-filter>


        <action android:name="android.nfc.action.NDEF_DISCOVERED" />

        <category android:name="android.intent.category.DEFAULT" />

        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>

This sets the NFC capturing Activity to be the only instance in the stack and there to be no history. I've overridden all the config changes that can stop and relaunch this activity, the latter can lead to intent data being redelivered to the activity, making it look like a duplicate scan.

In the Activity itself i have overridden onNewIntent to do nothing but show a bad scan screen. I also understand that onNewIntent should mirror onCreate from a functionality standpoint, but because previous versions of the app have sent 2 scans to the next Activity, i just want the NFC capturing code in one place, onCreate.

In onCreate i do further tests to counter against hovering over a tag and creating a bad scan.

  • I check the launched form history flag in the intent. Android can kill an app when low on memory and relaunch later REDELIVERING the original intent. This can cause what seems like a duplicate scan.
  • In onCreate i check that the user STILL has the phone connected to the tag. This proves the user is not hovering over the tag with ndefTag.connect();

The app seems to work fine but on one particular phone (Samsung Galaxy Young 2), if the user places the phone on the tag for say a few seconds the the NFC adapter seems to fire a few times in a row.

When this happens the original scan is cancelled. The reason for this is oncreate processes the tag but when a subsequent scan happens(by hovering, by accident), onPause -> onNewIntent runs. So the Activity jumps out of onCreate and stops processing the tag. onNewIntent shows a failed scan screen and launches the menu screen.

The above isn't too much of a problem as all that happens is the user must re-scan the tag.

What i would like to happen is:

When onCreate runs, the tag is processed no matter what, even if onNewintent executes. Is there a way maybe to intercept the intent before is reaches onNewintent and onPause?

Maybe there is a global flag i can use, that can be checked first to say that onCreate is still running and onNewIntent shouldn't, or more importantly onPause isn't called making onCreate stop running.

import java.util.List;
import java.util.concurrent.ExecutionException;

import org.ndeftools.Message;
import org.ndeftools.Record;

import android.app.Activity;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.os.Vibrator;
import android.util.Log;
import android.widget.Toast;

public class NfcActivity extends Activity {

    private static final String TAG = NfcActivity.class.getName();

    protected NfcAdapter nfcAdapter;
    protected PendingIntent nfcPendingIntent;

    Handler handler;
    Runnable runnable;

    Handler failHandler;
    Runnable failRunnable;

    Parcelable[] messages;

    Intent i;

    Tag tag;
    String tagId;

    boolean nfcConnected;

    ProgressDialog progressDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.nfcactivitylayout);
        Log.e(TAG, "oncreate");
        nfcConnected = false;

        // initialize NFC
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

        tag = null;
        tagId = null;

        i = getIntent();

        if ((i.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {

            //check to see if Android has previously killed the app and relaunched it from History
            //and delivered the original intent.
            //if it has do not process and launch the menu screen
                Intent processPayloadIntent = new Intent(NfcActivity.this, NfcscannerActivity.class);
                processPayloadIntent.setAction("QRCODE_ACTION"); 
                processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(processPayloadIntent);

            }else{



        tag = i.getParcelableExtra(NfcAdapter.EXTRA_TAG);

        tagId = bytesToHexString(tag.getId());

        Log.e(TAG, "tagID = " + tagId);

        Log.e(TAG, "oncreate intent action = " + i.getAction());




        //The activity has captured tag data, prove the user is not hovering over the tag and is doing a good scan
        //hovering can trigger the adapter twice

        AsyncNfcConnect asnc = new AsyncNfcConnect();
        try {
            asnc.execute().get();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }




        Log.e(TAG, "nfcConnected!!!!!!!!!!!!!!!!!!!!!!!!! = " + nfcConnected);

        if(nfcConnected == true){


            int buildVersionSdk = Build.VERSION.SDK_INT;
            int buildVersionCodes = Build.VERSION_CODES.GINGERBREAD;

            Log.e(TAG, "buildVersionSdk = " + buildVersionSdk
                    + "buildVersionCodes = " + buildVersionCodes);

            int themeVersion;
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {

                themeVersion = 2;

            } else {

                themeVersion = 1;
            }

            try{

            progressDialog = new ProgressDialog(this, themeVersion);
            progressDialog.setTitle("NFC Tag Scanned");
            progressDialog.setMessage("Processing tag...");
            progressDialog.setIndeterminate(true);
            progressDialog.show();

            }catch(Exception e){        }




        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(i.getAction()) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(i.getAction())) {            

            if(NfcScannerApplication.isCanScanNfcTag()){

            messages = i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            if (messages != null) {


                //setContentView(R.layout.successfulnfc);

                NfcScannerApplication.startNfcTimer();
                //Toast.makeText(this, "NFC timer set", Toast.LENGTH_LONG).show();

                Log.e(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one

                vibrate(); // signal found messages :-)



                initHandler();
                handler.postDelayed(runnable,  2000);

      }else{

          Toast.makeText(this, "Data on tag was not correct", Toast.LENGTH_LONG).show();

              try{

                handler.removeCallbacks(runnable);
                Log.e(TAG, "just removed callback to runnable that reads nfc tag data");

                }catch(Exception e){

                }




                initFailHandler();
                failHandler.postDelayed(failRunnable,  1);



      }

            }else{


                try{

                    handler.removeCallbacks(runnable);
                    Log.e(TAG, "just removed callback to runnable that reads nfc tag data");

                    }catch(Exception e){

                    }




                    initFailHandler();
                    failHandler.postDelayed(failRunnable,  1);


            }



        } else {

            Toast.makeText(this, "Tag not recognized correctly", Toast.LENGTH_LONG).show();

                try{

                handler.removeCallbacks(runnable);
                Log.e(TAG, "just removed callback to runnable that reads nfc tag data");

                }catch(Exception e){

                }




                initFailHandler();
                failHandler.postDelayed(failRunnable,  1);

        }


        }else{


            try{

                Toast.makeText(this, "Phone wasn't connected to Tag", Toast.LENGTH_LONG).show();

                handler.removeCallbacks(runnable);
                Log.e(TAG, "just removed callback to runnable that reads nfc tag data");

                }catch(Exception e){

                }




                initFailHandler();
                failHandler.postDelayed(failRunnable,  1);



        }//end of NFC connect test


        }//end of launched from history check


    }//end of onCreate





    @Override
    protected void onStart() {
        super.onStart();
        Log.e(TAG, "onStart");
    }





    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG, "onStop");
    }





    @Override
    public void onNewIntent(Intent intent) {
        Log.e(TAG, "onNewIntent");

                            Toast.makeText(this, "Bad scan!!!", Toast.LENGTH_LONG).show();



                            initFailHandler();
                            failHandler.postDelayed(failRunnable, 1);



    }//end of onNewIntent






    public void enableForegroundMode() {
        Log.e(TAG, "enableForegroundMode");

        IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); // filter for all
        IntentFilter[] writeTagFilters = new IntentFilter[] {tagDetected};
        nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null);
    }

    public void disableForegroundMode() {
        Log.e(TAG, "disableForegroundMode");

        nfcAdapter.disableForegroundDispatch(this);
    }





    @Override
    protected void onResume() {
     super.onResume();
     Log.e(TAG, "onResume");

        enableForegroundMode();
    }

    @Override
    protected void onPause() {
        Log.e(TAG, "onPause");

        super.onPause();

        disableForegroundMode();

        if(handler != null){
            handler.removeCallbacks(runnable);
        }


    }

    private void vibrate() {
        Log.e(TAG, "vibrate");

        Vibrator vibe = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE) ;
        vibe.vibrate(500);
    }


    public void initHandler(){

          handler = new Handler();
          runnable = new Runnable() {
                public void run() {
                    processTag();

                }

                private void processTag() {
                    Log.e(TAG, "about to process tag");

                    try{
                        progressDialog.dismiss();

                    }catch(Exception e){

                        //do nothing
                    }

                    // parse to records
                    for (int i = 0; i < messages.length; i++) {
                        try {
                            List<Record> records = new Message((NdefMessage)messages[i]);

                            Log.e(TAG, "Found " + records.size() + " records in message " + i);

                            for(int k = 0; k < records.size(); k++) {
                                Log.e(TAG, " Record #" + k + " is of class " + records.get(k).getClass().getSimpleName());

                                Record record = records.get(k);

                                NdefRecord ndefRecord = record.getNdefRecord();

                                byte[] arr = ndefRecord.getPayload();

                                String payload = new String(arr);


                                if(payload.length() > 0){

                                payload = payload.substring(3, payload.length());

                                Log.e(TAG, "payload = " + payload);

                                String[] splitPayload = payload.split(",");

                                String tagType = splitPayload[0];
                                String tagCompany = splitPayload[1];
                                String tagClientID = splitPayload[2];
                                String tagClientName = splitPayload[3];

                                if(! tagClientID.equalsIgnoreCase("0") && tagClientID.length() > 0){

                                    handler.post(new Runnable(){
                                        public void run() {

                                            setContentView(R.layout.successfulnfc);

                                          }
                                        });






                                Intent processPayloadIntent = new Intent(NfcActivity.this, NfcscannerActivity.class);
                                processPayloadIntent.putExtra("payload", payload);
                                processPayloadIntent.putExtra("tagid", tagId);
                                processPayloadIntent.setAction("NFC"); 
                                processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                //processPayloadIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
                                startActivity(processPayloadIntent);
                                finish();
                                overridePendingTransition(0, R.anim.activity_animation_zoom_in);





                                    }else{
                                        Toast.makeText(NfcActivity.this, "Tag data problem/Scan problem.", Toast.LENGTH_LONG).show();

                                        initFailHandler();
                                        failHandler.postDelayed(failRunnable, 1);


                                    }

                                }else{
                                    Toast.makeText(NfcActivity.this, "Tag data problem/Scan problem.", Toast.LENGTH_LONG).show();

                                    initFailHandler();
                                    failHandler.postDelayed(failRunnable, 1);

                                }



                            }
                        } catch (Exception e) {
                            Log.e(TAG, "Problem parsing message", e);
                        }

                    }

                }
            };

        }





    public void initFailHandler(){

          failHandler = new Handler();
          failRunnable = new Runnable() {
                public void run() {

                    returnToMainMenu();

                }

                private void returnToMainMenu() {
                    //Log.e(TAG, "about to return to main menu");

                    try{
                        progressDialog.dismiss();

                    }catch(Exception e){

                        //do nothing
                    }

                    Toast.makeText(NfcActivity.this, "Please check your scanning technique.\nPlease do not hover over tag or swipe...", Toast.LENGTH_LONG).show();

                    failHandler.post(new Runnable(){
                        public void run() {

                            setContentView(R.layout.nfcfail);

                          }
                        });






                    //onBackPressed();
                    Intent processPayloadIntent = new Intent(NfcActivity.this, NfcscannerActivity.class);
                    processPayloadIntent.setAction("QRCODE_ACTION"); 
                    processPayloadIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(processPayloadIntent);
                    finish();
                    //overridePendingTransition(0, R.anim.activity_animation_zoom_in);

                }
            };

        }




    private String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("0x");
        if (src == null || src.length <= 0) {
            return null;
        }

        char[] buffer = new char[2];
        for (int i = 0; i < src.length; i++) {
            buffer[0] = Character.forDigit((src[i] >>> 4) & 0x0F, 16);
            buffer[1] = Character.forDigit(src[i] & 0x0F, 16);
            System.out.println(buffer);
            stringBuilder.append(buffer);
        }

        return stringBuilder.toString();
    }



private class AsyncNfcConnect extends AsyncTask<String, Void, String> {






        @Override
        protected String doInBackground(String... params) {

            NfcActivity.this.nfcConnected = false;
            String result;
            Ndef ndefTag = Ndef.get(tag);

            try {
                Log.e(TAG, "about to test connect()********************************************");
                ndefTag.connect();  // this should already perform an IO operation and should therefore fail if there is no tag
                Log.e(TAG, "Ndef.connect() connected!********************************************");
                NdefMessage ndefMsg = ndefTag.getNdefMessage();  // this reads the current NDEF message from the tag and consequently causes an IO operation

                NfcActivity.this.nfcConnected = true;
                result = "OK";
                return result;

            } catch (Exception e) {
                // there is no tag or communication with tag dropped
                Log.e(TAG, "There a problem with connecting to the tag using Ndef.connect(");
                NfcActivity.this.nfcConnected = false;
                result = "NOTOK";
                return result;
            } finally {
                try {
                    ndefTag.close();
                } catch (Exception e) {
                }
            }


        }



    }//end of Async


}

解决方案

You seem to insist on not handling NFC intents in onNewIntent(). I would suggest that onCreate() and onNewIntent() both call a common procedure for scanning the tag. In that way, both entry points would follow the same code path.

Your claim that the app "jumps out of onCreate" is probably just a figure of speech? What happens is that your tag scanning AsyncNfcConnect runs on a separate thread as a background task (as it should). That task is created in onCreate() and continues running after onCreate() has finished (you could add add a Log statement at the end of onCreate() to check). When the connection with the tag is lost somehow and the tag is rediscovered, onNewIntent() is called, as you observed.

In any case there is no way to prevent this from happening, so your app has to be able to handle it. To detect this and deal with it, you could set some flag inside your activity to indicate that your background task is running or has run. You could also store the information whether an exception has occurred and simply try scanning the tag again when it is rediscovered (this probably requires that you implement the suggestion I made above). If you want to make your app even more failure proof, you could also store the ID of the last scanned tag to positively identify it again when it is rediscovered after you have successfully scanned it (or not). When exceptions keep occurring with the same tag, you could indicate his after a certain number of times to the user (e.g. by suggesting that the device be positioned differently w.r.t. the tag).

这篇关于如何onNewIntent执行之前拦截NFC标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆