Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27247] Android 7: Content URL's are returned as MediaStore columns

GitHub Issuen/a
TypeBug
PriorityNone
StatusResolved
ResolutionNot Our Bug
Resolution Date2019-07-17T07:49:41.000+0000
Affected Version/sn/a
Fix Version/sn/a
ComponentsAndroid
Labelsn/a
ReporterHans Knöchel
AssigneeUnknown
Created2019-07-16T18:09:04.000+0000
Updated2019-07-17T20:32:31.000+0000

Description

On Android 7, different to Android 9 for example, content URL's are returned like the following:
content://com.google.android.apps.docs.fetcher.FileProvider/vRHOEWuB7jY0n9y_26GoQn-5crFYq2Ljl6VgSX23hUA%3D?_display_name=pdf.pdf&mime_type=application%2Fpdf&_size=433994
Note _display_name for example, which is the raw column of the MediaStore class.

Comments

  1. Joshua Quick 2019-07-17

    So, what's the problem? Yes, 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. Note 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. https://github.com/appcelerator/titanium_mobile/blob/master/android/titanium/src/java/org/appcelerator/titanium/io/TitaniumBlob.java#L57 You can get the "display name" from a content URL in Titanium as follows...
       var file = Ti.Filesystem.getFile(yourContentUrl);
       var displayName = file.name;
       
  2. Hans Knöchel 2019-07-17

    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!
  3. Joshua Quick 2019-07-17

    bq. I think we just handled the URL too manually until now. I'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, FYI: 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.
  4. Hans Knöchel 2019-07-17

    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.

JSON Source