USB Permission Popup... Every time. (Serial component)

I've got the Serial component working, and can communicate with an Arduino attached to my phone with an OTG USB cable.

I plug in the USB cable into the phone, and then open the app. When I attempt to open a serial connection, the phone alerts me with a pop-up notification that says:

Allow the app [app] to access the USB device?
Use by default for this USB device

I would like my phone to remember the USB permission choice so that once the permission is given, it does not ask again. Checking the default box seems to have no effect.

  • If the USB cable is unplugged, upon replugging the pop up will come back.
  • If the phone is rebooted, the pop up will come back.
  • However, if the app is closed, but the cable remains plugged in, and then the app is reopened, the pop up does not come back.

In the phone settings, I can go to settings/apps/[my app]/permissions, and see a list of permissions allowed for my app. But USB access is not on the list.

The answer for this stack exchange post is referenced by a number of other stack posts, all dealing with this USB pop up. It discusses changing the manifest and adding USB "intents":

Has anyone ever tried this within AI2, or is it even possible? I'm guessing something like this might be possible through the activity starter component, or perhaps in post-processing with something like Java Bridge?

Or does anyone have any other avenues I may try (like an AskForPermission within the initialize block)? I am simply trying to make my phone remember the USB permission so that it does not ask every time the USB cable is plugged in.

Attached is a sample program: ArduinoInterface.aia (3.7 KB)

Thanks.

Going to see how far I get editing the manifest in APK Editor Studio, per this post, but would still welcome insight from other, more experienced users on the USB permissions topic.

So I can't believe it, but I actually got this working, mainly following @Anke's instructions.

  1. From App Inventor, build app to apk and save to computer.
    [Build/App (Save .apk to my computer)]

  2. From App Inventor, export keystore. [My Projects/Export Keystore]

  3. Rename android.keystore to android.ks, per this post.

  4. Download and install APK Editor Studio. You will also need to download Java JDK from Oracle. APK Editor Studio will indicate if you don't have it.

  5. Open the apk in APK Editor Studio.

  6. Click the gear icon [Preferences], click Signing APK, click Open Key Manager, enable custom keystore, navigate to your android.ks file. keystore password is "android", key alias is "androidkey", and key password is "android". Click okay. Exit preferences. (this is detailed with Anke's youtube video).

  7. Click Open Contents.

  8. Plug your arduino (or other device) into your computer usb port. Navigate to your system report (mac) or device manager, find the usb device, and find the vendor id and product id in the details. These will be hex numbers.

  9. Convert the hex vendor and product ids to decimal.

  10. From this stack exchange post, download the permission example project (zip file).

  11. Unzip the test project. Per the stack post, add the usb_device_filter.xml file in res/xml/ into the res/xml folder in your project. Edit that document with the vedor id and product id of your arduino or device. The entire code of the usb_device_filter.xml file is as follows (vendor id 9025 and product id 1 correspond to the vendor id of 0x2341 and the product id of 0x0001 of my arduino uno):

<?xml version="1.0" encoding="utf-8"?>

<resources>
	<usb-device vendor-id="9025" product-id="1" />
</resources>
  1. Open the Your AndroidManifest.xml file in your project in a code editor, and add the following to the <activity> section of your manifest, below any other intents:
<intent-filter>
    <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" />  
  1. Save your APK in APK Editor Studio. Upload to your phone and install. Now the phone will ask you once when you plug in your arduino which application to use, and remember your choice. It will also auto-open the application when you plug in the device.
1 Like

Hi blake

I think you have done a good job to succeed with that edit - but essentially you are circumventing a Google Security measure, and it's only a one click confirmation. A lot of work over a pop-up that does no harm........

You aren't wrong.

I am using my app/android phone as part of a control interface for an arduino-controlled robot that moves according to sms messages sent to it (i.e. receiving the text message "F6" would indicate the robot should drive forward 6 inches, etc.). My app is a one-off and will never make it onto any other phone much less the google app store. I needed to circumvent the pop up because it can't be clicked remotely by the robot in case something goes wrong.

This behavior might not ever be needed by the robot, but seemed like a good idea to eliminate the pop up that can only be pressed by a human. Also, since there is the "Use by default" button on the pop up, I feel like the button ideally should work as the wording implies. I've only tested with the arduino, so I'm not sure if other devices behave differently.

1 Like

Hi blake, I'm still not sure it should be the predicament that you are experiencing - a few things to clear-up:

  1. [ ] Use by default for this USB device. That is not what you assume, it's an extra element of security - in other words, if someone hooked-up a different USB device, the system should be triggered to question that (doesn't stop the bad guys really but Google developers live in a "no bad guy bubble" :joy: ) The theory is that you can send an alert somewhere if this should happen, or maybe close the App. *

  2. When the App is closed, if there is enough memory, Android does not actually close it but keeps it in suspended mode, so when you launch it next time it gets on screen a smidgen quicker (most of the big name manufactures let you pick your App out of those in suspension). Hence the pop-up is not triggered.

  3. For normal use, phone being rebooted affects everything, you surely can't be running a robot and decide to reboot the phone without consequences......

Does the USB cable become unplugged by the Robot? i.e. is the Robot connected to the USB cable? There are other approaches - the Arduino can have it's own independent WiFi to receive sms. More popular is a serial Bluetooth connection.

*Edit: It might stop a valid User from attaching the wrong device.

1 Like

Actually, the pop up occurs every time the exact same device is plugged in. That's the problem. And that's probably why lots and lots and lots of people ask about this same exact issue. Whether or not one thinks that should be the desired behavior, a non-trivial amount of people are not understanding that checkbox which indicates, at the very least, a UI design issue. :thinking:

Many other app permissions (camera access, contacts, sms, storage, etc.) are stored in Settings, and can be conveniently turned on or off by the user, with that behavioral choice remembered until altered. USB access is not listed. Perhaps google thinks USB access is that much more of a security risk than say, having access to your texts, contacts, or location, that the user should be explicitly asked to make that access choice every single time they plug the same device into their phone?

To answer your other points, see my last link for just one of many reasons a person may want the behavior I was looking for. Of course there are many ways to design something. This is what I needed.

Hi Blake

All your references are about Android.

In terms of App Inventor, a trivial number of people have expressed concern - currently I know of approx 1 person out of over 400,000 monthly Users.

There are many security measures invoked by Google. Some recent ones such as not allowing Apps to send SMS directly, have affected a lot of developers and indeed a lot of published Apps. There is nothing we can do to work-around Google's intent and still be able to have the Apps distributed via Google Play.

Yes.

1 Like

Hello

Thank you for the solution

Infortunetly the link doesn't work, can you send me the file please?
http://www.locusia.com/examples/permissionTest.zip

Private info removed by Mod

which link are you talking about?
Taifun

Hi Taifun, thank you for the answer

I am talking about this link to download the permission exemple project.zip

pointed in the step (10) of blake answer
http://www.locusia.com/examples/permission.zip

The original link still works for me. Here is an alternate:

permissionTest.zip

Thank you blake this link is working!

I wil post the result soon

This is what i get about the VID and PID of my arduino

USB\VID_2341&PID_0043\5543434373335130B1D1

I converted VID number to decimal and i get (9025)

But what about the PID and this series of numbers? after 0043\

This is what I see when I plug in a random Arduino Duemilanove into my macbook.

The VID/PID change depending on the type and brand of Arduino you're using. See this thread for more info:

https://forum.arduino.cc/t/comprehensive-list-of-uno-rev-3-usb-vendor-product-ids/429531

The third post in that thread lists off some VID/PID combos that Arduinos have, (full list available at this page: Github/Arduino/Boards.txt).

The very first combo given is 2341/0043. So I guess I'd suggest to try those values (which are identical to yours) and see what happens?

How did I find this info? I googled "what is the arduino uno vid pid" and the first result was the github page, and the third result was the forum post explaining it all.

Best,
B

Edit: Just want to add, you can also find the VID/PID in the Arduino IDE itself. Plug your board in, select your board and port in the tools menu, then select "tools/get board info". VID/PID are listed there.

Screen Shot 2022-01-13 at 6.15.28 PM

Ahhhh, it's clear now the numbers are just the serial number of the arduino , and i found them in the IDE as you said, thank you blake, by default i have already modified the xml file by (9025) for the VID and (65) for the PID , i will continu the process tomorow and i will give you a feedback , have a good night

1 Like

Hi everyone

sometimes chance creates funny situations :joy:, I tried all day to integrate this line of code as stipulated without any success,

<intent-filter>
    <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" /> 

At the last desperate try I searched the web for a similar code and I put it, I generate the apk without error, but when the application is installed on my phone I get two identical icons of the same application, one works successfully and it no longer asks for permission!!!, on the other hand the second icon does not launch the application it just briefly opens a black window, but honestly it would be interesting to understand this anomaly?
And this is the alternative code

<activity android:name=".FirstActivity">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
    </intent-filter>

    <meta-data
        android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/usb_device_filter" />
</activity>

maybe i made a mistake when i edited the ( android manifest.xml ) code because i don't have experience in the field , and this is the screenshot

Looks like it could be the category line:

android.intent.category.LAUNCHER

..........which is repeated twice in the code.

Ah ok and how can i fix that?

Well, I don't know - but you have moved away from Blake's solution so maybe you could try again using the code he provided. Failing that, experiment. What happens if you delete one of the "android.intent.category.LAUNCHER" lines, along with it's related lines?