How can I enable NFC reader via API?
Asked Answered
A

4

8

There is any way I can enable Android NFC reader using API?

Acarus answered 28/6, 2011 at 15:52 Comment(2)
If the user has it disabled, please leave it disabled. You are welcome to prompt the user to enable it, and even lead the user to the Settings screen where the NFC-enabled checkbox resides.Mulhouse
to be fair CommonsWare, when you don't know the application which is being developed here, this answer is a little short-sighted. For all you know GetUsername is developing something which allows the user to switch NFC on/ off by rules in his app. I'm sure in that case the user would be somewhat aware of his actions. And Google could just consider this and implement a permission for it, instead of locking everything up.Pathetic
D
6

So apparently there is no way to enable the NFC from the API, even though Google does so within their source code (see below).

If you look at a line from the API for NfcAdapter.isEnabled():

Return true if this NFC Adapter has any features enabled.

Application may use this as a helper to suggest that the user should turn on NFC in Settings.

If this method returns false, the NFC hardware is guaranteed not to generate or respond to any NFC transactions.

It looks like there is no way to do it within the API. Bummer. Your best bet is a dialog to inform the user they need to enable it in the settings, and perhaps launch a settings intent.

EDIT: The following is from the source, but it looks like they didn't allow the user to implement the methods in the API (I'm confused about this).

I found this from the android source code to help enable and disable the adapter.

Relevant source:

public boolean onPreferenceChange(Preference preference,
        Object value) {
    // Turn NFC on/off

    final boolean desiredState = (Boolean) value;
    mCheckbox.setEnabled(false);

    // Start async update of the NFC adapter state, as the API is
    // unfortunately blocking...
    new Thread("toggleNFC") {
        public void run() {
            Log.d(TAG, "Setting NFC enabled state to: "
                    + desiredState);
            boolean success = false;
            if (desiredState) {
                success = mNfcAdapter.enable();
            } else {
                success = mNfcAdapter.disable();
            }
            if (success) {
                Log.d(TAG,
                        "Successfully changed NFC enabled state to "
                                + desiredState);
                mHandler.post(new Runnable() {
                    public void run() {
                        handleNfcStateChanged(desiredState);
                    }
                });
            } else {
                Log.w(TAG, "Error setting NFC enabled state to "
                        + desiredState);
                mHandler.post(new Runnable() {
                    public void run() {
                        mCheckbox.setEnabled(true);
                        mCheckbox
                                .setSummary(R.string.nfc_toggle_error);
                    }
                });
            }
        }
    }.start();
    return false;
}
Duodenary answered 28/6, 2011 at 16:7 Comment(1)
Thats strange. I can't see enable() and disable() methods in NfcAdapter javadoc or SDK. What SDK version this snippet is related to?Acarus
P
3

I got it working through reflection

This code works on API 15, haven't checked it against other verions yet

public boolean changeNfcEnabled(Context context, boolean enabled) {
    // Turn NFC on/off
    final boolean desiredState = enabled;
    mNfcAdapter = NfcAdapter.getDefaultAdapter(context);

    if (mNfcAdapter == null) {
        // NFC is not supported
        return false;
    }

    new Thread("toggleNFC") {
        public void run() {
            Log.d(TAG, "Setting NFC enabled state to: " + desiredState);
            boolean success = false;
            Class<?> NfcManagerClass;
            Method setNfcEnabled, setNfcDisabled;
            boolean Nfc;
            if (desiredState) {
                try {
                    NfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
                    setNfcEnabled   = NfcManagerClass.getDeclaredMethod("enable");
                    setNfcEnabled.setAccessible(true);
                    Nfc             = (Boolean) setNfcEnabled.invoke(mNfcAdapter);
                    success         = Nfc;
                } catch (ClassNotFoundException e) {
                } catch (NoSuchMethodException e) {
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                }
            } else {
                try {
                    NfcManagerClass = Class.forName(mNfcAdapter.getClass().getName());
                    setNfcDisabled  = NfcManagerClass.getDeclaredMethod("disable");
                    setNfcDisabled.setAccessible(true);
                    Nfc             = (Boolean) setNfcDisabled.invoke(mNfcAdapter);
                    success         = Nfc;
                } catch (ClassNotFoundException e) {
                } catch (NoSuchMethodException e) {
                } catch (IllegalArgumentException e) {
                } catch (IllegalAccessException e) {
                } catch (InvocationTargetException e) {
                }
            }
            if (success) {
                Log.d(TAG, "Successfully changed NFC enabled state to "+ desiredState);
            } else {
                Log.w(TAG, "Error setting NFC enabled state to "+ desiredState);
            }
        }
    }.start();
    return false;
}//end method

This requires 2 permissions though, put them in the manifest:

 <!-- change NFC status toggle -->
    <uses-permission android:name="android.permission.NFC" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

The NFC button's state switches accordingly when the code is used, so there are no issues when doing it manually in the seetings menu.

Pathetic answered 1/7, 2012 at 23:34 Comment(4)
Nice work. If I had an API 15 phone I would test this, but for now I'll take your word that this works and has been tested.Duodenary
@JohnLeehey yes, very much so. I'll have to check against other API's anyway, I will try to post back how that goes. Thanks for your answer, that is what led me to the solution.Pathetic
mmmmm, I forgot to contemplate the fact that this ofcourse will only work on rooted devices! One can't write secure settings or settings unless the app is installed as a system app.Pathetic
API level 16 onwards, this will not work because permission "android.permission.WRITE_SECURE_SETTINGS" only allow for system app.Caldera
H
1

If you can see the NfcService Application Source Code, there is a Interface file INfcAdapter.aidl. In the file two API's are there namely "boolean enable()" and "boolean disable()". You can directly use this API's to enable and disable NfcService through an android application. But the trick over here is that you can not compile the code using SDK provided by the Android. You have to compile the application using the a makefile. I have successfully build a application.

Hyperplasia answered 5/6, 2014 at 16:28 Comment(0)
U
0

I hope this forum would be help you to resolve this issue as well to get the clear understanding on the NFC power on/off API barries.

http://ranjithdroid.blogspot.com/2015/11/turn-onoff-android-nfc-by.html

Underact answered 4/11, 2015 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.