Open rammere opened 9 years ago
Hello @rammere
You can add the following in your platforms/android/AndroidManifest.xml
in the <activity>
node
<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/device_filter" />
And add the following file named device_filter.xml
in platforms/android/res/xml/
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- arduino uno R3 -->
<usb-device vendor-id="9025" product-id="0067" />
</resources>
Where the vendor id and product id of your serial device are in decimal format. (the example provided above shows VID and PID of arduino uno R3).
I'm still looking for a way to do that when you run a cordova build
, if you have a clue, it's welcome.
Adding this to the plugin.xml
doesn't seem to work.
Regards,
Xavier
So it seems impossible from the config.xml or the plugin.xml, you would need a hook, please see http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/ for some doc about hooks
Any update @rammere ?
@rammere any updates?
@rammere cough cough! :)
Hi, i am experiencing the same problem, the permission to connect to the device is asked every time and the setting to use this permission as a standard for this device seems to have no effect. I applied the settings recommended by xseignard in AndroidManifest.xml and device_filter.xml with no effects.
In the code snippets of the usb-serial-for-android libraries i found that manager.openDevice() is just called and requestPermission() is only called on a failure of this function. If i apply this with this module my app just crashes.
Do you have any hints what i'm doing wrong? Is there any further documentation on how to use this module? I'm using cordova with the ionic framework.
Thank you,
Jan
The solution I provided should work. But if you say that manager.openDevice()
would do the trick then we just need to implement it in the plugin.
It would be a simple and nice addition.
Is it something you could achieve @raumfisch ?
Regards
@raumfisch any update?
Hi @xseignard. Thanks for a nice plugin. I also want to skip permissions, and was able to use your method above to automatically connect, but only when initially building the app and pushing to the device. On subsequent cycling of the USB OTG cable, the permission requests return even though it's the same arduino. I'm attempting to run my app in a pinned state (kiosk mode), which prevents system messages like the permissions to be displayed to the user, so ideally I'd like it to be handled automatically in the background.
Hi @nsted I never experienced such behavior, I should check it again.
In the meantime, could you show me your code?
Regards
Hi @xseignard Thank you for offering to look at my code. After looking again, I realized that I made a mistake by listing the PID/VID in Hex as opposed to Decimal as you indicated should be done. I've updated the code, and it now works. Cheers!
@nsted : glad to hear it works, have fun :)
Hi @xseignard Well done with an awesome plugin. I was hoping you would be you would be able to assist. I'm using the the same arduino and can connect with the HEX values that I received from lsusb -v VID=2a03 and PID=0043. According to this thread I need to insert the values in decimal. I converted the values with an online tool that gives me the decimal VID as 10755 and PID as 67. If I change these values it does not see the device ERROR:nodivice found. I have also tried different variations but still cant get the permission check bypassed. Any advice?
@jbprinsloo did you try 10755 and 0067?
Hi @xseignard
Thanks for the reply. Still no luck. I'm new to this so not sure where to go next. I also tried to connect like this without the changes in the AndroidManifest and the Device filter
serial.requestPermission({ vid: '2a03', pid: '0043' }, .... --> Works (Perminant Permission Request)
serial.requestPermission({ vid: '10755', pid: '0067' },.... --> No Device error
serial.requestPermission({ vid: '10755', pid: '67' }, ....--> No Device error
Then I tried to connect with the changes in the manifest and device filter like this
// request permission first
serial.requestPermission(
// if user grants permission
function (successMessage) {
// open serial port
serial.open( ....
AndriodManifest.xml Below
device_filter.xml
Not sure where I'm going wrong :\
Hi @xseignard
Well after spending the weekend playing with different devices and trying multiple variations of the settings I have finally got it sorted and its working perfectly as expected. Feeling rather sheepish I was passing in the VID and PID as strings that made your plugin think that it was hex values. Apologies for waiting your time and thanks for making a great plugin.
@jbprinsloo good to know! I'll try to update the docs to emphasis this subtle thing!
Have fun!
Regards
I wrote a hook for this in my project's hooks/after_platform_add
folder. It certainly has some room for improvement, but it's a good start and works fine on my project.
#!/usr/bin/env node
var fs = require('fs'),
parseString = require('xml2js').parseString,
xml2js = require('xml2js');
var rootdir = process.argv[2];
if (rootdir) {
// go through each of the platform directories that have been prepared
var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []);
for(var x=0; x<platforms.length; x++) {
// open up the index.html file at the www root
try {
var platform = platforms[x].trim().toLowerCase();
if(platform.includes('android')) {
if (!fs.existsSync('platforms/android/res/xml/device_filter.xml')) {
console.log("writing platforms/android/res/xml/device_filter.xml")
fs.createReadStream('hooks/assets/device_filter.xml').pipe(fs.createWriteStream('platforms/android/res/xml/device_filter.xml'));
}
fs.readFile('platforms/android/AndroidManifest.xml', 'utf-8', function (err, data){
if(err) console.log(err);
// we then pass the data to our method here
parseString(data, function(err, result){
if(err) console.log("ERROR",err);
// here we log the results of our xml string conversion
//console.log(result);
var json = result;
fs.readFile('hooks/assets/data_to_be_added.xml', 'utf-8', function(err, data_to_be_added){
if(err) console.log("ERROR", err);
parseString(data_to_be_added,function(err, result2){
if(err) console.log("ERROR",err);
var json_to_be_added = result2;
var activity = json.manifest.application[0].activity[0]
for (var property in json_to_be_added.body) {
if (json_to_be_added.body.hasOwnProperty(property)) {
if (activity.hasOwnProperty(property)) {
json.manifest.application[0].activity[0][property].push(json_to_be_added.body[property][0])
}
//if the property does not exist yet
else {
json.manifest.application[0].activity[0][property] = json_to_be_added.body[property];
}
}
}
// create a new builder object and then convert
// our json back to xml.
var builder = new xml2js.Builder();
var xml = builder.buildObject(json);
fs.writeFile('platforms/android/AndroidManifest.xml', xml, function(err, data){
if (err) console.log("error in writing xml file: ", err);
console.log("successfully written our update xml to file");
})
})
});
});
});
}
} catch(e) {
process.stdout.write(e);
}
}
}
With those two additional files in the following locations
hooks/assets/device_filter.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1027" product-id="24577" />
</resources>
and hooks/assets/data_to_be_added.xml
<?xml version="1.0" encoding="utf-8"?>
<body>
<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/device_filter" />
</body>
If you have the option to compile the android system, then there's nothing you cannot do.
You can add
public void onStart() {
super.onStart();
mPermissionGranted = true;
finish();
}
to frameworks/base/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
to bypass the the permission confirmation popup.
The AndoidManifest workaround works fine on android 5. But the same build fails to hide the popup on Android 7. Any idea why ?
Thought I would put here that permission may be sorted by your cordova config like this
<resource-file src="res/xml/device_filter.xml" target="res/xml/device_filter.xml" />
<config-file parent="/manifest/application/activity" target="AndroidManifest.xml">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
</config-file>
<config-file parent="/manifest/application/activity" target="AndroidManifest.xml">
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />
</config-file>
also update the namespaces in the config file to include the android namespace like this
<widget xmlns:android="http://schemas.android.com/apk/res/android">
in the root of the cordova project place a file with the right vendor and product id's.
similar to this
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="0403" product-id="6001" />
<usb-device vendor-id="10c4" product-id="ea60" />
</resources>
This will allow cordova to make the changes to the manifest and add the device filter list. Once this happens permissions, are requested only once and will only be requested again if the app is uninstalled.
These changes are limited to your cordova application source code so you don't have to go hacking around in the android platform source.
There is potential for the plugin config to make these changes also.
Hi p0wdrdotcom, I am newbie in cordova and I'm struggling to make your solution work. Could you point where to put your code:
`
<config-file parent="/manifest/application/activity" target="AndroidManifest.xml">
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />
</config-file>`
I have tried in the config.xml inside <platform name="android">
but It do not compile.
I will appreciate any help.
Thank you
Hi @xseignard
I tried the suggestions to add the settings in the Androidmanifest.xml file but still the permission dialog appears on reboot.
My Androidmanifest.xml contains following settings;
above
<activity android:directBootAware="true" ....
My device_filter.xml file contains following nodes (with VID and PID in decimal/integer value;
Now when I call the serial.requestPermission plugin function with following code, the serial communication works fine but when the device is rebooted, the permission box shows up again;
serial.requestPermission({ vid: '1A86', //hex value pid: '7523', driver: 'Ch34xSerialDriver' // or any other }
If I try to use the VID and PID as integer as follows, 'No Device' found error comes up.
serial.requestPermission({ vid: 6790, //integer value pid: 7523, driver: 'Ch34xSerialDriver' // or any other }
how to resolve the issue?
Thanks R
Hi , Can we skip the permission ? so the user won't be prompted with permission dialog ? And thank you for your great plugin :D Regards,