NfcAdapter.getDefaultAdapter(this) возвращает null, но NFC работает

мое приложение использует чтение NFC на заднем плане и на переднем плане. Для информации о пользователе я использую CountDownTimer (120 * 1000, 5 * 1000) в своей деятельности и метод onTick (long l) для проверки состояния NFC каждые 5 секунд. Иногда (на Android 4.2.2, как говорит мой клиент, со мной этого никогда не случалось) NfcAdapter.getDefaultAdapter(BaseActivity.this) возвращает null, но чтение NFC в фоновом и переднем плане все еще работает! Выключение и включение не помогает. Переустановка помогает.

Чтение BG через манифест:

<activity
            android:name=".activity.NfcReaderActivity"
            android:launchMode="singleTask"
            android:screenOrientation="portrait">

            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="http" />
                <data android:scheme="https" />
            </intent-filter>

            <intent-filter>
                <action android:name="android.nfc.action.TECH_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

            <meta-data
                android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />
        </activity>

Чтение FG через намерение:

IntentFilter ndef = new IntentFilter();
ndef.addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
ndef.addCategory(Intent.CATEGORY_DEFAULT);

try {
    ndef.addDataType("*/*");
} catch (IntentFilter.MalformedMimeTypeException e) {
    throw new RuntimeException("fail", e);
}

mNfcAdapter = NfcAdapter.getDefaultAdapter(this.mActivity);
mNfcPendingIntent = PendingIntent.getActivity(
        this.mActivity, 0,
        new Intent(this.mActivity, this.mActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
        0
);
mNfcFilters = new IntentFilter[] {
        ndef
};
mNfcTechLists = new String[][] { new String[] {
        // White solid cards
        NfcA.class.getName()
} };

if (mNfcAdapter != null) {
    mNfcAdapter.enableForegroundDispatch(
            mActivity,
            mNfcPendingIntent,
            mNfcFilters,
            mNfcTechLists
    );
}

Похоже, что NfcAdapter хранится или заморожен. У кого-нибудь есть такой же опыт? Где может быть проблема?


После некоторого тестирования у меня есть новые наблюдения. Это происходит только после перезагрузки. Хотя мое приложение запускалось дважды и присутствовали некоторые взаимоблокировки потоков, но этого не произошло. Если я запускаю CountDownTimer (вызывается в методе onCreate) с некоторой задержкой (3 или более секунд), он работает, а getDefaultAdapter НЕ равен нулю. Если задержка запуска слишком мала (2 или менее секунд), я нашел это сообщение в журналах: «E/NFC: не удалось получить службу NFC», а затем getDefaultAdapter возвращает значение null, пока я не переустановлю свое приложение.

Поэтому короткая задержка перед выполнением CountDownTimer (возможно, лучше будет Timer.schedule(..., delay, interval)) является временным решением, но если кто-то знает, какое решение лучше, дайте мне знать.


person Petr Pošvic    schedule 06.06.2016    source источник
comment
Как вы узнали, что NfcAdapter.getDefaultAdapter(this) возвращает null? Где в вашем приложении вы вызываете приведенный выше код? Является ли mActivity активностью переднего плана, когда вы вызываете код? Вы запросили разрешение NFC?   -  person Michael Roland    schedule 07.06.2016
comment
Я вызываю getDefaultAdapter в mActivity в методе onTick (CountDownTimer). Там я установил видимость для ImageView (исчез, если NFC включен, видим, если NFC выключен). Да, mActivity находится на переднем плане. У меня есть разрешение NFC в манифесте.   -  person Petr Pošvic    schedule 08.06.2016
comment
Итак, часть if (mNfcAdapter != null) { mNfcAdapter.enableForegroundDispatch [...] вызывается сразу после mNfcAdapter = NfcAdapter.getDefaultAdapter(this.mActivity); или они вызываются из разных методов? Может ли быть так, что ваша деятельность воссоздана в какой-то момент между ними?   -  person Michael Roland    schedule 08.06.2016
comment
Оба вызываются в методе onCreate. Но NfcAdapter.getDefaultAdapter(this.mActivity); вызывается в CountDownTimer каждые 5 секунд и возвращает null. Может быть, он возвращает null и в onCreate, я не знаю. Я думаю, что чтение NFC на переднем плане перестает работать, getDefaultAdapter возвращает значение null, но чтение NFC в фоновом режиме работает. Является ли это возможным?   -  person Petr Pošvic    schedule 10.06.2016
comment
Затем снова: уверены ли вы, что ваша активность все еще выполняется (т. е. находится между методами жизненного цикла onResume() и onPause()) во время выполнения обратного вызова таймера? И что ваша активность не была воссоздана (возможно, аннулирование ссылки в mActivity) какое-то время между ними?   -  person Michael Roland    schedule 10.06.2016
comment
у меня точно такая же проблема... Вы нашли причину?   -  person BvuRVKyUVlViVIc7    schedule 02.11.2016
comment
Нет, но появляется после перезагрузки на RugGear500. Другие устройства в порядке. Может быть, что-то не так с жизненным циклом?   -  person Petr Pošvic    schedule 04.12.2016


Ответы (1)


Вероятно использовалось на эмуляторе и на эмуляторе ничего нельзя сделать с NFC.

person Mladen Rakonjac    schedule 30.07.2017