please anyone help me to access device external memory(sd card) using Ionic-v4 and Angular 6 and platform is Android.
I have tried using Ionic native file, but it shows the path of Internal memory only.
// file system access
import { File } from '#ionic-native/file/ngx';
// file opener
import { FileOpener } from '#ionic-native/file-opener/ngx';
// document viewer
import { DocumentViewer, DocumentViewerOptions } from '#ionic-native/document-viewer/ngx';
............
let path = this.file.externalRootDirectory;
this.file.checkDir(path, 'mydir').then(_ => {
console.log('Directory exists');
this.showAlert('Directory exists','','Directory exists: '+path);
}).catch(err =>{
console.log('Directory doesnt exists');
this.showAlert('Directory doesnt exists','','Directory doesnt exists: '+path);
});
Then I tried getExternalSdCardDetails() method of cordova-diagnostic-plugin
import { Diagnostic } from '#ionic-native/diagnostic';
.........
this.diagnostic.getExternalSdCardDetails().then(obj => {
this.showAlert('xxxxxxxx','','xxxxxxxx: '+JSON.stringify(obj));
}, (errData)=>{
});
But it is not working.
I am new to Ionic, please anyone help to just read the external memory or sd-card in Ionic4 and angular6 for android platform.
Thank you.
I think you can use externalApplicationData in your app and move the app to an external SD card. Go to App Details > Storage. If the option to move to external is not available, enable developer options on the phone and "force enable apps to external card". Now, the app will have full access to its own sand-boxed data on external card, even though the Ionic file will still report something like "file://storage/emulated/0".
with file plugin you can use like that
await this.file.listDir(this.file.externalRootDirectory, '')
Or you can refer demo here in link that's a file manager app using ionic
https://github.com/JainBhavesh/FileManagerIonic4
Related
I am using Dio Package for downloading files and using the path_provider package to get the system path to save files.
Directory? appDocumentsDirectory =
Platform.isIOS ? await getApplicationDocumentsDirectory() : await getExternalStorageDirectory();
but I heard that the getAppicationDocuments directory and External Storage in android are visible to the user so how can I make it invisible?
You may like to use Flutter Secure Storage it stores encrypted file that is not accessible by the end-user except if the user has rooted the device.
https://pub.dev/packages/flutter_secure_storage
I am building app that allows people to post pictures and videos, mainly trying to learn about ionic, cordova, android, and the like, but for some reason whenever I try to open a file using the cordova File plugin, it doesn't ask the user permission to access storage, and the code fails and the user is stuck on a loading screen.
The code is pretty simple, they take a video, it gets transcoded, then the transcoded file is uploaded to a firebase storage bucket. If I quit the app, go to settings->apps->my app->permissions and then manually turn on the storage permission, it works. The problem is, I need to ask the user for permission either at run time or on install, and it doesn't. Here is the code..
this.media.captureVideo().then(file => {
this.editor.transcodeVideo({
fileUri: file[0].fullPath,
outputFileType: this.editor.OutputFileType.MPEG4,
outputFileName: 'temp_test',
saveToLibrary: false,
height: 800,
width: 800,
maintainAspectRatio: false
}).then(fileUri => {
let pathIndex = fileUri.lastIndexOf('/'),
finalPath = 'file://' + fileUri.substr(0, pathIndex),
name = fileUri.substr(pathIndex + 1, fileUri.length);
this.file.readAsArrayBuffer(finalPath, name).then(file => {
//upload
}).catch(err => { console.log(err); });
});
});
However, this only works if I open up the settings on my phone, go to apps, then my app, then permissions, then enable storage manually. Is there some way to request the permission in ionic? I have searched and searched and all the answers I can find are specific to camera, or work in Java, but ionic isn't java. Thank you.
Effectively cordova-plugin-media-capture uses cordova-plugin-file, so the READ_EXTERNAL_STORAGE permission must be programatically asked.
Ionic offers native support for Android Permissions:
this.androidPermissions.hasPermission(this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE)
.then(status => {
if (status.hasPermission) {
this.captureVideo();
} else {
this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE)
.then(status =>{
if(status.hasPermission) this.captureVideo();
});
}
}
Hope it helps.
The only thing that worked for me was the Android Diagnostic plugin. Check this post.
I'm trying this code:
function onDeviceReady() {
requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSystem) {
alert(fileSystem.root.toURL());
fileSystem.root.getDirectory('myDir', { create: true }, function (myDirEntry) {
alert(myDirEntry.toURL());
myDirEntry.getDirectory('mySubDir', { create: true }, function (mySubDirEntry) {
alert(mySubDirEntry.toURL());
alert('/myDir/mySubDir creation is done');
}, getDirectoryError);
}, getDirectoryError);
}, requestFileSystemError);
As a result of executing it on a Samsung SM-G318ML, Kernel version 3.10.17-983426, I got alerts showing the following messages:
file:data/data/com.mydomain.myapp/files/files/
file:data/data/com.mydomain.myapp/files/files/myDir
file:data/data/com.mydomain.myapp/files/files/myDir/mySubDir
/myDir/mySubDir creation is done.
Neverthless, when I look in my device's file system I have no desired directories created... besides it a strange directory, called .mtp, was created, void, at system root.
My goal is create and read files to/from /com.mydomain.mayapp/files/profile/images directory. My code is based on a sample provided (in the end of the page) in Sample Link Followed ; I am using Cordova.File plugin, version 4.1.0, in an Intel XDK hybrid app project.
I have the necessary android.permission.WRITE_EXTERNAL_STORAGE permission defined.
Can someone point me in the right direction? All advices are welcome... thanks in advance.
Another document that I found very useful is here:cordova-plugin-file
according to this document:
cordova.file.dataDirectory - Persistent and private data storage within the application's sandbox using internal memory (on Android, if you need to use external memory, use .externalDataDirectory). On iOS, this directory is not synced with iCloud (use .syncedDataDirectory). (iOS, Android, BlackBerry 10, windows)
The directories that you are writting, are inside data/data folders, which belongs only to your app, and can't be accessed thought the device file system.
If you want to use public folders, check this table
https://github.com/apache/cordova-plugin-file#android-file-system-layout
And choose a folder that don't be private.
For example: externalApplicationStorageDirectory
Happy coding!
I have used Cordova File Plugin to create files on mobile device. Below is the code to create files:
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (dir) {
alert(cordova.file.dataDirectory);
dir.getFile("log.txt", { create: true }, function (file) {
alert("got the file: "+ file.name + ', ' + file.fullPath);
});
});
When I deploy the app on my android phone, the file will create successfully, but I can't find the created file on my device.
Although cordova.file.dataDirectory is pointing to file:///data/data/io.cordova.myappId/files/ path on my device, the io.cordova.myappId folder doesn't exist in data>data path, but exists in Android>data path. By the way, I checked both storage>Android>data>io.Cordova.myappId>files & storage>data>data and the file doesn't exist.
Is this because:
The created file is located in another place, so where can I find that?
or
Because it's private and my file manager doesn't have access to it, so how can I change the permission setting to have a public file?
Why I can't find the file on my device?
The file is created successfully but I can't find that on my device because the dataDirectory path which I indicates to create the file, is a private path and my device file manager doesn't have access to it (base on this table). Actually dataDirectory is an Internal Storage option.
Internal Storage: Store private data on the device memory.
You can save files directly on the device's internal storage. By
default, files saved to the internal storage are private to your
application and other applications cannot access them (nor can the
user). When the user uninstalls your application, these files are
removed.(reference)
How to create a public file?
So, to create a file on my device that I can access it with the file manager, I have to use one of public path options like:externalDataDirectory. Before, I was thinking it is for storing files on an external SD Card that I had not on my phone, so I didn't test it. But testing it today, it creates the file on my internal device storage in Android/data/<app-id>/files path which is public and I can access it with device file manager.
Actually the term internal and external was misleading for me while external storage can be a removable storage media (such as an SD card) or an internal (non-removable) storage(reference).
Reading/wiring files in Cordova is painful. I wrote a script that uses promises to make this easier.
Add cordova-file-storage.js to your project, then do the following:
// the object you want to save
var objectToSave = { firstName: 'John', lastName: 'Doherty' };
// the filename and extension you want to use
var filename = 'whatever.txt';
// the data to write (convert JSON object to a string)
var data = JSON.stringify(objectToSave);
// call write with params, .then executes with the filePath once complete
fileStorage.write(filename, data).then(function(filePath) {
console.log(filePath);
})
.catch(function(err) {
// this executes if something went wrong
console.warn(err);
});
It uses external storage by default. To use sandboxed storage inaccessible to the user add true as the last param.
Im working on an app (flex 4.12 sdk, using flashbuilder 4.5, creating an app for ios and android, testing on an android htc one primarily)... and am using the camera to capture a file... Im then saving that image to the application storage directory, and I want to open the image in the default web browser or trigger a native dialog (android users) to choose the web browser of their choice... how it opens isnt really important right now -- Im mainly trying to just 'access' it with the device and 'load' it outside my air app...
heres the code I have:
var fs2 : FileStream = new FileStream();
fs2.addEventListener(Event.CLOSE, fileCompleteHandler);
var targetFile : File = File.applicationStorageDirectory.resolvePath("test.jpg");
fs2.openAsync(targetFile, FileMode.WRITE);
fs2.writeBytes(myBMDByteArray,0,myBMDByteArray.length);
fs2.close();
and for the event listener that detects the close of the newly created file:
function fileCompleteHandler(e:Event):void {
trace('File saved.');
trace('exists? ' + targetFile.exists);
trace('the url: ' + targetFile.url);
trace('path: ' + targetFile.nativePath);
navigateToURL(new URLRequest(targetFile.url));
}
I get the following info back from this listener
File saved.
exists? true
the url: app-storage:/test.jpg
path: /data/data/air.com.xxxxx.apptesting.debug/com.xxxxx.apptesting.debug/Local Store/test.jpg
... and problem is that navigateToURL cant access the location where the file is stored (the protocol shows in browser as file:///data/data/air.com/xxx... )
how can I use navigateToURL to get access to this newly created file in the web browser or whatever native application the device associates with the file (its a .JPG file)? I also have had success in adding the newly created image to the camera roll but couldnt figure out how to then open that newly saved image in the native camera roll or whatever app the device chooses or presents to the user for the .jpg format.
I can show the user the image INSIDE my app by referencing the bitmap data fine, I just want to give the user access to the physical file that Im creating on their device.
I even have had success in posting (via urlLoader) the bitmap data as base64 encoding and then creating a file on the server side and loading that url but the encoding and trip to and from the server to give the user the image adds a lot of overhead and it takes a little too long and I'd like to avoid that elongated process.
Thanks for any help anyone can provide - let me know if I need to be more specific in any of this.
Solved the issue... I was able to store / write my file in the documentsDirectory using:
var targetFile : File = File.documentsDirectory.resolvePath('test.jpg');
and then
navigateToURL(new URLRequest(targetFile.url));
And this works fine now. Hopefully it helps someone else! Seems that the storage directory SHOULD work but up until now I've only written to and read files stored there... maybe to open the files one HAS to copy it to a 'safe' location in the filesystem (i.e. sd card?)... will move on to test in ios Now - hope all works well in that OS. Thanks all who chimed in on this.
My first hunch is that you need to specify the proper user-permissions in your application descriptor so you can use the openWith functionality with content from your application.
Remember that you need to specify this for IOS and Android specifically.
On your application.xml you need this permissions set inside android > manifestAdditions > manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
With this permissions you can save files to applicationStorageDirectory:
const FILE_LOADER:URLLoader = new URLLoader();
FILE_LOADER.addEventListener(Event.COMPLETE, onTempFileComplete);
FILE_LOADER.dataFormat = URLLoaderDataFormat.BINARY;
FILE_LOADER.load(new URLRequest(BASE_URL + filePath));
The applicationStorageDirectory can only be accessed by the application it belongs too when using Android or iOS. navigateToURL() hands over your request to the default browser, which cannot access said directory.
documentsDirectory is a public directory in Android, but not in iOS. So it cannot be used for both platforms. Unfortunately none of the pre-compiled file paths File has point to a public directory in iOS. You can find a table explaining all the pre-compiled paths here