Android

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

More than 1 year has 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


参考ページ