{ "id": "167587", "key": "AC-4961", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "12217", "key": "AC", "name": "Appcelerator - INBOX", "projectCategory": { "id": "10000", "description": "", "name": "Customer Service" } }, "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2017-05-15T14:45:24.000+0000", "created": "2017-05-12T06:35:10.000+0000", "labels": [ "android", "requestPermission" ], "versions": [], "issuelinks": [], "assignee": { "name": "shossain", "key": "shossain", "displayName": "Shak Hossain", "active": false, "timeZone": "America/Los_Angeles" }, "updated": "2017-05-17T11:33:00.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": "14548", "name": "Titanium SDK & CLI", "description": "Please enter tickets related to the MobileSDK here." } ], "description": "I am trying ro write/read file into the external storage device. but getting the (Permission denied) error. I have already applied run time request permission.\r\n\r\nOSX, Titanium SDK 6.0.4 , Android Platform 6.0 , Android API 23\r\n===============\r\n\r\n{code:java}\r\n[ERROR] : TiFileProxy: (main) [1353,1353] IOException encountered\r\n[ERROR] : TiFileProxy: java.io.FileNotFoundException: /storage/emulated/0/com.example.sample/sample.txt: open failed: EACCES (Permission denied)\r\n[ERROR] : TiFileProxy: \tat libcore.io.IoBridge.open(IoBridge.java:452)\r\n[ERROR] : TiFileProxy: \tat java.io.FileOutputStream.(FileOutputStream.java:87)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.io.TiFile.getOutputStream(TiFile.java:273)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.io.TiFile.open(TiFile.java:336)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.io.TiFile.write(TiFile.java:460)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.TiFileProxy.write(TiFileProxy.java:287)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:196)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.kroll.KrollRuntime.runModule(KrollRuntime.java:241)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.TiLaunchActivity.loadActivityScript(TiLaunchActivity.java:128)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.TiLaunchActivity.windowCreated(TiLaunchActivity.java:183)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.TiRootActivity.windowCreated(TiRootActivity.java:172)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.TiBaseActivity.onCreate(TiBaseActivity.java:682)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.TiLaunchActivity.onCreate(TiLaunchActivity.java:169)\r\n[ERROR] : TiFileProxy: \tat org.appcelerator.titanium.TiRootActivity.onCreate(TiRootActivity.java:161)\r\n[ERROR] : TiFileProxy: \tat android.app.Activity.performCreate(Activity.java:6237)\r\n[ERROR] : TiFileProxy: \tat android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)\r\n[ERROR] : TiFileProxy: \tat android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)\r\n[ERROR] : TiFileProxy: \tat android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)\r\n[ERROR] : TiFileProxy: \tat android.app.ActivityThread.-wrap11(ActivityThread.java)\r\n[ERROR] : TiFileProxy: \tat android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)\r\n[ERROR] : TiFileProxy: \tat android.os.Handler.dispatchMessage(Handler.java:102)\r\n[ERROR] : TiFileProxy: \tat android.os.Looper.loop(Looper.java:148)\r\n[ERROR] : TiFileProxy: \tat android.app.ActivityThread.main(ActivityThread.java:5417)\r\n[ERROR] : TiFileProxy: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] : TiFileProxy: \tat com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)\r\n[ERROR] : TiFileProxy: \tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)\r\n[ERROR] : TiFileProxy: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)\r\n[ERROR] : TiFileProxy: \tat libcore.io.Posix.open(Native Method)\r\n[ERROR] : TiFileProxy: \tat libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)\r\n[ERROR] : TiFileProxy: \tat libcore.io.IoBridge.open(IoBridge.java:438)\r\n[ERROR] : TiFileProxy: \t... 26 more\r\n{code}\r\n", "attachment": [], "flagged": false, "summary": "TiFileProxy: java.io.FileNotFoundException: /storage/emulated/0/com.example.sample/sample.txt: open failed: EACCES (Permission denied)", "creator": { "name": "jignesh.igp", "key": "jignesh.igp", "displayName": "Jignesh Kasundra", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "jignesh.igp", "key": "jignesh.igp", "displayName": "Jignesh Kasundra", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "OSX, Titanium SDK 6.0.4 , Android Platform 6.0 , Android API 23\r\n", "comment": { "comments": [ { "id": "419604", "author": { "name": "jignesh.igp", "key": "jignesh.igp", "displayName": "Jignesh Kasundra", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Sample Code\r\n==============\r\n\r\napp.js\r\n------------\r\n\r\n{code:java}\r\nvar cameraPermission = \"android.permission.CAMERA\";\r\nvar storagePermission = \"android.permission.READ_EXTERNAL_STORAGE\";\r\nvar hasCameraPermission = Ti.Android.hasPermission(cameraPermission);\r\nvar hasStoragePermission = Ti.Android.hasPermission(storagePermission);\r\nvar permissionsToRequest = [];\r\n\r\n\r\n\r\nvar win = Ti.UI.createWindow({\r\n title: 'mywin',\r\n backgroundColor: '#fff',\r\n width : Ti.UI.FILL,\r\n height : Ti.UI.FILL\r\n});\r\n\r\nwin.open();\r\n\r\n\r\nif (!hasCameraPermission) {\r\n permissionsToRequest.push(cameraPermission);\r\n}\r\nif (!hasStoragePermission) {\r\n permissionsToRequest.push(storagePermission);\r\n}\r\nif (permissionsToRequest.length > 0) {\r\n Ti.Android.requestPermissions(permissionsToRequest, function(e) {\r\n if (e.success) {\r\n Ti.API.info(\"SUCCESS\");\r\n } else {\r\n Ti.API.info(\"ERROR: \" + e.error);\r\n }\r\n });\r\n}\r\n\r\n\r\n\t\tvar localPath = Ti.Filesystem.getFile(Ti.Filesystem.externalStorageDirectory).nativePath;\r\n\t\t\t\t\t\t\t\t\t\r\n\t\t\t\t\tvar sampletxtvar = Ti.Filesystem.getFile(localPath, \"sample.txt\");\r\n\t\t\t\t\tsampletxtvar.write(\"this is my sample text\");\r\n\r\n\t\t\t\t\tvar content = \"\";\t\t\r\n\r\n\t\t\t\t\tif (sampletxtvar.exists()) {\r\n\t\t\t\t\t\t\t\tcontent = nomediatxt.read().text;\r\n\t\t\t\t\t\t\t\talert(\"Content is ::: \" +content);\r\n\t\t\t\t\t}\r\n{code}\r\n\r\n\r\n===============\r\n\r\ntiapp.xml\r\n-------------\r\n\r\n\r\n{code:java}\r\n\r\n \r\n \r\n \r\n \r\n \r\n{code}\r\n", "updateAuthor": { "name": "jignesh.igp", "key": "jignesh.igp", "displayName": "Jignesh Kasundra", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2017-05-12T06:54:57.000+0000", "updated": "2017-05-12T06:54:57.000+0000" }, { "id": "419623", "author": { "name": "sdarda", "key": "sdarda", "displayName": "Sharif AbuDarda", "active": false, "timeZone": "Asia/Dhaka" }, "body": "Hello, My understanding is you are trying to access the external storage and write there without allowing the permission during runtime. So, what you need to do is, you need to put your code of writing inside a button eventlistner and on window open you allow the access and click on the button to write and so forth. Now, your code works on second run on my device cause i allowed the permission on first run and the app remembers it. Thanks.", "updateAuthor": { "name": "sdarda", "key": "sdarda", "displayName": "Sharif AbuDarda", "active": false, "timeZone": "Asia/Dhaka" }, "created": "2017-05-12T19:27:22.000+0000", "updated": "2017-05-12T19:27:22.000+0000" }, { "id": "419644", "author": { "name": "jignesh.igp", "key": "jignesh.igp", "displayName": "Jignesh Kasundra", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hi , thanks! it's working on second run, I am able to read and write the file in external storage. but *how can I make it work on first run*. because even after I had read/write file on button click eventListener still not working first run and it throws error while click on button >>>TiFileProxy: java.io.FileNotFoundException: /storage/emulated/0/com.example.sample/sample.txt: open failed: EACCES (Permission denied)\r\n\r\nNOTE : I have also added requestPermission under window.open event", "updateAuthor": { "name": "jignesh.igp", "key": "jignesh.igp", "displayName": "Jignesh Kasundra", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2017-05-13T03:39:43.000+0000", "updated": "2017-05-13T05:03:47.000+0000" }, { "id": "419681", "author": { "name": "sdarda", "key": "sdarda", "displayName": "Sharif AbuDarda", "active": false, "timeZone": "Asia/Dhaka" }, "body": "Hello, Take a look at my code below. \r\n{code}\r\nvar cameraPermission = \"android.permission.CAMERA\";\r\n\r\nvar storagePermission = \"android.permission.READ_EXTERNAL_STORAGE\";\r\n\r\nvar hasCameraPermission = Ti.Android.hasPermission(cameraPermission);\r\n\r\nvar hasStoragePermission = Ti.Android.hasPermission(storagePermission);\r\n\r\nvar permissionsToRequest = [];\r\n\r\nvar win = Ti.UI.createWindow({\r\n\r\n title : 'mywin',\r\n\r\n backgroundColor : '#fff',\r\n\r\n width : Ti.UI.FILL,\r\n\r\n height : Ti.UI.FILL\r\n\r\n});\r\n\r\nwin.open();\r\n\r\nif (!hasCameraPermission) {\r\n\r\n permissionsToRequest.push(cameraPermission);\r\n\r\n}\r\n\r\nif (!hasStoragePermission) {\r\n\r\n permissionsToRequest.push(storagePermission);\r\n\r\n}\r\n\r\nif (permissionsToRequest.length > 0) {\r\n\r\n Ti.Android.requestPermissions(permissionsToRequest, function(e) {\r\n\r\n if (e.success) {\r\n\r\n Ti.API.info(\"SUCCESS\");\r\n\r\n } else {\r\n\r\n Ti.API.info(\"ERROR: \" + e.error);\r\n\r\n }\r\n\r\n });\r\n\r\n}\r\n\r\nvar btn1 = Ti.UI.createButton({\r\n\r\n title : 'Write',\r\n top : 60\r\n\r\n});\r\nwin.add(btn1);\r\n\r\nbtn1.addEventListener('click', function() {\r\n var localPath = Ti.Filesystem.getFile(Ti.Filesystem.externalStorageDirectory).nativePath;\r\n\r\n var sampletxtvar = Ti.Filesystem.getFile(localPath, \"sample.txt\");\r\n\r\n sampletxtvar.write(\"this is my sample text\");\r\n\r\n alert(sampletxtvar.read().text);\r\n\r\n});\r\n{code} this works on first run. Thanks.", "updateAuthor": { "name": "sdarda", "key": "sdarda", "displayName": "Sharif AbuDarda", "active": false, "timeZone": "Asia/Dhaka" }, "created": "2017-05-15T14:45:00.000+0000", "updated": "2017-05-15T14:45:00.000+0000" }, { "id": "419876", "author": { "name": "jignesh.igp", "key": "jignesh.igp", "displayName": "Jignesh Kasundra", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hello,\r\n\r\nAfter using above code the issue still exist. first time app launch while click on write button , it throws same error. second app run it works fine.\r\n\r\nplease can you check this.", "updateAuthor": { "name": "jignesh.igp", "key": "jignesh.igp", "displayName": "Jignesh Kasundra", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2017-05-17T11:33:00.000+0000", "updated": "2017-05-17T11:33:00.000+0000" } ], "maxResults": 5, "total": 5, "startAt": 0 } } }