I am using HTML input
for choosing file in my Ionic3/Angular application. I am using below code:
// in .html file
<input #fileUpload type="file" name="myfile"(change)="onFileChoose($event)"/>
// in .ts file
onFileChoose($event): void {
this.fileChooser.getFileInfo($event).then((result) => {
this.fileName = result.fileName;
this.fileData = this.sanitizeFileData(result.fileData);
this.fileSize = result.fileSize;
this.fileType = result.fileType;
}, (error) => {
this.helperProvider.createAlert('Alert', 'File is corrupted.');
});
}
getFileInfo(event: Event): Promise<any> {
let target = event && event.target;
let files: Array<File> = target && target['files'];
console.log(files[0].type);
console.log(files[0].name);
return new Promise((resolve, reject) => {
if (files && files.length) {
files = Array.from(files);
let fileName = files[0].name;
let fileSize = files[0].size;
let fileType = files[0].type;
let fileReader = new FileReader();
fileReader.onload = () => resolve({
fileData: fileReader.result,
fileName: fileName,
fileSize: fileSize,
fileType: fileType
});
fileReader.onerror = error => reject(error);
fileReader.onabort = error => reject(error);
fileReader.readAsDataURL(files[0])
}
});
}
This is working fine in iOS
and Browser
. Both, in android and browser, i could get the original name, size and type of the file. But the problem occurs in Android.
Scenario-1(Android): When i choose an image file using the file chooser, i could get the original file name, size and type of the file.
Scenario-2(Android): When i choose a file other than image file like .pdf,.doc etc, i could not get the original file name and the type of the file. Suppose, i have choosen a file name "sample.pdf", but after i chose the file, i get the file name as a random number like 45675 and most importantly the file type, i got is empty.
Then, i researched in stackoverflow and saw these links (link1 and link2). It may be a security issue for android.
There is an ionic-native/file-chooser library but it is only for android platform.
Is there any way to force android to give the original file name?
Android does not give the original file name and file type using the above approach of mine and it is a security issue from android. So, i had to make below solution for retrieving the correct file name, file type, file size and the file data in base64.
You will need below four plugins:
FileChooserAndroidProvider:
import {Injectable} from '@angular/core';
import {File, FileEntry, IFile} from "@ionic-native/file";
import {Base64} from "@ionic-native/base64";
import {FilePath} from "@ionic-native/file-path";
import {FileChooser} from "@ionic-native/file-chooser";
@Injectable()
export class FileChooserAndroidProvider {
constructor(private base64: Base64, private filePath: FilePath, private file: File, private fileChooser: FileChooser) {
}
getFileInfo(): Promise<any> {
return this.fileChooser.open().then((fileURI) => {
return this.filePath.resolveNativePath(fileURI).then((filePath) => {
return this.file.resolveLocalFilesystemUrl(filePath).then((fileEntry: FileEntry) => {
return new Promise((resolve, reject) => {
fileEntry.file(meta => resolve(meta), error => reject(error));
});
}).then((fileMeta: IFile) => {
return new Promise((resolve, reject) => {
return this.base64.encodeFile(filePath).then((base64Data) => {
resolve({
fileData: base64Data,
fileName: fileMeta.name,
fileSize: fileMeta.size,
fileType: fileMeta.type
})
}).catch((error) => {
reject(error);
})
})
});
});
});
}
}
FileChooserAndroidProviderModule:
import {NgModule} from '@angular/core';
import {Base64} from "@ionic-native/base64";
import {FileChooser} from "@ionic-native/file-chooser";
import {FilePath} from "@ionic-native/file-path";
import {File} from "@ionic-native/file";
@NgModule({
declarations: [],
exports: [],
providers: [
FileChooser,
File,
FilePath,
Base64
]
})
export class FileChooserAndroidProviderModule {
}
SamplePage:
constructor(private fileChooserAndroid: FileChooserAndroidProvider){}
uploadFileForAndroid(): void {
this.fileChooserAndroid.getFileInfo().then((result) => {
this.fileName = result.fileName;
this.fileData = this.sanitizeFileData(result.fileData);
this.fileSize = result.fileSize;
this.fileType = result.fileType;
}).catch((error) => {
this.helperProvider.createAlert('Alert', 'File can not be uploaded.');
});
}
SamplePageModule:
@NgModule({
declarations: [
SamplePage
],
imports: [
FileChooserAndroidProviderModule
],
providers: [
FileChooserAndroidProvider
]
})
export class SamplePageModule {
}
来源:https://stackoverflow.com/questions/49719843/how-to-force-html-input-file-chooser-to-give-the-original-file-name-in-ionicand