Android NFC read fails after fullscreen launcher app comes from background

Ra.cavalieri :

My app is a launcher that I make the default right after the installation and it does read NFC tags without problems on the first launch but if I lock the phone and them unlock it (at this point my app is already on screen and onResume() is called) the app stops to read the tags (a different sound is played when an tag is read by the phone, I guess it's the NFC fail sound) and the onNewIntent(Intent intent) is not called.

I already tried to make my filters and intents being activity scoped instead of local (removed from setupForegroundDispatch) but stills the same problem. If I reopen the app (kill and start again) then the NFC reader does read right.

So below is my logic:

NfcAdapter nfcAdapter;

@Override
    protected void onResume() {
        super.onResume();

        if (nfcAdapter == null){
            nfcAdapter=NfcAdapter.getDefaultAdapter(this);
        }
        setupForegroundDispatch(this, nfcAdapter);
    }
public static void setupForegroundDispatch(Activity activity, NfcAdapter adapter) {
        final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());

        final PendingIntent pendingIntent = PendingIntent.getActivity(
                activity.getApplicationContext(), 0, intent, 0);

        IntentFilter[] filters = new IntentFilter[2];
        String[][] techList = new String[][]{};

        filters[0] = new IntentFilter();
        filters[0].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
        filters[1] = new IntentFilter();
        filters[1].addAction(NfcAdapter.ACTION_TECH_DISCOVERED);

        adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
    }
@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        String action = intent.getAction();
        if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) ||
                NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            if (tag != null) {
                 //do my logic here
            }
        }
    }
@Override
    protected void onPause() {
        super.onPause();
        nfcAdapter.disableForegroundDispatch(this);
    }

My manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="br.org.company.app">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
    <uses-permission android:name="android.permission.STATUS_BAR" />
    <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
    <uses-permission android:name="android.permission.PREVENT_POWER_KEY" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-permission android:name="android.permission.REORDER_TASKS" />
    <uses-permission android:name="android.permission.NFC" />

    <uses-feature
        android:name="android.hardware.nfc"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:sharedUserId="android.uid.system"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar"
        android:versionName="1.2.1xdk"
        android:usesCleartextTraffic="true">
        <meta-data
            android:name="com.google.android.actions"
            android:resource="@xml/actions" />

        <receiver android:name=".receivers.GpsLocationReceiver">
            <intent-filter>
                <action android:name="android.location.PROVIDERS_CHANGED" />

                <category android:name="android.intent.category.DEFAULT" />

                <action android:name="android.location.LocationManager.KEY_LOCATION_CHANGED" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".receivers.PassiveLocationChangedReceiver"
            android:enabled="true">
            <intent-filter>
                <action android:name="android.location.LocationManager.KEY_LOCATION_CHANGED" />
            </intent-filter>
        </receiver>
        <receiver
            android:name=".receivers.BootReceiver"
            android:enabled="true"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.BOOTUP_COMPLETE" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
        </receiver>
        <receiver android:name=".receivers.MyWakefulReceiver" />
        <receiver android:name=".receivers.InternetConnectionReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.WIFI_STATE_CHANGE" />
            </intent-filter>
        </receiver>
        <receiver android:name=".receivers.IncomingCall">
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>

        <activity
            android:name=".FirstScreenActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:screenOrientation="portrait"
            android:sharedUserId="android.uid.system"
            android:soundEffectsEnabled="true"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".FullscreenActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:screenOrientation="portrait"
            android:sharedUserId="android.uid.system"
            android:soundEffectsEnabled="true"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.CALL_BUTTON" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.nfc.action.TAG_DISCOVERED" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />

                <data android:mimeType="text/pg" />
            </intent-filter>

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

        <receiver
            android:name=".AppDeviceAdmin"
            android:description="@string/app_name"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_DEVICE_ADMIN">
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/app_device_admin" />
            <intent-filter>
                <action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE" />
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
        </receiver>

    </application>

</manifest>

On logcat there's no exceptions, seens that the NFC reads are not even delivered to my application. (After it gets back from the background and the phone reads a NFC not even the onPause(), onResume() are triggered on my application)

So far seens it's related to my application being a launcher, although I didn't find anything about this restriction.

Ra.cavalieri :

So I found an answer to my problem; This app is a total fullscreen (internal app of the company) so in my onCreate() I had various flags to keep the app on screen and to avoid the keyguard on lock screen whenever possible (to avoid users to go to other apps) and that was the problem, my app had

WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
WindowManager.LayoutParams.FLAG_FULLSCREEN

and for some reason preventing the keyguard to show up (run the app over the lock screen) disables the NFC delivery to the app (for security reasons, I guess). Since this is an internal app (and all the phones are pre seted by the I.T team) the solution was to manually remove the keyguard from lock screen by phone settings and remove the flags

WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD

so everytime the user locks and unlocks the phone the sistem enables the NFC reader again.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=126999&siteId=1