How to: Modifying NfcNci.apk to run when screen is turned off on Android Nougat

This guide is for advanced users, please only proceed if you have experience with decompiling apps, and modifying android apps.
You need a rooted android 7.0 phone to apply this mod.

First please install all these programs:

  • smali & baksmali
  • adb
  • zipalign
  • Java Development Kit

When you have all those programs, start by extracting the system files, that have to be modified, by running the following commands in an empty directory:

adb pull /system/framework/arm/
adb pull /system/app/NfcNci/NfcNci.apk
adb pull /system/app/NfcNci/oat/arm64/NfcNci.odex

Now we have all the files needed to modify NfcNci.apk.
To apply the mod, we need to decompile NfcNci.odex, using the following command:

baksmali x -c arm/boot.oat -d arm/ NfcNci.odex -o NfcNci/

Now go to NfcNci/com/android/nfc/ and open NfcService.smali in a text editor, then replace the following strings:

  • android.intent.action.SCREEN_OFF with android.intent.action.SCREEN_OFFA
  • android.intent.action.SCREEN_ON with android.intent.action.SCREEN_ONA
  • android.intent.action.USER_PRESENT with android.intent.action.USER_PRESENTA
  • android.intent.action.USER_SWITCHED with android.intent.action.USER_SWITCHEDA

Then find the first appearance of “if-lt”, and replace the 1st and 2nd parameters like this “if-lt p1, v5, :cond_99″ needs to be “if-lt v5, p1, :cond_99″.
You will probably not encounter the same parameters as me.
Now save and close NfcService.smali
Next up, open ScreenStateHelper.smali in a text editor. In this file, you have to find “.method checkScreenState()” and replace all instances of “const/4 v0, 0x…” with “const/4 v0, 0x3”, this will make the method always say the screen is turned on.
Now save and close ScreenStateHelper.smali and go back to the directory where NfcNci.apk is located.

Now you have to compile the directory NfcNci/ by running this command:

smali a -o classes.dex NfcNci/

Now insert classes.dex into NfcNci.apk using an archive manager.
Then create a zipaligned version of NfcNci.apk using this command:

zipalign -v 4 NfcNci.apk NfcNci_align.apk

Now you just need to copy NfcNci_align.apk to your phone using the following commands:

adb push NfcNci_align.apk /sdcard/NfcNci.apk
adb shell
su
busybox mount -o remount,rw system
mv /system/app/NfcNci/NfcNci.apk /system/app/NfcNci/NfcNci_bak.apk
cp /sdcard/NfcNci.apk /system/app/NfcNci/NfcNci.apk
chmod 755 /system/app/NfcNci/NfcNci.apk
killall com.android.nfc

There might appear a pop up on your phone you have to allow it.

Now NFC should work, when your screen is turned off.
Happy modding!

Lasse Hyldahl Jensen on EmailLasse Hyldahl Jensen on GithubLasse Hyldahl Jensen on GoogleLasse Hyldahl Jensen on InstagramLasse Hyldahl Jensen on LinkedinLasse Hyldahl Jensen on Twitter
Lasse Hyldahl Jensen

13 thoughts on “How to: Modifying NfcNci.apk to run when screen is turned off on Android Nougat

  1. Any chance you could provide a pre smali-baksmali’d version for those of us who are less talented? 😉

    Reply

  2. Ah, I see. Thanks for your response. I just realized that my main problem is that I am on 7.1.1 which does not appear to contain .odex files. Is that true? Am I pointing “adb pull /system/app/NfcNci/oat/arm64/NfcNci.odex” into the wrong directory? This is where I’m stuck. I’d appreciate any help you might be able to throw my way 🙂 Thanks again

    Reply

    1. all newer versions of Android contains the odex files, unless you have upgraded an old device. Which folders exist in “/system/app/NfcNci/oat/” ? and what is the device you are trying to mod?

      Reply

  3. It appears the us no folder called ‘oat’ for NfcNci (in root/system/app/ NfcNci) just an NfcNci.apk and a folder root/system/app/NfcNci/lib/

    I’m attempting this on Pixel XL on NOF27B (7.1.1)

    Reply

    1. If you have Telegram or G+ let me know if you’d prefer it, as it may be easier for us both to correspond

      Reply

  4. since 7.1 Bluetooth unlock: Again in Security > Smart Lock, you have the option to nominate trusted devices, so your Android will unlock when connected to something else. You can nominate Bluetooth devices (like your smartwatch or car Bluetooth) or select an NFC tag.
    SO just configure it and you’re done

    Reply

    1. I just tried it out, there seems to be a couple of disadvantages, Some of which are it doesn’t work with the screen off, it unlocks the device and it reads the tag twice, which makes a trigger task both assigned actions.

      But on the other side, it is much easier to configure than modifying the system files 🙂

      Reply

  5. Hello, thanks for the tutorial. It is very clear and I understand the most part of it, but please, can you explain the purpose of

    “Then find the first appearance of “if-lt”, and replace the 1st and 2nd parameters like this “if-lt p1, v5, :cond_99” changes to “if-lt v5, p1, :cond_99”.”

    That may depend on the android version or even the device manufacturer. According to the SONY stock NFC package it means to change the first -if- condition of the “computeDiscoveryParameters()” method, but its body is different than the one seen here: https://android.googlesource.com/platform/packages/apps/Nfc/+/master/src/com/android/nfc/NfcService.java#1580

    Please, I need some kind of explanation about your statement. You can get a reference here: https://github.com/bamsbamx/NFCScreenOFF

    Reply

    1. You’re absolutely right, for you it should work if you change “if-lt p1, v5, :cond_13” to “if-lt v5, p1, :cond_13”

      Sorry for the late reply & thanks for the credits 🙂

      Reply

      1. It did work without the condition modification actually. The mScreenState field is already. If I am not wrong, the screenState condition will be always SCREEN_STATE_ON, because of the ScreenStateHelper modification. So, it will be bigger than NFC_POLLING_MODE anyways (see https://android.googlesource.com/platform/packages/apps/Nfc/+/master/src/com/android/nfc/NfcService.java#1668), resulting in your modification not letting execute the condition body thus, the mod would not work properly. I think it is better, to make NFC_POLLING_MODE equals STATE_SCREEN_OFF (the smallest value)

        Reply

Leave a Reply