Android Question Content Chooser doesnt give usable values

JeffT

Member
Licensed User
Browsing for a specifc file which I know exists and is usable

File Dialog gives me
Dir = /storage/emulated/0/download
and
filename = Myfile.OXS


Content Chooser gives me
Dir = ContentDir
Filename = content//com.android.externalstorage.documents/document/primary%3ADownload%2FMyfile.OXS


If I check for existence with
if File.exists(Dir,filename)

or try to open the file in any way using the values returned by Content Chooser, everything fails.

eg the exact same file 'exists' using the File Dialog values, but not if I use the values returned by Content Chooser




The forum is full of people asking 'how do I get the path to a file returned by Content Chooser', and the answer is nearly always 'dont try' and 'it just works - why do you need a file path?'
But since it doesn't, how do you use the values like the ones coming from Content Chooser to actually work with a file?

B4X:
if File.exists(Dir,filename)
 

drgottjr

Expert
Licensed User
Longtime User
it's a resource. stop thinking of it as a "file" (which, in the end, it may well be). you obtain the resource with input stream. you are then free to save the resource as a file, if you like. files maintained by other apps are not accessible by you. if they choose to share them with your app, you use the resource sharing mechanism. what the other app's name for a file is is irrelevant for the purpose of sharing. it shares it as a resource with your app. you obtain it as a resource. you can work with it, pass it along or save it. if you save it, you can use whatever name you like, including the name used by the app which originally made it available to you. the file system is something very particular; not everything is a member of it just because somebody thinks of it as a "file". different os's have their own way of maintaining a file system. systems which enforce permissions have their own ways of dealing with things. android's sharing mechanism is one instance. we need to accept its way of dealing with sharing, not the other way around.
 
Upvote 0

JeffT

Member
Licensed User
Im really struggling with that concept.
It IS a file.. I put it there myself.
There is no other 'app'


>>you obtain it as a resource.<<
It sounds like you are saying I need to open the file I placed in the filing system <somehow> then save it somewhere else, then open it. <somehow>
I don't get it.



The file contains XML
How do I 'use it as a resource' using the data returned by the file chooser if Dir and Filename suggest it doesnt exist?


The help on ContentChooser (https://www.b4x.com/android/help/phone.html#contentchooser) says :
'
Note that these values may point to resources other than regular files. Still you can pass them to methods that expect Dir and FileName.
Only content types that can be opened with an InputStream are supported.'


But when I pass them to functions that expect Dir and Filename, they don't work.
And I'm pretty sure that XML (a text file) should work for InputStream



Is the problem 'If the user has installed a file manager then the ContentChooser can be used to select general files.'
How would I know if a File Manager is installed ?
(My tablet does have an app called File Manager, and I used it to place the file on the tablet in the first place.)
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
sorry, you need permission to read from the downloads folder. getsafedirdefaultexternal("Download"). you don't need the other stuff. that all has to do with sharing between apps. i saw "contentchooser", and that set me off.
add a runtime permission to your app: dim rp as runtimepermission, then dim path as string = rp.getsafedirdefaultexternal("Download"), then you should be able to open it. (maybe it's "Downloads". you can check). i'm going to try it myself now. you're not supposed to be saving stuff outside of your own area (File.DirInternal), so i don't have a working sample to post. but i will in a few minutes.
 
Last edited:
Upvote 0

JeffT

Member
Licensed User
Using File Manager, I copied it from an external USB card to 'Downloads'

File Dialog finds it and allows me to use it with no trouble.
 
Upvote 0

JeffT

Member
Licensed User
>>you're not supposed to be saving stuff outside of your own area (File.DirInternal)<<

I kinda get that for file creation.
It does raise the question of content chooser looking in my own file.dirinternal

When it's time for the user to get this file (or an image representation of it, or a PDF render) out into the wide world, I guess I need to look at file sharing and intents(?)
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
you don't need content chooser for file.dirinternal. this post talks about the runtime permission for accessing stuff outside your app's jail. it's pretty long, unfortunately, but about half way down you see the reference to getsafedefaultdirexternal() call that i mentioned earlier. your app is in a jail; there are ways to access stuff that is outside your jail, but android wants you to play nice in your area. and it has ways of enforcing that behavior
 
Upvote 0

drgottjr

Expert
Licensed User
Longtime User
just to recap, you're not supposed to write to folders outside your app's jail (file.dirinternal). if you insist on using the downloads or pictures folders, you need runtime permissions. but it looks like even that may soon no longer be possible.
without know what your app does, it's hard to speculate on what types of resource sharing you might need, but you could set your app up to receive resources from other apps or your app might share its resources with other apps. the mechanisms you've mentioned early on would come into play. an example might be a user takes a picture, and your app puts funny noses on pictures of people's face and then emails them to the user's friend. when you set your app up to put funny noses on images, it's listed as an app that can receive images from another app. the user chooses the "share" icon, and your app appears as a possible recipient of the image. she chooses your app. your app receives the image as a resource. you convert it to a bitmap and do your funny nose. you save your work and then offer to share it with an app that does email. the email app receives your resource and does its job. in theory, you could write an app that takes pictures, puts a funny nose on the image and then emails it. but 2 out of those 3 tasks have already been written, and - no offense - probably written better than you could write them. the whole system is set up to allow you to move resources from one app to another, with each app doing what it does best.
 
Upvote 0

JeffT

Member
Licensed User
Thanks for that overview.
It is certainly a different mindset.

My app creates a proprietary document (XML or text based) which my app can amend.
No other app would be interested in or be able to use it, (except possibly to email a copy 'outwards')
I want it to be able to use documents created on a desktop version of the 'sister' app.

So my primary concerns are:
How to get a file created on a laptop or desktop to a place on the tablet where this app can find the file and use it.
(today, I did it by putting the file into downloads)

and conversely , how to create a file using the tablet that someone can find and move, (using a connected laptop or detachable SD card), so that the sister app can share 'work done on the move'

Is this an unusual need?
Dont people do this with spreadsheets or similar?
 
Upvote 0
Top