Mar 31 | 7:25 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Mar 31 | 7:30 PM |
Jan S. | has entered the room |
Jan S. |
Hi.
|
Mark M. |
hello, Jan!
|
Mark M. |
how can I help you today?
|
Mar 31 | 7:35 PM |
Jan S. |
I am using an observer and it is working okay. I followed one of your examples and observe on the viewstate. The viewstate has a hashmap that doesn't change during the user actions. But the key used for the hashmap changes based on user actions. So I'm wondering if I need another observer to watch for changes to the key? I update the textView when that change happens -- and that's on a button click.
|
Mark M. |
so, they click a button, and you switch keys?
|
Jan S. |
Exactly.
|
Mark M. |
then, it sounds like your key is part of the viewstate
|
Mark M. |
on a button click, the UI can tell the viewmodel "yo! the user clicked the button!"
|
Mark M. |
the viewmodel emits a fresh copy of the viewstate, with the hashmap and the new key
|
Mark M. |
the UI layer then renders the UI based on that
|
Mark M. |
in *Exploring Android*, I take that approach for a filter menu, to allow the user to view all to-do items, completed ones, or incomplete ones
|
Mar 31 | 7:40 PM |
Mark M. |
(though in my case there is no hashmap -- I do fresh Room queries)
|
sudokai | has entered the room |
Jan S. |
I am not changing the hashmap like you do in the ToDo filter (using room queries). I'm just changing what I pull out of the hashmap when its key changes.
|
Mark M. |
(hello, sudokai -- I will be with you shortly!)
|
Jan S. |
So should I put the key in the viewstate along with the hashmap? It's the viewstate I'm observing.
|
Mark M. |
Jan: true, but that does not really change my recommendatino
|
Mark M. |
er, recommendation
|
Mark M. |
yes
|
Mark M. |
if your viewstate is using data classes, just copy() the existing state and replace the key in the copy
|
Mark M. |
so, something like oldstate.copy(key = newkeyBasedOnButtonClick)
|
Mark M. |
(and if your app is Java, my sincere apologies!)
|
Jan S. |
Okay. I'll make those changes.
|
Mark M. |
let me take a question from sudokai, and I'll be back with you in a bit
|
Mark M. |
sudokai: your turn! do you have a question?
|
Mar 31 | 7:45 PM |
Mark M. |
sudokai: if you have a question, let me know, and I'll turn back to you
|
sudokai |
Hi
|
Mark M. |
hi!
|
sudokai |
So I was looking into scoped storage and when does a RecoverableSecurityException get thrown
|
Mark M. |
so was I! https://commonsware.com/blog/2020/03/03/scoped-... :-)
|
sudokai |
Okay thanks I'll read it first!
|
Mark M. |
ah, I thought perhaps you had run into that post already
|
Mark M. |
yeah, it's probably worth reading, and if that does not fit your needs/expectations, I can try to help further
|
sudokai |
Well, basically everything is so complicated in Android Q....
|
Mark M. |
yeah, well, if it makes you feel better, Android R is (generally) not dramatically worse
|
sudokai |
I'm updating an app that still uses file paths to uris
|
Mark M. |
that's gonna hurt
|
Mar 31 | 7:50 PM |
sudokai |
Well, I'm gonna read that and come back if I have more questions
|
Mark M. |
OK, sounds good!
|
Mark M. |
in the meantime...
|
Mark M. |
Jan: back to you! do you have another question?
|
Jan S. |
View paste
|
Mark M. |
generally, a network unlocked device can be used without a SIM card, just via WiFi
|
Mark M. |
and, without a network, there is no network activation
|
Mark M. |
my books are read the world over, so any purchasing recommendations that I make would be useless for lots of readers
|
Mark M. |
personally, I tend to buy used devices off of eBay for older ones, and Amazon for newer ones
|
Jan S. |
Well if you put the Coder's TOC as its own booklet - that'd be helpful. I have to scroll a lot just trying to find all the topics. lol
|
Mark M. |
you can always search, either the PDF or online at wares.commonsware.com
|
Mark M. |
but, yeah, that book got kinda big
|
Mar 31 | 7:55 PM |
sudokai |
Wow, your "Scoped Storage Stories" series is fantastic. I'll definitely read the whole series.
|
Mark M. |
unfortunately, I have to keep writing more posts...
|
Mark M. |
(and thanks for the kind words!)
|
sudokai |
As I understand, I need not worry about RecoverableSecurityExceptions if my app never writes to a file created by another app?
|
sudokai |
I'm using the MediaStore
|
Mark M. |
correct -- if you are only updating your own content, you should be fine to do that
|
Mark M. |
now, eventually (Android S?), they're probably going to need to add some sort of "transfer of ownership" feature
|
Mark M. |
assuming that the permission to modify the content eventually times out
|
Mark M. |
I haven't tried doing any long-term tests to see -- I know it lasts longer than a process, but that's it
|
sudokai |
Well, what I do is to copy the file and insert it again into the MediaStore before modifying it
|
Mar 31 | 8:00 PM |
sudokai |
Then it's my file
|
Mark M. |
assuming the user is OK with that approach, that should be fine
|
Mark M. |
and, this will only work with real media -- for the MediaStore.Downloads collection, you cannot read other apps' stuff
|
sudokai |
Okay
|
sudokai |
I'm working with images. I saw there's an additional restriction you didn't mention in your Elements of Android Q book.
|
sudokai |
It's that you need the ACCESS_MEDIA_LOCATION permission to see the location of a photo via its EXIF
|
Mark M. |
I thought I covered that
|
Mark M. | |
sudokai |
Mmmm, my bad. It's in the following chapter I see
|
Mark M. |
I probably should have put a forward-reference to it in the chapter on MediaStore
|
Mark M. |
(BTW, Jan, if you have another question, feel free to chime in!)
|
sudokai |
Yes Jan, go ahead :)
|
Mar 31 | 8:05 PM |
Jan S. |
I'm considering enabling a long click on my list of items in RecyclerView. If you wanted to display a short description, how would you do it? I'm considering popupwindow, snackbar, or toast.
|
Mark M. |
actually, I try to minimize the use of that sort of popup, so I'd aim to display the information in the main UI somewhere
|
Mark M. |
but, of those three, I would go with a Snackbar, if you are using the Material Components for Android
|
Mark M. |
(or want to go with a third-party Snackbar implementation)
|
Jan S. |
Thanks. That's how I was leaning - if I decide to do it.
|
Jan S. |
That's all for me. Have a good night, everyone.
|
Mark M. |
you too!
|
sudokai |
Goodnight see you around Jan!
|
Mar 31 | 8:10 PM |
sudokai |
Mark Murphy: What's the difference between getApplicationContext().getContentResolver() vs getContentResolver()?
|
Mark M. |
the first one takes longer to type
|
Mark M. |
otherwise, there shouldn't be any difference
|
Mark M. |
unless somebody is overriding getContentResolver() in an unexpected place
|
Mark M. |
for UI concerns, your choice of Context matters (use the Activity)
|
sudokai |
Okay, because in your MediaStore example I saw the latter, but in Google's Android docs on MediaStore I saw the former and I was wondering
|
Mark M. |
¯\_(ツ)_/¯
|
Mark M. |
I wind up filing corrections for their samples a fair bit
|
sudokai |
:)
|
Mark M. |
on occasion, it turns out that I'm flat-out wrong or misread the sample
|
Mark M. |
on occasion, they agree and fix it
|
Mark M. |
and most of the time, the issue gets ignored
|
sudokai |
I think your books and blog are the best Android reference I've ever seen
|
Mark M. |
thanks! tell your friends! :-)
|
sudokai |
Yes, I wouldn't mind paying more for the subscription tbh
|
Mark M. |
I was planning on bumping the price a bit -- it's stayed flat for a few years now
|
Mar 31 | 8:15 PM |
Mark M. |
probably two options: $25/six months or $40/year
|
sudokai |
The app of the company I work for used to cost $5 a year, and we just bumped it to $10 and made the subscription auto-renewable.
|
Mark M. |
as a consumer, auto-renew on some things is fine
|
Mark M. |
as a privacy-and-security-focused business owner, I am uncomfortable with it
|
sudokai |
Some people complained, but when you look at the numbers, it was actually a loud minority
|
Mark M. |
that doesn't surprise me
|
sudokai |
Yeah, me too tbh. Google controls the subscription cycle completely.
|
sudokai |
It's pretty inflexible too.
|
sudokai |
Like, Stripe payments for example are great
|
sudokai |
They give you a lot of flexibility
|
Mark M. |
yes, I have had pretty good luck with them overall
|
sudokai |
Oh, you use Stripe? Nice to know.
|
Mar 31 | 8:20 PM |
Mark M. |
yes, the Warescription can be purchased by either PayPal or Stripe
|
sudokai |
Another Android question, still on the same images topic: when I request ACCESS_MEDIA_LOCATION after the user has accepted the WRITE_EXTERNAL_STORAGE permission, I get no additional permissions prompt
|
sudokai |
Nor I see the permission listed in my app settings
|
sudokai |
Have you encountered this before?
|
Mark M. |
no, but I only lightly experimented with ACCESS_MEDIA_LOCATION
|
Mark M. |
I focused more on seeing if the redaction worked in places other than the MediaStore, using ExifInterface
|
Mark M. |
(answer: it does not)
|
Mark M. |
so, I doubt I paid attention to what was in the Settings screen
|
sudokai |
Oh, on that topic...
|
Mark M. |
and I honestly don't recall the specifics of the permissions prompts
|
sudokai |
I'm trying to find the code
|
sudokai |
So I open the native gallery and select a file. I get a "temporary" uri.
|
Mark M. |
ACTION_PICK?
|
sudokai |
It seems that reading that Uri gives you the EXIF location, but I've seen people say otherwise
|
Mar 31 | 8:25 PM |
sudokai |
I mean it works on my phone
|
Mark M. |
well, in general, ACTION_PICK gives you permissions to work with the item that was picked
|
Mark M. |
for example, if you pick a contact, you can get at the name, email, etc. even though you do not hold READ_CONTACTS
|
sudokai |
new Intent(Intent.ACTION_GET_CONTENT)
|
Mark M. |
so, I am not terribly surprised that what you describe works, though I'm sure I didn't try it
|
sudokai |
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
sudokai |
intent.setType("image/jpeg");
|
sudokai |
startActivityForResult(intent, REQ_ADD_PICTURE);
|
Mark M. |
yeah, I would expect that to work as well -- after all, you could always use ExifInterface and get the location that way
|
sudokai |
Okay, yeah, it works for me as well.
|
sudokai |
I'm trying to refactor a RecyclerView ViewHolder that observes 2 RxJava Observable streams, one coming from an EventBus and it's a nightmare
|
Mark M. |
the ViewHolder observes RxJava streams?
|
Mark M. |
eek
|
sudokai |
Yeah
|
sudokai |
Haha, and not only one but two
|
sudokai |
And of course the RecyclerView itself is connected to Realm
|
sudokai |
As in, it's Realm that manages the list
|
Mar 31 | 8:30 PM |
sudokai |
through RealmRecyclerViewAdapter
|
Mark M. |
while I'm not a Realm fan, that part at least isn't scary
|
Jan S. | has left the room |
Mark M. |
but, that's a wrap for today's chat
|
sudokai |
Okay
|
Mark M. |
the next one is Tuesday at 8:30am US Eastern
|
sudokai |
Thanks Mark
|
sudokai |
Stay healthy during these days!
|
Mark M. |
you too!
|
sudokai |
It's scary out there
|
sudokai |
Thanks!!
|
sudokai | has left the room |
Mark M. | turned off guest access |