java - 使用 JavaFX 端口的 Android 上的 NFC

标签 java android javafx nfc javafxports

我最近一直在试验 JavaFXPorts我一直在尝试用它来构建原生 Android 应用程序。对于我正在构建的应用程序,我正在尝试加入 NFC 支持,但似乎没有太多关于此的信息。到目前为止我找到的唯一有用的指南是由 johanvos 编写的一些示例代码在他的 BitBucket Repo 上 here .

我现在面临的问题是使用此代码 fragment ,Netbeans 不断报告我尝试引用的 android 库不存在。

这是我的一些代码:

package com.afropolymath.waitress;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.StackPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import android.content.Context;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.ReaderCallback;
import android.nfc.Tag;
import android.os.Bundle;
import javafxports.android.FXActivity;

public class Waitress extends Application implements ReaderCallback {
    private Stage stage;
    private StackPane rootLayout;

    @Override
    public void start(Stage stage) {
        this.stage = stage;
        this.initLayout();
        Context ctx = FXActivity.getInstance();
        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(ctx);

        nfcAdapter.enableReaderMode(FXActivity.getInstance(), this, NfcAdapter.FLAG_READER_NFC_A, Bundle.EMPTY);
    }

    public void initLayout() {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/RootLayout.fxml"));
            rootLayout = (StackPane) loader.load();

            Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();

            Scene scene = new Scene(rootLayout, visualBounds.getWidth(), visualBounds.getHeight());

            stage.getIcons().add(new Image(Waitress.class.getResourceAsStream("/assets/icon.png")));

            stage.setScene(scene);
            stage.show();
        } catch (IOException e) {

        }
    }

    @Override
    public void onTagDiscovered(Tag tag) {

    }
}

这些是我遇到的错误:

/Users/chidieberennadi/NetBeansProjects/Waitress/src/main/java/com/afropolymath/waitress/Waitress.java:12: error: package android.content does not exist
import android.content.Context;
                      ^
/Users/chidieberennadi/NetBeansProjects/Waitress/src/main/java/com/afropolymath/waitress/Waitress.java:13: error: package android.nfc does not exist
import android.nfc.NfcAdapter;
                  ^
/Users/chidieberennadi/NetBeansProjects/Waitress/src/main/java/com/afropolymath/waitress/Waitress.java:14: error: package android.nfc.NfcAdapter does not exist
import android.nfc.NfcAdapter.ReaderCallback;
                             ^
/Users/chidieberennadi/NetBeansProjects/Waitress/src/main/java/com/afropolymath/waitress/Waitress.java:15: error: package android.nfc does not exist
import android.nfc.Tag;
                  ^
/Users/chidieberennadi/NetBeansProjects/Waitress/src/main/java/com/afropolymath/waitress/Waitress.java:16: error: package android.os does not exist
import android.os.Bundle;
                 ^

对可能出现的问题有什么想法吗?

最佳答案

虽然 Johan Vos 的 NFC 项目有效,但它是基于在主包上使用 android 和 dalvik 依赖项:

dependencies {
    compile files("${ANDROID_HOME}/platforms/android-21/android.jar")
    compile "org.javafxports:jfxdvk:8u60-b3"
}

但是 JavaFXPorts 旨在创建可以部署在不同平台上的项目,因此现在如果您使用 Gluon 的 NetBeans 插件创建项目,您会发现四个不同的文件夹来放置代码:

  • 源码包[Java],用于所有公共(public)代码,与所有平台共享
  • 桌面/Java 包,用于 Java 代码,只能在桌面上运行
  • Android/Java 包,用于 Java 或 Android 代码,仅适用于在 Android 上运行
  • Ios/Java 包,用于 Java 代码,只能在 iOS 上运行。

此外,如果您检查项目依赖项,您会注意到 android.jar 仅适用于 Android。

这意味着您应该在主包上创建您的常规项目,并在 Android 包中添加 android 部分。为了调用 android 类,您需要在主包上提供一些机制来创建它的实例。

如果您检查 HelloPlatform sample ,您会注意到 PlatformService 用于根据平台加载类,而 PlatformProvider 是一个接口(interface),其中包含可以从 main 调用的方法包,但将为每个平台提供实现。

有了这个想法,但使用 Class.forName() 而不是服务,Gluon Charm-Down库实现不同的本地服务。

您还可以查看 GoNative samplepost详细解释了它。

如果您想实现一项新服务,例如适用于 Android 的 NFC, 这些是可能需要的类。

主包

NFC 平台

public abstract class NFCPlatform {

    public abstract NFCService getNFCService();

}

NFC服务

public interface NFCService {

    boolean isAvailable();

    boolean isEnabled();

    StringProperty tagIdProperty();

    // other methods

}

安卓包

AndroidNFC 平台

public class AndroidNFCPlatform extends NFCPlatform {

    private AndroidNFCService nfcService;

    @Override
    public NFCService getNFCService() {
        if (nfcService == null) {
            nfcService = new AndroidNFCService();
        }
        return nfcService;
    }

}

AndroidNFCService

您对 NFC 服务的实现。这里我们可以使用Android API。 NetBeans 不会提示。

这是一个最小的实现:

public class AndroidNFCService implements NFCService, ReaderCallback {

    private final NfcAdapter nfcAdapter;
    private StringProperty tagId;

    public AndroidNFCService() {
        NfcManager manager = (NfcManager) FXActivity.getInstance().getSystemService(FXActivity.NFC_SERVICE);
        nfcAdapter = manager.getDefaultAdapter();
    }

    @Override
    public boolean isAvailable() {
        return nfcAdapter != null;
    }

    @Override
    public boolean isEnabled() {
        return isAvailable() && nfcAdapter.isEnabled();
    }

    @Override
    public StringProperty tagIdProperty() {
        if (tagId == null) {
            tagId = new SimpleStringProperty();
        }
        return tagId;
    }

    @Override
    public void onTagDiscovered(Tag tag) {
        Platform.runLater(() -> 
            tagIdProperty().set(new String(tag.getId())));
    }

}

最后,一旦您获得了 NFCPlatform 的实例,您就可以在您的主类上使用该服务。

public static NFCPlatform getNFCPlatform() {
    try {
        if ("android".equals(System.getProperty("javafx.platform", "desktop"))) {
            return (NFCPlatform) Class.forName("<your package>.AndroidNFCPlatform").newInstance();
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
        System.out.println("Error " + ex);
    }
    return null;
}

@Override
public void start(Stage stage) {

    NFCService nfcService = getNFCPlatform().getNFCService();

    if (nfcService != null) {
        System.out.println("Available: " + nfcService.isAvailable());

        ...
    }
}

关于java - 使用 JavaFX 端口的 Android 上的 NFC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34705617/

相关文章:

java - 无法到达 OnClickListener 函数内的(最终)按钮

android - "R cannot be resolved to a variable"?

javafx - 设置 JavaFX 表列名称填充

javascript - 获取输入并将其分配给变量的函数

java - 有没有办法在 Java 中反序列化对象的一部分?

java - 比较父类型的两个子类型时正确的 API 实现

Android 启用和禁用 GPS

java - 强制停止在外部线程上运行的 Java Files.copy()

java - 学习 Java Native Access 时出现 com.sun.glass.ui 包错误

java - 带有比较加三元运算符表达式的表达式 "a==1 ? 1 : 0"是原子的吗?