Help us understand the problem. What is going on with this article?

アプリからNFCをオンオフする

More than 3 years have passed since last update.

NFCのオンオフのためのAPIは公開されてないのでリフレクションで非公開のAPIを呼ぶ必要がある.また,この操作にはWRITE_SECURE_SETTINGSが必要で,この権限はシステム署名がされているか,/system/priv-appにインストールされているアプリでしか有効でないことに注意する1

テストした環境

  • Android 7.0
  • Nexus 5X (NRD90M)

コード

AndroidManifest.xml(抜粋)
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
setNfcState
public static final int NFC_STATE_DISABLE = 0;
public static final int NFC_STATE_ENABLE = 1;

public boolean setNfcState(Context context, int newState) {
    NfcManager nfc = (NfcManager)context.getSystemService(Context.NFC_SERVICE);
    NfcAdapter adapter = nfc.getDefaultAdapter();
    Method setEnable = null, setDisable = null;
    try {
        Class<?> NfcAdapterClass = adapter.getClass();
        setEnable = NfcAdapterClass.getDeclaredMethod("enable");
        setEnable.setAccessible(true);
        setDisable = NfcAdapterClass.getDeclaredMethod("disable");
        setDisable.setAccessible(true);
    } catch (NoSuchMethodException e) {
        return false;
    }
    try {
        if (newState == NFC_STATE_ENABLE) {
            setEnable.invoke(adapter);
        } else {
            setDisable.invoke(adapter);
        }
    } catch (InvocationTargetException|IllegalAccessException e) {
        return false;
    }
    return true;
}
使用例
private void toggleNfcState() {
    NfcManager nfc = (NfcManager)getSystemService(Context.NFC_SERVICE);
    NfcAdapter adapter = nfc.getDefaultAdapter();
    boolean ret = false;
    boolean enabled = adapter.isEnabled();
    if (enabled) {
        ret = setNfcState(this, NFC_STATE_DISABLE);
    } else {
        ret = setNfcState(this, NFC_STATE_ENABLE);
    }
    if (ret) {
        Toast.makeText(this, "NFCの状態を" + (enabled ? "無効" : "有効") + "にしました", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(this, "NFCのオンオフ切り替えに失敗しました", Toast.LENGTH_SHORT).show();
    }
}

/system/priv-appへのインストール

この方法でNFCをオンオフさせるには,アプリをシステムアプリとして動作させる必要がある.システムアプリとしてインストールするには上述の通り2つの方法があるようだが,今回は/system/priv-appにインストールする方法を使用した.ちなみに,一度/system/priv-appに入れてしまえば,その後のアップデートは普通にアップデートしてもNFCのオンオフが可能なようだ.

/system/priv-appにインストールする方法について,/systemをrwマウントした上で以下のようなコマンドを実行するか,ESファイルエクスプローラなど/systemを読み書きできるファイラアプリを使って同様の操作を行えば,作成したアプリをシステムアプリとしてインストールできる.

# $appnameは適当なアプリ名,$apkpathはシステムアプリとしてインストールするapkのパス
cd /system/priv-app
mkdir $appname
chmod 755 $appname
cd $appname
cp $apkpath .
chmod 644 $apkpath
reboot

参考ページ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away