安卓:你如何禁用扫描NFC标签,当你的应用程序重开? [英] Android: how do you disable that your app reopens when scanning a NFC tag?

查看:1369
本文介绍了安卓:你如何禁用扫描NFC标签,当你的应用程序重开?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个Android应用程序,从MIFARE经典卡(4K)读取数据。我已经编辑我的Andr​​oidManifest.xml文件,使应用程序被启动(或者我可以选择其他应用程序,使用NFC)。但是,当我的应用程序双头呆,我抱着我的卡旁边,我的手机,它给人的弹出再次在那里我可以选择要打开的应用程序。经过一番研究,我发现,我需要编辑功能: onNewIntent ,因为这是当你扫描,当你的应用程序正在运行一个标记,被调用的函数

这是我的code:(当我扫描我的名片,在 handleIntent 函数的第二行致祝酒辞曰: ACTION_TECH_DISCOVERED

 包be.khleuven.aanwezigheidssysteem;

进口android.app.Activity;
进口android.app.PendingIntent;
进口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.Bundle;
进口android.util.Log;
进口android.widget.TextView;
进口android.widget.Toast;
进口android.content.IntentFilter.MalformedMimeTypeException;

进口java.io.UnsupportedEncodingException;
进口java.util.Arrays中;




公共类登录扩展活动{
公共静态最后弦乐MIME_TEXT_PLAIN =text / plain的;
公共静态最终字符串变量=NfcDemo;

私人TextView的mTextView;
私人NfcAdapter mNfcAdapter;

@覆盖
保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_login);

    mTextView =(TextView中)findViewById(R.id.textView_explanation);

    mNfcAdapter = NfcAdapter.getDefaultAdapter(本);


    如果(mNfcAdapter == NULL){
        //到此为止,我们肯定需要NFC
        Toast.makeText(这一点,此设备不支持NFC。Toast.LENGTH_LONG).show();
        //完();
        返回;

    }

    如果(!mNfcAdapter.isEnabled()){
        mTextView.setText(NFC是禁用的。);
    } 其他 {
        mTextView.setText(R.string.explanation);
    }

    handleIntent(getIntent());
}

@覆盖
保护无效onResume(){
    super.onResume();

    / **
     *重要的是,该活动是在前台(恢复)。除此以外
     *一个IllegalStateException异常。
     * /
    setupForegroundDispatch(这一点,mNfcAdapter);
}

@覆盖
保护无效的onPause(){
    / **
     *在onPause之前调用它,否则,一则抛出为好。
     * /
    stopForegroundDispatch(这一点,mNfcAdapter);

    super.onPause();
}

@覆盖
公共无效onNewIntent(意向意图){
    / **
     *这个方法被调用,当一个新的意图获取与当前的活动实例相关联。
     而不是创建一个新的活动*,onNewIntent将被调用。欲了解更多信息,看看
     *在文档。
     *
     *在我们的情况下,这方法被调用,当用户附加一个标记到设备。
     * /
    handleIntent(意向);
}

私人无效handleIntent(意向意图){
    串动= intent.getAction();
    Toast.makeText(这一点,动作,Toast.LENGTH_LONG).show();
    如果(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(动作)){

        字符串类型= intent.getType();
        如果(MIME_TEXT_PLAIN.equals(类型)){

            标签标记= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            新NdefReaderTask()执行(标签);

        } 其他 {
            Log.d(TAG,错误的MIME类型:+型);
        }
    }否则如果(NfcAdapter.ACTION_TECH_DISCOVERED.equals(动作)){
        Toast.makeText(这一点,泽zijn gelijk,Toast.LENGTH_LONG).show();
        //如果我们仍然用科技发现的意图
        标签标记= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        的String [] techList = tag.getTechList();
        串searchedTech = Ndef.class.getName();

        对于(字符串科技:techList){
            如果(searchedTech.equals(高科技​​)){
                新NdefReaderTask()执行(标签);
                打破;
            }
        }
        TextView的T =(TextView中)findViewById(R.id.textView_explanation);
        t.se​​tText(的Mooi kaartje希济daar);
    }

    否则如果(NfcAdapter.ACTION_TAG_DISCOVERED.equals(动作)){

        //如果我们仍然用科技发现的意图
        标签标记= intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        的String [] techList = tag.getTechList();
        串searchedTech = Ndef.class.getName();

        对于(字符串科技:techList){
            如果(searchedTech.equals(高科技​​)){
                新NdefReaderTask()执行(标签);
                打破;
            }
        }
    }
    如果(NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())){
        TextView中的TextView =(TextView中)findViewById(R.id.textView_explanation);
        textView.setText(你好NFC标签!);
    } 其他 {
        // 忽略
    }

}

公共静态无效setupForegroundDispatch(最终活动活动,NfcAdapter适配器){
    最终意向意图=新的意图(activity.getApplicationContext(),activity.getClass());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    最终PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(),0,意图,0);

    IntentFilter的[]过滤器=新的IntentFilter [1];
    的String [] [] techList =新的String [] [] {};

    //注意,这是相同的过滤器如在我们的清单。
    滤波器[0] =新的IntentFilter();
    滤波器[0] .addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
    滤波器[0] .addCategory(Intent.CATEGORY_DEFAULT);
    尝试 {
        滤波器[0] .addDataType(MIME_TEXT_PLAIN);
    }赶上(MalformedMimeTypeException E){
        抛出新的RuntimeException(请检查您的MIME类型。);
    }

    adapter.enableForegroundDispatch(活动,pendingIntent,过滤器,techList);
}

公共静态无效stopForegroundDispatch(最终活动活动,NfcAdapter适配器){
    adapter.disableForegroundDispatch(活动);
}

私有类NdefReaderTask扩展的AsyncTask<标签,太虚,字符串> {

    @覆盖
    保护字符串doInBackground(标签... PARAMS){
        标签标签= PARAMS [0];

        NDEF NDEF = Ndef.get(标签);
        如果(NDEF == NULL){
            // NDEF不受此标签的支持。
            返回null;
        }

        NdefMessage ndefMessage = ndef.getCachedNdefMessage();

        NdefRecord []记录= ndefMessage.getRecords();
        对于(NdefRecord n​​defRecord:记录){
            如果(ndefRecord.getTnf()== NdefRecord.TNF_WELL_KNOWN&安培;&安培;满足Arrays.equals(ndefRecord.getType(),NdefRecord.RTD_TEXT)){
                尝试 {
                    返回READTEXT(ndefRecord);
                }赶上(UnsupportedEncodingException E){
                    Log.e(TAG,不支持的编码,E);
                }
            }
        }

        返回null;
    }

}
}
 

解决方案

您已经regisered的前景调度系统。这就是你通常会给予您的应用程序precedence超过其他已注册的​​应用程序,而这是前台应用程序。但是,只有注册的前景派出了包含NDEF消息,用文字记录(或类型的文本/ MIME类型的记录平原),这似乎并不适用于你的标签开始标签:

 过滤器[0] .addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
滤波器[0] .addCategory(Intent.CATEGORY_DEFAULT);
滤波器[0] .addDataType(MIME_TEXT_PLAIN);
 

相反,你可以注册赶上与前景调度系统是任何标记(您可以在以后自动删除你不感兴趣的标签):

 公共静态无效setupForegroundDispatch(最终活动活动,NfcAdapter适配器){
    最终意向意图=新的意图(活动,activity.getClass());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    最终PendingIntent pendingIntent = PendingIntent.getActivity(活性,0,意图,0);

    adapter.enableForegroundDispatch(活动,pendingIntent,NULL,NULL);
}
 

另外,你可以注册使用 NfcAdapter.enableForegroundDispatch()方法的最后两个参数,一个更具体的类型。

I'm writing an android application that reads data from a Mifare Classic card (4k). I have edited my AndroidManifest.xml file so that the app gets started (or I can choose another app that uses NFC). But when my app is openend and I hold my card next to my phone, it gives the popup again where I can choose which app to open. After some research I have found that I need to edit the function: onNewIntent, because this is the function that gets called when you scan a tag when your app is running.

This is my code: (When I scan my card, the toast on the second line of the handleIntent function reads: ACTION_TECH_DISCOVERED.)

package be.khleuven.aanwezigheidssysteem;

import android.app.Activity;
import android.app.PendingIntent;
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.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import android.content.IntentFilter.MalformedMimeTypeException;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;




public class Login extends Activity {
public static final String MIME_TEXT_PLAIN = "text/plain";
public static final String TAG = "NfcDemo";

private TextView mTextView;
private NfcAdapter mNfcAdapter;

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

    mTextView = (TextView) findViewById(R.id.textView_explanation);

    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()) {
        mTextView.setText("NFC is disabled.");
    } else {
        mTextView.setText(R.string.explanation);
    }

    handleIntent(getIntent());
}

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

    /**
     * It's important, that the activity is in the foreground (resumed). Otherwise
     * an IllegalStateException is thrown.
     */
    setupForegroundDispatch(this, mNfcAdapter);
}

@Override
protected void onPause() {
    /**
     * Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
     */
    stopForegroundDispatch(this, mNfcAdapter);

    super.onPause();
}

@Override
public void onNewIntent(Intent intent) {
    /**
     * This method gets called, when a new Intent gets associated with the current activity instance.
     * Instead of creating a new activity, onNewIntent will be called. For more information have a look
     * at the documentation.
     *
     * In our case this method gets called, when the user attaches a Tag to the device.
     */
    handleIntent(intent);
}

private void handleIntent(Intent intent) {
    String action = intent.getAction();
    Toast.makeText(this, action, Toast.LENGTH_LONG).show();
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {

        String type = intent.getType();
        if (MIME_TEXT_PLAIN.equals(type)) {

            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            new NdefReaderTask().execute(tag);

        } else {
            Log.d(TAG, "Wrong mime type: " + type);
        }
    } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
        Toast.makeText(this, "Ze zijn gelijk", Toast.LENGTH_LONG).show();
        // In case we would still use the Tech Discovered Intent
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String[] techList = tag.getTechList();
        String searchedTech = Ndef.class.getName();

        for (String tech : techList) {
            if (searchedTech.equals(tech)) {
                new NdefReaderTask().execute(tag);
                break;
            }
        }
        TextView t = (TextView) findViewById(R.id.textView_explanation);
        t.setText("Mooi kaartje heb je daar");
    }

    else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {

        // In case we would still use the Tech Discovered Intent
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String[] techList = tag.getTechList();
        String searchedTech = Ndef.class.getName();

        for (String tech : techList) {
            if (searchedTech.equals(tech)) {
                new NdefReaderTask().execute(tag);
                break;
            }
        }
    }
    if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
        TextView textView = (TextView) findViewById(R.id.textView_explanation);
        textView.setText("Hello NFC tag!");
    } else {
        // ignore
    }

}

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);
}

private class NdefReaderTask extends AsyncTask<Tag, Void, String> {

    @Override
    protected String doInBackground(Tag... params) {
        Tag tag = params[0];

        Ndef ndef = Ndef.get(tag);
        if (ndef == null) {
            // NDEF is not supported by this Tag.
            return null;
        }

        NdefMessage ndefMessage = ndef.getCachedNdefMessage();

        NdefRecord[] records = ndefMessage.getRecords();
        for (NdefRecord ndefRecord : records) {
            if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
                try {
                    return readText(ndefRecord);
                } catch (UnsupportedEncodingException e) {
                    Log.e(TAG, "Unsupported Encoding", e);
                }
            }
        }

        return null;
    }

}
}

解决方案

You already regisered for the foreground dispatch system. This is how you would typically give your app precedence over other registered apps while it is the foreground application. However, you only registered the foreground dispatch for tags that contain an NDEF message that starts with a Text record (or a MIME type record of type text/plain), which seems not to apply to your tag:

filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
filters[0].addDataType(MIME_TEXT_PLAIN);

Instead, you could register to catch just any tag with the foreground dispatch system (you can later silently drop tags that you are not interested in):

public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
    final Intent intent = new Intent(activity, activity.getClass());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    final PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);

    adapter.enableForegroundDispatch(activity, pendingIntent, null, null);
}

Alternatively, you could register for a more specific type using the last two parameters of the NfcAdapter.enableForegroundDispatch() method.

这篇关于安卓:你如何禁用扫描NFC标签,当你的应用程序重开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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