Andrea Aloi February 2016

ionic download file, save to temporary filesystem and open with default app

I've searched far and wide but couldn't find an appropriate answer for my use-case. Basically I'd like to download a base64-encoded file (could be a pdf, pgn, jpeg - using a pdf in the following example) from my backend, save it to a TEMPORARY fileSystem folder, then open it - possibly using the appropriate app on the device, if present. Let /file be a route served by the following ASP.NET MVC WebAPI Controller:

public class FileController : ApiController
{
    // POST api/file/
    public HttpResponseMessage Post([FromBody]string fullPath)
    {
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        var stream = new FileStream(fullPath, FileMode.Open);
        result.Content = new StreamContent(stream);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        return result;
    }

}

I came up with the following AngularJS script:

$scope.download = function(fileName) {
    window.requestFileSystem(window.TEMPORARY, 1024*1024*500, function(fileSystem) {
        fileSystem.root.getDirectory("TempDir", {create: true}, function(dirEntry) {
            dirEntry.getFile(fileName, {create: true, exclusive: false}, function(fileEntry) {
                $http.post("/file", JSON.stringify(fileName), {
                    headers: {Accept: "application/octet-stream"}
                }).success(function(res) {
                    fileEntry.createWriter(function(fileEntryContent) {
                        var blob = new Blob([res], {type: "application/pdf"});
                        fileEntryContent.write(blob);
                        //Now load file
                        $scope.load(fileName);
                    });
                }).error(function(err) {
                    console.warn(err);
                });
            }, function(err) {
                console.warn("getFile failed:", err);
            });
        

Answers


JOC February 2016

FileOpener2 plugin is pretty much you're only option I think - and it can work in this scenario. You'll need to make sure the file is saved outside your app's container on the device, as other apps cannot access this. You can find the file structure for each platform, and what is/isn't public, on the plugin page. You'll also need to save to different locations depending on the platform. This works for me:-

if (ionic.Platform.isIOS()) storagePath = cordova.file.cacheDirectory + "/temp";
else if(ionic.Platform.isAndroid()) storagePath = cordova.file.externalRootDirectory + "/yourapp/temp";

You can then use storagePath as the base for your targetPath when downloading. I would highly recommend using ngCordova. The sample below is partially based on something that I'm successfully using on iOS and Android but I haven't tested it

// add your options here, i.e. any headers you need to add to the request
var options = {};
$cordovaFileTransfer.download(url, targetPath, options, true).then(function(result) {
    //On successful transfer try and extract the file object
    result.file(function (file) {
        var localFile = file.localURL;
        resolveLocalFileSystemURL(localFile, function (entry) {
            var nativePath = entry.toURL();
            // Open in another app, will fail if app doesn't exist that can open the mime type
            $cordovaFileOpener2.open(nativePath, mime).then(function () {
               // Success!
            }, function (err) {
               // Error!
            });
        }, function(error) {
            //handle error here
        });   
    }, function (error) {
        // handle error here 
    });        
}, function (err) {
    //handle error here
});

Post Status

Asked in February 2016
Viewed 3,232 times
Voted 8
Answered 1 times

Search




Leave an answer