当授予权限时调用 UsbManager Request Permission 执行例程时的事件侦听器是什么?

What is the event listener for when UsbManager Request Permission is called to execute a routine when a permission is granted?

我一直在弄清楚如何请求访问 USB com 设备的权限,等待用户输入,然后在获得权限后相应地进行操作。当 UsbManager 请求权限时,我无法弄清楚“onRequestPermissionsResult”的用途。我注意到当 UsbManager 请求权限时,监听器永远不会被调用,所以它没有按照我最初想的那样使用。

此代码全部在MainActivity.

这里我正在设置我的 Intent 用于连接或断开我的 USB 设备,并初始化 UsbManager。 请注意,我没有使用 LOGCAT 来记录调试消息,因为我的 Android 设备必须与 Android Studio 断开连接才能插入我正在为其开发应用程序的 USB com 设备。相反,我正在登录应用 UI.

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);

   DoIntent();

   m_manager = (UsbManager) getSystemService(Context.USB_SERVICE);
}
   private void DoIntent () {

      m_usbReceiver = new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action) || UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)) {
               try {
                  OnDeviceConnected();
                  // m_textViewDebug.setText("USB Connected");
               } catch (Exception e) {
                  m_textViewDebug.setText(e.getMessage());
               }
            } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action) || UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
               m_port = null;
               m_serialIoManager = null;
               m_isInitialized = false;
               m_textViewDebug.setText("USB Disconnected");
            }
         }
      };

      IntentFilter filter = new IntentFilter();
      filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
      filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);

      registerReceiver(m_usbReceiver , filter);

下面是连接设备时发生的情况。我想在连接后立即建立权限。

   private void OnDeviceConnected () throws Exception {
      ProbeTable customTable = new ProbeTable();
      customTable.addProduct(0x239a, 0x800c, CdcAcmSerialDriver.class);
      UsbSerialProber prober = new UsbSerialProber(customTable);

      List<UsbSerialDriver> drivers = prober.findAllDrivers(m_manager);

      UsbDeviceConnection connection = null;
      UsbSerialDriver driver = drivers.get(0);

      PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(INTENT_ACTION_GRANT_USB), 0);
      m_manager.requestPermission(driver.getDevice(), usbPermissionIntent);

      /// Need some kind of pause or check for permissions here before executing forward.or
      /// handle everything after on a different routine called after permission has been selected.

      /// Continues to execute before user has time to respond to permissions.

      try {
         connection = m_manager.openDevice(driver.getDevice());
      } catch (Exception e) {
         throw new Exception(e.getMessage());
      }

      if (connection == null) {
         throw new Exception ("Could not open device.");
      }

      m_port = driver.getPorts().get(0);

      try {
         m_port.open(connection);
         m_port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
         m_port.setDTR(true);
      } catch (Exception e) {
         throw new Exception(e.getMessage());
      }

      m_serialIoManager = new SerialInputOutputManager(m_port, m_listener);
      m_executor.submit(m_serialIoManager);

      m_isInitialized = true;
   }

这就是我最初在获得许可后尝试做的事情。 我无法从这个范围中获得任何日志消息,所以我相信它永远不会被调用并且我使用不正确。

   @Override
   public void onRequestPermissionsResult(final int requestCode, String[] permissions, int[] grantResults) {

      MainActivity.this.runOnUiThread(new Runnable() {
         public void run() {
            /// Never gets called :/
            m_textViewDebug.setText(Integer.toString(requestCode));
         }
      });

      switch (requestCode) {
         case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            /// If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               /// permission was granted, yay! Do the
               /// contacts-related task you need to do.
            } else {
               /// permission denied, boo! Disable the
               /// functionality that depends on this permission.
            }
            return;

         case USB_PERMISSION_GRANTED: { /// Not the real enum because I'm not sure where to find what it is.
            try {
               /// Need to somehow pass driver from OnDeviceConnected to this scope, or make it class property.
               connection = m_manager.openDevice(driver.getDevice());
           } catch (Exception e) {
              throw new Exception(e.getMessage());
           }

           if (connection == null) {
               throw new Exception ("Could not open device.");
           }

            m_port = driver.getPorts().get(0);

            try {
              m_port.open(connection);
              m_port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
              m_port.setDTR(true);
            } catch (Exception e) {
               throw new Exception(e.getMessage());
            }

            m_serialIoManager = new SerialInputOutputManager(m_port, m_listener);
            m_executor.submit(m_serialIoManager);

            m_isInitialized = true
         }

         /// other 'case' lines to check for other
         /// permissions this app might request.
      }
   }

我正在尝试记录 requestCode 是什么,这样我就可以为任何 USB 许可代码写一个案例。我无法在文档中的任何地方找到 requestCode 可能的所有选项的编译列表。 MY_PERMISSIONS_REQUEST_READ_CONTACTS 实际上会抛出一个编译错误,因为我不知道它来自哪里。 This guide 没有特别详细地介绍 USB。该指南也是我在上述例程中获得 switch 语句的地方。

编辑:

我试着摆弄 UsbManager.EXTRA_PERMISSION_GRANTED 看看是否可行。我将它作为一个动作添加到我的意图过滤器中。

   IntentFilter filter = new IntentFilter();
   filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
   filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
   filter.addAction(UsbManager.EXTRA_PERMISSION_GRANTED);

   registerReceiver(m_usbReceiver, filter);

然后我将意图的操作记录到我的广播接收器中,但是当授予或拒绝 USB 权限时没有任何反应。

点击上图中的 "OK" 会触发什么样的动作或事件?在 API.

上摸索了几天

仔细查看 this 我终于明白了。

我在尝试建立意图过滤器之前有这个。

public static final String INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB";
PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(INTENT_ACTION_GRANT_USB), 0);
IntentFilter filter = new IntentFilter();

然后我改成了这个

private static final String ACTION_USB_PERMISSION = BuildConfig.APPLICATION_ID + ".USB_PERMISSION";
m_permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);

主要区别在于 new IntentFilter 需要 ACTION_USB_PERMISSION 字符串。

现在在我的 Broadcast Receiver 中,我有一个按预期调用的条件。

else if (ACTION_USB_PERMISSION.equals(action)) {
   if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
      m_textViewDebug.setText("USB Permission Granted");
      try {
         OnDevicePermissionGranted();
      } catch (Exception e) {
         m_textViewDebug.setText(e.getMessage());
      }
   }
   else {
      m_textViewDebug.setText("USB Permission Denied");
   }
}

我花了一段时间才弄清楚如何使用 EXTRA_PERMISSION_GRANTED。 当 this here 说 "EXTRA_PERMISSION_GRANTED containing boolean indicating whether permission was granted by the user" 时,我一直在想我试图在某个对象上找到一个布尔标志来验证权限。我没有意识到我必须在意图上调用一个特殊方法并提供该字符串以获得我的真或假。对我来说似乎很反直觉。

我意识到最大的错误是在制作新的 Intent 过滤器时没有提供正确的字符串。我找到了一堆没有任何参数的其他例子。