Android NFC Reader в MVP - onNewIntent не запускается - PullRequest
0 голосов
/ 04 мая 2018

У меня есть рабочий код для чтения / записи NFC. Используя тот же код, я добавил функцию чтения в другом приложении, которое соответствует архитектуре MVP.

Деятельность называется NFCReaderActivity. Создается отдельный класс NFC (NFCReader), который реализует интерфейс датчика.

Приложение должно работать как на переднем плане, так и при запуске, показывая информацию о теге 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();
    }

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

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
Я переместил весь код из класса NFCReader в NFCReaderActivity и оба режима переднего плана и запуска работают. Проблема с архитектурой MVP. Как конвертировать его обратно в MVP?

1 Ответ

0 голосов
/ 04 мая 2018

Вы, кажется, зарегистрировали ожидающее намерение для неправильного (фактически недопустимого) компонента (не вашего класса активности). Причина в том, что когда вы создаете PendingIntent, который вы присваиваете nfcPendingIntent, вы используете getClass(), чтобы получить класс экземпляра NFCReader. Вместо этого вам нужно будет использовать activity.getClass(), чтобы получить класс компонента активности.

...