I am unable to access the filesystem using steroid.js. I have used the exact same code within phonegap and do not have the issue. here is my code and I do not appear to get any errors in my console.
var captureSuccess = function(mediaFiles) {
mediaFiles[0].getFormatData(function(data) {
if(data.duration > 10) {
window.resolveLocalFileSystemURI(mediaFiles[0].fullPath, FileRemoveSuccess, function() {
navigator.notification.alert('Error: Unable to access file system')
});
}
else{
$('#video-content').append('<video width="320" height="240" controls><source src="' + mediaFiles[0].fullPath + '" type="video/mp4"></video><br><span>' + mediaFiles[0].fullPath + '</span>');
}
});
};
// capture error callback
var captureError = function(error) {
navigator.notification.alert('Error code: ' + error.code, null, 'Capture Error');
};
// start video capture
function RecordVideo(){
navigator.device.capture.captureVideo(captureSuccess, captureError, {duration:10});
}
I have also tried to access an image by putting in the path manually or a video and I have the same issues. Is there something I am missing?
If you're serving your app via localhost (e.g. steroids.config.location = http://localhost/index.html, then built-in WebKit security will block assets from file:///, since it's in a different domain. Is that the case? We're working on a solution for all CORS issues, but see http://guides.appgyver.com/steroids/guides/steroids-js/app-structure-on-device/ for information on how a Steroids app is structured on the device (and thus how you can access files via localhost).
It turns out that not only your index.html file needs to be served as a file but so do any other webviews you create using the new steroids.views.WebView command. Once I corrected this, the issue was resolved
Related
I am working on a hybrid android app using Cordova for the Galaxy Tab E.
Everything works as expected on my computer browser, same thing on my tab except for my audio files, but the sound is not working.
What I tried :
- Use HTML5 with on a button, image... : no sound (on the tab)
- Use JavaScript with « onclick » on a button, image... same
- Cordova Media Plugin with the associated script : same
- Try to change the path /www/audio/ with /android_assets/www/audio/ or file:/// (...) : same thing everywhere
- Try to change a .wav or .mp3 : same
It only works both on computer and on the tab when I use an URL to link the MP3, but not in local (and that’s definitely what I must implement, cause tabs will not have an internet connection)
Kindly guide to solve this issue, thanks.
Its probably best to follow the second answer given here How to get Path for local mp3 file from www in Phonegap IOS?
to generate the file path, however with that caveat this is the code that worked for me on Android with cordova-plugin-media:
audioSuccess = loadAudio('sounds/success.wav');
function loadAudio(file) {
var path = window.location.pathname;
path = path.substr(path, path.length - 10);
var id = path + file;
console.log('loading audio: ' + id);
var my_media = new Media(id,
// success callback
function () { console.log("loadAudio():Audio Success on id - now setting volume " + id);},
// error callback
function (err) { console.log("loadAudio():Audio Error: " + JSON.stringify(err) + ' on id ' + id); }
);
return my_media;
};
audioSuccess.play();
I'm a novice when it comes to the development of apps. I made a simple audio player app for android and iOS and build it with phonegap build.
The app uses the <audio> html tag to load mp3 files that are located on a remote server like so:
<div class="mobileui-music-cover-controls">
<audio ontimeupdate="udpateProgress()" id="player">
<source src="http://www.myserver.com/audiofile.mp3" type="audio/mpeg">
</audio>
<a id="playKnop" href="JavaScript:playMusic()" class="play"><i class="ion-ios-play"></i></a>
<a id="pauseKnop" href="JavaScript:pauseMusic()" class="play"><i class="ion-ios-pause"></i></a>
</div>
obviously, I changed the scr for this example.
It works fine as long as you have a stable internet connection but a few people are experiencing connection drops etc.
I would like to make the files offline available on user request. So it has to be optional (by clicking a button or something like that).
The app should detect if the file is present on the device and if so choose the local file over the remote file.
In short, I have 2 questions.
How can I download a specific file on user request?
How can I check whether the file is there or not and play the right file?
I can't seem to figure out how to do this I'm working on it for the last couple of days but I honestly have no clue on how to achieve this. Any help would be greatly appreciated.
As you said you need to download the file to your device. Since your using cordova you could use fileTransfer to download the audio. This is very straight forward (this is the offical example code):
// !! Assumes variable fileURL contains a valid URL to a path on the device,
// for example, cdvfile://localhost/persistent/path/to/downloads/
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://some.server.com/download.php");
fileTransfer.download(
uri,
fileURL,
function(entry) {
console.log("download complete: " + entry.toURL());
},
function(error) {
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("download error code" + error.code);
},
false,
{
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
The next time you want to play the audio you need to check if there is a local version. Either you check your device if that file exists (there are many ways, e.g. Cordova check if file in url exists) or you make use of something like localStorage which basically is a simple lil database.
// more or less pseudo code!!!
// callback from fileTransfer when your file was downloaded
function downloadSuccess(entry) {
// save it to localStorage
// key: the remote URL, value: the local URL
localStorage.setItem(remoteURL, entry.toURL());
}
...
...
// the check if there is a cached file
var remoteSrc = "http://www.myserver.com/audiofile.mp3";
var localSrc = localStorage.getItem(remoteSrc);
if(localSrc === null) {
// when there is NO cached version, use remote
audioElement.src = remoteSrc;
} else {
// when there IS a cached version, use local
audioElement.src = localSrc;
}
I hope this helps and gives you an idea how to accomplish simple caching yourself :)
I'm using cordova-plugin-file to read my mp3 file with the readAsArrayBuffer method. It works perfect with a file less than 20mb, but with a larger file it causes the app to crash with this error. (I'm using crosswalk browser)
E/chromium( 3330): [ERROR:simple_index_file.cc(223)] Failed to write the temporary index file
E/chromium( 3330): [ERROR:runtime_javascript_dialog_manager.cc(69)] Not implemented reached in virtual void xwalk::RuntimeJavaScriptDialogManager::ResetDialogState(content::WebContents*)
I'm so confused with what the problem is. Does the problem come from xwalk or cordova-plugin-file?
Please help me because this plugin can only read file smaller than 20mb size.
I found a solution for this bug.
I think Cordova-plugin-file can't send large amount of data from native to javascript. So I try to research from Crosswalk Browser API and very happy to see that they support File API. It can get access directly to Android file system through virtual root like : EXTERNAL, CACHEDIR, DOWNLOADS, ...
Here is the trick to read any big file with Crosswalk:
function readFileAsArrayBuffer(storage, path, file) {
xwalk.experimental.native_file_system.requestNativeFileSystem(storage,
function (fs) {
fs.root.getFile(storage + "/" + path + file, {create: false}, function (entry) {
entry.file(function (file) {
reader = new FileReader();
reader.onloadend = function (data) {
//Data after read.
};
reader.readAsArrayBuffer(file);
},
},
function (e) {
console.error("2-" + JSON.stringify(e))
});
},
function (e) {
console.error("3-" + JSON.stringify(e));
});
}
//test
readFileAsArrayBuffer("EXTERNAL", "downloads/folder/", "file.mp3");
I am able to download an image if I specify the path directly with
file:///storage/sdcard0/
How can I save an image to my one of the folders in my app ? I tried this approach to set app path but it doesn't work for me.
This is what I am using so far and it works if you want to save and image to sdcard:
var fileName = "myImage.png";
var fileTransfer = new FileTransfer();
var uri = encodeURI("http://my.url.to.image/myImage.png");
var filePath = "file:///storage/sdcard0/uploads/myImage.png";
fileTransfer.download(
uri,
filePath,
function(entry) {
alert("download complete: " + entry.fullPath);
console.log("download complete: " + entry.fullPath);
},
function(error) {
alert("download error source/target/code:\n" + error.source +" \n||| "+error.target+" \n||| "+error.code);
console.log("download error source/target/code " + error.source+" / "+error.target+" / "+error.code);
}
);
If I use this function:
function getPhoneGapPath() {
'use strict';
var path = window.location.pathname;
var phoneGapPath = path.substring(0, path.lastIndexOf('/') + 1);
return phoneGapPath;
}
I get /android_asset/www/. How would I get the correct path to my app?
The app is using AngularJS and is not bootstrapped in onDeviceReady (developer before me made it that way and now changing it to something like this is beyond me (tried but didn't work)).
Another question I can refer to was asked here.
I also tried this, this, this and this but none worked for me. I get "" for fullPath and recently I managed to get path printed with .toURL() and it was "cdvfile://localhost/persistent". The above download code now also works if I use
filePath = "cdvfile://localhost/persistent/MyAppID/uploads/myImage.png";
but this creates folder /MyAppID/uploads in /storage/sdcard0 which is bad again. My app needs to get to images with
<img src="uploads/myImage.png" alt="myimg"/>
Another useful link is here but it offers no help as to how to write to pre-created folder of your own app.
EDIT: As far as I've learned you cannot write within your own app(read only). That's why I tried to reference images from sdcard with
<img src="file:///storage/sdcard0/Android/data/com.app.my/cache/myImage.png" alt="myimg"/>
and this works! :) Unfortunately this is hardcoded and not good since other phones might have a different persistent location.
If I try
<img src="cdvfile://localhost/persistent/Android/data/com.app.my/cache/myImage.png" alt="myimg"/>
this does not reference the picture :/ (it does download it on storage/sdcard0/Android/data/com.app.my/cache/ though)
I would use the folder alias as defined in the plugin docs here (https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md). Specifically cordova.file.dataDirectory. Note that this is not, afaik, under the www of your original project, but it seems to be the preferred place to store downloads. Once saved there you can resolve that to a URL that you could use to load via AJAX, or in an img tag if you are downloading graphics.
As far as I learned you cannot write to your own app (change items inside your app - /www folder on Android).
My solution was to save images to PERSISTENT storage (sdcard usually).
You can get the path of your app's persistent storage with these steps:
function onDeviceReady() {
console.log('Device Platform: ' + device.platform); // returns 'Android' or 'iOS' for instance
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
cacheFolderSubPath = "Android/data/com.id.myApp/cache/"; // this is app's cache folder that is removed when you delete your app! (I don't know what this path should be for iOS devices)
}
Then inside gotFS success callback
function gotFS(fileSystem) {
var nturl = fileSystem.root.toNativeURL(); // cdvfile://localhost/persistent/
window.resolveLocalFileSystemURL(nturl+cacheFolderSubPath, onResolveSuccess, onResolveFail);
}
and in onResolveSuccess
function onResolveSuccess(fileEntry){
appCachePath = fileEntry.toNativeURL()+"/"; // file:///storage/sdcard0/Android/data/com.id.myApp/cache/ in my case but some other Androids have storage/emulated/0 or something like that ...
continueCustomExecution();
}
and now in continueCustomExecution() you can run your program and do whatever it is you do ... and in this case download images into appCachePath that we got earlier. You can now successfully reference images in src tags with our appCachePath+yourImageName.
Unfortunately I still don't know how to download an image successfully on iOS. I get an error code 1 with FileTransfer plugin ... (saving to file:///var/mobile/Applications/my.app.id/Documents/). Probably should save somewhere else but this is the path I get when requesting PERSISTENT FileSystem.
Cheers
I have made an HTML 5 application that downloads a pdf file on my server, and writes it in the browser sandbox system.
When I go to filesystem:myServerUrl/persistent, I see my pdf file with the correct size. I click on it, and there is a "download started" notification, but about one second later, I get a download error (Reason 404 when I look into the Android logs).
I tried with a Download. But I have the same error.
Note that it is working fine on my computer, and when I try with an image, I can display it directly (just clicking on the file name), but cannot download it.
I can't find any piece of information anywhere, am I missing something ?
How I download my file :
function fetchResource() {
var xhr = new XMLHttpRequest();
xhr.open("GET", resourceURL, true);
xhr.responseType = "arraybuffer";
xhr.onload = function(e) {
console.log("xhr responded");
if (this.status == 200) {
console.log("status 200");
writeFile(this.response);
}
}
xhr.send();
console.log("xhr sent");
}
How I write my file :
function writeFile(content){
console.log("writeFile");
fs1.root.getFile('test2.pdf', {create: true}, function(fileEntry) {
// Create a FileWriter object for our FileEntry (log.txt).
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) {
console.log('Write completed.');
alert("completed");
};
fileWriter.onerror = function(e) {
console.log('Write failed: ' + e.toString());
alert("erreur: "+e.toString());
};
var blob = new Blob([content]);
fileWriter.write(blob);
}, errorHandler);
});
}
Update: the exact error message in English is
<Untitled>
Download unsuccessful
Also, when I display a local image, and I long-click it, the option "Save Image" is disabled. Could it be intented? Why?
I have just tested this on Stable, Beta. And it kind of works.
Stable (27) has a problem where it can't download client generated files. For example if you use the a[download] attribute you will see that it opens up the downloader but just sits there doing nothing.
In the Beta (28) everything works as expected, so I would expect your pdf to also save.
I simplified your code here: http://jsbin.com/opavet/latest which works for both links on Beta. But only the later on stable.