Android 6 doesn't load images from a remote url, while Android 5 works fine. All of the following 4 are not shown on Android 6.
var win = Ti.UI.createWindow();
var view = Ti.UI.createScrollView({
scrollType: 'vertical',
layout: 'vertical'
});
view.add(Ti.UI.createLabel({
text: 'Remote HTTPS from AppC'
}));
view.add(Ti.UI.createImageView({
image: 'https://www.appcelerator.com/wp-content/themes/appc-rwd/assets/media/images/logo.png'
}));
view.add(Ti.UI.createLabel({
text: 'Remote HTTP from AppC'
}));
view.add(Ti.UI.createImageView({
image: 'http://www.appcelerator.com/wp-content/themes/appc-rwd/assets/media/images/logo.png'
}));
view.add(Ti.UI.createLabel({
text: 'Remote HTTPS from CloudFront'
}));
view.add(Ti.UI.createImageView({
image: 'https://cfimagesstaging.zipwire.com/56325c2e7dec0.jpg'
}));
view.add(Ti.UI.createLabel({
text: 'Remote HTTP from CloudFront'
}));
view.add(Ti.UI.createImageView({
image: 'http://cfimagesstaging.zipwire.com/56325c2e7dec0.jpg'
}));
win.add(view);
win.open();
adb logcat shows a failing TiDownloader request:
{noformat}
11-05 16:26:13.015 23434 23480 E TiDownloadManager: (pool-2-thread-1) [100607,100607] Exception downloading
https://cfimagesstaging.zipwire.com/56325c2e7dec0.jpg
11-05 16:26:13.015 23434 23480 E TiDownloadManager: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.zipwire.test/cache/_tmp/remote-cache/5b7624468b64d5e3153101a30a50891c94dace39.hdr: open failed: ENOENT (No such file or directory)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at libcore.io.IoBridge.open(IoBridge.java:452)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at java.io.FileOutputStream.
(FileOutputStream.java:87)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at java.io.FileOutputStream.(FileOutputStream.java:72)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at java.io.FileWriter.(FileWriter.java:42)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at org.appcelerator.titanium.util.TiResponseCache.put(TiResponseCache.java:472)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at com.android.okhttp.internal.huc.CacheAdapter.put(CacheAdapter.java:57)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at com.android.okhttp.internal.http.HttpEngine.maybeCache(HttpEngine.java:554)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:826)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:439)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at java.net.URL.openStream(URL.java:470)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at org.appcelerator.titanium.util.TiDownloadManager$DownloadJob.run(TiDownloadManager.java:135)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at java.lang.Thread.run(Thread.java:818)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at libcore.io.Posix.open(Native Method)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: at libcore.io.IoBridge.open(IoBridge.java:438)
11-05 16:26:13.015 23434 23480 E TiDownloadManager: ... 17 more
{noformat}
I searched and found this Java issue:
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4620571
It seems like Java can't handle a protocol redirect. I am just checking if we do this for images.
Hi , I tested this issue and experienced the same behaviour as the reporter. This a valid issue.Remote images from secure url not loaded on android 6 , but it's load fine on android 5. Find the attached screenshot . *Environment*
!android 5 .png|thumbnail! !android 6.png|thumbnail!
[~shossain] I wonder if this is related to TIMOB-11863 and not the secure URL but the redirect is the problem?
I checked back with our backend guy and he said that there is no redirect. I tried both https and http and it fails for both. The code snippet was after my second try ... sorry about that. The images are served via CloudFront ... This is tested on actual devices: Nexus 4 with latest Android 5, Nexus 7 with latest Android 6.
I just tested again: Local images load on Android 6 (a single jpg loaded from Resources/images/ ) both on sdk 5.0.2.GA and 5.1.0.v20151104073721. ANY remote image fails to load on Android 6 on both sdk'. I tried random images from Google image search ... to be sure that it is not our server setup.
OK, weird... I just updated the sample and tested with: * Titanium 5.0.2.GA and Android 5.1.0 via Genymotion: All OK * Titanium 5.1.0.RC and Android 5.1.0 via Genymotion: All OK * Titanium 5.0.2.GA and Android 6.0 on Nexus 5: All OK * Titanium 5.1.0.RC and Android 6.0 on Nexus 5: All OK In other words... cannot reproduce with: * android 6.0 (3.4.0-g2aa165e) * jdk1.8.0_60 * build-tools 23.0.1. * node v0.12.7, 4.2.2 * mac os x 10.11.1 !android_20151110-115315.png|thumbnail!
[~aislam] could you try again with the updated sample to see if it still doesn't work for you (since it does work for me) and if so drop the specs of your device, os, jdk here to compare with mine and [~janruehling] (where the updated sample fails still)
A few more infos to help troubleshooting: - device: Nexus 7 2013 - os version (Kernel): 3.4.0-ga5a4133 (android-build@wpix7.hot.corp.google.com #1 -- Mon Aug 17 21:50:19 UTC 2015) - mac os version: 10.11.1 - java version: 1.8.0_60 - android build tools version: 23.0.1 - titanium SDK: 5.1.0.v20151104073721 - titanium CLI: 5.0.5 - nodejs version: 0.12.7, 4.1.0, 4.2.0 - npm version: 2.14.3 !Screenshot_20151110-114826.png|thumbnail! Update: I just tried the emulator with Android 6 -- the images showed up
Another dump ... maybe it helps. It always fails in the TiDownloadManager I think:
Same error here. Tried in my current project and created a brand new project just to make sure. Android 6.0 !http://i.imgur.com/Up0E6Tl.png|width=300,height=400! Android 5.0 !http://i.imgur.com/ENgvE5A.png|width=300,height=400! * device: Genymotion Android 6.0 simulator, Android Stock 6.0 simulator * mac os version: 10.11.1 * java version: 1.8.0_45 * android build tools version: 23.0.2 * titanium SDK: 5.1.0.GA * CLI Version: 5.0.4 * Node.js Version: 5.1.0 * npm Version: 3.3.12
Error occurs because of this
11-05 16:26:13.015 23434 23480 E TiDownloadManager: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.zipwire.test/cache/_tmp/remote-cache/5b7624468b64d5e3153101a30a50891c94dace39.hdr: open failed: ENOENT (No such file or directory)
It's trying to write into storage for cache. It fails in Android 6.0 cause of the new permission system. Quick fix is to go to the Settings>Apps>YourApp>Permissions and enable Storage.Thanks for your help Ashraf! I'm not using Titanium Studio so not sure what I need to modify. I already have
in my tiapp.xmp
[~velan] Besides setting the permission in the manifest, you would need to ask for permission again from the user in Android 6.0 http://developer.android.com/training/permissions/requesting.html As mentioned earlier one band-aid is to do: Go to the Settings>Apps>YourApp>Permissions and enable Storage. But that's something the enduser needs to do. This is an issue that needs to be addressed. Current image loading logic does not support for this permission requesting in Android 6.0.
Oh misunderstood it was on the device. It does indeed work when I manually change the permissions in the settings. So to be clear there's nothing I can do to make my app work on an Android 6 device right now? Would it work if I downgrade to SDK 5.0.0 and build tools v22? Do you know if this issue is being worked on somewhere? Thanks a lot for your help! P.S: Just saw your message, will try!
Yup. I just edited the code as well.
You're a lifesaver! Awesome!
[~velan] No problem. But this issue probably needs some working and love so that you don't need to use that workaround.
Added an alternative workaround in TIMOB-20103 if anyone is interested to look into that.
I've created a module temporarily. https://github.com/gimdongwoo/Ti-Android-RequestStoragePermission
Titanium 5.0.2.RC is out and this fix isn't in fixed yet. Can we assume it will be done by the time GA comes out?
[~engross] That's cool. You could use that but I think just writing it in Javascript is doable as well. [~thebrousse] Are you using the workaround?
The fix for this is to actually specify the write permission for external storage within the tiapp.xml.
Also, per the Android documentation, reading from external storage will also require a permission tag as well.
This is documented here: http://developer.android.com/training/basics/data-storage/files.html Adding the Camera privilege can work since it requires storage access, but isn't necessary. Using the above works just fine.
[~bgrantges@appcelerator.com] What you mention is true. Though it needs to ask for permissions at runtime as well. From Android 6.0 and above, permissions have to be requested at run time as well as adding it to the manifest. Refer to: http://developer.android.com/training/permissions/requesting.html This is why we need the
requestCameraPermissions
at runtime.Created a jira ticket to provide for method to request for storage permission. TIMOB-20235
I don't think TIMOB-20235 is the way to resolve this ticket because you don't want an app that just uses some remote images to prompt (in Android 6.0+) the user for run-time permission to external storage.
[~fokkezb] It's not the best way. Remote images (logic) will need to be addressed in a way that storage isn't used.
I Think this is a really severe Bug. Our app is using a lot of remote images and besides the fact that it's not a solution to prompt the users for permission to show content, it seems like the app tries to download the images all the time. This is causing a major dataleak / excessive datausage (3x-4x compared to Android 5). console output: {noformat} [ERROR] : TiDownloadManager: (pool-5-thread-2) [37045,42502] Exception downloading http://images.cgames.de/images/idgwpgsgp/bdb/2734717/368x207.jpg [ERROR] : TiDownloadManager: java.net.ConnectException: failed to connect to images.cgames.de/2.17.123.58 (port 80): connect failed: ENETUNREACH (Network is unreachable) [ERROR] : TiDownloadManager: at libcore.io.IoBridge.connect(IoBridge.java:124) [ERROR] : TiDownloadManager: at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183) [ERROR] : TiDownloadManager: at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:452) [ERROR] : TiDownloadManager: at java.net.Socket.connect(Socket.java:884) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.Platform.connectSocket(Platform.java:117) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.http.SocketConnector.connectRawSocket(SocketConnector.java:160) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.http.SocketConnector.connectCleartext(SocketConnector.java:67) [ERROR] : TiDownloadManager: at com.android.okhttp.Connection.connect(Connection.java:152) [ERROR] : TiDownloadManager: at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185) [ERROR] : TiDownloadManager: at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388) [ERROR] : TiDownloadManager: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231) [ERROR] : TiDownloadManager: at java.net.URL.openStream(URL.java:470) [ERROR] : TiDownloadManager: at org.appcelerator.titanium.util.TiDownloadManager$DownloadJob.run(TiDownloadManager.java:135) [ERROR] : TiDownloadManager: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) [ERROR] : TiDownloadManager: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) [ERROR] : TiDownloadManager: at java.lang.Thread.run(Thread.java:818) [ERROR] : TiDownloadManager: Caused by: android.system.ErrnoException: connect failed: ENETUNREACH (Network is unreachable) [ERROR] : TiDownloadManager: at libcore.io.Posix.connect(Native Method) [ERROR] : TiDownloadManager: at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:111) [ERROR] : TiDownloadManager: at libcore.io.IoBridge.connectErrno(IoBridge.java:137) [ERROR] : TiDownloadManager: at libcore.io.IoBridge.connect(IoBridge.java:122) [ERROR] : TiDownloadManager: ... 20 more [ERROR] : TiDownloadManager: (pool-5-thread-2) [5,42512] Exception downloading http://images.cgames.de/images/idgwpgsgp/bdb/2734334/368x207.jpg [ERROR] : TiDownloadManager: (pool-5-thread-1) [1,42513] Exception downloading http://images.cgames.de/images/idgwpgsgp/bdb/2734506/368x207.jpg [ERROR] : TiDownloadManager: (pool-5-thread-2) [1,42514] Exception downloading http://images.cgames.de/images/idgwpgsgp/bdb/2734679/368x207.jpg [ERROR] : TiDownloadManager: (pool-5-thread-1) [3,42517] Exception downloading http://images.cgames.de/images/idgwpgsgp/bdb/2734570/368x207.jpg [ERROR] : TiDownloadManager: (pool-5-thread-1) [1688,155903] Exception downloading http://images.cgames.de/images/idgwpgsgp/bdb/2734575/368x207.jpg [ERROR] : TiDownloadManager: java.io.FileNotFoundException: /storage/emulated/0/Android/data/de.gamestar.news/cache/_tmp/remote-cache/a62cc5d065aa30ab829e5923be29b3879e63c4ce.hdr: open failed: ENOENT (No such file or directory) [ERROR] : TiDownloadManager: at libcore.io.IoBridge.open(IoBridge.java:452) [ERROR] : TiDownloadManager: at java.io.FileOutputStream.
[~mbiel] Thank you for letting us know. This ticket is currently being looked into in resolving the issue without needing storage permissions.
With TIMOB-20251, remote images can load without Storage Permissions.
Resolved this as Duplicate.
Closing as duplicate.