1

我有一个使用 NFC 的应用程序。我有一个扩展 BaseActivity 的 MainActivity。在 BaseActivity 中,在“onCreate”方法中,我初始化了 nfc。

---- Base Activity ----
....
private void initializeNfc() {
        NfcManager manager = (NfcManager) getSystemService(NFC_SERVICE);
        nfcAdapter = manager.getDefaultAdapter();
        IntentFilter filterNdef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
            try {
                filterNdef.addDataScheme(CipherClient.nfcDataScheme());
                filterNdef.addDataAuthority(CipherClient.nfcDataAuthority(), null);
                filterNdef.addDataPath(CipherClient.nfcDataPath(), PatternMatcher.PATTERN_SIMPLE_GLOB);
            } catch (Exception e) {
                Log.e(TAG, "Errore", e);
                return;
            }
            intents = new IntentFilter[]{filterNdef};
            pending = PendingIntent.getActivity(this, 0, new Intent(getApplicationContext(), getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
            techs = new String[][]{new String[]{NfcF.class.getName()}};

            }

在 MainActivity 我有一个带有 4 个选项卡的滑块,在每个选项卡中我都有一个片段。我可以使用 nfc 的片段只有数字 0(NfcFragment)。

我第一次启动 MainActivity 时,会调用“onCreate”方法并显示第一个片段(FirstFragment)。如果我不在 NfcFragment 中并且我接近一个 nfc 标签,我会得到一个祝酒词,上面写着“移动到 NfcFragment 以使用 nfc”。

---- MainActivity ----

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                Log.i(TAG, "onPageSelected - position: "+position);
                currentTabPosition = position;

                if(position == 0) {
                    // I am in the NFC tab. So I set true the flag
                    if (verifyNfc()) {
                        nfcON = true;
                    }
                }
                else{
                    // I'm not on the nfc tab, so I set false the flag
                    nfcON = false;

                    enableForegroundDispatch();

                }

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

private boolean verifyNfc() {
        boolean nfcEnabled = nfcAdapter.isEnabled();
        if (!nfcEnabled) {
            Log.i(TAG, "NFC not activated");
            // NFC disabled
            Toast....
        }
        return nfcEnabled;
    }

如果我移动到 NfcFragment 并接近一个 nfc 标签,则会调用“onNewIntent”方法并打开一个新活动 (MyNewActivity)。从 MyNewActivity 我按回,“onBackPressed”被调用,我执行“finish()”。

---- MainActivity ----

@Override
    protected void onNewIntent(Intent intent) {
        Log.i(TAG, "onNewIntent");

        if (nfcON) {
            // nfcHandlingInProgress is a variable that checks if you are already using the nfc (in read or write) or is free
            if (!nfcHandlingInProgress) {

                nfcHandlingInProgress = true;
                handleIntent(intent);
            }
            else {

                String message = "NFC already in use, wait a few moments and try again";
                Log.d(TAG, message);
                Toast...
            }
        }
        else {
            // If I am not on the tab that contains the NFC fragment, I do not continue and invite the user to move to this tab.
            String message = "To use the NFC move to the NFC section";
            Log.d(TAG, message);
            Toast...
        }
    }


private void handleIntent(Intent intent) {
        Log.i(TAG, "handleIntent");

..... // if the nfc scheme, data and authority are known, I start a new activity

        nfcHandlingInProgress = false;

        Intent i = new Intent(this, MyNewActivity.class);
        startActivity(i);
    }


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

        disableForegroundDispatch();
    }

public void disableForegroundDispatch(){
        Log.i(TAG, "disableForegroundDispatch");

        try {
            if (nfcAdapter != null) {
                nfcAdapter.disableForegroundDispatch(this);
            }
        }
        catch (Exception e){
            Toast...
        }
    }

从 MyNewActivity 我返回并再次在 MainActivity 中找到自己(它已经实例化,因此不称为“onCreate”而是“onResume”)。

---- MyNewActivity ----

@Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }


---- MainActivity ----

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

       enableForegroundDispatch();

        if(currentTabPosition == 0)
            nfcON = true;
        else
            nfcON = false;
    }

public void enableForegroundDispatch(){
        Log.i(TAG, "enableForegroundDispatch");

        try {
            if (nfcAdapter != null) {
                if (nfcAdapter.isEnabled())
                    nfcAdapter.enableForegroundDispatch(this, pending, intents, techs);
            }
        }
        catch (Exception e){
            Toast...
        }

    }

现在,如果我转到不是 NfcFragment 的片段,它应该显示一个 toast 对吗?相反,不,从任何片段,如果我接近一个 nfc 标签,MyNewActivity 就会打开。问题是 onNewIntent 方法不再被调用,它被绕过了。

我在“onPause”中正确使用了 disableForegroundDispatch 方法,在“onResume”中正确使用了 enableForegroundDispatch 方法。我还使用了标志 FLAG_ACTIVITY_SINGLE_TOP、FLAG_ACTIVITY_SINGLE_TASK 等。

如果我在 MainActivity 的 onResume 方法中重新初始化 nfc,或者如果我在 MyNewActivity 的“onBackPressed”方法中执行 startActivity(this, MainActivity.class),则此行为得到解决,因为调用了 onCreate 方法并且活动的新实例是创建的。但这是一种解决方法,我不想重复初始化 nfc。



---- MyNewActivity ----
// Solution 1 to which I do not want to resort because it is heavy to load 4 tabs together in the main activity
@Override
    public void onBackPressed() {
        super.onBackPressed();
        Intent i = new Intent(this, MainActivity.class);
        startActivity(i);
        finish();
    }



---- MainActivity ----
// Solution 2 that I don't want to use because onResume is called more than once
@Override
    protected void onResume() {
        Log.i(TAG, "onResume");
        super.onResume();

       // NEW NEW NEW
       initializeNFC();     // <----------------------------

       enableForegroundDispatch();

        if(currentTabPosition == 0)
            nfcON = true;
        else
            nfcON = false;
    }

请有人给我一个解决方案来初始化 nfc 并始终使用 onNewIntent 方法拦截 nfc 标签?即使我从 MyNewActivity 回到 MainActivity ,所以称为 onResume 方法而不是 onCreate 方法。

有什么建议么 ?非常感谢

4

0 回答 0