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!
|
Mark M. |
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.
|
Apr 9 | 4:00 PM |
Mark M. |
thanks for the kind words!
|
Mark M. |
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
|
Mark M. |
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
|
Mark M. |
as I seem to point out a lot, a Uri is not necessarily a file: http://commonsware.com/blog/2014/07/04/uri-not-...
|
Mark M. |
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).
|
Apr 9 | 4:05 PM |
Mark M. |
the provider has to offer persistable permissions
|
Mark M. |
you are taking only what is offered
|
Mark M. |
I have no idea what MediaStore does in this area
|
Mark M. |
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
|
Mark M. |
that'd be the "progressive enhancement/graceful degradation" approach
|
Mark M. |
personally, I haven't had a need for durable access to stuff like this, so I don't have a worked-out solution
|
Mark M. |
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?
|
Mark M. |
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
|
Apr 9 | 4:10 PM |
mikemcelligott |
Hmm... that's true, great point. Problem solved!
|
mikemcelligott |
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.
|
mikemcelligott |
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
|
Apr 9 | 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
|
Mark M. |
perhaps switch to using an event bus or something to get the result back
|
Mark M. |
the behavior you are seeing is the documented behavior
|
Mark M. | |
Mark M. |
oh, no, that's a different scenario
|
Apr 9 | 4:25 PM |
Mark M. |
never mind that point
|
mikemcelligott |
No, you're right... it's doing what it says it will do.
|
mikemcelligott |
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
|
Mark M. |
regardless...
|
Mark M. |
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
|
Mark M. |
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
|
Apr 9 | 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
|
Mark M. |
LocalBroadcastManager and Square's Otto are the other two main one
|
Mark M. |
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
|
Mark M. |
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 |