Office Hours — Today, April 9

Tuesday, April 7

Apr 9
3:55 PM
Mark M.
has entered the room
Mark M.
turned on guest access
mikemcelligott
has entered the room
Mark M.
hello, um... mikemcelligott!
mind if I call you Mike?
mikemcelligott
Hi Mark, I was literally thinking earlier that the internet should just send you money for all the help you've provided over the years, then clicked on some link to find out that you do micro-consulting, which is fantastic. Mike's fine.
4:00 PM
Mark M.
thanks for the kind words!
how can I help you today?
mikemcelligott
Here's my problem. Developing an app for a client suppporting 4.1 - 5.1. One of the functions is to retrieve an image reference from the gallery, or to take a picture with the camera. When retrieving the image ref from the gallery I'm finding that I can't "takePermissions" from the intent - I get an exception back. My workaround has been to copy the image file to external storage and reference a filepath, but I'd rather do things "right" and just refer to the original file so as to be a good citizen. Thoughts?
Mark M.
well, the take-permissions stuff is new to 4.4 IIRC
mikemcelligott
Specifically SecurityException. You've responded to this exact issue on SO previously.
Mark M.
yeah, takePersistableUriPermission() is new to 4.4
so you'll need some workaround for 4.1-4.3 anyway
mikemcelligott
4.1 - 4.3 just give me back a usable file url, so that's easy.
Mark M.
um, I would not count on that
as I seem to point out a lot, a Uri is not necessarily a file: http://commonsware.com/blog/2014/07/04/uri-not-...
bear in mind that that not only do device manufacturers replace the stock AOSP Gallery app, but users can install third party ones that might respond to stock Intent actions
mikemcelligott
I know. Whatever I do should handle all of it. Mostly I just don't know how to get a persistable set of permissions. I saw something about forcing an older image chooser, but I'm not seeing a lot about why these permissions are not persistable (as you mention is probably the case for this problem).
4:05 PM
Mark M.
the provider has to offer persistable permissions
you are taking only what is offered
I have no idea what MediaStore does in this area
and your Uri might not be from MediaStore anyway
mikemcelligott
So in that case the "workaround" may actually be the correct answer? I have access to the binary data after the chooser exits..
Mark M.
off the cuff, I'd try takePersistableUriPermissions(), and if it fails (or you're on 4.3 or earlier), fall back to the workaround of making a local copy
that'd be the "progressive enhancement/graceful degradation" approach
personally, I haven't had a need for durable access to stuff like this, so I don't have a worked-out solution
my needs have been usually transient (e.g., upload the data), in which case just rolling with openInputStream() on ContentResolver (for content:// Uri values) should suffice
mikemcelligott
Okay, I see. Well that makes me feel a bit better about my implementation. My main concern is that I'm dealing with health data and the client wants to keep it private. I obviously don't want to use internal storage, but maybe I can encrypt the files on external storage.
Mark M.
"I obviously don't want to use internal storage" -- why?
internal storage would seem like the right answer
mikemcelligott
No guarantee on the amount available and I'm storing what are probably high-res photos?
Mark M.
bear in mind that on 3.0+, internal storage and external storage are almost always on the same partition, so the old Android 1.x/2.x "don't put big stuff on internal storage" rules don't really apply
4:10 PM
mikemcelligott
Hmm... that's true, great point. Problem solved!
I think that's all I have right now. I'll just switch to internal storage, which is essentially what I just said about "external storage + encryption", right?
Mark M.
it's more access control than encryption
mikemcelligott
Internal storage on a rooted phone yields unencrypted files?
Mark M.
yes
mikemcelligott
Okay, good to know.
You're providing one hell of a value, I appreciate it. Looking forward to reading the book as well.
Mark M.
I try to be useful :-)
mikemcelligott
It's fantastic. Alright, I'm going to implement those changes. Thanks for your help.
Mark M.
you are very welcome
mikemcelligott
Bye!
mikemcelligott
has left the room
Mark M.
BTW, the chat transcripts get posted to http://commonsware.com/office-hours/ shortly after the end of the chat
4:20 PM
mikemcelligott
has entered the room
Mark M.
hello again!
mikemcelligott
Oh hey Mark, I guess I might as well avail myself of your knowledge a bit further. I'm finding that onActivityResult is not called if the NO_HISTORY flag has been set on Intent launch. Any great workaround? I really don't want my interim activity showing up on the back stack but I've found that what I expect to happen given the documentation often is not what seems to happen.
Mark M.
um
perhaps switch to using an event bus or something to get the result back
the behavior you are seeing is the documented behavior
oh, no, that's a different scenario
4:25 PM
Mark M.
never mind that point
mikemcelligott
No, you're right... it's doing what it says it will do.
I hadn't seen that previously. In that case, and maybe I've just had some error in what I've attempted, is there a way to get an activity result but not have the launched activity in the back stack? They seem like they should be two different things to me..
Mark M.
yeah, well, that's where I was misreading the docs
regardless...
again, I'd consider an event bus or some other separate communications path, avoiding the ...ForResult() stuff
mikemcelligott
I took over this project from an overseas group to fix it. Possibly the worst decision I've ever made. It takes longer to figure out what they're trying to do than it would be to start over, but I can never be quite certain until I've spent the time pulling apart their code. Okay, I'll look into an event bus.
Mark M.
yeah, adopting a large existing code base can have its issues
FWIW, I am working on a chapter on tasks now, and I'll whip up some samples of NO_HISTORY/startActivityForResult() to try to nail down the behavior for that section
4:30 PM
mikemcelligott
It seems kind of shoddily implemented (though again, I only try to make things work for so long before deciding it just doesn't). Can you recommend a simple event bus off the top of your head? I'm searching in parallel.
Mark M.
oh, I'm a fan of greenrobot's EventBus
LocalBroadcastManager and Square's Otto are the other two main one
er, ones
mikemcelligott
Was just looking at that. Okay, great. I'll give it a go.
Mark M.
I have a chapter on "Event Bus Alternatives" in the book, walking through each
mikemcelligott
Okay, great. Sorry, haven't read the book yet. Joined just because I've been seeing your comments on SO for so long.
Mark M.
oh, I was just mentioning the chapter so you could go read it
you're probably not really the sort who needs to start from page one :-)
mikemcelligott
Thanks again, delving into EventBus now, and I'll take a look at the chapter as well.
mikemcelligott
has left the room

Tuesday, April 7

 

Office Hours

People in this transcript

  • Mark Murphy
  • mikemcelligott