この記事は...
こんにちは、STORES 決済 Androidチームのみっちゃん(@mimimi_engineer)です。 この記事は、3/7に開催されたチームラボ社とWantedly社が主催するモバイル勉強会にて登壇させていただいた時の発表を記事にまとめ直したものです。
どうしてAndroidでNFCを無効化したかったのか
私は STORES 決済 というアプリの開発に日々取り組んでおります。
STORES 決済 はお店の決済を支えるアプリで、オーナーさんのスマホにインストールして頂き、決済端末(画像の白い端末)とBluetoothで連携しています。
最近だとタッチ決済も導入したので、お客さんがクレジットカードで決済を行いたい時、決済端末にカードをかざすだけで簡単に決済が完了します。 もちろんスマホでクレジットカードを管理している場合、スマホを決済端末に近づけることで通常通りのタッチ決済が可能です。
しかし、STORES 決済 がインストールされているオーナーさんのスマホにおサイフケータイやGoogle Payなどが入っていて、しかもそこにオーナーさんのプライベートなクレジットカードなどが登録されていると、どうなるでしょう。
オーナーさんのスマホと決済端末の位置が非常に近い場合、お客さんのスマホの中のカードではなく、オーナーさんのスマホの中のカードが反応してしまう可能性があります。
その場合、オーナーさんはご自身の商品を売ってお商売をしているのに、その支払いを自分のカードで行うことになってしまうわけです。これではお商売になりません!
なので、オーナーさんのスマホ(STORES 決済 がインストールされているスマホ)ではNFCをオフにして、オーナーさんのスマホの中のGoogle Payやおサイフケータイが決済端末に反応しないようにする必要があります。
iOSではどうしている?
iOSではPassKitというライブラリに生えているrequestAutomaticPassPresentationSuppressionというAPIを使って制御しています。
この方法は、NFC またはその他の RF リーダーの近くで操作するときにフォアグラウンドにとどまる必要があるアプリでのみ使用してください。このメソッドは、iOS デバイスが互換性のあるリーダーを検出したときに、Apple Pay パスを自動的に表示しないようにします。
ちなみに、このAPIでiOS端末のWallet機能を無効化した場合、次のようなシステムポップアップがユーザーに表示されるようになります。
AndroidでもNFCをオフにするAPIはないの?
AndroidでもiOS同様に、APIを使って端末のNFCをprogramaticallyにオフにする方法がないか調べてみました。
NfcAdapter
はじめにNfcAdapterというAPIを発見しました。 端末のNFCに関してあれこれさせてくれそうな気配を感じますね。
しかしドキュメントを読み進めてみるも、AndroidのNFC設定をオフにさせてくれそうなメソッドは特に生えていない模様。
これは、Adapterという名前からも予想できる通り、端末のNFCリーダライター機能を使うためのAPIのようです。
もう少し詳しく説明すると、Androidにはスマホ上でNFCやFeliCaのカードを読み書きできるリーダーライター機能が搭載されていて、NfcAdapterを使うとその機能を利用することができるようになります。たとえばアプリを通してNFCカードの情報を受けとったり、NFCカードの情報を書き換えたりするためのAPIです。
一方で、今回私がやりたいと考えているのは、Android端末のNFC設定をオフにすることです。
STORES 決済 アプリが入ってるスマホのNFCを無効化したいのであって、決済アプリ上でNFCの情報を受け取ってなんやかんやしたいわけではないのです。
というわけで、NfcAdapterは使えなさそうです...。
ドキュメントを読もう
ドキュメントを読みましょう。 やはりドキュメントなのです。
Android-powered devices are usually looking for NFC tags when the screen is unlocked, unless NFC is disabled in the device’s Settings menu.
Android搭載デバイスは、デバイスの設定メニューでNFCが無効になっていない限り、通常、画面のロックが解除されたときにNFCタグを探します。
この記述からは、ユーザーが自分でスマホの設定画面へ行きNFCを無効化しない限りはNFCを無効化できないというふうに読み取れます。
みんなはどうしているんだ
Stack Overflowで同様のお悩みを見つけました。 Android: Changing NFC settings (on/off) programmatically
It’s not possible programatically without rooting device. But you can start NFC Settings Activity by intent action Settings.ACTION_NFC_SETTINGS for api level 16 and above. For api < 16 use Settings.ACTION_WIRELESS_SETTINGS.Previous selected answer suggests to use WIFI_SETTINGS but we can directly move to NFC_SETTINGS
ここでは、programaticallyに端末のNFC設定を無効化するのは不可能なので、intent
を使って内部的にスマホの設定画面に遷移させ、そこでユーザー自身の手によってNFCの設定をオフにしてもらうよう提案されています。
最終提案
- 内部的に無効化するのはおそらく不可能
代替案
- アプリから内部的にスマホの設定画面に遷移し、ユーザー自身の手によってNFCの設定をオフにしてもらう
- 「Android端末をお使いのオーナーさんは、スマホの設定画面からNFC機能をオフにするようお願いします」的なコミュニケーションをとることで回避 (そもそもこの問題の発生頻度は極めてまれなので、こういったコミュニケーションでの回避でも十分だと思いました。
と、最終的には以上のように提案する運びとなりました。
最後に
Android端末のNFC設定を内部的にオフにする方法がわかった/知っているという人がいれば是非知見を共有いただきたいです。