Mapbox-gl-native: [android] Using asset:// URL with path outside of APK

Created on 7 Sep 2016  路  9Comments  路  Source: mapbox/mapbox-gl-native

Platform: Android
Mapbox SDK version: react-native-mapbox-gl 5.0.0 which uses mapbox-android-sdk 4.1.1

Issue

The only way to access local files on Android via asset:// is if it's bundled with the APK. Since you can't modify the APK from the app, Android currently doesn't support assets that have been downloaded after the app is installed.

On iOS, I've been able to specify a path where files were downloaded onto the user's device, so no issues there.

My Use Case

In the app I'm developing, a user has to log in. Afterwards, the app will use their account information to generate the user's style and tilejson files along with downloading a set of vector tiles.

On iOS, I can point the asset:// URL to these generated and downloaded files, and everything works great. But on Android, there's not a way to shove these files into the signed APK programatically.

Am I missing something obvious to make this use case work on Android? Or am I hampered by asset:// only allowing access to pre-bundled APK assets?

Android

Most helpful comment

Right. The asset:// URL that you can currently set via setStyleUrl() is backed by an asset_file_source where assets are Android assets, which are limited to files in the app package.

In order to support arbitrary files that the app has access to, but are outside the app package, I suggest we add a third type of source, say a local_file_source set by a file:// path, that handles that specific case. Another option would be to handle this with a check inside asset_file_source but it'd feel confusing that we could access non-asset files (the way Android defines them) using the asset:// protocol.

How does this sound?

All 9 comments

@1ec5 It's been a week, so I'm just checking in. Does this issue make sense? Should I clarify? Or Is everything working as intended and I need to find another way to make my use case work?

Or is everyone too busy right now to look into my little issue here?

Hi @bigsassy, unfortunately, I鈥檓 not very familiar with the Android side, since I usually work on the iOS and macOS SDKs. The cross-platform components of Mapbox GL allow you to specify an absolute path to an asset. For example, a style URL of asset:///dev/null would resolve to /dev/null. That should work in the Android SDK unless it does any validation on the URL string that isn鈥檛 aware of this format. Does that work for you?

@1ec5 Thanks for answering. No, that doesn't seem to work for me (but I would LOVE to be wrong about this). From what I've read, you are confined to anything bundled with the APK when utilizing asset:// on Android.

@ljbade Since you appear to be one of the main people involved with this part of the codebase, do you have any insight here? I base this on your activity in issue https://github.com/mapbox/mapbox-gl-native/issues/579.

@1ec5: In android the asset:// urls are handled differently. The asset:// urls load resources basically from the android zip resource file which is bundled with an application. This zip is opened and the file is read from there, and it is impossible for an application to modify it.

@bigsassy: I believe you are correct, there is no nice way to load resources, like styles, which have been downloaded.

In order to get the same functionality as iOS has, I've actually been forced to implement a web server locally, and loading assets from http://localhost:12345/myfile type urls. Yes this is ugly, but it is currently the only way to do on android what is really easy in iOS.

@cammace @zugaldia, is there any other way to refer to a local file that isn鈥檛 part of the .apk? For what it鈥檚 worth, the iOS and macOS SDKs had the same limitation until #6026. If it comes down to what AssetFileSource::Impl does with the URL, then would it be straightforward to detect and support absolute paths there?

For comparison, the iOS and macOS SDKs use the default, cross-platform implementation of mbgl::AssetFileSource. Perhaps the Android-specific implementation can make use of this logic to support non-APK files in addition to the usual code path.

Right. The asset:// URL that you can currently set via setStyleUrl() is backed by an asset_file_source where assets are Android assets, which are limited to files in the app package.

In order to support arbitrary files that the app has access to, but are outside the app package, I suggest we add a third type of source, say a local_file_source set by a file:// path, that handles that specific case. Another option would be to handle this with a check inside asset_file_source but it'd feel confusing that we could access non-asset files (the way Android defines them) using the asset:// protocol.

How does this sound?

I think it would be good for all the platforms to use the file: scheme for absolute paths and asset: only for things in the asset directory. The way asset: is overloaded in the default implementation feels like a hack to me. (If not for the special requirements that the Android SDK has for pulling resources out of the APK, I鈥檇 even argue that we should remove the asset: scheme in favor of absolute paths via file:.)

/cc @jfirebaugh

Was this page helpful?
0 / 5 - 0 ratings