I am developing an Android App that reads an NFC tag, retrieves the NDEF Message, and then passes it to a WebView activity to display that URLs Website. I am checking on the Logcat and the URL is being read, but I don't think that the URL is being passed as I get the following error:
Attempt to cast generated internal exception:
java.lang.ClassCastException: android.os.Parcelable[] cannot be cast to java.lang.String
This is the MainActivity:
class MainActivity : AppCompatActivity() {
// NFC adapter for checking NFC state in the device
private var nfcAdapter: NfcAdapter? = null
// Pending intent for NFC intent foreground dispatch.
// Used to read all NDEF tags while the app is running in the foreground.
private var nfcPendingIntent: PendingIntent? = null
// Optional: filter NDEF tags this app receives through the pending intent.
//private var nfcIntentFilters: Array<IntentFilter>? = null
private val KEY_LOG_TEXT = "logText"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Restore saved text if available
if (savedInstanceState != null) {
dahcor.text = savedInstanceState.getCharSequence(KEY_LOG_TEXT)
}
// Check if NFC is supported and enabled
nfcAdapter = NfcAdapter.getDefaultAdapter(this)
Log.i("NFC supported", (nfcAdapter != null).toString())
Log.i("NFC enabled", (nfcAdapter?.isEnabled).toString())
// Read all tags when app is running and in the foreground
// Create a generic PendingIntent that will be deliver to this activity. The NFC stack
// will fill in the intent with the details of the discovered tag before delivering to
// this activity.
nfcPendingIntent = PendingIntent.getActivity(this, 0,
Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0)
// Optional: Setup an intent filter from code for a specific NDEF intent
// Use this code if you are only interested in a specific intent and don't want to
// interfere with other NFC tags.
// In this example, the code is commented out so that we get all NDEF messages,
// in order to analyze different NDEF-formatted NFC tag contents.
//val ndef = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED)
//ndef.addCategory(Intent.CATEGORY_DEFAULT)
//ndef.addDataScheme("https")
//ndef.addDataAuthority("*.andreasjakl.com", null)
//ndef.addDataPath("/", PatternMatcher.PATTERN_PREFIX)
// More information: https://stackoverflow.com/questions/30642465/nfc-tag-is-not-discovered-for-action-ndef-discovered-action-even-if-it-contains
//nfcIntentFilters = arrayOf(ndef)
if (intent != null) {
// Check if the app was started via an NDEF intent
Log.i("Found intent in onCreate", intent.action.toString())
processIntent(intent)
}
// Make sure the text view is scrolled down so that the latest messages are visible
}
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);
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
Log.i("Found intent in onNewIntent", intent?.action.toString())
// If we got an intent while the app is running, also check if it's a new NDEF message
// that was discovered
if (intent != null) processIntent(intent)
}
/**
* Check if the Intent has the action "ACTION_NDEF_DISCOVERED". If yes, handle it
* accordingly and parse the NDEF messages.
* @param checkIntent the intent to parse and handle if it's the right type
*/
private fun processIntent(checkIntent: Intent) {
// Check if intent has the action of a discovered NFC tag
// with NDEF formatted contents
if (checkIntent.action == NfcAdapter.ACTION_NDEF_DISCOVERED) {
Log.i("New NDEF intent", checkIntent.toString())
// Retrieve the raw NDEF message from the tag
val rawMessages = checkIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
if (rawMessages != null) {
Log.i("Raw messages", rawMessages.size.toString())
}
// Complete variant: parse NDEF messages
if (rawMessages != null) {
val messages = arrayOfNulls<NdefMessage?>(rawMessages.size)// Array<NdefMessage>(rawMessages.size, {})
for (i in rawMessages.indices) {
messages[i] = rawMessages[i] as NdefMessage
val intent = Intent(this, Webview::class.java)
intent.putExtra("Url", rawMessages)
startActivity(intent)
}
// Process the messages array.
processNdefMessages(messages)
}
// Simple variant: assume we have 1x URI record
//if (rawMessages != null && rawMessages.isNotEmpty()) {
// val ndefMsg = rawMessages[0] as NdefMessage
// if (ndefMsg.records != null && ndefMsg.records.isNotEmpty()) {
// val ndefRecord = ndefMsg.records[0]
// if (ndefRecord.toUri() != null) {
// logMessage("URI detected", ndefRecord.toUri().toString())
// } else {
// // Other NFC Tags
// logMessage("Payload", ndefRecord.payload.contentToString())
// }
// }
//}
}
}
This is the Webview activity, the one that is supposed to take the URL and load it:
class Webview : AppCompatActivity() {
private lateinit var webview: Webview1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_webview)
val myWebView: WebView = findViewById(R.id.webview)
val url = intent.getStringExtra("Url").toString()
if (url != null) {
Log.i("Url", url)
}
myWebView.webViewClient = object : WebViewClient () {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
if (url != null) {
view?.loadUrl(url)
}
return true
}
}
myWebView.loadUrl(url)
myWebView.settings.javaScriptEnabled=true
myWebView.settings.allowContentAccess=true
myWebView.settings.domStorageEnabled=true
myWebView.settings.useWideViewPort=true
}
}
I want to get the URL received from the tag to the
myWebView.loadUrl()
Which will later load the website. Thank you for any help.