{ "id": "172411", "key": "TIMOB-26447", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2018-10-24T17:50:09.000+0000", "created": "2018-10-09T09:19:59.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [], "versions": [ { "id": "20183", "description": "", "name": "Release 7.4.0", "archived": false, "released": true, "releaseDate": "2018-09-17" } ], "issuelinks": [], "assignee": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2018-10-24T17:50:53.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "h6.Problem\r\n\r\nCustomer is trying to download the pdf from remote server using URL, save them to external or application directory and then open them in external pdf viewer using intent. Like example in post https://www.appcelerator.com/blog/2015/08/appcelerator-pdf-viewer-demo/. But throwing following error on Android 8.\r\n\r\n{code}\r\n[ERROR] : TiFileProxy: (KrollRuntimeThread) [9574,75852] IOException encountered \r\n[ERROR] : TiFileProxy: java.io.FileNotFoundException: /storage/emulated/0/com.edf.mobile/EDF Bill 10 August 2018.pdf (Permission denied) \r\n[ERROR] : TiFileProxy: at java.io.FileOutputStream.open0(Native Method) \r\n[ERROR] : TiFileProxy: at java.io.FileOutputStream.open(FileOutputStream.java:287) \r\n[ERROR] : TiFileProxy: at java.io.FileOutputStream.(FileOutputStream.java:223) \r\n[ERROR] : TiFileProxy: at org.appcelerator.titanium.io.TiFile.getOutputStream(TiFile.java:304) \r\n[ERROR] : TiFileProxy: at org.appcelerator.titanium.io.TiFile.open(TiFile.java:368) \r\n[ERROR] : TiFileProxy: at org.appcelerator.titanium.io.TiFile.write(TiFile.java:414) \r\n[ERROR] : TiFileProxy: at org.appcelerator.titanium.TiFileProxy.write(TiFileProxy.java:331) \r\n[ERROR] : TiFileProxy: at org.appcelerator.kroll.runtime.v8.V8Object.nativeCallProperty(Native Method) \r\n[ERROR] : TiFileProxy: at org.appcelerator.kroll.runtime.v8.V8Object.callProperty(V8Object.java:75) \r\n[ERROR] : TiFileProxy: at org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1208) \r\n[ERROR] : TiFileProxy: at android.os.Handler.dispatchMessage(Handler.java:101) \r\n[ERROR] : TiFileProxy: at android.os.Looper.loop(Looper.java:164) \r\n[ERROR] : TiFileProxy: at org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:117) \r\n{code}\r\n\r\nh6.Note\r\n\r\nThe strange problem is not happening to all model of devices. For example\r\n\r\nOn Android 7\r\nSeems all devices work well. At least, all the test devices are working well.\r\n\r\nOn Android 8\r\nMoto G device which is on android 8 worked fine.\r\nbut others, like Google Pixel or Samsung Note 8, will get above error. \r\n\r\nh6.Example code\r\n{code}\r\nfunction testPDF() {\r\n\tvar tempFile = Titanium.Filesystem.getFile(Titanium.Filesystem.isExternalStoragePresent() ? Titanium.Filesystem.externalStorageDirectory : Titanium.Filesystem.applicationDataDirectory, '/' + 'EDF Bill ' + e.source.text + '.pdf'); \r\n\tvar appfilepath = tempFile.nativePath; \r\n\r\n\tvar url = \"http://www.mbta.com/uploadedfiles/Documents/Schedules_and_Maps/Rapid%20Transit%20w%20Key%20Bus.pdf\";\r\n\tvar xhr = Ti.Network.createHTTPClient(); \r\n\r\n\txhr.onload = function() { \r\n\t\ttempFile.write(this.responseData); \r\n\t\ttry{ \r\n\t\t\tTi.Android.currentActivity.startActivity(Ti.Android.createIntent({ \r\n\t\t\t\taction: Ti.Android.ACTION_VIEW, \r\n\t\t\t\ttype: 'application/pdf', \r\n\t\t\t\tdata: appfilepath \r\n\t\t\t})); \r\n\t\t} catch(e) { \r\n\t\t\tTi.API.info('error trying to launch activity, e = '+e); \r\n\t\t\talert('No PDF apps installed!'); \r\n\t\t} \r\n\t};\r\n \r\n\txhr.onerror = function() { \r\n\t\talert(\"Cannot retrieve PDF from web site\") ;\r\n\t}; \r\n\r\n\txhr.timeout = 10000; \r\n\txhr.open(\"GET\", url); \r\n\txhr.send();\r\n}\r\n{code}\r\n\r\nPlease check this asap, very important function for customer's app. ", "attachment": [ { "id": "65698", "filename": "test.js", "author": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "created": "2018-10-11T10:15:42.000+0000", "size": 2370, "mimeType": "text/javascript" } ], "flagged": false, "summary": "Android 8: Unable open PDF on some devices", "creator": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "subtasks": [], "reporter": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "environment": "Android 8\r\nSDK 7.4.0", "comment": { "comments": [ { "id": "442494", "author": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "body": "It's correct that they need to add the required storage permissions into the {{tiapp.xml}}. But on later Android versions they also need to request storage permissions:\r\n\r\nFor example, they could amend their {{onload}} to request storage permissions:\r\n{code:js}\r\nxhr.onload = function() {\r\n Ti.Filesystem.requestStoragePermissions(function (e) {\r\n if (e.success) {\r\n tempFile.write(this.responseData);\r\n try{\r\n Ti.Android.currentActivity.startActivity(Ti.Android.createIntent({\r\n action: Ti.Android.ACTION_VIEW,\r\n type: 'application/pdf',\r\n data: appfilepath\r\n }));\r\n } catch(e) {\r\n Ti.API.info('error trying to launch activity, e = '+e);\r\n alert('No PDF apps installed!');\r\n }\r\n } else {\r\n Ti.API.error('could not obtain required storage permissions!');\r\n }\r\n });\r\n};\r\n{code}", "updateAuthor": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-10-10T18:20:24.000+0000", "updated": "2018-10-10T18:20:24.000+0000" }, { "id": "442542", "author": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "body": "You will want write permissions too:\r\n{code:js}\r\nTi.Android.requestPermissions(\r\n [ 'android.Manifest.permission.READ_EXTERNAL_STORAGE', 'android.permission.WRITE_EXTERNAL_STORAGE' ],\r\n function (e) {\r\n if (e.success) {\r\n tempFile.write(this.responseData);\r\n try{\r\n Ti.Android.currentActivity.startActivity(Ti.Android.createIntent({\r\n action: Ti.Android.ACTION_VIEW,\r\n type: 'application/pdf',\r\n data: appfilepath\r\n }));\r\n } catch(e) {\r\n Ti.API.info('error trying to launch activity, e = '+e);\r\n alert('No PDF apps installed!');\r\n }\r\n } else {\r\n Ti.API.error('could not obtain required storage permissions!');\r\n }\r\n }\r\n);\r\n{code}", "updateAuthor": { "name": "gmathews", "key": "gmathews", "displayName": "Gary Mathews", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-10-11T22:07:04.000+0000", "updated": "2018-10-11T22:07:04.000+0000" } ], "maxResults": 6, "total": 6, "startAt": 0 } } }