MOBILE-4492 file: Avoid problems with toURL in Android
parent
7c21fd4f27
commit
bcbd31535c
|
@ -18,6 +18,7 @@ import { CoreFileEntry, CoreFileHelper } from '@services/file-helper';
|
||||||
import { CoreFileSession } from '@services/file-session';
|
import { CoreFileSession } from '@services/file-session';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
|
import { AddonModDataFieldPluginBaseComponent } from '../../../classes/base-field-plugin-component';
|
||||||
|
import { CoreFile } from '@services/file';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component to render data picture field.
|
* Component to render data picture field.
|
||||||
|
@ -129,7 +130,7 @@ export class AddonModDataFieldPictureComponent extends AddonModDataFieldPluginBa
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.image) {
|
if (this.image) {
|
||||||
this.imageUrl = 'name' in this.image
|
this.imageUrl = 'name' in this.image
|
||||||
? this.image.toURL() // Is Offline.
|
? CoreFile.getFileEntryURL(this.image) // Is Offline.
|
||||||
: CoreFileHelper.getFileUrl(this.image);
|
: CoreFileHelper.getFileUrl(this.image);
|
||||||
}
|
}
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
|
@ -80,7 +80,7 @@ export class AddonModLtiProvider {
|
||||||
|
|
||||||
const entry = await CoreFile.writeFile(LAUNCHER_FILE_NAME, text);
|
const entry = await CoreFile.writeFile(LAUNCHER_FILE_NAME, text);
|
||||||
|
|
||||||
return entry.toURL();
|
return CoreFile.getFileEntryURL(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -98,7 +98,7 @@ export class CoreLocalFileComponent implements OnInit {
|
||||||
this.fileExtension = CoreMimetypeUtils.getFileExtension(file.name);
|
this.fileExtension = CoreMimetypeUtils.getFileExtension(file.name);
|
||||||
|
|
||||||
// Let's calculate the relative path for the file.
|
// Let's calculate the relative path for the file.
|
||||||
this.relativePath = CoreFile.removeBasePath(file.toURL());
|
this.relativePath = CoreFile.removeBasePath(CoreFile.getFileEntryURL(file));
|
||||||
if (!this.relativePath) {
|
if (!this.relativePath) {
|
||||||
// Didn't find basePath, use fullPath but if the user tries to manage the file it'll probably fail.
|
// Didn't find basePath, use fullPath but if the user tries to manage the file it'll probably fail.
|
||||||
this.relativePath = file.fullPath;
|
this.relativePath = file.fullPath;
|
||||||
|
@ -139,7 +139,7 @@ export class CoreLocalFileComponent implements OnInit {
|
||||||
options.iOSOpenFileAction = this.defaultIsOpenWithPicker ? OpenFileAction.OPEN : OpenFileAction.OPEN_WITH;
|
options.iOSOpenFileAction = this.defaultIsOpenWithPicker ? OpenFileAction.OPEN : OpenFileAction.OPEN_WITH;
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreUtils.openFile(this.file.toURL(), options);
|
CoreUtils.openFile(CoreFile.getFileEntryURL(this.file), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -324,7 +324,7 @@ export class CoreEmulatorCaptureMediaComponent implements OnInit, OnDestroy {
|
||||||
const fileEntry = await CoreFile.writeFile(this.getFilePath(), this.mediaBlob);
|
const fileEntry = await CoreFile.writeFile(this.getFilePath(), this.mediaBlob);
|
||||||
|
|
||||||
if (this.isImage && !this.isCaptureImage) {
|
if (this.isImage && !this.isCaptureImage) {
|
||||||
this.dismissWithData(fileEntry.toURL());
|
this.dismissWithData(CoreFile.getFileEntryURL(fileEntry));
|
||||||
} else {
|
} else {
|
||||||
// The capture plugin should return a MediaFile, not a FileEntry. Convert it.
|
// The capture plugin should return a MediaFile, not a FileEntry. Convert it.
|
||||||
const metadata = await CoreFile.getMetadata(fileEntry);
|
const metadata = await CoreFile.getMetadata(fileEntry);
|
||||||
|
|
|
@ -170,7 +170,7 @@ export class CoreFileUploaderAudioRecorderComponent extends CoreModalComponent<C
|
||||||
|
|
||||||
this.close({
|
this.close({
|
||||||
name: fileEntry.name,
|
name: fileEntry.name,
|
||||||
fullPath: fileEntry.toURL(),
|
fullPath: CoreFile.getFileEntryURL(fileEntry),
|
||||||
type: 'audio/mpeg',
|
type: 'audio/mpeg',
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -185,7 +185,7 @@ export class CoreFileUploaderHelperProvider {
|
||||||
|
|
||||||
if (upload) {
|
if (upload) {
|
||||||
// Pass true to delete the copy after the upload.
|
// Pass true to delete the copy after the upload.
|
||||||
return this.uploadGenericFile(fileEntry.toURL(), name, file.type, true);
|
return this.uploadGenericFile(CoreFile.getFileEntryURL(fileEntry), name, file.type, true);
|
||||||
} else {
|
} else {
|
||||||
return fileEntry;
|
return fileEntry;
|
||||||
}
|
}
|
||||||
|
@ -455,7 +455,7 @@ export class CoreFileUploaderHelperProvider {
|
||||||
|
|
||||||
await this.confirmUploadFile(file.size);
|
await this.confirmUploadFile(file.size);
|
||||||
|
|
||||||
await this.uploadGenericFile(fileEntry.toURL(), file.name, file.type, deleteAfterUpload, siteId);
|
await this.uploadGenericFile(CoreFile.getFileEntryURL(fileEntry), file.name, file.type, deleteAfterUpload, siteId);
|
||||||
|
|
||||||
CoreDomUtils.showToast('core.fileuploader.fileuploaded', true, undefined, 'core-toast-success');
|
CoreDomUtils.showToast('core.fileuploader.fileuploaded', true, undefined, 'core-toast-success');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
@ -195,7 +195,10 @@ export class CoreFileUploaderProvider {
|
||||||
clearTmpFiles(files: (CoreWSFile | FileEntry)[]): void {
|
clearTmpFiles(files: (CoreWSFile | FileEntry)[]): void {
|
||||||
// Delete the temporary files.
|
// Delete the temporary files.
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
if ('remove' in file && CoreFile.removeBasePath(file.toURL()).startsWith(CoreFileProvider.TMPFOLDER)) {
|
if (
|
||||||
|
'remove' in file &&
|
||||||
|
CoreFile.removeBasePath(CoreFile.getFileEntryURL(file)).startsWith(CoreFileProvider.TMPFOLDER)
|
||||||
|
) {
|
||||||
// Pass an empty function to prevent missing parameter error.
|
// Pass an empty function to prevent missing parameter error.
|
||||||
file.remove(() => {
|
file.remove(() => {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
|
@ -568,7 +571,7 @@ export class CoreFileUploaderProvider {
|
||||||
const destFile = CorePath.concatenatePaths(folderPath, file.name);
|
const destFile = CorePath.concatenatePaths(folderPath, file.name);
|
||||||
result.offline++;
|
result.offline++;
|
||||||
|
|
||||||
await CoreFile.copyFile(file.toURL(), destFile);
|
await CoreFile.copyFile(CoreFile.getFileEntryURL(file), destFile);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -642,9 +645,10 @@ export class CoreFileUploaderProvider {
|
||||||
usedNames[name] = file;
|
usedNames[name] = file;
|
||||||
|
|
||||||
// Now upload the file.
|
// Now upload the file.
|
||||||
const options = this.getFileUploadOptions(file.toURL(), name, undefined, false, 'draft', itemId);
|
const filePath = CoreFile.getFileEntryURL(file);
|
||||||
|
const options = this.getFileUploadOptions(filePath, name, undefined, false, 'draft', itemId);
|
||||||
|
|
||||||
await this.uploadFile(file.toURL(), options, undefined, siteId);
|
await this.uploadFile(filePath, options, undefined, siteId);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,9 +705,10 @@ export class CoreFileUploaderProvider {
|
||||||
// Now upload the file.
|
// Now upload the file.
|
||||||
const extension = CoreMimetypeUtils.getFileExtension(fileName);
|
const extension = CoreMimetypeUtils.getFileExtension(fileName);
|
||||||
const mimetype = extension ? CoreMimetypeUtils.getMimeType(extension) : undefined;
|
const mimetype = extension ? CoreMimetypeUtils.getMimeType(extension) : undefined;
|
||||||
const options = this.getFileUploadOptions(fileEntry.toURL(), fileName, mimetype, isOnline, 'draft', itemId);
|
const filePath = CoreFile.getFileEntryURL(fileEntry);
|
||||||
|
const options = this.getFileUploadOptions(filePath, fileName, mimetype, isOnline, 'draft', itemId);
|
||||||
|
|
||||||
const result = await this.uploadFile(fileEntry.toURL(), options, undefined, siteId);
|
const result = await this.uploadFile(filePath, options, undefined, siteId);
|
||||||
|
|
||||||
return result.itemid;
|
return result.itemid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -333,7 +333,7 @@ export class CoreH5PFileStorage {
|
||||||
|
|
||||||
const file = await CoreFile.getFile(this.getContentIndexPath(folderName, siteId));
|
const file = await CoreFile.getFile(this.getContentIndexPath(folderName, siteId));
|
||||||
|
|
||||||
return file.toURL();
|
return CoreFile.getFileEntryURL(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -201,7 +201,7 @@ export class CoreH5PHelper {
|
||||||
const destFolder = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName);
|
const destFolder = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName);
|
||||||
|
|
||||||
// Unzip the file.
|
// Unzip the file.
|
||||||
await CoreFile.unzipFile(file.toURL(), destFolder, onProgress);
|
await CoreFile.unzipFile(CoreFile.getFileEntryURL(file), destFolder, onProgress);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Notify that the unzip is starting.
|
// Notify that the unzip is starting.
|
||||||
|
|
|
@ -145,7 +145,7 @@ export class CoreH5PPlayer {
|
||||||
|
|
||||||
const fileEntry = await CoreFile.writeFile(indexPath, html);
|
const fileEntry = await CoreFile.writeFile(indexPath, html);
|
||||||
|
|
||||||
return fileEntry.toURL();
|
return CoreFile.getFileEntryURL(fileEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -227,7 +227,7 @@ export class CoreSharedFilesHelperProvider {
|
||||||
} else if (siteIds.length == 1) {
|
} else if (siteIds.length == 1) {
|
||||||
return this.storeSharedFileInSite(fileEntry, siteIds[0], !path);
|
return this.storeSharedFileInSite(fileEntry, siteIds[0], !path);
|
||||||
} else if (!this.isChoosingSite()) {
|
} else if (!this.isChoosingSite()) {
|
||||||
this.goToChooseSite(fileEntry.toURL(), !path);
|
this.goToChooseSite(CoreFile.getFileEntryURL(fileEntry), !path);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|
|
@ -245,7 +245,7 @@ export class CoreSharedFilesProvider {
|
||||||
// Create dir if it doesn't exist already.
|
// Create dir if it doesn't exist already.
|
||||||
await CoreFile.createDir(sharedFilesFolder);
|
await CoreFile.createDir(sharedFilesFolder);
|
||||||
|
|
||||||
const newFile = await CoreFile.moveExternalFile(entry.toURL(), newPath);
|
const newFile = await CoreFile.moveExternalFile(CoreFile.getFileEntryURL(entry), newPath);
|
||||||
|
|
||||||
CoreEvents.trigger(CoreEvents.FILE_SHARED, { siteId, name: newName });
|
CoreEvents.trigger(CoreEvents.FILE_SHARED, { siteId, name: newName });
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ export class CoreFileProvider {
|
||||||
|
|
||||||
const newDirEntry = await File.createDir(base, firstDir, true);
|
const newDirEntry = await File.createDir(base, firstDir, true);
|
||||||
|
|
||||||
return this.create(isDirectory, restOfPath, failIfExists, newDirEntry.toURL());
|
return this.create(isDirectory, restOfPath, failIfExists, this.getFileEntryURL(newDirEntry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -874,12 +874,29 @@ export class CoreFileProvider {
|
||||||
getInternalURL(fileEntry: FileEntry): string {
|
getInternalURL(fileEntry: FileEntry): string {
|
||||||
if (!fileEntry.toInternalURL) {
|
if (!fileEntry.toInternalURL) {
|
||||||
// File doesn't implement toInternalURL, use toURL.
|
// File doesn't implement toInternalURL, use toURL.
|
||||||
return fileEntry.toURL();
|
return this.getFileEntryURL(fileEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileEntry.toInternalURL();
|
return fileEntry.toInternalURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the URL (absolute path) of a file.
|
||||||
|
* Use this function instead of doing fileEntry.toURL because the latter causes problems with WebView and other plugins.
|
||||||
|
*
|
||||||
|
* @param fileEntry File Entry.
|
||||||
|
* @returns URL.
|
||||||
|
*/
|
||||||
|
getFileEntryURL(fileEntry: Entry): string {
|
||||||
|
if (CorePlatform.isAndroid()) {
|
||||||
|
// Cordova plugin file v7 changed the format returned by toURL, the new format it's not compatible with
|
||||||
|
// Ionic WebView or FileTransfer plugin.
|
||||||
|
return fileEntry.nativeURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileEntry.toURL();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the basePath to a path if it doesn't have it already.
|
* Adds the basePath to a path if it doesn't have it already.
|
||||||
*
|
*
|
||||||
|
@ -934,7 +951,7 @@ export class CoreFileProvider {
|
||||||
// If destFolder is not set, use same location as ZIP file. We need to use absolute paths (including basePath).
|
// If destFolder is not set, use same location as ZIP file. We need to use absolute paths (including basePath).
|
||||||
destFolder = this.addBasePathIfNeeded(destFolder || CoreMimetypeUtils.removeExtension(path));
|
destFolder = this.addBasePathIfNeeded(destFolder || CoreMimetypeUtils.removeExtension(path));
|
||||||
|
|
||||||
const result = await Zip.unzip(fileEntry.toURL(), destFolder, onProgress);
|
const result = await Zip.unzip(this.getFileEntryURL(fileEntry), destFolder, onProgress);
|
||||||
|
|
||||||
if (result == -1) {
|
if (result == -1) {
|
||||||
throw new CoreError('Unzip failed.');
|
throw new CoreError('Unzip failed.');
|
||||||
|
|
|
@ -771,7 +771,7 @@ export class CoreFilepoolProvider {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add the anchor again to the local URL.
|
// Add the anchor again to the local URL.
|
||||||
return fileEntry.toURL() + (anchor || '');
|
return CoreFile.getFileEntryURL(fileEntry) + (anchor || '');
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
// Download finished, delete the promise.
|
// Download finished, delete the promise.
|
||||||
delete this.filePromises[siteId][downloadId];
|
delete this.filePromises[siteId][downloadId];
|
||||||
|
@ -1278,7 +1278,7 @@ export class CoreFilepoolProvider {
|
||||||
const filePath = await this.getFilePath(siteId, fileId, '');
|
const filePath = await this.getFilePath(siteId, fileId, '');
|
||||||
const dirEntry = await CoreFile.getDir(filePath);
|
const dirEntry = await CoreFile.getDir(filePath);
|
||||||
|
|
||||||
return dirEntry.toURL();
|
return CoreFile.getFileEntryURL(dirEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1666,7 +1666,7 @@ export class CoreFilepoolProvider {
|
||||||
const path = await this.getFilePath(siteId, fileId);
|
const path = await this.getFilePath(siteId, fileId);
|
||||||
const fileEntry = await CoreFile.getFile(path);
|
const fileEntry = await CoreFile.getFile(path);
|
||||||
|
|
||||||
return CoreFile.convertFileSrc(fileEntry.toURL());
|
return CoreFile.convertFileSrc(CoreFile.getFileEntryURL(fileEntry));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1685,7 +1685,7 @@ export class CoreFilepoolProvider {
|
||||||
const fileEntry = await CoreFile.getFile(path);
|
const fileEntry = await CoreFile.getFile(path);
|
||||||
|
|
||||||
// This URL is usually used to launch files or put them in HTML.
|
// This URL is usually used to launch files or put them in HTML.
|
||||||
return fileEntry.toURL();
|
return CoreFile.getFileEntryURL(fileEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1701,7 +1701,7 @@ export class CoreFilepoolProvider {
|
||||||
|
|
||||||
const fileEntry = await CoreFile.getFile(filePath);
|
const fileEntry = await CoreFile.getFile(filePath);
|
||||||
|
|
||||||
return fileEntry.toURL();
|
return CoreFile.getFileEntryURL(fileEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1797,7 +1797,7 @@ export class CoreFilepoolProvider {
|
||||||
const dirPath = await this.getFilePath(siteId, dirName, '');
|
const dirPath = await this.getFilePath(siteId, dirName, '');
|
||||||
const dirEntry = await CoreFile.getDir(dirPath);
|
const dirEntry = await CoreFile.getDir(dirPath);
|
||||||
|
|
||||||
return dirEntry.toURL();
|
return CoreFile.getFileEntryURL(dirEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -185,7 +185,7 @@ export class CoreMimetypeUtilsProvider {
|
||||||
// @todo linting: See if this can be removed
|
// @todo linting: See if this can be removed
|
||||||
(file as { embedType?: string }).embedType = embedType;
|
(file as { embedType?: string }).embedType = embedType;
|
||||||
|
|
||||||
path = path ?? (CoreUtils.isFileEntry(file) ? file.toURL() : CoreFileHelper.getFileUrl(file));
|
path = path ?? (CoreUtils.isFileEntry(file) ? CoreFile.getFileEntryURL(file) : CoreFileHelper.getFileUrl(file));
|
||||||
path = path && CoreFile.convertFileSrc(path);
|
path = path && CoreFile.convertFileSrc(path);
|
||||||
|
|
||||||
switch (embedType) {
|
switch (embedType) {
|
||||||
|
|
|
@ -258,7 +258,7 @@ export class CoreWSProvider {
|
||||||
onProgress && transfer.onProgress(onProgress);
|
onProgress && transfer.onProgress(onProgress);
|
||||||
|
|
||||||
// Download the file in the tmp file.
|
// Download the file in the tmp file.
|
||||||
await transfer.download(url, fileEntry.toURL(), true, {
|
await transfer.download(url, CoreFile.getFileEntryURL(fileEntry), true, {
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': navigator.userAgent,
|
'User-Agent': navigator.userAgent,
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,6 +12,7 @@ For more information about upgrading, read the official documentation: https://m
|
||||||
- With the upgrade to Ionic7 ion-datetime has changed its usage. We recommend using ion-datetime-button. More info here: https://ionicframework.com/docs/updating/6-0#datetime
|
- With the upgrade to Ionic7 ion-datetime has changed its usage. We recommend using ion-datetime-button. More info here: https://ionicframework.com/docs/updating/6-0#datetime
|
||||||
- CoreLoginHelper.getErrorMessages has been removed. Please create the messages object yourself.
|
- CoreLoginHelper.getErrorMessages has been removed. Please create the messages object yourself.
|
||||||
- CoreAppProvider.isAutomated() has been deprecated, use CorePlatformService.isAutomated() instead.
|
- CoreAppProvider.isAutomated() has been deprecated, use CorePlatformService.isAutomated() instead.
|
||||||
|
- Due to a breaking change in cordova-plugin-file, avoid using FileEntry.toURL(). Use CoreFileProvider.getFileEntryURL instead.
|
||||||
|
|
||||||
=== 4.3.0 ===
|
=== 4.3.0 ===
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue