{ "id": "173886", "key": "TIMOB-27247", "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": "11", "description": "Is not a bug in our product", "name": "Not Our Bug" }, "resolutiondate": "2019-07-17T07:49:41.000+0000", "created": "2019-07-16T18:09:04.000+0000", "priority": { "name": "None", "id": "6" }, "labels": [], "versions": [], "issuelinks": [], "assignee": null, "updated": "2019-07-17T20:32:31.000+0000", "status": { "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", "name": "Resolved", "id": "5", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "On Android 7, different to Android 9 for example, content URL's are returned like the following:\r\n{code}\r\ncontent://com.google.android.apps.docs.fetcher.FileProvider/vRHOEWuB7jY0n9y_26GoQn-5crFYq2Ljl6VgSX23hUA%3D?_display_name=pdf.pdf&mime_type=application%2Fpdf&_size=433994\r\n{code}\r\nNote {{_display_name}} for example, which is the raw column of the MediaStore class.", "attachment": [], "flagged": false, "summary": "Android 7: Content URL's are returned as MediaStore columns", "creator": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "subtasks": [], "reporter": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "environment": null, "closedSprints": [ { "id": 1153, "state": "closed", "name": "2019 Sprint 15", "startDate": "2019-07-15T18:30:38.331Z", "endDate": "2019-07-28T18:30:00.000Z", "completeDate": "2019-07-29T15:34:51.860Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "449854", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "So, what's the problem?\r\n\r\nYes, content URLs will be different between different apps and different app versions. This is normal. There is no consistency. An app's ContentProvider can set up the content URL any way they want.\r\n\r\nNote that Titanium already correctly reads the display name from a content URL. You can see us doing it in the code below. The correct way of doing it is querying it via a {{ContentResolver}} like how we are doing it. You never parse the content URL since there is no standard format you can rely on.\r\nhttps://github.com/appcelerator/titanium_mobile/blob/master/android/titanium/src/java/org/appcelerator/titanium/io/TitaniumBlob.java#L57\r\n\r\nYou can get the \"display name\" from a content URL in Titanium as follows...\r\n{code:javascript}\r\nvar file = Ti.Filesystem.getFile(yourContentUrl);\r\nvar displayName = file.name;\r\n{code}\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-07-17T01:35:32.000+0000", "updated": "2019-07-17T01:35:32.000+0000" }, { "id": "449858", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Thanks Josh, I think we just handled the URL too manually until now. There is one remaining issue that is about {{extension()}} being null on those, but I think you filed a ticket for that already. I will close this again!", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2019-07-17T07:49:22.000+0000", "updated": "2019-07-17T07:49:22.000+0000" }, { "id": "449877", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "bq. I think we just handled the URL too manually until now.\r\n\r\nI'm not sure what else we can do about this. We don't have direct file access (and it might not exist in the filesystem at all). Natively, we have to go through a {{ContentResolver}}/{{ContentProvider}} interface to get the file's bytes and do SQL-like queries to get info about it. We wrap the content URL via a Titanium {{File}} and {{Blob}} to help make it as cross-platform as possible,\r\n\r\nFYI: A content URL may not always provide a file extension. Especially if it references an embedded \"res\" file within the APK (they never have extensions). However, we can fetch its mime-type via a {{ContentResolver}} and we support doing this. In Titanium, the only way to acquire a content URL's mime-type is doing a {{File.read()}} to get the blob and then read the blob's \"mimetype\" property. So, be warned that when we do implement the {{extension()}} method, it can still return null or empty string if URL has no extension. The \"mimetype\" string is the way to go in the end.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-07-17T18:15:14.000+0000", "updated": "2019-07-17T20:32:31.000+0000" }, { "id": "449882", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "Thanks for the insight! I just meant that we used to do string operations on the URL which isn't required anymore, since the Ti.File object works pretty good.", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2019-07-17T19:07:54.000+0000", "updated": "2019-07-17T19:07:54.000+0000" } ], "maxResults": 4, "total": 4, "startAt": 0 } } }