NFCのオンオフのためのAPIは公開されてないのでリフレクションで非公開のAPIを呼ぶ必要がある.また,この操作にはWRITE_SECURE_SETTINGSが必要で,この権限はシステム署名がされているか,/system/priv-appにインストールされているアプリでしか有効でないことに注意する1.
テストした環境
- Android 7.0
- Nexus 5X (NRD90M)
コード
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
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
参考ページ
-
詳しくはこちらを参照: Androidエミュレータでシステム署名が必要な処理の動作を確認する - Qiita ↩