简体   繁体   English

全屏启动器应用程序来自后台后,Android NFC读取失败

[英]Android NFC read fails after fullscreen launcher app comes from background

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. 我的应用程序是一个启动程序,我在安装后立即进行默认设置,它确实在第一次启动时读取NFC标签而没有问题,但如果我锁定手机并解锁它(此时我的应用程序已经在屏幕上并且onResume()被叫)应用程序停止读取标签(当手机读取标签时播放不同的声音,我猜这是NFC失败声音)并且不调用onNewIntent(Intent intent)

I already tried to make my filters and intents being activity scoped instead of local (removed from setupForegroundDispatch ) but stills the same problem. 我已经尝试使我的过滤器和意图成为活动作用域而不是本地(从setupForegroundDispatch删除)但仍然存在同样的问题。 If I reopen the app (kill and start again) then the NFC reader does read right. 如果我重新打开应用程序(杀死并重新开始),那么NFC阅读器就会正确读取。

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. 在logcat上没有例外,NFC读取的甚至没有传送到我的应用程序。 (After it gets back from the background and the phone reads a NFC not even the onPause(), onResume() are triggered on my application) (在它从后台返回并且手机读取NFC甚至没有onPause()之后,onResume()在我的应用程序上被触发)

So far seens it's related to my application being a launcher, although I didn't find anything about this restriction. 到目前为止,它与我的应用程序是一个启动器有关,虽然我没有发现任何有关此限制的内容。

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 这个应用程序是一个完整的全屏幕(公司的内部应用程序)所以在我的onCreate()我有各种标志来保持应用程序在屏幕上,并尽可能避免锁定屏幕上的键盘锁(以避免用户转到其他应用程序)和这是问题,我的应用程序了

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). 并且由于某种原因阻止键盘保护显示(通过锁定屏幕运行应用程序)禁用NFC传送到应用程序(出于安全原因,我猜)。 Since this is an internal app (and all the phones are pre seted by the IT team) the solution was to manually remove the keyguard from lock screen by phone settings and remove the flags 由于这是一个内部应用程序(并且所有手机都由IT团队预先安装),解决方案是通过电话设置从锁定屏幕手动移除键盘锁并删除标记

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. 因此,每次用户锁定和解锁手机时,系统都会再次启用NFC阅读器。

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

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