简体   繁体   English

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

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

Hello I would like to know which is the ideal way to detect if a jar/java program is running on raspberry pi or not. 您好我想知道哪个是检测jar / java程序是否在raspberry pi上运行的理想方法。

Why do I want that? 我为什么要这样? I want to use the watchdog in the raspberry pi but also I use the java program from windows which doesn't or doesn't require the watchdog. 我想在树莓派中使用看门狗,但我也使用windows中的java程序,它不需要或不需要看门狗。

Is there a way to detect if the jar is running on a raspberry the same way some people detect the operative system? 有没有办法检测罐子是否在覆盆子上运行,就像有些人检测到操作系统一样?

The same way people use that... 人们用同样的方式......

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

Here is some code from one of my helper classes. 这是我的一个助手类的一些代码。 Notice how isPiUnix is set to true. 注意isPiUnix是如何设置为true的。 This technique relies on the PRETTY_NAME or NAME value in the os-release file. 此技术依赖于os-release文件中的PRETTY_NAME或NAME值。 Tweak necessary to detect any variations of your supported systems. 必须进行调整以检测所支持系统的任何变体。 Note that isLinux and isPiLinux will both return true when running on the Pi which is expected. 请注意, isLinuxisPiLinux在预期的Pi上运行时都会返回true。 You only need to test for isPiLinux . 您只需要测试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();
        }
    }
}

You should be able to work out details of the operating system your JVM is running on by testing the values of these Java system properties: 您应该能够通过测试这些Java系统属性的值来计算运行JVM的操作系统的详细信息:

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

Use System.getProperty(name) to fetch the value of a system property. 使用System.getProperty(name)获取系统属性的值。


If that isn't sufficiently precise, then you need to resort to non-portable solutions, such as using System.exec(...) to run uname -1 or similar. 如果这不够精确,那么您需要求助于非便携式解决方案,例如使用System.exec(...)来运行uname -1或类似的。

Note: the "raspberrypi" you see on your system is actually the default hostname, and is not a reliable indicator. 注意:您在系统上看到的“raspberrypi”实际上是默认主机名,并不是一个可靠的指标。 (It will often be set by the user to something else.) (它通常由用户设置为其他内容。)

Building on Java42's answer here is a complete helper class. 基于Java42的答案在这里是一个完整的帮助类。

Usage in Java code 在Java代码中的用法

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

Test result 测试结果

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

Raspberry.java 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());
    }
  }
}

Like Stephen C said you can use the os.* properties. 就像Stephen C所说,你可以使用os。*属性。

You may run the uname -a from inside your Java app, but that is probably a bad idea because the format varies wildly. 您可以从Java应用程序中运行uname -a,但这可能是一个坏主意,因为格式变化很大。 My RPI2 running OMC (media player distro) I get with your code: 我的RPI2运行OMC(媒体播放器发行版)我得到你的代码:

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

and uname -a reports: 和uname -a报道:

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

Also you can give a look at the PI4J project. 您还可以查看PI4J项目。 They have an example that outputs info about the PI it is running. 他们有一个示例输出有关正在运行的PI的信息。 Try to see the code on how do they do it. 试着看看他们是如何做到的代码。

this function will detect if is RasberryPi 这个函数会检测是否是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