Hi all,
My apps need choose file pdf, docx, excel,… and upload to server.
I have search and find some plugins:
but don’t support IOS.
Can you recommended plugin?
Thank you so much!
Hi all,
My apps need choose file pdf, docx, excel,… and upload to server.
I have search and find some plugins:
but don’t support IOS.
Can you recommended plugin?
Thank you so much!
Well either plugin will work for android so you can use which ever you want.
For iOS, you sadly don’t have a file browser/chooser.
Not going to be possible sadly.
Apparently there’s this one, haven’t tried it and sadly it’s only for iOS8 (and higher?):
Anyway I suppose that if you understand the physical file system structure of iOS and you have the time then you could always build a UI yourself using the Cordova File plugin. Don’t know about iCloud and so on though.
By the way I tried https://github.com/don/cordova-filechooser and it worked perfectly.
The other one (https://github.com/cdibened/filechooser) seems more complicated to set up and gave me build errors on my initial attempt, so I went with the other one.
Well I’ve done it like this, this should work on Android and on iOS but I’ve only tested it on Android:
function checkFileType(path, fileExt) {
return path.match(new RegExp(fileExt + '$', 'i'));
}
function chooseFileOk(deferred, uri, fileExt) {
$log.debug('FileManager#chooseFile - uri: ' + uri + ', fileType: ' + fileExt);
if (!checkFileType(uri, fileExt)) {
deferred.reject('wrong_file_type');
} else {
deferred.resolve(uri);
}
}
function chooseFileError(deferred, source) {
$log.debug('FileManager#chooseFile - ' + source + ' error: ' + JSON.stringify(error));
// assume operation cancelled
deferred.reject('cancelled');
}
var chooseFile = function (fileExt) {
var deferred = $q.defer();
// iOS (NOTE - only iOS 8 and higher): https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin
if (ionic.Platform.isIOS()) {
FilePicker.pickFile(
function (uri) {
chooseFileOk(deferred, uri, fileExt);
},
function (error) {
chooseFileError(deferred, 'FilePicker');
}
);
// Android: https://github.com/don/cordova-filechooser
} else {
fileChooser.open(
function (uri) {
chooseFileOk(deferred, uri, fileExt);
},
function (error) {
chooseFileError(deferred, 'fileChooser');
}
);
}
The main function is called “chooseFile” and I can pass it a “fileExt” parameter to restrict the kind of files that can be selected (e.g. only ‘pdf’ files).
Typically you’d package the function inside a service. It returns a promise so you then use it like:
FilePickerService.chooseFile('.pdf').then(function(url) {
// do something with the selected file
}).catch(error) {
// something wrong, log it or show a message
});
The code uses 2 plugins: FilePicker for iOS and fileChooser for Android. Install them as follows:
ionic plugin add https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin.git
ionic plugin add https://github.com/don/cordova-filechooser
Does that make sense?
can you now tell if filechooser for ios is workable anyway ?
Thanks for sharing such a nice solution…
I faced Issue in Pdf filtering in above script. In android file extension was not available in uri. to solve this issue I used cordova-plugin-filepath
for getting native file path.
1 plugin used.
cordova plugin add cordova-plugin-filepath
I modified function chooseFileOk() see below …
` function chooseFileOk(deferred, uri, fileExt) {
$log.debug('FileManager#chooseFile - uri: ’ + uri + ', fileType: ’ + fileExt);
window.FilePath.resolveNativePath(uri, function(localFileUri) {
if(localFileUri!= 'undefined' && localFileUri!="" )
{
if(localFileUri.match(new RegExp(fileExt + '$', 'i'))){
console.log("This must execute.....");
deferred.resolve(uri);
}else{
deferred.reject('wrong_file_type');
}
}else{
deferred.reject('URI NOT Resulted to any File in system');
}
});
}`
Thanks.
As an addition to this post, the original cordova-plugin-filepath does not work on Android 6, due to the permission system.
I forked the code, and updated the plugin, although it requires Cordova 6.0.0 now (originally, it required Cordova 3.4.0).
Version 1 of the updated plugin can be found at:
Installation:
Either:
cordova plugin add cordova-filepath-resolver
Or:
ionic plugin add cordova-filepath-resolver
… whichever you prefer.
[EDIT] Plugin is in the repo’s now, updated the links
hi leob,
I use this code.but i get following error
filechooser.chooseFileok is not a function
How can i access only audio files in both internel and externel storage using fileChooser plugin.
Please Advice me…
Thanks & Regards,
Probably you didn’t install the Cordova plugins then? You need to do:
ionic plugin add https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin.git
ionic plugin add https://github.com/don/cordova-filechooser
I think that’s the reason for the “missing function”.
And regarding the audio files, you can set file name filters on the plugin.
hi leob,
again i reinstall plugin
ionic plugin add https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin.git
ionic plugin add https://github.com/don/cordova-filechooser
This is my code
MediaSrv.chooseFile(’.mp3’).then(function(url) {
console.log(url);
});
and
app.factory(“MediaSrv”, function($q) {
var deferred = $q.defer();
function checkFileType(path, fileExt) {
return path.match(new RegExp(fileExt + '$', 'i'));
}
function chooseFileOk(deferred, uri, fileExt) {
$log.debug('FileManager#chooseFile - uri: ' + uri + ', fileType: ' + fileExt);
if (!checkFileType(uri, fileExt)) {
deferred.reject('wrong_file_type');
} else {
deferred.resolve(uri);
}
}
function chooseFileError(deferred, source) {
$log.debug('FileManager#chooseFile - ' + source + ' error: ' + JSON.stringify(error));
// assume operation cancelled
deferred.reject('cancelled');
}
var chooseFile = function (fileExt) {
//function chooseFile(fileExt){
var deferred = $q.defer();
// iOS (NOTE - only iOS 8 and higher): https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin
if (ionic.Platform.isIOS()) {
FilePicker.pickFile(
function (uri) {
chooseFileOk(deferred, uri, fileExt);
},
function (error) {
chooseFileError(deferred, 'FilePicker');
}
);
// Android: https://github.com/don/cordova-filechooser
} else {
fileChooser.open(
function (uri) {
chooseFileOk(deferred, uri, fileExt);
},
function (error) {
chooseFileError(deferred, 'fileChooser');
}
);
}
}
return deferred.promise;
});
But Still i get MediaSrv.chooseFileok is not a function error
Pls help me
Thanks& Regards,
The definition of your factory looks a bit weird.
Why does your factory start with declaring a deferred, and end with returning a deferred? And the function ‘chooseFile’ itself isn’t exported from the factory. Maybe that’s the reason why it says “chooseFileOk” unknown.
Have a look at my implementation:
;(function () {
"use strict";
angular.module('app.image')
//
// https://github.com/apache/cordova-plugin-file
// http://www.raymondcamden.com/2014/08/18/PhoneGapCordova-Example-Getting-File-Metadata-and-an-update-to-the-FAQ
// http://www.html5rocks.com/en/tutorials/file/filesystem/
// http://community.phonegap.com/nitobi/topics/dataurl_to_png
//
.factory('FileManager', function ($q, $log, $cordovaFile, $cordovaFileTransfer) {
var downloadFile = function(sourceURI, targetDir, targetFile) {
var deferred = $q.defer();
$log.debug("FileManager#downloadFile source (original): '" + sourceURI + "'");
sourceURI = decodeURI(sourceURI);
var targetPath = targetDir + targetFile;
var trustHosts = true;
var options = {};
$cordovaFileTransfer.download(sourceURI, targetPath, options, trustHosts).then(
function(result) {
deferred.resolve(result);
}, function(error) {
deferred.reject(error);
}, function (progress) {
//$timeout(function () {
// $scope.downloadProgress = (progress.loaded / progress.total) * 100;
//})
});
return deferred.promise;
};
var getFileInfo = function (baseDir, filePath) {
var deferred = $q.defer();
$log.debug("FileManager#checkFile baseDir = '" + baseDir + "', filePath = '" + filePath + "'");
$cordovaFile.checkFile(baseDir, filePath).then(
function (fileEntry) {
fileEntry.getMetadata(
function (result) {
deferred.resolve(result);
},
function (error) {
deferred.reject(error);
}
);
},
function (error) {
deferred.reject(error);
}
);
return deferred.promise;
};
var removeFile = function (baseDir, filePath) {
$log.debug("FileManager#removeFile baseDir = '" + baseDir + "', filePath = '" + filePath + "'");
return $cordovaFile.removeFile(baseDir, filePath);
};
//function checkFileType(path, fileExt) {
// return path.match(new RegExp(fileExt + '$', 'i'));
//}
var checkFileType = function (uri, fileType) {
var deferred = $q.defer();
$log.log("FileManager#checkFileType uri = " + uri + " fileType = " + fileType);
// See: https://github.com/hiddentao/cordova-plugin-filepath and:
// stackoverflow.com/questions/31338853/cordova-camera-plugin-obtain-full-image-path-from-gallery-android
window.FilePath.resolveNativePath(uri,
function (result) {
var fileURI = 'file://' + result;
$log.log('FileManager#checkFileType uri = ' + uri + ' fileURI = ' + fileURI);
// See: https://github.com/cfjedimaster/Cordova-Examples/wiki/PhoneGap-Cordova-File-System-FAQ#meta
window.resolveLocalFileSystemURL(fileURI,
function (fileEntry) {
fileEntry.file(function(file) {
var s = "";
s += "name: " + file.name + " ";
s += "localURL: " + file.localURL + " ";
s += "type: " + file.type + " ";
s += "lastModifiedDate: " + (new Date(file.lastModifiedDate)) + " ";
s += "size: " + file.size;
$log.info('FileManager#checkFileType uri = ' + uri + ' fileURI = ' + fileURI + ' INFO: ' + s);
if (file.type && file.type === fileType) {
deferred.resolve(file);
} else {
$log.warn('FileManager#checkFileType uri = ' + uri + ' fileURI = ' + fileURI +
' wrong file type: ' + file.type + ' instead of ' + fileType);
deferred.reject('wrong_file_type');
}
});
},
function (error) {
$log.error('FileManager#checkFileType uri = ' + uri + ' fileURI = ' + fileURI +
' ERR = ' + JSON.stringify(error));
deferred.reject(error);
}
);
},
function (error) {
$log.error('FileManager#checkFileType uri = ' + uri + ' ERR = ' + JSON.stringify(error));
deferred.reject(error);
}
);
return deferred.promise;
};
function chooseFileOk(deferred, uri) {
$log.log('FileManager#chooseFile - uri: ' + uri);
deferred.resolve(uri);
}
function chooseFileError(deferred, source) {
$log.debug('FileManager#chooseFile - ' + source + ' error: ' + JSON.stringify(error));
// assume operation cancelled
deferred.reject('cancelled');
}
var chooseFile = function () {
var deferred = $q.defer();
// iOS (NOTE - only iOS 8 and higher): https://github.com/jcesarmobile/FilePicker-Phonegap-iOS-Plugin
if (ionic.Platform.isIOS()) {
FilePicker.pickFile(
function (uri) {
chooseFileOk(deferred, uri);
},
function (error) {
chooseFileError(deferred, 'FilePicker');
}
);
// Android: https://github.com/don/cordova-filechooser
} else {
fileChooser.open(
function (uri) {
chooseFileOk(deferred, uri);
},
function (error) {
chooseFileError(deferred, 'fileChooser');
}
);
}
return deferred.promise;
};
return {
downloadFile: downloadFile,
checkFileType: checkFileType,
getFileInfo: getFileInfo,
removeFile: removeFile,
chooseFile: chooseFile
};
});
}());
Hello,
I tried the code you provide and I get the file browser to show up and I can pick a file. However, the callback is not getting triggered…
I see this error in the android console
W/CordovaInterfaceImpl: Got an activity result, but no plugin was registered to receive it
I am using cordova 6.3.1 and SDK 23 android 5.2.2
Thanks for your help.
I’ll have a look at it, right now I’m traveling but I’ll be in a hotel with Wifi tonight, will have a look when I have some time …
Hello Leob,
Just checking to see if you had a moment to look into this issue…
Thanks
Not yet but it’s in my inbox, I’ll get around to it.
Will Same plugin work on Ionic 2, I am trying the same for Ionic 2 but getting the following error on real device
[Error] EXCEPTION: undefined is not an object (evaluating ‘a.plugins.fileChooser.open().then’)
FilePicker is Available & returning true, Following is my code
fileChooser = {
open () : Promise {
console.log(‘FilePicker will Load in new Way’);
return FilePicker.pickFile().then((uri) => {
return uri;
}, (err) => {
console.log(‘Failed to Load’);
});
},
}
Well, for Android I’m using the file chooser plugin but for iOS I’ve switched from the “FilePicker” plugin to a simple HTML5 “file” input element, which turns out to be easier to use AND functionally superior … see here how to implement it:
Actually I did not literally use the code from the gist, I still had to make a few changes to get it working properly (with the code from the gist the “onchange” event didn’t always fire). If anyone is interested in my final solution then I can post it here.
And for iOS 9 and higher you need to configure “entitlements” (for iOS 10 therre’s even an additional requirement), all in all I think I spent the better part of a week just to get the iOS solution working!