jibon57 / nativescript-mediafilepicker

A complete file picker solution for NativeScript
Apache License 2.0
51 stars 39 forks source link

Android 11: Custom File Picker not showing files #128

Open jajatismail opened 3 years ago

jajatismail commented 3 years ago

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.

Upd4ting commented 3 years ago

This is because of the new android scoped storage

kislasi commented 3 years ago

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

giog12 commented 3 years ago

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

sublime392 commented 3 years ago

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

SergeyMell commented 3 years ago

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

itsmerockingagain commented 3 years ago

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

nituwda commented 2 years ago

any update?

nituwda commented 2 years ago

This is because of the new android scoped storage

have you learned how to solve it?

xpalacincreditoh commented 2 years ago

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 :)

nituwda commented 2 years ago

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

calleja23 commented 2 years ago

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

ianshi95 commented 2 years ago

@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!

jajatismail commented 2 years ago

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.

Ederagp commented 2 years ago

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

OPADA-Eng commented 2 years ago

Any progress on this?

manojpraharsha commented 2 years ago

` "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_IMAGECAPTURE); date = new Date(); timeStamp = date.getFullYear() + "" + (date.getMonth() + 1) + "" + date.getDate() + "" + date.getHours() + "" + date.getMinutes() + "" + date.getSeconds(); file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORYDCIM).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_VIDEOCAPTURE); date = new Date(); timeStamp = date.getFullYear() + "" + (date.getMonth() + 1) + "" + date.getDate() + "" + date.getHours() + "" + date.getMinutes() + "" + date.getSeconds(); file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORYDCIM).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

xpalacincreditoh commented 2 years ago

Finally I use for NS8

manojpraharsha commented 1 year ago
       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"/>

ray007 commented 1 year ago

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.

Ederagp commented 1 year ago

"@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

Maxeeezy commented 1 year ago

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"
csimpi commented 1 year ago

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