65.9K
CodeProject 正在变化。 阅读更多。
Home

使用Android手机创建APRS跟踪器和自动相机

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (8投票s)

2011年4月26日

CPOL

4分钟阅读

viewsIcon

51111

downloadIcon

3363

按设定时间拍摄照片并广播 GPS 位置,可用于气球有效载荷或作为独立追踪器

引言

这是一个安卓手机的项目,它使用业余无线电 APRS 基础设施来拍摄照片并广播手机 GPS 坐标。我把它用作高空气球项目的备用追踪器,但它也可以用于其他用途,例如设置在一个地方并存储延时照片,或在地图上图形化地跟踪手机的位置。

例如,我把它放在我的后院,因为我知道鸭子会定期来访,我能够拍到这张照片

duck.jpg

这是使用aprs.fi跟踪手机位置的图片(这次没有鸭子参与)

Capture.JPG

背景

APRS是一种基于业余无线电的技术,用于使用分组无线电通信信息。它也有一个互联网基础设施(根本不使用无线电),这很方便,因为您可以免费获得所有映射和跟踪业余无线电基础设施,例如aprs.fi。如果您不是持照的业余无线电操作员,您将无法按原样使用此代码,并且必须修改它发布 GPS 信息的方式,并且需要自己实现映射。获得业余无线电许可证很有趣而且相当容易,所以我鼓励您走这条路

Using the Code

附加的代码是一个针对 Android 2.1 的 Eclipse 项目。如果您也想针对该版本,它也可以在 Android 1.5 上运行。我升级它只是为了获得更多暴露的相机功能,用于设置图片质量和其他属性。该项目主要分为三个部分

  1. 检索 GPS 坐标和海拔信息
  2. 从手机摄像头拍摄照片并将其存储在 SD 卡上
  3. 通过现有的 APRS 基础设施提交 GPS 信息

此外,还有一些代码可以保存输入的信息,这样就不必每次都重新输入。我添加此功能的主要原因是用于呼号和密码,以便可以将 GPS 信息发送到 APRS 服务器。如果您不是持照的业余无线电操作员,您将没有任何东西可以放在这里,并且必须更改代码以发布到您自己的服务器(然后在地图上显示它)或者去获取一个业余无线电许可证。

我白天主要是一名 .NET 开发人员,因此设置 Eclipse 和 Android 对我来说是一件新鲜事。所以如果你是一位经验丰富的 Java 开发人员,并且在 Java 代码中发现任何奇怪之处,那就是原因!我发现这个过程非常简单明了,并且与使用 Visual Studio for .NET Micro 项目非常相似。在大多数情况下,一切都按预期工作,并且您可以在设备本身上进行调试,这非常好。

  1. 检索 GPS 坐标和海拔信息

    您需要的只是对位置管理器的引用即可获得 GPS 位置和海拔高度。其余代码只是将其格式化为 APRS 基础设施。

    Location location = locationManager
       .getLastKnownLocation(LocationManager.GPS_PROVIDER);
    
    String latitude = 
          getAsDegreesMinutesSeconds(location.getLatitude(), "N", "S");
    String longitude = 
          getAsDegreesMinutesSeconds(location.getLongitude(), "E", "W");
    String altitude = 
          ExactNumDigits(((int)location.getAltitude()) + "", 6);
  2. 从手机摄像头拍摄照片并将其存储在 SD 卡上

    这需要大量的反复试验才能正确,但一旦完成,它看起来很简单。确保在拍照前开始预览(尽管您显然不必显示它),并且始终在完成后进行清理,以便用户从您的应用程序切换到基于摄像头的应用程序时,他们仍然可以使用摄像头。

    public void takePicture() {
      try {
          toastText("Taking picture");
          Camera camera = Camera.open();
          camera.setErrorCallback(errorCallback);
          
          try {
           camera.startPreview();
              camera.takePicture(null, null, jpegCallback);
          } finally {
              camera.stopPreview();
              camera.release();
              camera = null;
          }
      } catch(Exception ex) {
       toastText(ex.toString());
      }
    }
    
     Camera.ErrorCallback errorCallback = new Camera.ErrorCallback() {
      public void onError(int arg0, Camera arg1) {
       toastText("Camera error: " + arg0);
      }
     };
        
        // Handles data for jpeg picture
        PictureCallback jpegCallback = new PictureCallback() { // <8>
          public void onPictureTaken(byte[] data, Camera camera) {
          String filePath = String.format("/sdcard/Pics/%1$s.jpg", 
                        new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date()));
          toastText("Writing " + data.length + " bytes to " + filePath);
             FileOutputStream outStream = null;
             try {
               // Write to SD Card
               outStream = new FileOutputStream(filePath); 
               outStream.write(data);
               outStream.close();
             } catch (Exception e) {
              toastText(e.toString());
             }
          }
        };
  3. 通过现有的 APRS 基础设施提交 GPS 信息

    有关更多信息,请参阅 APRS 标准,了解应如何提交信息,但这只是一个普通的 TCP/IP 连接,在客户端和服务器之间发送和接收string。如果呼号/密码不匹配,服务器将不接受位置报告,您将无法在诸如aprs.fi之类的网站上看到它。

    Socket socket = null;
    try {
     socket = new Socket("texas.aprs2.net", 14580); 
     BufferedReader inReader = new BufferedReader(
      new InputStreamReader(socket.getInputStream())
     );
    
     String input = inReader.readLine();
     
     PrintWriter out = new PrintWriter(
      new BufferedWriter(
       new OutputStreamWriter(socket.getOutputStream())
      ), 
      true
     );  
    
     String loginText = 
      String.format("user %1$s pass %2$s -1 vers APRSAndroid 1.0_00 filter m/5", 
      callSign, 
      passCode
     );
     out.println(loginText);  
    
     input = inReader.readLine();
     if(!input.startsWith(String.format("# logresp %1$s verified", callSign)))
      throw new Exception("Unable to verify call sign/pass code");
     
     String locationString = 
         String.format("%1$s>APRS,TCPIP*:=%2$s/0%3$s$/A=%4$sAPRSAndroid", 
          callSign, 
       latitude, 
       longitude, 
       altitude
      );
     out.println(locationString);  
    
     toastText(
      String.format("Sent location %1$s/%2$s /A=%3$s for %4$s", 
      latitude, 
      longitude, 
      altitude, 
      callSign
     ));
    } catch (Exception e) {
     toastText("Unable to connect: " + e.getMessage());
    }
    finally {
     try {
      if(socket != null) {
       socket.close();
      }
     } catch (IOException e1) { }
    }

摘要

这就是拥有一个价值 100 美元的设备,可以广播 GPS 位置并自动拍摄照片所需的全部内容!我使用的 Android 设备是 AT&T Backflip,很容易从 Ebay 上获得,我真的很喜欢使用它。我认为这是一种简单易用的自动化图片方式,类似于使用 CHDK,但可以在设备上进行调试,还可以使用手机的其他功能,例如 GPS 和网络访问。下面是界面的屏幕截图 - 它不会为我赢得任何 UI 设计奖项,但可以充分控制所有功能。

Capture2.JPG

尽情享用!

© . All rights reserved.