jibon57/nativescript-mediafilepicker

Android 11: Custom File Picker not showing files

Opened this issue · 22 comments

The plugin can run normally as if there were no errors. But when the popup window appeared, there weren't any files listed.

Also I found this bug on Android 10. But there it can be solved by simply adding android:requestLegacyExternalStorage="true" to the manifest file. That way doesn't work on Android 11.

✔ Component nativescript has 7.0.10 version and is up to date.
✔ Component @nativescript/core has 7.0.11 version and is up to date.
✔ Component @nativescript/android has 7.0.0 version and is up to date.

This is because of the new android scoped storage

is it something that going to be solved? do I need to change something to support android 11?

I have the same problem, it was working on 10 but no longer works on 11. Should we change configuration files?

I see that Google has set May 5th as the deadline for removing requestLegacyExternalStorage from the manifest. What to do?

Any update on this? Could anybody provide an alternative version of the plugin which allows to select arbitrary files?

Any update to support android 11 for camera and file picker ?

any update?

This is because of the new android scoped storage

have you learned how to solve it?

It doesn't work for me either with Android 11 SDK 30 I see that the official nativescript plugin https://github.com/NativeScript/plugins/tree/main/packages/imagepicker give solution in an update https://github.com/NativeScript / plugins / issues / 93

JonasLykkeIOspect commented on 22 Feb
Hi. First of all, thanks for fixing the Android 11 problem. But its not "all done" yet :)

For it to work, you need to have a FileProvider in your AndroidManifest.

@NativeScript/camera comes with one. So if you're already using that one. Change line 160 in the index.android.js:

From:
return FileProviderPackageName.FileProvider.getUriForFile(Application.android.context, Application.android.nativeApp.getPackageName() + '.fileprovider', file);

To:
return FileProviderPackageName.FileProvider.getUriForFile(Application.android.context, Application.android.nativeApp.getPackageName() + '.provider', file);

'.provider' is the FileProvider that @NativeScript/camera makes. So you can reuse that.

This is a fix, until the plugin is updated with a FileProvider :)

It doesn't work for me either with Android 11 SDK 30 I see that the official nativescript plugin https://github.com/NativeScript/plugins/tree/main/packages/imagepicker give solution in an update https://github.com/NativeScript / plugins / issues / 93

JonasLykkeIOspect commented on 22 Feb
Hi. First of all, thanks for fixing the Android 11 problem. But its not "all done" yet :)

For it to work, you need to have a FileProvider in your AndroidManifest.

@NativeScript/camera comes with one. So if you're already using that one. Change line 160 in the index.android.js:

From:
return FileProviderPackageName.FileProvider.getUriForFile(Application.android.context, Application.android.nativeApp.getPackageName() + '.fileprovider', file);

To:
return FileProviderPackageName.FileProvider.getUriForFile(Application.android.context, Application.android.nativeApp.getPackageName() + '.provider', file);

'.provider' is the FileProvider that @NativeScript/camera makes. So you can reuse that.

This is a fix, until the plugin is updated with a FileProvider :)

how can u apply code from here? sorry im just so lost

Hi,
i´ve implemented this soloution, its working for me
in mediafilepicker.android.js
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var observable_1 = require("tns-core-modules/data/observable"); var app = require("tns-core-modules/application"); var utils = require("tns-core-modules/utils/utils"); var permissions = require("nativescript-permissions"); const FILE = require("tns-core-modules/file-system"); const fs = require("tns-core-modules/file-system"); var AudioPickActivity = com.vincent.filepicker.activity.AudioPickActivity; var ImagePickActivity = com.vincent.filepicker.activity.ImagePickActivity; var NormalFilePickActivity = com.vincent.filepicker.activity.NormalFilePickActivity; var VideoPickActivity = com.vincent.filepicker.activity.VideoPickActivity; var Constant = com.vincent.filepicker.Constant; var Util = com.vincent.filepicker.Util; var Intent = android.content.Intent; var MediaStore = android.provider.MediaStore; var Environment = android.os.Environment; var File = java.io.File; var ContentValues = android.content.ContentValues; var Uri = android.net.Uri; var FileUtils = android.os.FileUtils;
var Mediafilepicker = (function (_super) { __extends(Mediafilepicker, _super); function Mediafilepicker() { return _super.call(this) || this; } Mediafilepicker.prototype.openImagePicker = function (params) { var intent, pickerType, options = params.android; if (options.isCaptureMood) { this.performCapturing("image", options); return; } intent = new Intent( app.android.foregroundActivity, ImagePickActivity.class ); options.isNeedCamera ? intent.putExtra(ImagePickActivity.IS_NEED_CAMERA, true) : intent.putExtra(ImagePickActivity.IS_NEED_CAMERA, false); options.maxNumberFiles ? intent.putExtra(Constant.MAX_NUMBER, options.maxNumberFiles) : intent.putExtra(Constant.MAX_NUMBER, 99); options.isNeedFolderList ? intent.putExtra(ImagePickActivity.IS_NEED_FOLDER_LIST, true) : intent.putExtra(ImagePickActivity.IS_NEED_FOLDER_LIST, false); pickerType = Constant.REQUEST_CODE_PICK_IMAGE; this.callIntent(intent, pickerType); }; `` Mediafilepicker.prototype.openVideoPicker = function (params) { var intent, pickerType, options = params.android; if (options.isCaptureMood) { this.performCapturing("video", options); return; } intent = new Intent( app.android.foregroundActivity, VideoPickActivity.class ); options.isNeedCamera ? intent.putExtra(VideoPickActivity.IS_NEED_CAMERA, true) : intent.putExtra(VideoPickActivity.IS_NEED_CAMERA, false); options.maxNumberFiles ? intent.putExtra(Constant.MAX_NUMBER, options.maxNumberFiles) : intent.putExtra(Constant.MAX_NUMBER, 99); options.isNeedFolderList ? intent.putExtra(VideoPickActivity.IS_NEED_FOLDER_LIST, true) : intent.putExtra(VideoPickActivity.IS_NEED_FOLDER_LIST, false); if (options.maxDuration > 0) { intent.putExtra(Constant.MAX_VIDEO_DURATION, options.maxDuration); } intent.putExtra(Constant.VIDEO_QUALITY, 1); if (options.videoQuality === 0) { intent.putExtra(Constant.VIDEO_QUALITY, 0); } pickerType = Constant.REQUEST_CODE_PICK_VIDEO; this.callIntent(intent, pickerType); }; `` Mediafilepicker.prototype.openAudioPicker = function (params) { var intent, pickerType, options = params.android; if (options.isCaptureMood) { this.performCapturing("audio", options); return; } intent = new Intent( app.android.foregroundActivity, AudioPickActivity.class ); options.isNeedRecorder ? intent.putExtra(AudioPickActivity.IS_NEED_RECORDER, true) : intent.putExtra(AudioPickActivity.IS_NEED_RECORDER, false); options.maxNumberFiles ? intent.putExtra(Constant.MAX_NUMBER, options.maxNumberFiles) : intent.putExtra(Constant.MAX_NUMBER, 99); options.isNeedFolderList ? intent.putExtra(AudioPickActivity.IS_NEED_FOLDER_LIST, true) : intent.putExtra(AudioPickActivity.IS_NEED_FOLDER_LIST, false); if (options.maxSize > 0) { intent.putExtra(Constant.MAX_AUDIO_SIZE, options.maxSize); } intent.putExtra(AudioPickActivity.IS_TAKEN_AUTO_SELECTED, true); pickerType = Constant.REQUEST_CODE_PICK_AUDIO; this.callIntent(intent, pickerType); }; `` Mediafilepicker.prototype.openFilePicker = function (params) { var intent, pickerType, options = params.android, extensions; if (options.extensions.length > 0) { extensions = Array.create(java.lang.String, options.extensions.length); for (var i = 0; i < options.extensions.length; i++) { extensions[i] = options.extensions[i]; } } intent = new android.content.Intent( android.content.Intent.ACTION_GET_CONTENT ); intent.setType("*/*"); intent.putExtra(NormalFilePickActivity.SUFFIX, extensions); intent.addCategory(android.content.Intent.CATEGORY_OPENABLE); intent.setAction(android.content.Intent.ACTION_OPEN_DOCUMENT); pickerType = Constant.REQUEST_CODE_PICK_FILE; this.callIntent(intent, pickerType); }; `` Mediafilepicker.prototype.performCapturing = function (type, options) { var t = this; var requestPermissions = [ android.Manifest.permission.WRITE_EXTERNAL_STORAGE, ]; if (type === "image" || type === "video") { requestPermissions.push(android.Manifest.permission.CAMERA); } else if (type === "audio") { requestPermissions.push(android.Manifest.permission.RECORD_AUDIO); } permissions .requestPermission( requestPermissions, "Need these permissions to access files" ) .then(function () { t.handleOnlyCaptureMode(type, options); }) .catch(function () { t.msg = "Permission Error!"; t.notify({ eventName: "error", object: t, }); }); }; `` Mediafilepicker.prototype.handleOnlyCaptureMode = function (type, options) { var context = app.android.context, t = this, intent, date, timeStamp, contentValues, file, uri; switch (type) { case "image": intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); date = new Date(); timeStamp = date.getFullYear() + "" + (date.getMonth() + 1) + "" + date.getDate() + "_" + date.getHours() + "" + date.getMinutes() + "" + date.getSeconds(); file = new File( Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DCIM ).getAbsolutePath() + "/IMG_" + timeStamp + ".jpg" ); var mImagePath = file.getAbsolutePath(); this.captureFilePath = mImagePath; contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, mImagePath); var mImageUri = context .getContentResolver() .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); this.captureContentUrl = mImageUri; intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri); if (Util.detectIntent(context, intent)) { this.callIntent(intent, Constant.REQUEST_CODE_TAKE_IMAGE); } else { this.msg = "No photo capture app installed!"; this.notify({ eventName: "error", object: this, }); } break; case "video": intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); date = new Date(); timeStamp = date.getFullYear() + "" + (date.getMonth() + 1) + "" + date.getDate() + "_" + date.getHours() + "" + date.getMinutes() + "" + date.getSeconds(); file = new File( Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DCIM ).getAbsolutePath() + "/VID_" + timeStamp + ".mp4" ); var mVideoPath = file.getAbsolutePath(); this.captureFilePath = mVideoPath; contentValues = new ContentValues(1); contentValues.put(MediaStore.Images.Media.DATA, mVideoPath); uri = context .getContentResolver() .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); this.captureContentUrl = uri; intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); if (options.maxDuration > 0) { intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, options.maxDuration); } if (options.videoQuality === 0) { intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); } if (Util.detectIntent(context, intent)) { this.callIntent(intent, Constant.REQUEST_CODE_TAKE_VIDEO); } else { this.msg = "No video recorder app installed!"; this.notify({ eventName: "error", object: this, }); } break; case "audio": intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); if (options.maxSize > 0) { var MAX_SIZE = android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES; intent.putExtra(MAX_SIZE, options.maxSize); } if (Util.detectIntent(context, intent)) { this.callIntent(intent, Constant.REQUEST_CODE_TAKE_AUDIO); } else { this.msg = "No audio recorder app installed!"; this.notify({ eventName: "error", object: this, }); } break; } }; `` Mediafilepicker.prototype.callIntent = function (intent, pickerType) { var t = this; var requestPermissions = [ android.Manifest.permission.WRITE_EXTERNAL_STORAGE, ]; if ( pickerType === Constant.REQUEST_CODE_TAKE_IMAGE || pickerType === Constant.REQUEST_CODE_PICK_IMAGE || pickerType === Constant.REQUEST_CODE_TAKE_VIDEO || pickerType === Constant.REQUEST_CODE_PICK_VIDEO ) { requestPermissions.push(android.Manifest.permission.CAMERA); } else if ( pickerType === Constant.REQUEST_CODE_TAKE_AUDIO || pickerType === Constant.REQUEST_CODE_PICK_AUDIO ) { requestPermissions.push(android.Manifest.permission.RECORD_AUDIO); } permissions .requestPermission( requestPermissions, "Need these permissions to access files" ) .then(function () { app.android.foregroundActivity.startActivityForResult( intent, pickerType ); }) .catch(function () { t.msg = "Permission Error!"; t.notify({ eventName: "error", object: t, }); }); app.android.on(app.AndroidApplication.activityResultEvent, onResult); function onResult(args) { app.android.off(app.AndroidApplication.activityResultEvent, onResult); t.handleResults(args.requestCode, args.resultCode, args.intent); } }; `` Mediafilepicker.prototype.handleResults = function ( requestCode, resultCode, data ) { var _this = this; var androidAcivity = android.app.Activity; var context = app.android.context; var output = []; var t = this; switch (requestCode) { case Constant.REQUEST_CODE_PICK_IMAGE: if (resultCode === androidAcivity.RESULT_OK) { var list = data.getParcelableArrayListExtra( Constant.RESULT_PICK_IMAGE ); list = list.toArray(); for (var index_1 = 0; index_1 < list.length; index_1++) { var item = list[index_1]; var file = { type: "image", file: item.getPath(), rawData: item, }; output.push(file); } } break; case Constant.REQUEST_CODE_PICK_VIDEO: if (resultCode === androidAcivity.RESULT_OK) { var list = data.getParcelableArrayListExtra( Constant.RESULT_PICK_VIDEO ); list = list.toArray(); for (var index_2 = 0; index_2 < list.length; index_2++) { var item = list[index_2]; var file = { type: "video", file: item.getPath(), rawData: item, }; output.push(file); } } break; case Constant.REQUEST_CODE_PICK_AUDIO: if (resultCode === androidAcivity.RESULT_OK) { var list = data.getParcelableArrayListExtra( Constant.RESULT_PICK_AUDIO ); list = list.toArray(); for (var index_3 = 0; index_3 < list.length; index_3++) { var item = list[index_3]; var file = { type: "audio", file: item.getPath(), rawData: item, }; output.push(file); } } break; case Constant.REQUEST_CODE_PICK_FILE: if (resultCode === androidAcivity.RESULT_OK) { let storageFile, filePath; var uri = data.getData(); let cursor = context .getContentResolver() .query(uri, null, null, null, null); cursor.moveToFirst(); let nameIndex = cursor.getColumnIndex( android.provider.OpenableColumns.DISPLAY_NAME ); let name = cursor.getString(nameIndex); let documents = fs.knownFolders.documents(); // let folders= documents.getFolder("downloads").path; let folders = android.os.Environment.getExternalStoragePublicDirectory( android.os.Environment.DIRECTORY_DOWNLOADS ).getAbsolutePath(); let folderPathDocuments = android.os.Environment.getExternalStoragePublicDirectory( android.os.Environment.DIRECTORY_DOCUMENTS ).getAbsolutePath(); filePath = fs.path.join(folders, name); if (FILE.File.exists(filePath)) { storageFile = fs.File.fromPath(filePath); } else { filePath = fs.path.join(folderPathDocuments, name); storageFile = fs.File.fromPath(filePath); } let file = { type: storageFile.extension, file: storageFile.path, rawData: storageFile, }; output.push(file); } break; case Constant.REQUEST_CODE_TAKE_IMAGE: if (resultCode === androidAcivity.RESULT_OK) { var rawData = new File(this.captureFilePath); var file = { type: "capturedImage", file: this.captureFilePath, rawData: rawData, }; output.push(file); } else { utils.ad .getApplicationContext() .getContentResolver() .delete(this.captureContentUrl, null, null); } break; case Constant.REQUEST_CODE_TAKE_VIDEO: if (resultCode === androidAcivity.RESULT_OK) { var rawData = new File(this.captureFilePath); var file = { type: "capturedVideo", file: this.captureFilePath, rawData: rawData, }; output.push(file); } else { utils.ad .getApplicationContext() .getContentResolver() .delete(this.captureContentUrl, null, null); } break; case Constant.REQUEST_CODE_TAKE_AUDIO: if (resultCode === androidAcivity.RESULT_OK) { var rawData = Uri.parse(data.getData().toString()); var cursor = context .getContentResolver() .query(rawData, null, null, null, null); var column_index = cursor.getColumnIndex(MediaStore.Audio.Media.DATA); cursor.moveToFirst(); var file = { type: "capturedAudio", file: cursor.getString(column_index), rawData: rawData, }; output.push(file); cursor.close(); } break; } setTimeout(function () { _this.results = output; if (output.length > 0) { t.notify({ eventName: "getFiles", object: t, }); } else { t.msg = "Picker cancel or no file has been selected."; t.notify({ eventName: "cancel", object: t, }); } }, 300); }; `` Mediafilepicker.prototype.greet = function () { return "Hello, NS"; }; return Mediafilepicker; })(observable_1.Observable); exports.Mediafilepicker = Mediafilepicker; //# sourceMappingURL=mediafilepicker.android.js.map
hope this OS helps and someone fork and update with this

@calleja23 I guess I'm using a newer version of NS and this plugin, so the code didn't work for me. Could you please clarify where did you change in this file? Thanks!

Looks like this repo is no longer maintained.
TGIF. I found this plugin https://github.com/nativescript-community/ui-document-picker instead.. Easier to use.

@calleja23 it didn't work, I'm testing with ns6

Any progress on this?

`
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});

var observable_1 = require("tns-core-modules/data/observable");
var app = require("@nativescript/core/application");
var utils = require("@nativescript/core/utils");
var permissions = require("nativescript-permissions");
const FILE = require("@nativescript/core/file-system");
const fs = require("@nativescript/core/file-system");

// import { Application, Observable, Utils, AndroidApplication } from "@nativescript/core";
// import { request as RequestPermission } from "@nativescript-community/perms";

var AudioPickActivity = com.vincent.filepicker.activity.AudioPickActivity;
var ImagePickActivity = com.vincent.filepicker.activity.ImagePickActivity;
var NormalFilePickActivity = com.vincent.filepicker.activity.NormalFilePickActivity;
var VideoPickActivity = com.vincent.filepicker.activity.VideoPickActivity;
var Constant = com.vincent.filepicker.Constant;
var Util = com.vincent.filepicker.Util;
var Intent = android.content.Intent;
var MediaStore = android.provider.MediaStore;
var Environment = android.os.Environment;
var File = java.io.File;
var ContentValues = android.content.ContentValues;
var Uri = android.net.Uri;
var FileUtils = android.os.FileUtils;
var Mediafilepicker = (function (_super) {
__extends(Mediafilepicker, _super);

function Mediafilepicker() {
return _super.call(this) || this;
}
Mediafilepicker.prototype.openImagePicker = function (params) {
var intent, pickerType, options = params.android;
if (options.isCaptureMood) {
this.performCapturing("image", options);
return;
}
intent = new Intent(app.android.foregroundActivity, ImagePickActivity.class);
options.isNeedCamera ? intent.putExtra(ImagePickActivity.IS_NEED_CAMERA, true) : intent.putExtra(ImagePickActivity.IS_NEED_CAMERA, false);
options.maxNumberFiles ? intent.putExtra(Constant.MAX_NUMBER, options.maxNumberFiles) : intent.putExtra(Constant.MAX_NUMBER, 99);
options.isNeedFolderList ? intent.putExtra(ImagePickActivity.IS_NEED_FOLDER_LIST, true) : intent.putExtra(ImagePickActivity.IS_NEED_FOLDER_LIST, false);
pickerType = Constant.REQUEST_CODE_PICK_IMAGE;
this.callIntent(intent, pickerType);
};
Mediafilepicker.prototype.openVideoPicker = function (params) {
var intent, pickerType, options = params.android;
if (options.isCaptureMood) {
this.performCapturing("video", options);
return;
}
intent = new Intent(app.android.foregroundActivity, VideoPickActivity.class);
options.isNeedCamera ? intent.putExtra(VideoPickActivity.IS_NEED_CAMERA, true) : intent.putExtra(VideoPickActivity.IS_NEED_CAMERA, false);
options.maxNumberFiles ? intent.putExtra(Constant.MAX_NUMBER, options.maxNumberFiles) : intent.putExtra(Constant.MAX_NUMBER, 99);
options.isNeedFolderList ? intent.putExtra(VideoPickActivity.IS_NEED_FOLDER_LIST, true) : intent.putExtra(VideoPickActivity.IS_NEED_FOLDER_LIST, false);
if (options.maxDuration > 0) {
intent.putExtra(Constant.MAX_VIDEO_DURATION, options.maxDuration);
}
intent.putExtra(Constant.VIDEO_QUALITY, 1);
if (options.videoQuality === 0) {
intent.putExtra(Constant.VIDEO_QUALITY, 0);
}
pickerType = Constant.REQUEST_CODE_PICK_VIDEO;
this.callIntent(intent, pickerType);
};
Mediafilepicker.prototype.openAudioPicker = function (params) {
var intent, pickerType, options = params.android;
if (options.isCaptureMood) {
this.performCapturing("audio", options);
return;
}
intent = new Intent(app.android.foregroundActivity, AudioPickActivity.class);
options.isNeedRecorder ? intent.putExtra(AudioPickActivity.IS_NEED_RECORDER, true) : intent.putExtra(AudioPickActivity.IS_NEED_RECORDER, false);
options.maxNumberFiles ? intent.putExtra(Constant.MAX_NUMBER, options.maxNumberFiles) : intent.putExtra(Constant.MAX_NUMBER, 99);
options.isNeedFolderList ? intent.putExtra(AudioPickActivity.IS_NEED_FOLDER_LIST, true) : intent.putExtra(AudioPickActivity.IS_NEED_FOLDER_LIST, false);
if (options.maxSize > 0) {
intent.putExtra(Constant.MAX_AUDIO_SIZE, options.maxSize);
}
intent.putExtra(AudioPickActivity.IS_TAKEN_AUTO_SELECTED, true);
pickerType = Constant.REQUEST_CODE_PICK_AUDIO;
this.callIntent(intent, pickerType);
};

Mediafilepicker.prototype.openFilePicker = function (params) {
var intent, pickerType, options = params.android,
extensions;
if (options.extensions.length > 0) {
extensions = Array.create(java.lang.String, options.extensions.length);
for (var i = 0; i < options.extensions.length; i++) {
extensions[i] = options.extensions[i];
}
}
intent = new android.content.Intent(android.content.Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf,image/jpeg,image/png");
// intent.setType("image/jpeg,image/png");
// intent.setType("application/pdf");
intent.putExtra(NormalFilePickActivity.SUFFIX, extensions);
intent.addCategory(android.content.Intent.CATEGORY_OPENABLE);
intent.setAction(android.content.Intent.ACTION_OPEN_DOCUMENT);
pickerType = Constant.REQUEST_CODE_PICK_FILE;
this.callIntent(intent, pickerType);
};
Mediafilepicker.prototype.performCapturing = function (type, options) {
var t = this;
var requestPermissions = [android.Manifest.permission.WRITE_EXTERNAL_STORAGE, ];
if (type === "image" || type === "video") {
requestPermissions.push(android.Manifest.permission.CAMERA);
} else if (type === "audio") {
requestPermissions.push(android.Manifest.permission.RECORD_AUDIO);
}
permissions.requestPermission(requestPermissions, "Need these permissions to access files").then(function () {
t.handleOnlyCaptureMode(type, options);
}).catch(function () {
t.msg = "Permission Error!";
t.notify({
eventName: "error",
object: t,
});
});
};
Mediafilepicker.prototype.handleOnlyCaptureMode = function (type, options) {
var context = app.android.context,
t = this,
intent, date, timeStamp, contentValues, file, uri;
switch (type) {
case "image":
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
date = new Date();
timeStamp = date.getFullYear() + "" + (date.getMonth() + 1) + "" + date.getDate() + "" + date.getHours() + "" + date.getMinutes() + "" + date.getSeconds();
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + "/IMG
" + timeStamp + ".jpg");
var mImagePath = file.getAbsolutePath();
this.captureFilePath = mImagePath;
contentValues = new ContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, mImagePath);
var mImageUri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
this.captureContentUrl = mImageUri;
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
if (Util.detectIntent(context, intent)) {
this.callIntent(intent, Constant.REQUEST_CODE_TAKE_IMAGE);
} else {
this.msg = "No photo capture app installed!";
this.notify({
eventName: "error",
object: this,
});
}
break;
case "video":
intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
date = new Date();
timeStamp = date.getFullYear() + "" + (date.getMonth() + 1) + "" + date.getDate() + "" + date.getHours() + "" + date.getMinutes() + "" + date.getSeconds();
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + "/VID
" + timeStamp + ".mp4");
var mVideoPath = file.getAbsolutePath();
this.captureFilePath = mVideoPath;
contentValues = new ContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, mVideoPath);
uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
this.captureContentUrl = uri;
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
if (options.maxDuration > 0) {
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, options.maxDuration);
}
if (options.videoQuality === 0) {
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
}
if (Util.detectIntent(context, intent)) {
this.callIntent(intent, Constant.REQUEST_CODE_TAKE_VIDEO);
} else {
this.msg = "No video recorder app installed!";
this.notify({
eventName: "error",
object: this,
});
}
break;
case "audio":
intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
if (options.maxSize > 0) {
var MAX_SIZE = android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES;
intent.putExtra(MAX_SIZE, options.maxSize);
}
if (Util.detectIntent(context, intent)) {
this.callIntent(intent, Constant.REQUEST_CODE_TAKE_AUDIO);
} else {
this.msg = "No audio recorder app installed!";
this.notify({
eventName: "error",
object: this,
});
}
break;
}
};
Mediafilepicker.prototype.callIntent = function (intent, pickerType) {
var t = this;
var requestPermissions = [android.Manifest.permission.WRITE_EXTERNAL_STORAGE, ];
if (pickerType === Constant.REQUEST_CODE_TAKE_IMAGE || pickerType === Constant.REQUEST_CODE_PICK_IMAGE || pickerType === Constant.REQUEST_CODE_TAKE_VIDEO || pickerType === Constant.REQUEST_CODE_PICK_VIDEO) {
requestPermissions.push(android.Manifest.permission.CAMERA);
} else if (pickerType === Constant.REQUEST_CODE_TAKE_AUDIO || pickerType === Constant.REQUEST_CODE_PICK_AUDIO) {
requestPermissions.push(android.Manifest.permission.RECORD_AUDIO);
}
permissions.requestPermission(requestPermissions, "Need these permissions to access files").then(function () {
app.android.foregroundActivity.startActivityForResult(intent, pickerType);
}).catch(function () {
t.msg = "Permission Error!";
t.notify({
eventName: "error",
object: t,
});
});
app.android.on(app.AndroidApplication.activityResultEvent, onResult);

function onResult(args) {
  app.android.off(app.AndroidApplication.activityResultEvent, onResult);
  t.handleResults(args.requestCode, args.resultCode, args.intent);
}

};
Mediafilepicker.prototype.handleResults = function (requestCode, resultCode, data) {
var _this = this;
var androidAcivity = android.app.Activity;
var context = app.android.context;
var output = [];
var t = this;
switch (requestCode) {
case Constant.REQUEST_CODE_PICK_IMAGE:
if (resultCode === androidAcivity.RESULT_OK) {
var list = data.getParcelableArrayListExtra(Constant.RESULT_PICK_IMAGE);
list = list.toArray();
for (var index_1 = 0; index_1 < list.length; index_1++) {
var item = list[index_1];
var file = {
type: "image",
file: item.getPath(),
rawData: item,
};
output.push(file);
}
}
break;
case Constant.REQUEST_CODE_PICK_VIDEO:
if (resultCode === androidAcivity.RESULT_OK) {
var list = data.getParcelableArrayListExtra(Constant.RESULT_PICK_VIDEO);
list = list.toArray();
for (var index_2 = 0; index_2 < list.length; index_2++) {
var item = list[index_2];
var file = {
type: "video",
file: item.getPath(),
rawData: item,
};
output.push(file);
}
}
break;
case Constant.REQUEST_CODE_PICK_AUDIO:
if (resultCode === androidAcivity.RESULT_OK) {
var list = data.getParcelableArrayListExtra(Constant.RESULT_PICK_AUDIO);
list = list.toArray();
for (var index_3 = 0; index_3 < list.length; index_3++) {
var item = list[index_3];
var file = {
type: "audio",
file: item.getPath(),
rawData: item,
};
output.push(file);
}
}
break;
case Constant.REQUEST_CODE_PICK_FILE:
if (resultCode === androidAcivity.RESULT_OK) {
let storageFile, filePath;
var uri = data.getData();
let cursor = context.getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
let nameIndex = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME);
let name = cursor.getString(nameIndex);
let documents = fs.knownFolders.documents(); // let folders= documents.getFolder("downloads").path;
let folders = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
let folderPathDocuments = android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();
filePath = fs.path.join(folders, name);
if (FILE.File.exists(filePath)) {
storageFile = fs.File.fromPath(filePath);
} else {
filePath = fs.path.join(folderPathDocuments, name);
storageFile = fs.File.fromPath(filePath);
}
let file = {
type: storageFile.extension,
file: storageFile.path,
rawData: storageFile,
};
output.push(file);
}
break;
case Constant.REQUEST_CODE_TAKE_IMAGE:
if (resultCode === androidAcivity.RESULT_OK) {
var rawData = new File(this.captureFilePath);
var file = {
type: "capturedImage",
file: this.captureFilePath,
rawData: rawData,
};
output.push(file);
} else {
utils.ad.getApplicationContext().getContentResolver().delete(this.captureContentUrl, null, null);
}
break;
case Constant.REQUEST_CODE_TAKE_VIDEO:
if (resultCode === androidAcivity.RESULT_OK) {
var rawData = new File(this.captureFilePath);
var file = {
type: "capturedVideo",
file: this.captureFilePath,
rawData: rawData,
};
output.push(file);
} else {
utils.ad.getApplicationContext().getContentResolver().delete(this.captureContentUrl, null, null);
}
break;
case Constant.REQUEST_CODE_TAKE_AUDIO:
if (resultCode === androidAcivity.RESULT_OK) {
var rawData = Uri.parse(data.getData().toString());
var cursor = context.getContentResolver().query(rawData, null, null, null, null);
var column_index = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
var file = {
type: "capturedAudio",
file: cursor.getString(column_index),
rawData: rawData,
};
output.push(file);
cursor.close();
}
break;
}
setTimeout(function () {
_this.results = output;
if (output.length > 0) {
t.notify({
eventName: "getFiles",
object: t,
});
} else {
t.msg = "Picker cancel or no file has been selected.";
t.notify({
eventName: "cancel",
object: t,
});
}
}, 300);
};
Mediafilepicker.prototype.greet = function () {
return "Hello, NS";
};
return Mediafilepicker;
})(observable_1.Observable);
exports.Mediafilepicker = Mediafilepicker;
//# sourceMappingURL=mediafilepicker.android.js.map
`

@calleja23
Thanks this code worked but extensions are not taking but i'm able to see pdf files
installed tns-core-modules package along with above code

Finally I use for NS8

  • "@nativescript/camera": "^5.0.10"
  • "@nativescript/imagepicker": "^1.0.6"
  • "@nativescript-community/ui-document-picker": "^1.1.7"
       if(!android.os.Environment.isExternalStorageManager()){
            let intent = new Intent(android.provider.Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);

            const activity = Application.android.foregroundActivity || Application.android.startActivity;

            activity.startActivityForResult(intent,0);

       }

Need have this permission for accesing files it worked for me in android 11 and above
need android sdk 30 for 'ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION'
Add this in maifest.
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>

Google does not like to grant ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION, my app was rejected because of that last week.

No idea yet if it will work, but I'll try https://github.com/pierremacedo/nativescript-android-fs next.

"@angular/core": "~14.0.0",
"@nativescript-community/ui-document-picker": "~1.1.12",
"@nativescript/core": "~8.3.4",

works fine on real device!!!

"@nativescript/core": "~8.2.5" -> not Work

For me its working on the physical device with the mediafilepicker now.

"@angular/core": "^12.2.0",
"nativescript-mediafilepicker": "^4.0.2",
"@nativescript/core": "^8.3.1",

AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

android:requestLegacyExternalStorage="true"

We have problems with several phones too. Using a custom file picker shows zero files. We would need to see XLSX files downloaded from a website. My old Note shows the files, other phones show zero files. @jibon57