I am needing to have my cordova wrapped html show a picture and run a video file located off the root of the external SD. There did not seem to be a place to ask these questions on the git hub for the cordova-plugin-file.
A) I am not sure I understand what path to use in 2 B&C below in order to accomplish this if the files are in those two sub directories off the root?
B) Are ALL those values in 3 B necessary if all I need is access to the ext SD?
Here is what I know from the documentation so far ... but obviously I don't have it all correct because I get the error (see below)
1) Set up environment from CMD line
cordova create MyApp
cd /MyApp
cordova platform add android#latest
cordova plugin add cordova-plugin-whitelist
cordova plugin add cordova-plugin-file
corddova build android (after step 3 below)
2) Add these to index.html
A) cdvfile: scheme to Content-Security-Policy meta tag of the index page, e.g.:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap:cdvfile:https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src
B) <img src="cdvfile:///img/logo.png" />
C) <p>Play video</p>
3) Add these to config.xml
A) <access origin="cdvfile://*" />
B) <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,assets,root" />
The error I get on the Android when clicking on the video link is ...
net::ERR_UNKNOWN_URL_SCHEME (cdvfile:video/0001_a1.mp4)
===========
EDIT #1
Now trying recommendation by #DaveAlden ... using plugin called [cordova.plugins.diagnostic][2] with this configuration to locate root path on ExtSD to play video BUT get the error (see below) ...
config.xml
<preference name="android-minSdkVersion" value="14" />
<preference name="android-targetSdkVersion" value="14" />
<preference name="android-maxSdkVersion" value="25" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<plugin name="cordova.plugins.diagnostic" />
Index.html
<body>
<!-- Set up path to ExtSD on Android -->
<script>
function getSdRefAndEmbed(){
cordova.plugins.diagnostic.getExternalSdCardDetails(function(details){
details.forEach(function(detail){
if(detail.type === "root"){
cordova.file.externalSdCardRoot = detail.filePath;
embedMedia();
}
});
}, function(error){
console.error(error);
});
}
function embedMedia(){
$('.extSdVideo').each(function(){
$(this).attr('href', cordova.file.externalSdCardRoot + $(this).attr('href'));
});
}
$(document).on('deviceready', getSdRefAndEmbed);
$(document).on('pageinit', embedMedia);
</script>
<!-- Play video file -->
<a class="extSdVideo" href="video/0001_a1.mp4" id="0001_a1"> a1 </a>
</body>
Application Error
net::ERR_FILE_NOT_FOUND (file:///android_assest/www/HHR/hhr-cm_cameroon-cm1-fra-spa/hhr/hhr-cm_cameroon-cm1-fra-spa/video/0001_a1.mp4
Tried placing the 0001_a1.mp4 in either of these two directories...
extSDRoot/video/0001_a1.mp4
and/or
extSDRoot/www/HHR/hhr-cm_cameroon-cm1-fra-spa/hhr/hhr-cm_cameroon-cm1-fra-spa/video/0001_a1.mp4
=================== EDIT #2
#DaveAlden Suggested trying these three things...
1) Put console.dir(details) inside of getExternalSdCardDetails() to see what native paths the plugin is finding.
RESULT: it gives the same path in the error message
Application Error
net::ERR_FILE_NOT_FOUND
(file:///android_asset/www/hhr/cm_cameroon-cm1-fra-spa/0001_a1.mp4)
2) Try the example project (https://github.com/dpa99c/cordova-diagnostic-plugin-example) on the same device to see if the ext SD example works.
RESULT 1: The build for the example project failed...
BUILD FAILED Total time: 47.426 secs Error: cmd: Command failed with exit code 1 Error output: F:\DIAGNOSTIC_WORKING\cordova-diagnostic-plugin-example\platforms\android\build\ intermediates\res\merged\debug\values-v24\values-v24.xml:3: AAPT: Error retrievi ng parent for item: No resource found that matches the given name 'android:TextA ppearance.Material.Widget.Button.Borderless.Colored'.
#DaveAlden response to the Build Fail...
You have missing/outdated Android SDK components in your build
environment and/or are using an outdated version of cordova-android
platform. See documentation
(https://github.com/dpa99c/cordova-diagnostic-plugin#building-for-android)
and this issue
(https://github.com/dpa99c/cordova-diagnostic-plugin/issues/161).
My Actions:
I checked the Android SDK Manager to see that all API levels were on the same level for the required products by running this command
C:> Android -v
Android SDK Tool 25.2.5
SDK platform 25
Android Support Repository 46
Google Play services 39
Google Repository 45
I ran this command...
cordova platform check android
Got this result...
F:\DIAGNOSTIC_WORKING\cordova-diagnostic-plugin-example>cordova platform check android
Subproject Path: CordovaLib
android # 6.1.2; current did not install, and thus its version cannot be determined
Why do I get this "current did not install"? Could this be the issue why the diagnostic plugin is not finding the correct path for the extSD?
I ran this command...
cordova platform rm android && cordova platform add android#latest && cordova build android
Now the Build Succeeded for Example Project!
See screen shot of the example diagnostic app showing path to the extSD. This path looks very different from the path I am getting when I run the diagnostic plugin in my app.
Note the button "Write External SD File" did not write anything when pressed. I checked with my file manager.
The path given for the Example Project is very different for the path that the diagnostic plugin gives for my app (see mine below). These results were from the same Galaxy S7.
net::ERR_FILE_NOT_FOUND (file:///android_assest/www/HHR/hhr-cm_cameroon-cm1-fra-spa/hhr/hhr-cm_cameroon-cm1-fra-spa/video/0001_a1.mp4
I ran this command for my app but no change ...
cordova platform rm android && cordova platform add android#latest && cordova build android
3) #DaveAlden suggested running a debug using Chrome... I'll do that next.
Found this...
============= EDIT 3 SUCCESSFULLY played video from extSD using cordova-diagnostic-plugin
Here's how...
The final hurdle was that because I have an Android 6+ phone I had to also add a function to check for run time permission to read the extSD. The code kept bombing with the error show in Edit #2 (see above) like it was trying to see an internal path. Once I added the function to check for run time permission it finally gave the correct external path. Hint ... it is not enough to just provide the permission in the manifest. You can read about it here. Thanks #DaveAlden for your example project!
https://github.com/dpa99c/cordova-diagnostic-plugin-android-runtime-example
Android runtime permissions
Android 6 / API 23 introduces the concept of runtime permissions. Similar to >iOS, certain "dangerous" permissions must be requested at runtime in addition >to being listed in the Android manifest.
Runtime permissions only apply if the device/emulator the app is running on has >Android 6.0 or above AND the app is built using API 23 or higher. For Cordova, >this means using the Cordova Android platform version 5.0.0 or above. If the >app is built with version 4.x or below (API 22 or below), runtime permissions >do not apply - all permissions are granted at installation time.
Add to Config.xml
<access origin="*" />
<plugin name="cordova-plugin-whitelist" version="*" />
<plugin name="cordova.plugins.diagnostic" version="*" />
<plugin name="cordova-plugin-file" version="*" />
<preference name="android-minSdkVersion" value="21" />
<preference name="android-targetSdkVersion" value="23" />
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Thanks to #DaveAlden for this code... I only added the function to check the run time read permission. Dave you should just add this code for reading media files from the extSD to your project example so you don't have to help the next person as much as you did me. :)
Add to Index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src * gap://ready file:; style-src 'self' 'unsafe-inline'; img-src * 'self' data:; script-src * 'unsafe-inline' 'unsafe-eval'">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<h3>Play video and img file</h3>
<img class="extSdImg" src="img/image1.png"/>
<img class="extSdImg" src="img/image2.png"/>
<p>
<a class="extSdVideo" href="video/video1.mp4">Play video</a>
</p>
<p>
<a class="extSdVideo" href="video/video2.mp4">Play video</a>
</p>
</body>
</html>
Add to Index.js
function authorizerequestExtSD() {
cordova.plugins.diagnostic.requestExternalStorageAuthorization(function(status){
console.log("Successfully requested external storage authorization: authorization was " + status);
checkState();
getSdRefAndEmbed();
}, function(error){
console.error(error);
});
}
function getSdRefAndEmbed(){
cordova.plugins.diagnostic.getExternalSdCardDetails(function(details){
details.forEach(function(detail){
if(detail.type === "root"){
cordova.file.externalSdCardRoot = detail.filePath;
embedMedia();
}
});
}, function(error){
console.error(error);
});
}
function embedMedia(){
$('.extSdImg').each(function(){
$(this).attr('src', cordova.file.externalSdCardRoot + $(this).attr('src'));
});
$('.extSdVideo').each(function(){
$(this).attr('href', cordova.file.externalSdCardRoot + $(this).attr('href'));
});
}
$(document).on('deviceready', authorizerequestExtSD);
$(document).on('pageinit', embedMedia);
Add local file copy of jQuery (found one in this project https://github.com/dpa99c/cordova-diagnostic-plugin-example):
jquery-2.1.3.min.js
Your approach is not going to work: cdvfile:// is an internal pseudo-protocol defined by cordova where the first part of the path defines an internal reference point (cdvfile://localhost/persistent|temporary|another-fs-root*/path/to/file) whereas 2B and 2C are defining paths as if relative to the root of the external SD card root.
Note that cordova-plugin-media will not help you, since it's only for playing audio and does not itself resolve file locations.
If your media files are on an external removable SD card (e.g. in Samsung Galaxy devices), cordova-plugin-file does not provide a reference to access this location. The "external" references used by cordova-plugin-file (e.g. cordova.file.externalRootDirectory) actually point to an internal memory location - /scard/. This is because not all devices have removable external SD cards (e.g. Google Nexus) so /sdcard is an "emulated" storage location which is guaranteed to exist on all Android devices.
If you wish to read files from the external removable SD card, you can do so using cordova-diagnostic-plugin to obtain a valid filepath reference to the external SD card root. Note that this will need to by done dynamically in JS as opposed to hardcoding static paths in HTML:
index.html
<body>
<img class="extSdImg" src="img/image1.png"/>
<img class="extSdImg" src="img/image2.png"/>
<p><a class="extSdVideo" href="video/video1.mp4">Play video</a></p>
<p><a class="extSdVideo" href="video/video2.mp4">Play video</a></p>
</body>
index.js
function getSdRefAndEmbed(){
cordova.plugins.diagnostic.getExternalSdCardDetails(function(details){
details.forEach(function(detail){
if(detail.type === "root"){
cordova.file.externalSdCardRoot = detail.filePath;
embedMedia();
}
});
}, function(error){
console.error(error);
});
}
function embedMedia(){
$('.extSdImg').each(function(){
$(this).attr('src', cordova.file.externalSdCardRoot + $(this).attr('src'));
});
$('.extSdVideo').each(function(){
$(this).attr('href', cordova.file.externalSdCardRoot + $(this).attr('href'));
});
}
$(document).on('deviceready', getSdRefAndEmbed);
$(document).on('pageinit', embedMedia);
Related
I have a iOS and Android application, and I load a external website inside my app (this external website is mine too).
My problem is that this website has a file upload feature and this feature does not work on Android (it works on iOS).
I saw that this behavior is normal on Android, but is there any way to make it work or it's definitely not an option ?
Thank you
EDIT 1
I tried to create a new app with a simple page like this (hosted on AWS) :
<html>
<head>
<title>Upload Test !</title>
</head>
<body>
<div>Upload Test</div>
<div>
<input type="file" id="imgFile" name="files[]" accept="image/x-png, image/gif, image/jpeg">
</div>
</body>
and I added this script in my generated index.html in my Cordova project.
<script type="text/javascript">
document.addEventListener("deviceready", function(event) {
console.log('TEST CONSOLE LOG !');
var url = 'https://s3-eu-west-1.amazonaws.com/***/file-upload.html';
ref = window.open(url, "_blank", "location=no,toolbar=no,zoom=no,hidden=yes");
ref.addEventListener('loadstop', function () {
ref.show();
});
ref.addEventListener('loaderror', function () {
ref.close();
ref = undefined;
});
}, false);
</script>
It doesn't work on my nexus 5 (android M).
There's an issue with both Android and iOS that prevents file uploads when clicking on a file input tag like this within the inappbrowser:
<input type="file">
There's a couple of fixes for both which I've consolidated into a single location to make it easy for anyone else facing this issue. You should be able to modify your config.xml file to use it by including this:
<plugin spec="https://github.com/jverlee/cordova-plugin-inappbrowser-camera.git" version="1.1.0" source="git" />
Instead of the default inappbrowser plugin.
More details can be found here:
https://github.com/jverlee/cordova-plugin-inappbrowser-camera
#Verl's code is pretty good! However, it cannot be installed through his installation guide... So here is mine:
cordova plugin remove cordova-plugin-inappbrowser-camera
cordova plugin add https://github.com/jverlee/cordova-plugin-inappbrowser-camera.git
By the way, if I follow his guide, I only gets:
Error: Cannot read property 'variables' of undefined
I'm trying to upgrade my existing app from Cordova 4.x to Cordova 5.4. I've had no problem updating it in the past, but this time, I'm seeing the following error when I try to startup my app:
"Uncaught ReferenceError: google is not defined"
My declaration remains unchanged in my index.html and this is near the top of call my JS declarations. Any idea?
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="lib/sencha-touch/sencha-touch-all.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3&sensor=false&libraries=geometry"></script>
I verified that my config.xml and the correct cordova.js is being copied into the /www directory of my Android app (per an earlier posted soln), but still get this error. The same upgraded app works fine on iOS with all the Google Maps functionality.
It seems with Cordova 4.0.0+ for Android you have to install the cordova-whitelist-plugin and add this to your config.xml:
<access origin="*" />
<!-- Wildcards are allowed for the protocol, as a prefix
to the host, or as a suffix to the path -->
<allow-intent href="https://*.example.com/*" />
<allow-navigation href="*://*/*" />
When I run my application either in the Android emulator or on my Android device, I get he following error on all AJAX requests:
Failed to load resource: the server responded with a status of 404 (Not Found)
I have tried all the following steps to solve this problem, but it persists.
Installed the whitelist plugin to the project using npm.
Added <plugin name="cordova-plugin-whitelist" version="1" /> to
config.xml.
Added <uses-permission android:name="android.permission.INTERNET" />
to platforms\android\AndroidManifest.xml.
Added <meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline';"> and <meta http-equiv="X-XSS-Protection" content="0"> to the <head> of www/index.html file.
Added <access origin="*" />, <allow-navigation href="*" /> and
<allow-intent href="*" /> to the config.xml file.
Regardless I still get the same errors. Any ideas?
The project compiles fine. I'm on Windows 7, using Cordova 5.4.0, Android 5.1.1
Removing the whole Android part of the application with:
cordova platform remove android
and adding it again with:
cordova platform add android
solved the problem, which is still a mystery to me.
Perhaps there was something wrong left from the earlier versions of Cordova that wasn't getting on well with the current Cordova version.
I think the problem's with your Content Security Policy meta tag - try adding * to the default-src to open up Ajax requests to anywhere. You could also add a connect-src clause specifically for Ajax requests and list the hosts and protocols you want to be able to access. For example:
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; connect-src http://myhost.mydomain.com">
Would allow Ajax requests to http://myhost.mydomain.com
I wrote a blog post addressing this topic that you may find helpful, it can be read here.
Update Android
cordova platform update android#5.1.1
I had the problem for me connect to a php page on my server and I made an update to android
I am trying to use webintents with a cordova app to be able to send images from another app to mine.
I am using cordova 5.1.1 and added the following plugins to my android platform project:
com.virtualartifacts.webintent 1.0.0 "WebIntent"
cordova-plugin-camera 1.1.0 "Camera"
cordova-plugin-console 1.0.0 "Console"
cordova-plugin-device 1.0.0 "Device"
cordova-plugin-file 2.0.0 "File"
cordova-plugin-file-transfer 1.1.0 "File Transfer"
cordova-plugin-whitelist 1.0.0 "Whitelist"
The index.html file for the project looks like:
<!DOCTYPE html>
<html>
<head>
<title>WebIntent Test</title>
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
<script src="cordova.js"></script>
<script src="js/webintent.js"></script>
<script>
function init() {
document.addEventListener("deviceready",deviceReady,false);
}
function deviceReady() {
console.log("App started. Device ready");
window.plugins.webintent.getExtra(window.plugins.webintent.EXTRA_STREAM,
function(data) {
console.log(data); // which never gets called
}, function(e) {
console.log(e);
// I simply get the message "Error"
});
}
</script>
</head>
<body onload="init()">
<h1>Demo WebIntent</h1>
</body>
</html>
so nothing really special here.
after searching the net for a while I found some information about the webintent plugin being buggy (as mentioned here on SO. So i found the patched version and double checked that the right code is in the WebIntent.java file, which is.
I also added the intent-filter tags in the AndroidManifest.xml file like so:
<intent-filter>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="image/*" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
When i installed the app on the device and try to share an Image my app shows up in the list of apps that are able to handle this sharing, and i also get the "App started..." text, so I know it gets called.
But no matter what kind of image i try i always reach the "error" part of the getExtra method and my console.log only shows "Error". Debugging is done directly on the device via GapDebug.
Is there anything I am missing or has anyone an idea on making my app getting images from other apps to work with?
Thanks in advance!
There is a bug in that Cordova plugin, use this fork instead
https://github.com/florentvaldelievre/virtualartifacts-webintent
so just remove the old one
cordova plugin rm com.virtualartifacts.webintent
and add the new one
cordova plugin add https://github.com/florentvaldelievre/virtualartifacts-webIntent.git
that should be it, although I'm didn't need to run js\webintent.js to get it to work.
This works when selecting a single image, arrays of streams doesn't seem to work yet.
I am integrating famo.us application with apache cordova, i've followed the following steps to achieve this task
1) Installed the cordova , famo.us and all the other packges necessary to build cordova as well as famo.us applications
2) I've created a famo.us project using yo famous, as per suggested on this link : https://github.com/Famous/famous and have also served it using grunt serve
3) i copied the timbre tutorial from the famo.us starter kit and pasted into the app folder of the famo.us project (build through yo famous ).
4) Then again i served the project using grunt serve and it worked absolutely fine in browser (chrome and Firefox both)
5) Then i created a project in netbeans by new project -> html5 -> cordova application
6) Then i copied all the content in app folder of famo.us application and pasted in www folder of cordova project and built it using net beans and tested it on browser and it worked absolutely fine (both chrome and firefox)
7) Then i built the cordova project on my Android and it's not showing the strip view of the Timbre Sample Application of famo.us, it opens the menu drawer but there all i can see the blank white background and nothing where it was supposed to show the strip view options of the timbre project
8) Then i copied the package from cordova project platform -> android -> AndroidManifest.xml and pasted it into the DDMS of eclips and opened the menu drawer and see the following error on it:
err: has no method 'now' at http://code.famo.us/famous/0.2/famous.min.js:48
I don't know where i am going wrong, I've also tried download http://code.famo.us/famous/0.2/famous.min.js file and saved it into the js folder in www folder of cordova project and included it into the html and also check it is including, but facing the same problem.
I am doing Google on it from so many time but no success. Please guide me in this regards. it's working absolutely fine on browser but not on the Android.
Also please let me know if there is any other more efficient way to integrate Famo.us Project with Apache Cordova.
EDIT
I've added the code.famo.us in my whitelist, the config.xml code is:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<widget xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" id="com.coolappz.coda" version="1.0.0">
<name>coda</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="dev#cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html"/>
<access origin="*"/>
<access uri="code.famo.us" subdomains="false" />
<access uri="*" subdomains="true" />
</widget>
but still i got the error
err: 09-17 13:23:58.666: E/Web Console(13557): Uncaught TypeError: Object #<Performance> has no method 'now' at file:///android_asset/www/js/famous.min.js:48
index.html file is:
<!DOCTYPE HTML>
<title>famo.us App</title>
<meta name="viewport" content="width=device-width, maximum-scale=1, user-scalable=no" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- shims for backwards compatibility -->
<script type="text/javascript" src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<script type="text/javascript" src="http://code.famo.us/lib/classList.js"></script>
<script type="text/javascript" src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<!-- module loader -->
<script type="text/javascript" src="http://code.famo.us/lib/require.js"></script>
<!-- <script type="text/javascript" src="js/famous.min.js" ></script>-->
<!-- famous -->
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.2/famous.css" />
<script type="text/javascript" src="http://code.famo.us/famous/0.2/famous.min.js"></script>
<!-- app code -->
<link rel="stylesheet" type="text/css" href="css/app.css" />
<script type="text/javascript">
require.config({
baseUrl: './src/'
});
require(['main']);
</script>
<body></body>