我有一个正在工作的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


活动

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

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

最佳答案

您似乎为错误的(实际上是无效的)组件(而不是活动类)注册了挂起的意图。原因是在创建分配给PendingIntentnfcPendingIntent时,使用getClass()获取NFCReader实例的类。相反,您将需要使用activity.getClass()获取活动组件的类。

10-08 15:06