[TIMOB-20470] Android 6.0 (Post 5.2.0 SDK): java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
GitHub Issue | n/a |
Type | Bug |
Priority | Critical |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2016-04-05T02:05:02.000+0000 |
Affected Version/s | Release 5.2.0 |
Fix Version/s | Release 5.4.0 |
Components | Android |
Labels | permissions |
Reporter | Eric Cheung |
Assignee | Hieu Pham |
Created | 2016-02-24T22:13:19.000+0000 |
Updated | 2016-07-15T06:25:36.000+0000 |
Description
Steps to Reproduce
I played around with the latest 5.2.0 SDK and Nexus 6P... for the most part everything seems to work except for one case with runtime permission.
if I use Ti.Filesystem.tempDirectory as my storage and created the permission checks, this still fails on first try even if you accept the Permission.
Log:
[INFO] : Permission granted? true
[ERROR] : TiFileProxy: (KrollRuntimeThread) [66154,66154] IOException encountered
[ERROR] : TiFileProxy: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.apptest.tempdirperm/cache/_tmp/GettingStartedTitanium_Linux.pdf: open failed: ENOENT (No such file or directory)
[ERROR] : TiFileProxy: at libcore.io.IoBridge.open(IoBridge.java:452)
[ERROR] : TiFileProxy: at java.io.FileOutputStream.(FileOutputStream.java:87)
[ERROR] : TiFileProxy: at org.appcelerator.titanium.io.TiFile.getOutputStream(TiFile.java:273)
[ERROR] : TiFileProxy: at org.appcelerator.titanium.io.TiFile.open(TiFile.java:336)
[ERROR] : TiFileProxy: at org.appcelerator.titanium.io.TiFile.write(TiFile.java:382)
[ERROR] : TiFileProxy: at org.appcelerator.titanium.TiFileProxy.write(TiFileProxy.java:290)
[ERROR] : TiFileProxy: at org.appcelerator.kroll.runtime.v8.V8Object.nativeCallProperty(Native Method)
[ERROR] : TiFileProxy: at org.appcelerator.kroll.runtime.v8.V8Object.callProperty(V8Object.java:73)
[ERROR] : TiFileProxy: at org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1155)
[ERROR] : TiFileProxy: at android.os.Handler.dispatchMessage(Handler.java:98)
[ERROR] : TiFileProxy: at android.os.Looper.loop(Looper.java:148)
[ERROR] : TiFileProxy: at org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:118)
[ERROR] : TiFileProxy: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
[ERROR] : TiFileProxy: at libcore.io.Posix.open(Native Method)
[ERROR] : TiFileProxy: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
[ERROR] : TiFileProxy: at libcore.io.IoBridge.open(IoBridge.java:438)
[ERROR] : TiFileProxy: ... 11 more
[INFO] : ALERT: (KrollRuntimeThread) [41,66195] File exist? false}}
Steps to recreate:
Create new Mobile App Project and paste in code to index.js
Compile and run, make sure it is a clean install on device
Click the 'Hello, World' to trigger the download and permission.
Accept the permission on popup.
Accessing the file in temporary directory fails. (alert will say file does not exist)
Close the app
Check permission in settings > app permission (storage should be enabled)
Restart the app
Click 'Hello, World' again to trigger download.
Alert will now say file exists.
Workaround:
If I switch the Ti.Filesystem.tempDirectory to Ti.Filesystem.applicationDataDirectory, I do not run into the issue of having to restart the app to open the file. But I have to make sure those files are deleted after use.
It would be best to use temporary directory so that the files are automatically removed after app is closed.
Actual Result
File does not exist in tempDirectory when permission is enabled on RunTime.
Expected Result
File should exist in tempDirectory.
Attachments
Ti.Filesystem.tempDirectory cannot access filesystem even if Storage Permissions is allowed after the *very first* run-time prompt. After the app restart, permission works as normal for temp directory.
Looks like something we didn't fix with TIMOB-20251
What if you do a setTimeout in the permission request callback? Maybe the permission is not yet available immediately right after the callback is called.
Im having the same issue in production for my android marshmallow users. Any update on this fix?
[~echeung@leviton.com] Could you try this. Writing it this way will allow it to work:-
If it's okay, I'll resolve this ticket.
[~msamah] shouldn't we handle creation of the temp directory?
Ashraf Abu this is my test:
Result:
I'll check this out more.
It must be fixed in 5.2.1.GA. Which meaning to release sdk if it not usable in last Android ?
With ref to the code I wrote earlier, fully written it should be:-
Permission is still required. Directory needing to be created seems to be an Android 6 thing/issue. Meanwhile, the issue does have a workaround which is to create the dir (with permissions). Even though this workaround exists, this should continue to be looked into.
some news on that?
https://github.com/appcelerator/titanium_mobile/pull/7913
PR https://github.com/appcelerator/titanium_mobile/pull/7913 reviewed and merged.
We must notify the developer that the files can in some cases be available to other applications. Files will be in private storage if
getCacheDir
butgetExternalCacheDir
not: {quote} There is no security enforced with these files. For example, any application holding WRITE_EXTERNAL_STORAGE can write to these files. {quote} Also: {quote} Starting in KITKAT, no permissions are required to read or write to the returned path; it's always accessible to the calling app. This only applies to paths generated for package name of the calling application. To access paths belonging to other packages, WRITE_EXTERNAL_STORAGE and/or READ_EXTERNAL_STORAGE are required. {quote} In both cases this note for Android, may be for iOS: {quote} The returned path may change over time if different shared storage media is inserted, so only relative paths should be persisted. {quote} [getCacheDir()](http://developer.android.com/intl/ru/reference/android/content/Context.html#getCacheDir%28%29) [getExternalCacheDir()](http://developer.android.com/intl/ru/reference/android/content/Context.html#getExternalCacheDir%28%29)[~bimmel] ^^
Guys, I'm having this problem on Android 6 using the latest SDK 5.2.2.GA. Just downloaded the 5.4.0 and it's gone. What should I do? What do you think is better? Is there a way to merge these fixes into the current SDK (5.2.2)? Because I can not wait till the GA release of 5.4. Thanks in advance
[~chmiiller] You could cherry-pick the changes https://github.com/appcelerator/titanium_mobile/pull/7913 into the 5.2.X branch and create a custom SDK for yourself. Related info: http://docs.appcelerator.com/platform/latest/#!/guide/Building_the_Titanium_SDK_From_Source 5.4.0 is not GA yet.
Ok good, thanks
Verified the fix. No
java.io.FileNotFoundException
seen & the file could be accessed. Closing. Environment: Appc Studio : 4.6.0.201605201934 Ti SDK : 5.4.0.v20160608165242 Ti CLI : 5.0.8 Alloy : 1.8.7 MAC El Capitan : 10.11.4 Appc NPM : 4.2.7-2 Appc CLI : 5.4.0-11 Node: 4.4.4 Nexus 6 - Android 6.0.0[~lchoudhary] There seems to be some issues in TIMOB-23562 Could you also check that TIMOB-23562 is a valid bug which affects this ticket? And if so, either reopen this ticket or do whatever actions you deem necessary.
[~lokeshchdhry] Ignore my last comment. It's another thing which I'll address in TIMOB-23562.