0

I have an NFC TAG scanner application which works fine and scans the tag and i can also read and write into tags without any issues , the only issue is that when i change the app package name and start the code , the nfc no longer works and scans tags , but when i revert to the other package name it works fine , any reason why and what could be wrong , Thank you in advance

class ActivateActivity : AppCompatActivity() {
    private lateinit var binding : ActivityActivateScreenBinding
    lateinit var writeTagFilters: Array<IntentFilter>
    var nfcAdapter: NfcAdapter? = null
    var pendingIntent: PendingIntent? = null
    var writeMode = false
    var myTag: Tag? = null
    var actualMsg = ""
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityActivateScreenBinding.inflate(layoutInflater)
        setContentView(binding.root)


        binding.btnActivate.setOnClickListener {
            val organizationId = binding.organizationIdEdit.text.toString()
            val nfcMsg = binding.txtNFCMessage.text.toString()
            actualMsg = DOMAIN + organizationId + ucync + nfcMsg

            try {
                if(myTag == null){
                    Toast.makeText(this, ERROR_DETECTED,Toast.LENGTH_LONG).show()
                } else {
                     write(actualMsg,myTag)
                    Toast.makeText(this, WRITE_SUCCESS,Toast.LENGTH_LONG).show()
                }
            }
            catch (e : IOException){
                Toast.makeText(this, WRITE_ERROR, Toast.LENGTH_LONG).show()
                e.printStackTrace()
            }
            catch (e: FormatException){
                Toast.makeText(this, WRITE_ERROR, Toast.LENGTH_LONG).show()
                e.printStackTrace()
            }

        }

        nfcAdapter = NfcAdapter.getDefaultAdapter(this)
        if (nfcAdapter == null) {
            // Stop here, we definitely need NFC
            Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show()
            finish()
        }

        //For when the activity is launched by the intent-filter for android.nfc.action.NDEF_DISCOVERE
        readFromIntent(intent)
        pendingIntent = PendingIntent.getActivity(this, 0, Intent(this, javaClass)
            .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
            PendingIntent.FLAG_IMMUTABLE)
        val tagDetected = IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
        tagDetected.addCategory(Intent.CATEGORY_DEFAULT)
        writeTagFilters = arrayOf(tagDetected)
    }


    /******************************************************************************
     * Read From NFC Tag
     ****************************************************************************/
    private fun readFromIntent(intent: Intent) {
        val action = intent.action
        if (NfcAdapter.ACTION_TAG_DISCOVERED == action || NfcAdapter.ACTION_TECH_DISCOVERED == action || NfcAdapter.ACTION_NDEF_DISCOVERED == action) {
            myTag = intent.getParcelableExtra<Parcelable>(NfcAdapter.EXTRA_TAG) as Tag?
            val rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
            val msgs = mutableListOf<NdefMessage>()
            if (rawMsgs != null) {
                for (i in rawMsgs.indices) {
                    msgs.add(i, rawMsgs[i] as NdefMessage)
                }
                buildTagViews(msgs.toTypedArray())
            }
        }
    }
    private fun buildTagViews(msgs: Array<NdefMessage>) {
        if (msgs.isEmpty()) return
        val text: String
        val payload = msgs[0].records[0].payload
        val textEncoding: Charset = if ((payload[0] and 128.toByte()).toInt() == 0) Charsets.UTF_8 else Charsets.UTF_16 // Get the Text Encoding
        val languageCodeLength: Int = (payload[0] and 51).toInt() // Get the Language Code, e.g. "en"
        try {
            // Get the Text
            text = String(payload, languageCodeLength + 1, payload.size - languageCodeLength - 1, textEncoding)
            Log.d("VALUE","VALUE IS " + text)
        } catch (e: UnsupportedEncodingException) {
            Log.e("UnsupportedEncoding", e.toString())
        }
    }


    /******************************************************************************
     * Write to NFC Tag
     ****************************************************************************/
    private fun write(msg : String , tag : Tag?){
        val records = arrayOf(createRecord(msg))
        val message = NdefMessage(records)
        // Get an instance of Ndef for the tag.
        val ndef = Ndef.get(tag)
        // Enable I/O
        ndef.connect()
        // Write the message
        ndef.writeNdefMessage(message)
        // Close the connection
        ndef.close()
    }
    @Throws(UnsupportedEncodingException::class)
    private fun createRecord(text: String): NdefRecord {
        val lang = "en"
        val textBytes = text.toByteArray()
        val langBytes = lang.toByteArray(charset("US-ASCII"))
        val langLength = langBytes.size
        val textLength = textBytes.size
        val payload = ByteArray(1 + langLength + textLength)

        // set status byte (see NDEF spec for actual bits)
        payload[0] = langLength.toByte()

        // copy langbytes and textbytes into payload
        System.arraycopy(langBytes, 0, payload, 1, langLength)
        System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength)
        return NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, ByteArray(0), payload)
    }


    /**
     * For reading the NFC when the app is already launched
     */
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        readFromIntent(intent)
        if (NfcAdapter.ACTION_TAG_DISCOVERED == intent.action) {
            myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
        }
    }

    public override fun onPause() {
        super.onPause()
        writeModeOff()
    }

    public override fun onResume() {
        super.onResume()
        writeModeOn()
    }

    /******************************************************************************
     * Enable Write and foreground dispatch to prevent intent-filter to launch the app again
     ****************************************************************************/
    private fun writeModeOn() {
        writeMode = true
        nfcAdapter!!.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null)
    }

    /******************************************************************************
     * Disable Write and foreground dispatch to allow intent-filter to launch the app
     ****************************************************************************/
    private fun writeModeOff() {
        writeMode = false
        nfcAdapter!!.disableForegroundDispatch(this)
    }
 <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.NFC"/>
    <uses-feature android:name="android.hardware.nfc"
        android:required="true"/>

    <application
        android:name=".BaseApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.UcyncBusiness"
        tools:targetApi="31">
        <activity
            android:name=".ui.ActivateActivity"
            android:exported="false">
            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
        <activity
            android:name=".ui.HomeActivity"
            android:exported="false">

            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
            <meta-data
                android:name="android.nfc.action.TECH_DISCOVERED"
                android:resource="@xml/nfc_tech_filter" />

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
        <activity
            android:name=".ui.SplashActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
        <activity android:name=".MainActivity" />
    </application>

Taki
  • 3,290
  • 1
  • 16
  • 41
  • Did you rename your package properly ? did you check you package name in Gradle and Manifest too ? – Mokhtar Abdelhalim Jan 01 '23 at 13:47
  • @MokhtarAbdelhalim Yeah and it is weird it does not work with new package but when i set the old one back , it works fine – Taki Jan 01 '23 at 13:49
  • Can you rename to new package and post the name of the new package, then show your Gradle and Manifest file to check it – Mokhtar Abdelhalim Jan 01 '23 at 13:56
  • The code shown in the question doesn't contain any (relevant) interaction with the android nfc api. Specifically readFromIntent and buildTagViews don't do anything. – Michael Roland Jan 01 '23 at 15:44
  • I guess this code is just using the manifest entries to get sent an Intent by the NFC system service, you need to post your manifest xml file after you have changed the package name. I also suggest that you manually uninstall the old named App before you install the App with the new package name (Don't trust Android Studio to do a re-install correctly) – Andrew Jan 01 '23 at 16:14
  • @MichaelRoland I have added more code , please check it out – Taki Jan 01 '23 at 16:28
  • Ok, so what does your app do and what would you expect it to do instead? – Michael Roland Jan 02 '23 at 09:07
  • @MichaelRoland It actually writes into nfc tags and reads from them , i have the original code which works fine , but whenever i change the package name , nfc stops working , i do not understand why , i have tried different packages but no luck – Taki Jan 02 '23 at 15:45
  • "stops working" isn't really helpful. What is your observed behavior before and after (or observed vs expected). If writing into a tag us the desired behavior, you will need to redesign your application logic. You simply can't reliably store a tag handle for later use. Writing to a tag upon button press is a no-go and it's pure luck if that works for some users (regardless of the package name). – Michael Roland Jan 02 '23 at 18:46
  • Also using the `Intent` based system with Manifest filters and `enableForegroundDispatch` for writing to Tags in real life is very unreliable because the user is notified that operations are complete by the system service generating a notification sound before you have had a chance to actually write to the Tag, so that the user tends to remove the Tag out of range before the write completes.. It is much better to use the newer and better `enableReaderMode` API as you can control the notification and make a notification after successful write. – Andrew Jan 02 '23 at 20:22
  • See https://stackoverflow.com/questions/64920307/how-to-write-ndef-records-to-nfc-tag/64921434#64921434 for an example of `enableReaderMode` – Andrew Jan 02 '23 at 20:23

0 Answers0