如何在应用程序处于后台时从Arduino USB串行端口获取数据?

时间:2017-10-06 18:01:58

标签: android service arduino broadcastreceiver job-scheduling

这篇文章很长,因为我试图解释我的问题的完整情况。请耐心地阅读。

现在,我尝试使用连接到Arduino的一些物理按钮来控制应用功能。要将Arduino连接到移动设备,请使用OTG电缆。

我有三项活动。一个是启动活动,它是启动活动。另外两个是Activity1和Activity2,我使用这个Arduino。

所以现在我已经制作了一个用于系统动作的广播接收器,即USB Permission,USB Attached和USB Detached。我分别在活动中写了广播接收器。我在创建活动时注册了接收者,即onCreate()。这适用于这两项活动。当活动被破坏时,我取消注册接收器。

在广播接收器的onReceive()方法中,我编写如下代码:

private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
  //Broadcast Receiver to automatically start and stop the Serial connection.
  @Override
  @AddTrace(name = "broadcast receiver", enabled = true/*Optional*/)
  public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
      boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
      Toast.makeText(NewCameraActivity.this, String.valueOf(granted), Toast.LENGTH_SHORT).show();
      device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
      if (granted) {
        connection = usbManager.openDevice(device);
        serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
        if (serialPort != null) {
          if (serialPort.open()) {
            //Set Serial Connection Parameters.
            serialPort.setBaudRate(9600);
            serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
            serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
            serialPort.setParity(UsbSerialInterface.PARITY_NONE);
            serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
            serialPort.read(mCallback);
            Toast.makeText(NewCameraActivity.this, "Port Opening", Toast.LENGTH_SHORT).show();
          } else {
            Log.d("SERIAL", "PORT NOT OPEN");
            Toast.makeText(NewCameraActivity.this, "PORT NOT OPEN", Toast.LENGTH_SHORT).show();
          } else {
            Log.d("SERIAL", "PORT IS NULL");
            Toast.makeText(NewCameraActivity.this, "PORT IS NULLg", Toast.LENGTH_SHORT).show();
          }
        } else {
          Log.d("SERIAL", "PERM NOT GRANTED");
          Toast.makeText(NewCameraActivity.this, "PERM NOT GRANTED", Toast.LENGTH_SHORT).show();
        }
      } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
        onClickStart();
      } else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
        onClickStop();
        finish();
      }
    };
  };

  UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
    @Override
    public void onReceivedData(byte[] arg0) {
      String data;
      try {
        data = new String(arg0, "UTF-8");
        final String finalData = data;
        runOnUiThread(new Runnable() {
          @Override
          public void run() {
            switch (finalData) {
              case "portopen":
                break;
              case "portinc":
                System.exit(0);
                break;
              case "scan":
                onClickStop();
                requestPicture();
                break;
              case "lang":
                counter++;
                counter = counter % 3;
              if (counter == 0) {
                ImageNameSingleton.getInstance().setLanguage("eng");
                textToSpeech.speak("English selected", TextToSpeech.QUEUE_FLUSH, myHash1);
              } else if (counter == 1) {
                ImageNameSingleton.getInstance().setLanguage("hin");
                textToSpeech.speak("Hindi Selected", TextToSpeech.QUEUE_FLUSH, myHash1);
              } else if (counter == 2) {
                ImageNameSingleton.getInstance().setLanguage("mar");
                textToSpeech.speak("Marathi Selected", TextToSpeech.QUEUE_FLUSH, myHash1);
              }
              break;
            default:
              break;
          }
        }
      });
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
  } //Defining a Callback which triggers whenever data is read.
};

@AddTrace(name = "onClickstart", enabled = true/*Optional*/)
public void onClickStart() {
  Toast.makeText(NewCameraActivity.this, "onClickStart", Toast.LENGTH_SHORT).show();
  HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
  if (!usbDevices.isEmpty()) {
    boolean keep = true;
    for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
      device = entry.getValue();
      int deviceVID = device.getVendorId();
      Toast.makeText(NewCameraActivity.this, String.valueOf(deviceVID), Toast.LENGTH_SHORT).show();
      if (deviceVID == 0x1A86) {
        //Arduino Vendor ID
        Toast.makeText(NewCameraActivity.this, "Device Found", Toast.LENGTH_SHORT).show();
        Toast.makeText(NewCameraActivity.this, String.valueOf(deviceVID) + String.valueOf(device.getProductId()), Toast.LENGTH_SHORT).show();
        PendingIntent pendingintent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        Toast.makeText(this, String.valueOf(usbManager.hasPermission(device)), Toast.LENGTH_SHORT).show();
        usbManager.requestPermission(device, pendingintent);
        keep = false;
        connectionEstablished = true;
      } else {
        Toast.makeText(NewCameraActivity.this, "Device Not Found", Toast.LENGTH_SHORT).show();
        connection = null;
        device = null;
      }
      if (!keep) break;
    }
  }
}

private void onClickStop() {
  if(serialPort!=null) serialPort.close();
  else Toast.makeText(this, "No serial port", Toast.LENGTH_SHORT).show();
}

此处,当设备连接到USB时,USB连接操作将启动,它将开始查找设备,并将搜索具有该vendorID的特定设备。当它获得设备时,它将启动USB权限操作以检查是否给出了权限。如果是,则将执行USB权限操作中的代码。如果没有,它将要求用户许可。

两项活动的一切都是一样的。

现在在Activity1中,打开串口后,我会通过单击按钮发送一个字符串,然后在活动中收到它。根据字符串,将完成一个特定的工作(你可以在回调部分看到它)。在工作之后(如点击图像),数据将被发送到Activity2,Activity1将与接收者一起被销毁。

在Activity2中,我将再次注册接收器,然后我再次打开端口,并且我正在使用字符串来完成工作。

这是工作流程。现在的问题是,我希望应用程序打开(在前台),当在Arduino中单击按钮时应用程序是在后台还是被杀死。此外,应用程序应在单击任何其他按钮时关闭。

怎么做?有什么办法吗?或者我的方法不正确?任何人帮助我...

任何帮助都将不胜感激。

0 个答案:

没有答案