summaryrefslogtreecommitdiffstats
path: root/src/android/nfc/src/org/qtproject/qt/android/nfc/QtNfc.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/nfc/src/org/qtproject/qt/android/nfc/QtNfc.java')
-rw-r--r--src/android/nfc/src/org/qtproject/qt/android/nfc/QtNfc.java145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/android/nfc/src/org/qtproject/qt/android/nfc/QtNfc.java b/src/android/nfc/src/org/qtproject/qt/android/nfc/QtNfc.java
new file mode 100644
index 00000000..9d8cae92
--- /dev/null
+++ b/src/android/nfc/src/org/qtproject/qt/android/nfc/QtNfc.java
@@ -0,0 +1,145 @@
+// Copyright (C) 2016 Centria research and development
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+package org.qtproject.qt.android.nfc;
+
+import java.lang.Runnable;
+
+import android.content.Context;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nfc.NfcAdapter;
+import android.content.IntentFilter.MalformedMimeTypeException;
+import android.os.Build;
+import android.os.Parcelable;
+import android.util.Log;
+import android.content.pm.PackageManager;
+
+public class QtNfc
+{
+ static private final String TAG = "QtNfc";
+ static private NfcAdapter m_adapter = null;
+ static private PendingIntent m_pendingIntent = null;
+ static private Context m_context = null;
+ static private Activity m_activity = null;
+
+ static public void setContext(Context context)
+ {
+ m_context = context;
+ if (context instanceof Activity) m_activity = (Activity) context;
+ m_adapter = NfcAdapter.getDefaultAdapter(context);
+
+ if (m_activity == null) {
+ Log.w(TAG, "New NFC tags will only be recognized with Android activities and not with Android services.");
+ return;
+ }
+
+ if (m_adapter == null) {
+ return;
+ }
+
+ // Since Android 12 (API level 31) it's mandatory to specify mutability
+ // of PendingIntent. We need a mutable intent, which was a default
+ // option earlier.
+ int flags = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? PendingIntent.FLAG_MUTABLE
+ : 0;
+ m_pendingIntent = PendingIntent.getActivity(
+ m_activity,
+ 0,
+ new Intent(m_activity, m_activity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
+ flags);
+ }
+
+ static public boolean startDiscovery()
+ {
+ if (m_adapter == null || m_activity == null
+ || !m_activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC))
+ return false;
+
+ m_activity.runOnUiThread(new Runnable() {
+ public void run() {
+ IntentFilter[] filters = new IntentFilter[3];
+ filters[0] = new IntentFilter();
+ filters[0].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
+ filters[0].addCategory(Intent.CATEGORY_DEFAULT);
+ filters[1] = new IntentFilter();
+ filters[1].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
+ filters[1].addCategory(Intent.CATEGORY_DEFAULT);
+ try {
+ filters[1].addDataType("*/*");
+ } catch (MalformedMimeTypeException e) {
+ throw new RuntimeException("IntentFilter.addDataType() failed");
+ }
+ // some tags will report as tech, even if they are ndef formatted/formattable.
+ filters[2] = new IntentFilter();
+ filters[2].addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
+ String[][] techList = new String[][]{
+ {"android.nfc.tech.Ndef"},
+ {"android.nfc.tech.NdefFormatable"}
+ };
+ try {
+ m_adapter.enableForegroundDispatch(m_activity, m_pendingIntent, filters, techList);
+ } catch(IllegalStateException e) {
+ // On Android we must call enableForegroundDispatch when the activity is in foreground, only.
+ Log.d(TAG, "enableForegroundDispatch failed: " + e.toString());
+ }
+ }
+ });
+ return true;
+ }
+
+ static public boolean stopDiscovery()
+ {
+ if (m_adapter == null || m_activity == null
+ || !m_activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC))
+ return false;
+
+ m_activity.runOnUiThread(new Runnable() {
+ public void run() {
+ try {
+ m_adapter.disableForegroundDispatch(m_activity);
+ } catch(IllegalStateException e) {
+ // On Android we must call disableForegroundDispatch when the activity is in foreground, only.
+ Log.d(TAG, "disableForegroundDispatch failed: " + e.toString());
+ }
+ }
+ });
+ return true;
+ }
+
+ static public boolean isEnabled()
+ {
+ if (m_adapter == null) {
+ return false;
+ }
+
+ return m_adapter.isEnabled();
+ }
+
+ static public boolean isSupported()
+ {
+ return (m_adapter != null);
+ }
+
+ static public Intent getStartIntent()
+ {
+ Log.d(TAG, "getStartIntent");
+ if (m_activity == null) return null;
+
+ Intent intent = m_activity.getIntent();
+ if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) ||
+ NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) ||
+ NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
+ return intent;
+ } else {
+ return null;
+ }
+ }
+
+ static public Parcelable getTag(Intent intent)
+ {
+ return intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
+ }
+}