简体   繁体   English

MVP 中的 Android NFC 阅读器 - onNewIntent 未触发

[英]Android NFC Reader in MVP - onNewIntent not firing

I have a working NFC reader/writer code.我有一个有效的 NFC 读取器/写入器代码。 Using the same code, I added the reader function in another app which is following MVP architecture.使用相同的代码,我在另一个遵循 MVP 架构的应用程序中添加了阅读器功能。

The activity is named NFCReaderActivity .该活动名为NFCReaderActivity A separate NFC class is created ( NFCReader ), which implements Sensor interface.创建了一个单独的 NFC 类 ( NFCReader ),它实现了 Sensor 接口。

The app is supposed to work both in the foreground and launch showing the NFC tag info.该应用程序应该在前台运行和启动时显示 NFC 标签信息。 The launch part is working fine and app launches and reads the tag and shows its content.启动部分工作正常,应用程序启动并读取标签并显示其内容。

However, in the foreground, on scanning, it does nothing.然而,在前台,在扫描时,它什么也不做。 I only hear the scan beep but no onNewIntent is firing.我只听到扫描哔声,但没有onNewIntent触发。

Below are the log entries captured for foreground and launch actions.以下是为前台和启动操作捕获的日志条目。 There is a difference in the class names:类名有区别:

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

Activity活动

onCreate在创建

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

Presenter主持人

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

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

Manifest显现

 <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>

UPDATE更新
I moved all the code from NFCReader class to NFCReaderActivity and both foreground and launch modes are working.我将所有代码从 NFCReader 类移动到 NFCReaderActivity 并且前台和启动模式都在工作。 The issue is with MVP architecture.问题在于 MVP 架构。 How to convert it back to MVP?如何将其转换回MVP?

You seem to register the pending intent for the wrong (actually an invalid) component (not your activity class).您似乎为错误的(实际上是无效的)组件(不是您的活动类)注册了待处理的意图。 The reason is that when you create the PendingIntent that you assign to nfcPendingIntent , you use getClass() to obtain the class of the NFCReader instance.原因是当您创建分配给nfcPendingIntentPendingIntent时,您使用getClass()获取NFCReader实例的类。 Instead you would need to use activity.getClass() to obtain the class of your activity component.相反,您需要使用activity.getClass()来获取您的活动组件的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM