首页 > 解决方案 > MVP中的Android NFC阅读器-onNewIntent未触发

问题描述

我有一个有效的 NFC 读写器代码。使用相同的代码,我在另一个遵循 MVP 架构的应用程序中添加了阅读器功能。

活动名为NFCReaderActivity。创建了一个单独的 NFC 类 ( NFCReader),它实现了 Sensor 接口。

该应用程序应该在前台和启动时显示 NFC 标签信息。启动部分工作正常,应用程序启动并读取标签并显示其内容。

但是,在前台,在扫描时,它什么也不做。我只听到扫描哔声,但没有onNewIntent发射。

以下是为前台和启动操作捕获的日志条目。类名有区别:

When not launching
I/ActivityManager: START u0 {act=android.nfc.action.NDEF_DISCOVERED typ=application/com.abc.vi flg=0x14008000 cmp=com.abc.vi/.ui.reader.NFCReader (has extras)} from uid 10038 on display 0

When launching
I/ActivityManager: START u0 {act=android.nfc.action.NDEF_DISCOVERED typ=application/com.abc.vi cmp=com.abc.vi/.ui.reader.NFCReaderActivity (has extras)} from uid 1027 on display 0

活动

创建

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "__onCreate__  " );

        setContentView(R.layout.activity_nfc_reader);

        VI.setNFCReaderActivityContext(this); //VI is the Application class
        ButterKnife.bind(this);

        presenter = new ReaderPresenter(this);
    }

onNewIntent

@Override
    public void onNewIntent(Intent intent) {
        Log.i(TAG, "__onNewIntent__  " );
        // onResume gets called after this to handle the intent
//        setIntent(intent);
        presenter.onNewIntent(intent);
    }

onResume, onPause

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

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

主持人

ReaderPresenter(ReaderContract.View view) {
        this.view = view;
        initSensor();
    }

    @Override
    public void initSensor() {
        nfcReader = new NFCReader(VI.getNFCReaderActivityContext(), this); //VI is the Application class
    }

    @Override
    public void onNewIntent(Intent intent) {
        nfcReader.resolveIntent(intent);
    }


    @Override
    public void onResume() {
        nfcReader.onResume();
    }

    @Override
    public void onPause() {
        nfcReader.onPause();
    }

    @Override
    public void onDestroy() {
        speech.onDestroy();
    }

NFC阅读器

public class NFCReader implements Sensors {

    private static final String TAG = NFCReader.class.getSimpleName();

    private NfcAdapter nfcAdapter;
    private PendingIntent nfcPendingIntent;
    private NFCReaderActivity activity;
    private ReaderPresenter presenter;


    NFCReader(NFCReaderActivity nfcReaderActivity, ReaderPresenter readerPresenter) {
        this.activity = nfcReaderActivity;
        this.presenter = readerPresenter;
        init();
    }

    @Override
    public void init() {
        //Initialize NFC adapter
        nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
        nfcPendingIntent = PendingIntent.getActivity(activity, 0, new Intent(activity,
                getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);
    }

    public void onResume() {
        if (nfcAdapter != null) {

            nfcAdapter.enableForegroundDispatch(activity, nfcPendingIntent, null, null);
            // if NFC not enabled
            if (!nfcAdapter.isEnabled()) {
                new AlertDialog.Builder(activity)
                        .setPositiveButton(activity.getString(R.string.update_setting_btn),
                                (dialog, which) -> {
                                    Intent setNfc = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
                                    activity.startActivity(setNfc);
                                })
                        .setOnCancelListener(
                                dialog -> activity.finish()
                        )
                        .create().show();
            }
            resolveIntent(activity.getIntent());
        } else {
            Toast.makeText(VI.getAppContext(),
                    activity.getString(R.string.error_no_nfc_found), Toast.LENGTH_LONG).show();
        }
    }

    public void onPause() {
        if (nfcAdapter != null) {
            nfcAdapter.disableForegroundDispatch(activity);
        }
    }

    public void resolveIntent(Intent intent){
        Log.i(TAG, "__resolveIntent__");
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
            NdefMessage[] messages = null;
            Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
            if (rawMsgs != null) {
                messages = new NdefMessage[rawMsgs.length];
                for (int i = 0; i < rawMsgs.length; i++) {
                    messages[i] = (NdefMessage) rawMsgs[i];
                }
            }
            if ((messages != null ? messages[0] : null) != null) {
                StringBuilder result = new StringBuilder();
                byte[] payload = messages[0].getRecords()[0].getPayload();
                for (byte aPayload : payload) { 
                    result.append((char) aPayload);
                }
                Log.i(TAG,"Decoded --> "+result.toString());
                presenter.getData(result.toString());
            }
        }
    }
}

显现

 <activity android:name=".ui.reader.NFCReaderActivity">
            <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="@string/mime_type" />
            </intent-filter>
        </activity>

更新
我将所有代码从 NFCReader 类移动到 NFCReaderActivity 并且前台和启动模式都在工作。问题在于 MVP 架构。如何将其转换回 MVP?

标签: javaandroidandroid-intentnfcandroid-mvp

解决方案


您似乎为错误的(实际上是无效的)组件(不是您的活动类)注册了待处理的意图。原因是当您创建PendingIntent分配给 的 时nfcPendingIntent,您用于getClass()获取NFCReader实例的类。相反,您需要使用activity.getClass()来获取活动组件的类。


推荐阅读