【问题标题】:How can I enable NFC reader via API?如何通过 API 启用 NFC 阅读器?
【发布时间】:2011-09-24 10:58:39
【问题描述】:

有什么方法可以使用 API 启用 Android NFC 阅读器?

【问题讨论】:

  • 如果用户禁用了它,请保持禁用状态。欢迎您提示用户启用它,甚至将用户引导到启用 NFC 的复选框所在的设置屏幕。
  • 公平地说CommonsWare,当你不知道这里正在开发的应用程序时,这个答案有点短视。众所周知,GetUsername 正在开发允许用户通过应用程序中的规则打开/关闭 NFC 的东西。我敢肯定,在这种情况下,用户会在一定程度上意识到他的行为。 Google 可以考虑这一点并为其实施权限,而不是锁定所有内容。

标签: android nfc


【解决方案1】:

显然没有办法从 API 启用 NFC,即使 Google 在其源代码中这样做(见下文)。

如果您查看NfcAdapter.isEnabled() 的 API 中的一行:

如果此 NFC 适配器有,则返回 true 启用任何功能。

应用程序可以使用它作为助手 建议用户转 在设置中的 NFC 上。

如果此方法返回 false,则 NFC 硬件保证不产生 或响应任何 NFC 交易。

似乎没有办法在 API 中执行此操作。真可惜。您最好的选择是一个对话框,通知用户他们需要在设置中启用它,并可能启动一个设置意图。

编辑:以下内容来自源代码,但看起来他们不允许用户在 API 中实现方法(我对此感到困惑)。

我从android source code 中找到了这个来帮助启用和禁用适配器。

相关来源:

public boolean onPreferenceChange(Preference preference,
        Object value) {
    // Turn NFC on/off

    final boolean desiredState = (Boolean) value;
    mCheckbox.setEnabled(false);

    // Start async update of the NFC adapter state, as the API is
    // unfortunately blocking...
    new Thread("toggleNFC") {
        public void run() {
            Log.d(TAG, "Setting NFC enabled state to: "
                    + desiredState);
            boolean success = false;
            if (desiredState) {
                success = mNfcAdapter.enable();
            } else {
                success = mNfcAdapter.disable();
            }
            if (success) {
                Log.d(TAG,
                        "Successfully changed NFC enabled state to "
                                + desiredState);
                mHandler.post(new Runnable() {
                    public void run() {
                        handleNfcStateChanged(desiredState);
                    }
                });
            } else {
                Log.w(TAG, "Error setting NFC enabled state to "
                        + desiredState);
                mHandler.post(new Runnable() {
                    public void run() {
                        mCheckbox.setEnabled(true);
                        mCheckbox
                                .setSummary(R.string.nfc_toggle_error);
                    }
                });
            }
        }
    }.start();
    return false;
}

【讨论】:

  • 这很奇怪。我在NfcAdapter javadoc 或 SDK 中看不到 enable() 和 disable() 方法。此 sn-p 与哪个 SDK 版本相关?
【解决方案2】:

我通过反射得到了它

此代码适用于 API 15,尚未针对其他版本进行检查

public boolean changeNfcEnabled(Context context, boolean enabled) {
    // Turn NFC on/off
    final boolean desiredState = enabled;
    mNfcAdapter = NfcAdapter.getDefaultAdapter(context);

    if (mNfcAdapter == null) {
        // NFC is not supported
        return false;
    }

    new Thread("toggleNFC") {
        public void run() {
            Log.d(TAG, "Setting NFC enabled state to: " + desiredState);
            boolean success = false;
            Class<?> NfcManagerClass;
            Method setNfcEnabled, setNfcDisabled;
            boolean Nfc;
            if (desiredState) {
                try {
                    NfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
                    setNfcEnabled   = NfcManagerClass.getDeclaredMethod("enable");
                    setNfcEnabled.setAccessible(true);
                    Nfc             = (Boolean) setNfcEnabled.invoke(mNfcAdapter);
                    success         = Nfc;
                } catch (ClassNotFoundException e) {
                } catch (NoSuchMethodException e) {
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                }
            } else {
                try {
                    NfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
                    setNfcDisabled  = NfcManagerClass.getDeclaredMethod("disable");
                    setNfcDisabled.setAccessible(true);
                    Nfc             = (Boolean) setNfcDisabled.invoke(mNfcAdapter);
                    success         = Nfc;
                } catch (ClassNotFoundException e) {
                } catch (NoSuchMethodException e) {
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                }
            }
            if (success) {
                Log.d(TAG, "Successfully changed NFC enabled state to "+ desiredState);
            } else {
                Log.w(TAG, "Error setting NFC enabled state to "+ desiredState);
            }
        }
    }.start();
    return false;
}//end method

不过,这需要 2 个权限,请将它们放在清单中:

 <!-- change NFC status toggle -->
    <uses-permission android:name="android.permission.NFC" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

使用代码时,NFC 按钮的状态会相应切换,因此在设置菜单中手动执行此操作没有问题。

【讨论】:

  • 干得好。如果我有一部 API 15 手机,我会测试这个,但现在我相信你的话,它有效并且已经过测试。
  • @JohnLeehey 是的,非常如此。无论如何,我将不得不检查其他 API,我将尝试发回它是如何进行的。感谢您的回答,这就是导致我找到解决方案的原因。
  • mmmmm,我忘了考虑这个当然只能在有根设备上工作的事实!除非应用程序作为系统应用程序安装,否则无法编写安全设置或设置。
  • API 级别 16 及以上,这将不起作用,因为权限“android.permission.WRITE_SECURE_SETTINGS”只允许系统应用。
【解决方案3】:

如果能看到NfcService Application Source Code,就有一个Interface文件INfcAdapter.aidl。在文件中,有两个 API,即“boolean enable()”和“boolean disable()”。您可以直接使用此 API 通过 android 应用程序启用和禁用 NfcService。但是这里的窍门是你不能使用 Android 提供的 SDK 编译代码。您必须使用 makefile 编译应用程序。我已经成功构建了一个应用程序。

【讨论】:

    【解决方案4】:

    我希望这个论坛也能帮助您解决这个问题,并清楚地了解 NFC 电源开/关 API 障碍。

    http://ranjithdroid.blogspot.com/2015/11/turn-onoff-android-nfc-by.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多