Ionic - EACCES (Permission denied) error when uploading video - android

I'm having some difficulties trying upload video file to server using Cordova Camera Plugin and cordova-plugin-advanced-http. The code works like a charm when uploading an image from gallery, but no matter what I do, I always receive EACCES (Permission denied) when uploading a video from gallery:
file url -> file:///storage/emulated/0/DCIM/Camera/VID_20200908_114957.mp4
post-post-module-es2015.js:240 {status: -1, error: "There was an error with the request: /storage/emulated/0/DCIM/Camera/VID_20200908_114957.mp4: open failed: EACCES (Permission denied)"
Looking only at the error message, we can conclude it's a permission issue, so I tried use cordova-plugin-android-permissions and request READ_EXTERNAL_STORAGE permission. No success, the app has the permission but the error remains the same.
This is part of the code used to upload
private chooseContentUsingCameraPlugin(SOURCE: number) {
const options: CameraOptions = {
destinationType: this.camera.DestinationType.FILE_URI,
mediaType: this.camera.MediaType.ALLMEDIA,
sourceType: SOURCE
};
this.camera.getPicture(options).then((contentUrl: string) => {
if (contentUrl.indexOf('://') === -1)
contentUrl = 'file://' + contentUrl;
const queryIndex = contentUrl.lastIndexOf('?');
if (queryIndex !== -1)
contentUrl = contentUrl.substring(0, queryIndex);
console.log('file url -> ', contentUrl);
this.startUpload(contentUrl);
}, (err) => this.onUploadError(err));
}
private startUpload(fileUrl){
...
this.nativeHttp.uploadFile(req.url, null, headers, fileUrl, fileName).then(res => {
let data = res.data;
if (res.data && (req.responseType === undefined || req.responseType === 'json'))
data = JSON.parse(res.data);
console.log(data)
}).catch(error => {
console.log(error)
});
}
can someone explain what could be causing this issue?

It's possible that the file you're trying to upload is not in the scope of your permission. This is what the documentation says:
This is a soft restricted permission which cannot be held by an app it its full form until the installer on record whitelists the permission. Specifically, if the permission is whitelisted the holder app can access external storage and the visual and aural media collections while if the permission is not whitelisted the holder app can only access to the visual and aural medial collections. Also the permission is immutably restricted meaning that the whitelist state can be specified only at install time and cannot change until the app is installed. For more details see PackageInstaller.SessionParams.setWhitelistedRestrictedPermissions(Set).

Related

Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/Snapchat/Snapchat-441126967.jpg: open failed: EACCES (Permission denied)

Please I keep getting this error, each time I try to pick an image on my flutter application. Taking a live picture from my camera on the app works well though, but when I try to access my storage the error keeps coming forth.
Note:
I use the image_picker package to pick both images and access the camera.
Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/Snapchat/Snapchat-441126967.jpg: open failed: EACCES (Permission denied)
Everything was working well, of a sudden I started having this issue. I have done the following.
In my android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Also I have the requestLegacyExternalStorage set to true.
In Pubsec.yaml
permission_handler: ^8.1.2
image_picker:
Flutter Version
Flutter 2.0.5 • channel stable
Block of code to pick image
Future<void> _pickImage(ImageSource source) async {
print(":: Pick Image executed :::");
try {
await Permission.storage.request();
var status = await Permission.storage.status;
print(":::: The Status of the permission is ::::");
print(status);
if (status.isGranted) {
File selected =
await ImagePicker.pickImage(source: source, imageQuality: 30);
final bytes = selected.readAsBytesSync();
String _img64 = base64Encode(bytes);
setState(() {
_imageFile = selected;
base64 = _img64;
});
uploadFile();
}
} catch (error) {
print(error);
}
}
The permission is granted as shown by the permission package but I still keep getting the error at the end of the day when I select an image from by device gallery.
So eventually I found out that the problem was peculiar to only android 10 devices. The way forward was to update my image_picker package to the latest version which is at this moment 0.8.1+3.
And everything worked very well.
It's happening because of android storage permission. They solved the problem in the latest version. Please check out there read me file .
Starting with version 0.8.1 the Android implementation support to pick (multiple) images on Android 4.3 or higher.
No configuration required - the plugin should work out of the box.
It is no longer required to add android:requestLegacyExternalStorage="true" as an attribute to the tag in AndroidManifest.xml, as image_picker has been updated to make use of scoped storage.

Unable to open mobile camera in Ionic app

My objective is to upload multiple files either via camera or file storage, I'm using ng2FileSelect for uploading multiple files to the server via Ionic app, this is the HTML for it:
<input (change)="upload()" type="file" ng2FileSelect
[uploader]="uploader" multiple accept="image/*" capture="environment">
On running it on localhost on chrome, it is successfully giving options, either to open mobile camera or select files from storage. But on testing it on Ionic DevApp or on android device(via APK), it is directly opening file storage and not giving option of opening mobile camera. Is it possible to achieve the said objective with the above input tag, or I have to use a separate method for uploading files from the camera such as Cordova camera plugin, etc. ?
ng2FileSelect is specific for browsers it may create a problem on the native device. My suggestion is to use cordova camera plugin.
You can install the plugin via this commands
ionic cordova plugin add cordova-plugin-camera
npm install #ionic-native/camera
It Supports following platforms
Android
Browser
iOS
Windows
Usage
import { Camera, CameraOptions } from '#ionic-native/camera/ngx';
constructor(private camera: Camera) { }
...
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64 (DATA_URL):
let base64Image = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
// Handle error
});

How to resolve ssl issue in ionic3 filetransfer?

I'm facing an issue while trying to use the IONIC Cordova File Transfer plugin to upload a file while the laravel Server is running in HTTPS.
I'm able to login to the application and access all APIs from the server with get and post, but when I try to use fileTransfer for uploading data I'm getting the below message.
body: null
code: 3
exception: "java.security.cert.CertPathValidatorException: Trust anchor for certification path not found."
http_status: null
source: "content://com.android.providers.media.documents/document/image%3A16679"
target: "https://reddyflix.com/api/profile/photo/update"
I have dowloaded the (.cer) certificate file into the www directory of the project and setSSLCertMode = pinned. But I am still facing this issue.
let options: FileUploadOptions = {
httpMethod: "post",
chunkedMode: false,
fileKey: 'file',
fileName: 'name.png',
headers: headers
};
let trustAllHosts = true;
fileTransfer.upload(
uri,encodeURI('https://domain/api/profile/photo/update'), options,trustAllHosts)
.then((data) => {
console.log(data);
}, (err) => {
console.log(err);
})

Cordova File Plugin: SECURITY_ERR

I have a hybrid app in production (iOS/Android) that uses Cordova plugins. I have one Android user who is getting a SECURITY_ERR when using the File plugin. This seems to be happening on a call to writeFile(). The file path I'm writing to for Android is externalRootDirectory.
Can anyone help me understand why 1 user (out of 300-400) would have this problem? The user is on Android 6.0.1 if that helps.
Some code is below. The error I'm getting is [Error creating file] – Error Msg: [SECURITY_ERR], so the .writeFile() catch is being hit in this case.
//Handle Native download
if (this.appConfig.isNative) {
this.loggingService.debug("Starting to create native file");
//Get base file path for android/ios
let filePath = (this.appConfig.isNativeAndroid) ? this.file.externalRootDirectory : this.file.cacheDirectory;
//Write the file
this.file.writeFile(filePath, fileName, data, { replace: true })
.then((fileEntry: FileEntry) => {
this.loggingService.debug("Created file: " + fileEntry.toURL());
//Open with File Opener plugin
this.fileOpener.open(fileEntry.toURL(), data.type)
.then(() => this.loggingService.debug('File is opened'))
.catch(e => this.loggingService.error('Error openening file', e));
})
.catch((err) => {
this.loggingService.error("Error creating file", err);
throw err; //Rethrow - will be caught by caller
});
}
I was able to figure this one out. Looks like after Android 6.0 certain permissions must be requested during use of the app (not just at install time). This is also alluded to in the Cordova File plugin docs, under Android Quirks.
Marshmallow requires the apps to ask for permissions when reading/writing to external locations. By default, your app has permission to write to cordova.file.applicationStorageDirectory and cordova.file.externalApplicationStorageDirectory, and the plugin doesn't request permission for these two directories unless external storage is not mounted. However due to a limitation, when external storage is not mounted, it would ask for permission to write to cordova.file.externalApplicationStorageDirectory.
So on Android 6.0+, when writing a file to disk the Cordova File plugin will display a prompt similar to:
Allow APP_NAME to access photos, media and files on your device?
If the user selects Deny to this request, then the Cordova file write will get this SECURITY_ERR, even if the app requests this permission at install time.

Appcelerator: Share Screenshot of a specific view as a File cause Permission denied message

TargetSDK 23, Titanium SDK 5.4.0
Permissions set:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I take a Screenshot of a view by writing it to a file. That worked, because I can add this file to an imageview and see the image.
var blob = masterView.views[currentSavedPage].toImage();
var file = Titanium.Filesystem.getFile(Titanium.Filesystem.externalStorageDirectory, "myNewImage.jpg");
file.write(blob);
As I try to share the image with additional text, the other App (Facebook, Whatsapp, ...) can't access the image.
intent = Ti.Android.createIntent({
action : Ti.Android.ACTION_SEND,
type : "image/jpeg"
});
intent.putExtra(Ti.Android.EXTRA_TEXT, text);
intent.putExtra(Ti.Android.EXTRA_SUBJECT, subject);
intent.putExtraUri(Ti.Android.EXTRA_STREAM, file.nativePath);
share = Ti.Android.createIntentChooser(intent, 'Bild teilen');
I only got a Permission denied as Error and don't know how to fix this. This worked with an lower SDK Version.
fb4a.RequestLoggingListener: java.io.FileNotFoundException: /data/user/0/de.myapp.id/app_appdata/myNewImage.jpg: open failed: EACCES (Permission denied)
ExifInterface: java.io.FileNotFoundException: /data/user/0/de.myapp.id/app_appdata/myNewImage.jpg: open failed: EACCES (Permission denied)
BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /data/user/0/de.myapp.id/app_appdata/myNewImage.jpg: open failed: EACCES (Permission denied)
Solution:
if (!Ti.Filesystem.hasStoragePermissions()) {
Ti.Filesystem.requestStoragePermissions(function(result) {
if (result.success) {
openShareIntent();
} else {
alert('Permissions denied.');
}
});
} else {
openShareIntent();
}
You need to implement runtime permissions for Android 6.0 and above. As it does not have the permission, even though defined in the manifest or tiapp.xml. Provide runtime permission and it should not give permission errors.
If it's not already did :
Try to go to your settings->Application->YourApp;
then click permission and authorize access to storage.
But you should ask the permission directly from the app.
The exemple of the official doc is simple : https://developer.android.com/training/permissions/requesting.html

Categories

Resources