Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NativeScript 8.2 - Android 11+ file handle 'content://' #9871

Closed
3 tasks done
Siergiej29 opened this issue Apr 14, 2022 · 4 comments · Fixed by #9874
Closed
3 tasks done

NativeScript 8.2 - Android 11+ file handle 'content://' #9871

Siergiej29 opened this issue Apr 14, 2022 · 4 comments · Fixed by #9874
Assignees
Labels

Comments

@Siergiej29
Copy link

@Siergiej29 Siergiej29 commented Apr 14, 2022

Issue Description

I am in the process of creating dynamic forms with the possibility of sending files of various types, recognized by their extension.

I use the ui-document-picker plugin for this (or whatever else plugin may be).
Unable to read content from content: //

According to the information at Nativescript Blog

Android 11+ file handling
If you had been targeting newer Android SDK's or devices you may have run into trouble with content: // uri's. 8.2 now properly handles those under the hood with the same existing file APIs.

It should be possible to read the contents of the file from content: //, but it is not possible because it returns an error:

JS: TypeError: Cannot read property 'readSync' of null
JS: at FileSystemAccess29.readSync (file: src \ webpack: \ ns-file-android11 ​​\ node_modules \ @nativescript \ core \ file-system \ file-system-access.android.js: 692: 0)
JS: at file: src \ webpack: \ ns-file-android11 ​​\ src \ app \ app.component.ts: 16:46
JS: at Array.forEach (<anonymous>)
JS: at file: src \ webpack: \ ns-file-android11 ​​\ src \ app \ app.component.ts: 15: 0
JS: at _ZoneDelegate.invoke (file: src \ webpack: \ ns-file-android11 ​​\ node_modules \ zone.js \ fesm2015 \ zone.js: 372: 0)
JS: at Object.onInvoke (file: src \ webpack: \ ns-file-android11 ​​\ node_modules \ @angular \ core \ fesm2015 \ core.mjs: 25548: 0)
JS: at _ZoneDelegate.invoke (file: src \ webpack: \ ns-file-android11 ​​\ node_modules \ zone.js \ fesm2015 \ zone.js: 371: 0)
JS: at Zone.run (file: src \ webpack: \ ns-file-android11 ​​\ node_modules \ zone.js \ fesm2015 \ zone.js: 134: 0)
JS: at file: ///data/data/org.nativescript.nsfileandroid11/files/app/vendor.js: ...

error:

at FileSystemAccess29.readSync (file: src \ webpack: \ ns-file-android11 ​​\ node_modules \ @nativescript \ core \ file-system \ file-system-access.android.js: 692: 0)

points to file-system-access.android - 815

where getOrSetHelper returns null and therefore we cannot read the contents of the file.

Does Nativescirpt 8.2 really have the correct file handling for android 11?
This is probably not a plug-in problem, just core NS itself.

Reproduction

I have created a sample repository with the problem already in place

https://gitlab.com/NiepozornyJanusz/ns-file-android11

  1. clone repo
  2. npm i
  3. tns/ns run android (11)
  4. click on button and select file

example selected file uri: content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2Fdom-opole.jpg

Relevant log output (if applicable)

No response

Environment

√ Component nativescript has 8.2.3 version and is up to date.
√ Component @nativescript/core has 8.2.2 version and is up to date.
× Component @nativescript/ios is not installed.
√ Component @nativescript/android has 8.2.2 version and is up to date.

Angular CLI:    13.2.7
Node            14.15.0
Java JDK        11.0.14.1
Gradle          7.4.1
Windows         11
Android API 30  11
"dependencies": {
  "@angular/animations": "~13.2.0",
  "@angular/cli": "^13.2.0",
  "@angular/common": "~13.2.0",
  "@angular/compiler": "~13.2.0",
  "@angular/core": "~13.2.0",
  "@angular/forms": "~13.2.0",
  "@angular/platform-browser": "~13.2.0",
  "@angular/platform-browser-dynamic": "~13.2.0",
  "@angular/router": "~13.2.0",
  "@nativescript-community/ui-document-picker": "^1.1.12",
  "@nativescript/angular": "^13.0.0",
  "@nativescript/core": "8.2.2",
  "@nativescript/theme": "~3.0.2",
  "nativescript-envinfo": "^1.0.9",
  "rxjs": "~7.5.0",
  "zone.js": "~0.11.5"
},
"devDependencies": {
  "@angular-devkit/build-angular": "~13.2.0",
  "@angular/compiler-cli": "~13.2.0",
  "@nativescript/android": "8.2.2",
  "@nativescript/types": "~8.2.0",
  "@nativescript/webpack": "~5.0.6",
  "@ngtools/webpack": "~13.2.0",
  "typescript": "~4.5.5"
}

Please accept these terms

@Siergiej29 Siergiej29 added the bug-pending-triage label Apr 14, 2022
@Siergiej29 Siergiej29 reopened this Apr 14, 2022
@triniwiz triniwiz self-assigned this Apr 15, 2022
@triniwiz triniwiz added bug and removed bug-pending-triage labels Apr 15, 2022
triniwiz added a commit that referenced this issue Apr 15, 2022
@NathanWalker
Copy link
Contributor

@NathanWalker NathanWalker commented Apr 15, 2022

@Siergiej29 you can try this fix by setting your package.json to this:

"@nativescript/core": "8.2.3-alpha.0"

Then be sure to run ns clean

Please let us know if it works for you and upon confirmation we will publish the patch.

@Siergiej29
Copy link
Author

@Siergiej29 Siergiej29 commented Apr 15, 2022

Thank you for your time.

After updating @nativescript/core to version 8.2.3-alpha.0, it seems that getOrSetHelper no longer returns null for png and jpg extensions, but for the others it does, and the following information also appears for different file extensions.
Any attempt to read the file returns null.

Ofc project was cleaned.

Updated in reproduction: https://gitlab.com/NiepozornyJanusz/ns-file-android11

Example code:

 data.files.forEach(selected => {
            let applicationContext = getNativeApplication().getApplicationContext();
            const getOrSetHelper: org.nativescript.widgets.FileHelper = org.nativescript.widgets.FileHelper.fromString(applicationContext, selected);
            console.log('##################');
            console.log('applicationContext', applicationContext);
            console.log('selected: ', selected);
            console.log('getOrSetHelper: ', getOrSetHelper);
            console.log('##################');

            const fileRead = getFileAccess().read(selected)
            console.log('### fileRead: ', fileRead);

            const readSync = getFileAccess().readSync(selected)
            console.log('### fileSync: ', readSync);

            const readText = getFileAccess().readText(selected);
            console.log('### fileReadText: ', readText);

            getFileAccess().readAsync(selected).then(
              readAsyncResolve => {
                console.log('### fileAsyncResolve: ', readAsyncResolve)},
              readAsyncRejected => {
                console.log('### fileAsyncRejected: ', readAsyncRejected)}
            );
          });

Selecting direct from downloaded

PNG, JPG:

JS: ##################
JS: applicationContext com.tns.NativeScriptApplication@ac31395
JS: selected:  content://com.android.providers.downloads.documents/document/msf%3A45
JS: getOrSetHelper:  org.nativescript.widgets.FileHelper@319fc1a
JS: ##################
JS: ### fileRead:  null
JS: ### fileSync:  null
JS: ### fileReadText:  null
JS: ### fileAsyncRejected:  java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content:
//com.android.providers.downloads.documents/document/msf:45 from pid=7539, uid=10195 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

PDF, DOCX

JS: ##################
JS: applicationContext com.tns.NativeScriptApplication@ac31395
JS: selected:  content://com.android.providers.downloads.documents/document/msf%3A41
JS: getOrSetHelper:  null
JS: ##################
JS: ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'readSync' of null
JS: TypeError: Cannot read property 'readSync' of null
JS:     at FileSystemAccess29.readSync (file: src\webpack:\ns-file-android11\node_modules\@nativescript\core\file-system\file-system-access.android.js:693:0)
JS:     at file: src\webpack:\ns-file-android11\src\app\app.component.ts:24:46
JS:     at Array.forEach (<anonymous>)
JS:     at file: src\webpack:\ns-file-android11\src\app\app.component.ts:16:0
JS:     at _ZoneDelegate.invoke (file: src\webpack:\ns-file-android11...

JPEG, XLSX, CSV

JS: ##################
JS: applicationContext com.tns.NativeScriptApplication@ac31395
JS: selected:  content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2F13598.jpeg
JS: getOrSetHelper:  null
JS: ##################
JS: ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'readSync' of null
JS: TypeError: Cannot read property 'readSync' of null
JS:     at FileSystemAccess29.readSync (file: src\webpack:\ns-file-android11\node_modules\@nativescript\core\file-system\file-system-access.android.js:693:0)
JS:     at file: src\webpack:\ns-file-android11\src\app\app.component.ts:24:46
JS:     at Array.forEach (<anonymous>)
JS:     at file: src\webpack:\ns-file-android11\src\app\app.component.ts:16:0
JS:     at _ZoneDelegate.invoke (file: src\webpack:\ns-file-android11\...

I wonder why there is a content to the file (PNG, JPG, PDF, DOCX) content://com.android.providers.downloads.documents/document/msf%3A41 once, and already with another extension (JPEG, XLSX, CSV) eg. content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2F13598.jpeg

Select from external storage

After selecting a file from another location (not direct downloaded) from external storage, I can read the graphic file

JPEG, JPG, PNG

JS: ##################
JS: applicationContext com.tns.NativeScriptApplication@65be60b
JS: selected:  content://com.android.externalstorage.documents/document/primary%3ADocuments%2F13598.jpeg
JS: getOrSetHelper:  org.nativescript.widgets.FileHelper@85e324e
JS: ##################
JS: ### fileRead:  [B@ea50105
JS: ### fileSync:  [B@dde8c68
JS: ### fileReadText:  ����
JS: ### fileAsyncResolve:  [B@8c13575

Other files (PDF, DOCX, CSV, TXT) like bellow:

JS: ##################
JS: applicationContext com.tns.NativeScriptApplication@65be60b
JS: selected:  content://com.android.externalstorage.documents/document/primary%3ADocuments%2FIP.Zal_2-strona_www.docx
JS: getOrSetHelper:  org.nativescript.widgets.FileHelper@d915d6c
JS: ##################
JS: ### fileRead:  null
JS: ### fileSync:  null
JS: ### fileReadText:  null
JS: ### fileAsyncRejected:  java.io.FileNotFoundException: /storage/emulated/0/Documents/IP.Zal_2-strona_www.docx: open failed: EACCES (Permission denied)  

In all files extensions from external storage I have getOrSetHelper (is not null)

@matteo6b
Copy link

@matteo6b matteo6b commented Jun 7, 2022

In this pull request return the path of the file that is necessary for openFile() and the background-http plugin and it works with android 11

palikollar/ns-device-import-activity@334453f

@rafal2603
Copy link

@rafal2603 rafal2603 commented Jun 15, 2022

Hi!,

Can this problem be expected to be resolved?
I need it for yesterday

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants