Nov 12 | 8:25 AM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Kai H. | has entered the room |
Kai H. | has left the room |
Kai H. | has entered the room |
Kai H. |
Hello
|
Mark M. |
was it something I said? :-)
|
Mark M. |
(referring to your joining, leaving, then joining again)
|
Kai H. |
"It's not you, it's me"
|
Mark M. |
anyway, hi! how can I help you today?
|
Nov 12 | 8:30 AM |
Kai H. |
Hello
|
Kai H. |
A Garfield quote comes to mind: "Was it something I said or several things I've done?" ;)
|
Kai H. |
I do have one of those probably not easy to answer questions.
|
Mark M. |
so long as you don't mind answers that may involve frantic hand-waving... go right ahead!
|
Kai H. |
I have a file system wrapper in a library. And I use it in my app. Part of the functionality is to put a file in external storage to share it with Mickysoft apps.
|
Kumar V. | has entered the room |
Kumar V. |
Hello Mark
|
Mark M. |
yup, we've discussed that over a couple of chats
|
Mark M. |
(BTW, hello Kumar! I will be with you shortly!)
|
Kai H. |
Now with Android 11, the best way to get a directory to share said file in is to ask the user to pick one via SAF.
|
Kumar V. |
Sure
|
Kai H. |
For that I want to create a Dialog, explain the situation and then invoke the file picker.
|
Kai H. |
Now, between asking the user for a directory and later using it, the directory could be deleted.
|
Kai H. |
And I wonder how to deal with that, architecturally.
|
Kai H. |
Should the file system wrapper bubble up an exception when the directory is not found?
|
Nov 12 | 8:35 AM |
Mark M. |
presumably
|
Kai H. |
I thought about having the library invoke the Dialog in question, but the app has its own style that wouldn't be applied.
|
Kai H. |
How would you do it?
|
Mark M. |
when I think of "file system wrapper", I don't think of it has dealing with UI concerns
|
Mark M. |
er, "as dealing with UI concerns"
|
Mark M. |
whether it is an exception or some other type of response, the file system wrapper should be letting its caller know that this problem exists
|
Mark M. |
and the caller would handle getting a new document tree from the user via ACTION_OPEN_DOCUMENT_TREE
|
Kai H. |
Which means that wherever I use any calls of the file system wrapper that could run into that problem, I need code to fatch it.
|
Kai H. |
fetch it.
|
Mark M. |
you need code that will arrange to deal with the problem
|
Kai H. |
The caller would handle it? Huh. I would have put that into the file system wrapper as well. Felt like a responsibility of it.
|
Mark M. |
from an Android standpoint, the fact that we're using startActivityForResult() or the ActivityResult APIs to me strongly suggests that it's gotta be an activity/fragment concern
|
Kai H. |
Good point.
|
Mark M. |
and, if you intended for this wrapper to be used by lots of people, you probably shouldn't assume how everyone wants to handle the problem
|
Kai H. |
It's just used by me so far and my two apps.
|
Mark M. |
I thought that it might be something like that
|
Kai H. |
But I'd like a clean approach nonetheless
|
Mark M. |
in which case, you have more flexibility to do what you want
|
Nov 12 | 8:40 AM |
Mark M. |
the problem starts to get worse as you need to use this wrapper in places where you *can't* ask for a new location, such as from a WorkManager Worker
|
Kai H. |
That would probably not work.
|
Kai H. |
But as of now I think it's limited to a very narrow use case, mostly the Mickysoft App case.
|
Mark M. |
saying you have an adjunct to the wrapper that provides a reusable pattern for dealing with the problem is reasonable, but personally I'd try to keep the wrapper itself clean from UI concerns
|
Mark M. |
let me take a question from Kumar, and I'll be back with you in a bit
|
Mark M. |
Kumar: your turn! how can I help you today?
|
Kai H. |
Sure, thank you.
|
Kumar V. |
Some issue with scoped storage thing in Android 11.
|
Kumar V. |
I am not able to update MediaStore columns like title, album , artist of the song, though I request for uri permission and user grants. When I do ContentResolver.update , noOfRowsUpdate is 1, but no changes are applied.
|
Kumar V. | |
Mark M. |
some of those things I think MediaStore may want to populate itself from the media's metadata
|
Mark M. |
and, there is https://commonsware.com/blog/2020/04/04/scoped-...
|
Kumar V. |
Oh, so not all tag values can be updated ?
|
Nov 12 | 8:45 AM |
Mark M. |
partly, it's a question of whether MediaStore might overwrite what you supply using the media metadata
|
Mark M. |
and, as I outline in that post, there's a screwy workaround that involves the IS_PENDING flag
|
Kumar V. |
Is there any way that I can update those values in MediaStore ?
|
Mark M. |
I outline that in the blog post that I linked to: https://commonsware.com/blog/2020/04/04/scoped-...
|
Mark M. |
though I have not re-tested this on the final Android 11, so there might be issues
|
Kumar V. |
Ok, will read more on this and try
|
Mark M. |
https://gitlab.com/commonsguy/movie-lister/-/tr... is the associated project, and I use this hack to update the TAGS value
|
Mark M. |
(at least, I think it's TAGS -- it might be DESCRIPTION)
|
Mark M. |
but, yeah, I recommend reading through that and seeing if it helps
|
Kumar V. |
Yes, I saw this the code I compared against everything was pretty much same
|
Kumar V. |
is*
|
Kumar V. |
When I request for MediaStore.createWriteRequest , does that mean I am now allowed to edit at the file level as well using java File object ?
|
Kumar V. |
Actually when I did that it failed. Even when I got permission using SAF, it still failed when I tried to edit using File object.
|
Mark M. |
I assume that you are referring to https://stackoverflow.com/q/64804287/115145
|
Nov 12 | 8:50 AM |
Kumar V. |
Yes, I just posted this question sometime back.
|
Mark M. |
an hour ago, according to Stack Overflow :-)
|
Mark M. |
anyway createWriteRequest() is for MediaStore, not files
|
Kumar V. |
Yeah . (Smile )
|
Kai H. |
I think I ran into a similar problem, getting some permission to a directory and then trying to write it via the File() API.
|
Mark M. |
I do not recall any way to get filesystem write access to something that you don't normally have filesystem write access to
|
Kai H. |
And wondering why it didn't work (and thinking it should, now that File() uses MediaStore in the background, apparently).
|
Kumar V. |
Kai H., Did it work ?
|
Kai H. |
No. I had pretty much the same conversation with Mark that you just had ;-)
|
Kai H. |
Just wanted to tell so you know you're not the only one stumbling over that.
|
Kumar V. |
Ok. In this video https://www.youtube.com/watch?v=RjyYCUW-9tY&...) she clearly tells using File object is supported now in Android 11, but I am not able to figure out how do I get the permission to use that file.
|
Mark M. |
if I recall that video, I think she's referring to read access, or write access using MANAGE_EXTERNAL_FILES
|
Mark M. |
(and the latter has Play Store ramifications)
|
Nov 12 | 8:55 AM |
Kumar V. |
Yes but this is something that was there in Android 10 as well MANAGE_EXTERNAL_FILES
|
Kumar V. |
If I am not wrong
|
Mark M. |
Android 10 is covered by android:requestLegacyExternalStorage
|
Mark M. |
add that to the <application>, set to true, and 10 works like 9
|
Mark M. |
11 also supports this, until you reach targetSdkVersion 30, sometime next year
|
Mark M. |
but, even then, *10* should still be honoring it
|
Kai H. |
This is where she talks about it btw: https://youtu.be/RjyYCUW-9tY?t=257
|
Kumar V. |
Yes this is if you don't want scoped storage, but if someone wishes to use scoped storage in Android 10, they had MANAGE_EXTERNAL_FILES this option as well.
|
Mark M. |
from that video: "you do not get any additional access to files than you would have gotten using MediaStore APIs"
|
Mark M. |
so, I can certainly see an argument about why MediaStore.createWriteRequest() should affect the filesystem APIs... but, at the same time, I am not surprised if that does not work
|
Nov 12 | 9:00 AM |
Kumar V. |
and neither does SAF help to get the access to file using file path.
|
Mark M. |
correct
|
Mark M. |
as we discussed last time, the libraries that you are using that need filesystem paths really need to be augmented to be more flexible
|
Mark M. |
now, in principle, there is nothing stopping you from copying the content to some file that you control (e.g., getCacheDir()), using the library to modify that copy, then replace the original
|
Kumar V. |
Yes and in the video she gives example of ffmpeg library, I have not used this personally, but have seen the code which again wants the input in the form of File
|
Mark M. |
that's for reading
|
Mark M. |
reading works fine -- your problem is writing, correct?
|
Kumar V. |
Yes, writing to the file is the problem
|
Kumar V. |
ffmpeg is more commonly used to edit as well right,
|
Mark M. |
my guess is that she's "finessing the problem" -- FFMPEG should work fine for reading from external storage and writing to getCacheDir(), for example
|
Nov 12 | 9:05 AM |
Mark M. |
let me take another question from Kai, and I'll swing back to you in a little while
|
Mark M. |
Kai: back to you! do you have another question?
|
Kumar V. |
Ya sure, I don't have anything right now.
|
Kai H. |
Do you also perceive the current storage situation as... challenging?
|
Mark M. |
ooooooo... "challenging" is a nice, non-offensive term!
|
Kai H. |
Yes. I tried to go around terms like "cluster fuck" and such
|
Mark M. |
to quote Steve Rogers: "Language!"
|
Mark M. |
while 11 improves the situation from 10, I actually found the 10 approach to be easier to explain
|
Mark M. |
but, as I mentioned in some recent chat, trying to restrict things that had been open is always a problem
|
Mark M. |
and it's one that we have run into from time to time in recent years with Android (see "The War on Background Processing")
|
Mark M. |
and the biggest problem, in many respects, are for apps like Kumar's, where functionality that was perfectly doable is now very much a problem
|
Mark M. |
and we're stuck with trying to find workarounds (that may or may not hold up) or trying to explain to users why things are different now
|
Kai H. |
And it's not only that it's a problem, it's so hard to understand and make sense of all the information (and some lack thereof).
|
Mark M. |
yes, Google's documentation (or lack thereof) has not helped
|
Nov 12 | 9:10 AM |
Kai H. |
I've been working on "getting the app ready" for longer already that I am willing to admit. And I still have quite some time ahead of me.
|
Kai H. |
But just knowing that I don't have to question my sanity or skill as a developer when dealing with it helps ;-)
|
Mark M. |
it's a mess
|
Mark M. |
and for new construction, you can at least steer your feature set around the mess
|
Mark M. |
just as you can try to avoid the need for background processing and so forth
|
Kumar V. |
and for new construction, you can at least steer your feature set around the mess --> even I have thought as much
|
Kai H. |
New construction. Now that would be something...
|
Nov 12 | 9:15 AM |
Mark M. |
at this point in the chat, if either of you have questions, go right ahead!
|
Kai H. |
Do you have a link to "The war on background processing"? Google doesn't give my anything.
|
Mark M. |
that was my tagline for Doze mode, app standby, and all those related changes
|
Kai H. |
Ah, I thought it was a article line like "the death of external storage"
|
Mark M. |
I used it in https://commonsware.com/blog/2017/04/11/android... and https://commonsware.com/blog/2017/05/24/android... and some Stack Overflow answers
|
Kai H. |
Ok
|
Kumar V. |
Ok guys, that's it from me, I will leave. Thanks Mark and Kai. See you in next chat. Good day to both of you. :)
|
Kai H. |
Same.
|
Mark M. |
see you later!
|
Kumar V. | has left the room |
Nov 12 | 9:20 AM |
Nov 12 | 9:30 AM |
Kai H. |
I think that concludes todays chat :P
|
Mark M. |
yup
|
Mark M. |
next one is Saturday at 4pm US Eastern
|
Mark M. |
have a pleasant day!
|
Kai H. |
Have a good time and thanks for your answers.
|
Mark M. |
you're welcome!
|
Kai H. | has left the room |
Mark M. | turned off guest access |