繁体   English   中英

从java(jar)检测树莓派的理想方法

[英]The ideal way to detect a raspberry pi from java (jar)

您好我想知道哪个是检测jar / java程序是否在raspberry pi上运行的理想方法。

我为什么要这样? 我想在树莓派中使用看门狗,但我也使用windows中的java程序,它不需要或不需要看门狗。

有没有办法检测罐子是否在覆盆子上运行,就像有些人检测到操作系统一样?

人们用同样的方式......

class ShowProperties {
    public static void main(String[] args) {
        System.getProperties().list(System.out);
    }
}

这是我的一个助手类的一些代码。 注意isPiUnix是如何设置为true的。 此技术依赖于os-release文件中的PRETTY_NAME或NAME值。 必须进行调整以检测所支持系统的任何变体。 请注意, isLinuxisPiLinux在预期的Pi上运行时都会返回true。 您只需要测试isPiLinux

private static boolean isWindows       = false;
private static boolean isLinux         = false;
private static boolean isHpUnix        = false;
private static boolean isPiUnix        = false;
private static boolean isSolaris       = false;
private static boolean isSunOS         = false;
private static boolean archDataModel32 = false;
private static boolean archDataModel64 = false;

static {
    final String os = System.getProperty("os.name").toLowerCase();
    if (os.indexOf("windows") >= 0) {
        isWindows = true;
    }
    if (os.indexOf("linux") >= 0) {
        isLinux = true;
    }
    if (os.indexOf("hp-ux") >= 0) {
        isHpUnix = true;
    }
    if (os.indexOf("hpux") >= 0) {
        isHpUnix = true;
    }
    if (os.indexOf("solaris") >= 0) {
        isSolaris = true;
    }
    if (os.indexOf("sunos") >= 0) {
        isSunOS = true;
    }
    if (System.getProperty("sun.arch.data.model").equals("32")) {
        archDataModel32 = true;
    }
    if (System.getProperty("sun.arch.data.model").equals("64")) {
        archDataModel64 = true;
    }
    if (isLinux) {
        final File file = new File("/etc", "os-release");
        try (FileInputStream fis = new FileInputStream(file);
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis))) {
            String string;
            while ((string = br.readLine()) != null) {
                if (string.toLowerCase().contains("raspbian")) {
                    if (string.toLowerCase().contains("name")) {
                        isPiUnix = true;
                        break;
                    }
                }
            }
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
}

您应该能够通过测试这些Java系统属性的值来计算运行JVM的操作系统的详细信息:

  • os.name操作系统名称
  • os.arch操作系统体系结构
  • os.version操作系统版本

使用System.getProperty(name)获取系统属性的值。


如果这不够精确,那么您需要求助于非便携式解决方案,例如使用System.exec(...)来运行uname -1或类似的。

注意:您在系统上看到的“raspberrypi”实际上是默认主机名,并不是一个可靠的指标。 (它通常由用户设置为其他内容。)

基于Java42的答案在这里是一个完整的帮助类。

在Java代码中的用法

if (Raspberry.isPi()) {
 ...
}

测试结果

javac Raspberry.java
java Raspberry
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"

Raspberry.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

/**
 * Raspberry PI helper class
 * @author wf
 *
 */
public class Raspberry {

  public static boolean debug = false;

  /**
   * check if this java vm runs on a raspberry PI
   * https://stackoverflow.com/questions/37053271/the-ideal-way-to-detect-a-raspberry-pi-from-java-jar
   * 
   * @return true if this is running on a Raspbian Linux
   */
  public static boolean isPi() {
    String osRelease = osRelease();
    return osRelease != null && osRelease.contains("Raspbian");
  }

  /**
   * read the first line from the given file
   * 
   * @param file
   * @return the first line
   */
  public static String readFirstLine(File file) {
    String firstLine = null;
    try {
      if (file.canRead()) {
        FileInputStream fis = new FileInputStream(file);
        BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(fis));
        firstLine = bufferedReader.readLine();
        fis.close();
      }
    } catch (Throwable th) {
      if (debug)
        th.printStackTrace();
    }
    return firstLine;
  }

  /**
   * get the operating System release
   * 
   * @return the first line from /etc/os-release or null
   */
  public static String osRelease() {
    String os = System.getProperty("os.name");
    if (os.startsWith("Linux")) {
      final File osRelease = new File("/etc", "os-release");
      return readFirstLine(osRelease);
    }
    return null;
  }

  /**
   * entry point to call from command line
   */
  public static void main(String args[]) {
    if (isPi()) {
      System.out.println(osRelease());
    }
  }
}

就像Stephen C所说,你可以使用os。*属性。

您可以从Java应用程序中运行uname -a,但这可能是一个坏主意,因为格式变化很大。 我的RPI2运行OMC(媒体播放器发行版)我得到你的代码:

os.arch=arm
os.name=Linux
os.version=4.4.6-3-osmc

和uname -a报道:

Linux osmc 4.4.6-3-osmc #1 SMP PREEMPT Fri Apr 1 20:55:03 UTC 2016 armv7l GNU/Linux

您还可以查看PI4J项目。 他们有一个示例输出有关正在运行的PI的信息。 试着看看他们是如何做到的代码。

这个函数会检测是否是RasberryPi

private static StringBuilder StringBuilderResult;

private static boolean DetectRaspBPi() {
    GetInfoByExecuteCommandLinux("cat /proc/device-tree/model", false);
    return StringBuilderResult.toString().toLowerCase().contains("raspberry");
}

private static void GetInfoByExecuteCommandLinux(String command, boolean getList){
    try {
        Process pb = new ProcessBuilder("bash", "-c", command).start();
        BufferedReader reader=new BufferedReader(
                new InputStreamReader(pb.getInputStream())
        );
        String line;
        if (getList){
            ListStringBuilderResult = new ArrayList<>();
        } else {
            StringBuilderResult = new StringBuilder();

        while((line = reader.readLine()) != null)
        {
            if (getList){
                ListStringBuilderResult.add(line);
            } else {
                StringBuilderResult.append(line);
            }
        }
    } catch (Exception e){
        System.out.println(e.getMessage());
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM