/* * Copyright (C) 2019 Yubico. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.yubico.yubikit.transport.nfc; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.nfc.NfcAdapter; import android.nfc.Tag; import com.yubico.yubikit.exceptions.NfcDisabledException; import com.yubico.yubikit.exceptions.NfcNotFoundException; import androidx.annotation.NonNull; /** * This class allows you to communicate with local NFC adapter */ public class NfcDeviceManager { /** * Action for intent to tweak NFC settings in Android settings view * on Q Android supports Settings.Panel.ACTION_NFC, we might update with release on Q * */ public static final String NFC_SETTINGS_ACTION = "android.settings.NFC_SETTINGS"; private final Context context; private final NfcDispatcher dispatcher; private final NfcAdapter adapter; private NfcSessionListener listener; /** * Creates instance of {@link NfcDeviceManager} * @param context the application context * @param dispatcher optional implementation of NfcDispatcher to use instead of the default. */ public NfcDeviceManager(Context context, NfcDispatcher dispatcher) { this.context = context; adapter = NfcAdapter.getDefaultAdapter(this.context); if (dispatcher == null) { dispatcher = new NfcReaderDispatcher(adapter); } this.dispatcher = dispatcher; } public NfcDeviceManager(Context context) { this(context, null); } /** * Sets listener to Nfc session discovery * @param listener the listener */ public void setListener(final @NonNull NfcSessionListener listener) { dispatcher.setOnTagHandler(new NfcDispatcher.OnTagHandler() { @Override public void onTag(Tag tag) { listener.onSessionReceived(new NfcSession(tag)); } }); } /** * Enable discovery of nfc tags for foreground activity * @param activity activity that is going to dispatch nfc tags * @param nfcConfiguration additional configurations for NFC discovery * @throws NfcDisabledException in case if NFC turned off * @throws NfcNotFoundException in case if NFC not available on android device */ public void enable(final @NonNull Activity activity, final NfcConfiguration nfcConfiguration) throws NfcDisabledException, NfcNotFoundException { if (checkAvailability(nfcConfiguration.isHandleUnavailableNfc())) { dispatcher.enable(activity, nfcConfiguration); } } /** * Disable active listening of nfc events * @param activity activity that goes to background or want to stop dispatching nfc tags */ public void disable(final @NonNull Activity activity) { if (adapter == null) { return; } dispatcher.disable(activity); } /** * Checks if user turned on NFC_TRANSPORT and returns result via listener callbacks * @param handleUnavailableNfc true if prompt user for turning on settings with UI dialog, otherwise returns error if no settings on or NFC_TRANSPORT is not available * @throws NfcDisabledException in case if NFC turned off * @throws NfcNotFoundException in case if NFC not available on android device */ private boolean checkAvailability(boolean handleUnavailableNfc) throws NfcDisabledException, NfcNotFoundException { if (adapter == null) { throw new NfcNotFoundException("NFC transport is not available on this device"); } if (!adapter.isEnabled() && !handleUnavailableNfc) { throw new NfcDisabledException("Please activate NFC_TRANSPORT"); } if (!adapter.isEnabled()) { context.startActivity(new Intent(NFC_SETTINGS_ACTION)); return false; } else { return true; } } }