android - 扫描适当的NFC标签后,有什么方法可以启动我的应用程序的适当 Activity ?

标签 android kotlin nfc

我想通过适当的 Activity 在NFC Signal上打开我的应用程序。

将Tag格式化为URI时,它可以工作并更改我的 Activity ,但仅在打开应用程序时有效。当它关闭时,它不会打开该应用程序。
当Tag设置为文本格式时,它只会打开我的应用程序,而不会将其更改为适当的 Activity ,并显示数据为空。

如何在NFC标签信号上打开我的应用程序的指定 Activity ,标签应使用哪种格式? URI还是文本?

如果我对标签使用URI,是否应该更改 list 中的<data android:mimeType="text/plain" />

这是我的 list 文件:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="ge.softservice.nfcwithactivties">

    <uses-permission android:name="android.permission.NFC" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <!--For processing data from NFC Tag (launchMode)-->

    <application
        android:launchMode="singleInstance"

        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".Menu2Activity"></activity>
        <activity android:name=".Menu1Activity">




        </activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />

                <data android:mimeType="text/plain" />

                <action android:name="android.nfc.action.TECH_DISCOVERED" />


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

        </activity>
    </application>

</manifest>

这是我的MainActivity:
     package ge.softservice.nfcwithactivties

import android.app.PendingIntent
import android.content.ContentResolver
import android.content.Intent
import android.nfc.*
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.MimeTypeFilter
import kotlinx.android.synthetic.main.activity_main.*

    const val TAG = "MainActivity"

    class MainActivity : AppCompatActivity() {

    var nfcAdapter: NfcAdapter? = null
    var nfcPendingIntent: PendingIntent? = null

    private var KEY_LOG_TEXT = "logText"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val text = findViewById<TextView>(R.id.text)
        val nfcSupported = findViewById<TextView>(R.id.nfc_support)
        val nfcEnabled = findViewById<TextView>(R.id.nfc_enabled)

        // Restore saved text if available
        if (savedInstanceState != null) {
            text.text = savedInstanceState.getCharSequence(KEY_LOG_TEXT)
        }

        // Check if NFC is supported and enabled
        nfcAdapter = NfcAdapter.getDefaultAdapter(this)
        if (nfcAdapter == null) {
            nfcSupported.append("your phone has not NFC")
        } else {
            nfcSupported.append(" Your phone has NFC")
        }

        if (nfcAdapter?.isEnabled != null) {
            nfcEnabled.append(" you have NFC turned on")
        } else {
            nfcEnabled.append(" your NFC is turned off")
        }

        nfcPendingIntent = PendingIntent.getActivity(this, 0,
            Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)

        if (intent?.data.toString() == "1. " ) {
            openMenu1()
            text.append(intent?.data.toString())
        } else if (intent?.data.toString() == "2. ") {
            openMenu2()
            text.append(intent?.data.toString())
        } else {
            Toast.makeText(this, "Ups.. Unknown tag detected", Toast.LENGTH_SHORT).show()
            text.append(intent?.data.toString())
        }

    }

    override fun onResume() {
        super.onResume()
        // Get all NDEF discovered intents
        // Makes sure the app gets all discovered NDEF messages as long as it's in the foreground.
        nfcAdapter?.enableForegroundDispatch(this, nfcPendingIntent, null, null)
        // Alternative: only get specific HTTP NDEF intent
        //nfcAdapter?.enableForegroundDispatch(this, nfcPendingIntent, nfcIntentFilters, null)
    }

    override fun onPause() {
        super.onPause()
        // Disable foreground dispatch, as this activity is no longer in the foreground
        nfcAdapter?.disableForegroundDispatch(this)
    }

    fun openMenu1() {
        val intent = Intent(this, Menu1Activity::class.java)
        startActivity(intent)
    }

    fun openMenu2() {
        val intent = Intent(this, Menu2Activity::class.java)
        startActivity(intent)
    }
    }

非常感谢,提前

最佳答案

我认为您的问题是您使用onNewIntent方法解析卡中的数据的方法非常粗糙。

您应该为NFC卡中的NDEF消息正确解析Intent数据。

有关如何执行操作,请参见https://developer.android.com/guide/topics/connectivity/nfc/nfc#obtain-info

您还需要首先考虑一下NFC数据格式,问题中没有足够的信息来准确回答这一问题,但是有两种可能性:

1)您无法控制卡上的数据,因此需要了解数据格式并调整onNewIntent中的Intent读取以匹配并使用toString是不可行的,因为无法保证它将返回其中的一部分您需要读取的NFC数据。

您应该完全了解NDEF消息的所有选项。

如果您在使用NDEF数据格式时遇到问题,请使用NXPinfo应用程序读取卡片https://play.google.com/store/apps/details?id=com.nxp.taginfolite并在新问题中添加详细信息。

2)您可以控制卡上的数据,然后建议您使用自定义的mimeType例如“信号/菜单”或其他合适的组合,这将减少其他应用或系统尝试处理您的卡的可能性。因为您知道NDEF消息中的数据格式,这也将使数据解析更加容易。

关于android - 扫描适当的NFC标签后,有什么方法可以启动我的应用程序的适当 Activity ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60561693/

相关文章:

android - 从相机捕获的图像未显示在 imageview android 中

java - Android 上的蓝牙套接字连接如何工作?

android:如何制作三角形布局

java - 在发布到应用商店后,Android应用会为所有设备引发UnsatisfiedLinkError

java - 调用 dynamicRealm.beginTransaction() 后应用卡住

android - Android Studio 中 NFC 技术过滤器不支持的类型技术列表

Python - 将整数字符串转换为 Ascii

android - Android 虚拟设备 (AVD) 的 NFC 标签仿真

android - 是否可以通过 GTalk Intent 发送消息?

android - 当项目添加到 RecyclerView 时,RecyclerView 中的 EditText 值发生变化