3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-08-28

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

参考ページ

  1. 詳しくはこちらを参照: Androidエミュレータでシステム署名が必要な処理の動作を確認する - Qiita

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?