Nov 25 | 7:25 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Brent | has entered the room |
Mark M. |
hello, Brent!
|
Mark M. |
how can I help you today?
|
Brent |
Hi Mark.
|
Brent |
I'm trying to use your camera library for an app.
|
Nov 25 | 7:30 PM |
Brent |
Trying to present a square preview...
|
Nov 25 | 7:30 PM |
Brent |
and then a square picture.
|
Mark M. |
that's not really what the library is aiming for
|
Brent |
oh. So any advice on how to do that?
|
Mark M. |
it's just to be able to take a basic picture, without having to rely on shaky ACTION_IMAGE_CAPTURE stuff
|
Brent |
hmm.
|
Mark M. |
with respect to the preview, I haven't the foggiest
|
Brent |
ok. so can you suggest an approach?
|
Brent |
ok
|
Mark M. |
with respect to the photo, you'd have to do your own cropping logic
|
Brent |
yeah, that's my stratgy
|
Brent |
strategy
|
Mark M. |
e.g., find the shortest axis, then crop the edges of the longer side so both axes match
|
Mark M. |
also note that my library is going to have to get overhauled
|
Brent |
yeah, makes sense
|
Mark M. |
as android.hardware.Camera is now deprecated
|
Brent |
because of 5.0?
|
Brent |
right
|
Mark M. |
yes
|
Mark M. |
so I'll need to rework matters to be less reliant on things like Camera.Parameters
|
Brent |
though the camera2 has no backward compatibility, right?
|
Mark M. |
correct
|
Mark M. |
so I'll need to use both APIs
|
Brent |
ouch
|
Mark M. |
but it means that my library's API can't be exposing Camera.Parameters
|
Mark M. |
as that won't be used in some cases
|
Brent |
oh, so that will be a big change
|
Mark M. |
I'll be writing a blog post about all of this sometime next week, I think
|
Brent |
at least in the way that some people are using the library, i assume
|
Mark M. |
yes, it will be a total rewrite, pretty much
|
Mark M. |
and I'll be scaling back the use cases to focus on the itch that I need to scratch, which is taking basic pictures
|
Mark M. |
(and videos)
|
Brent |
ok. I'm actually able to get your preview to be square just by putting a mask over it
|
Brent |
in a framelayout
|
Mark M. |
if that works for you, cool
|
Mark M. |
I can see that being OK for TextureView
|
Nov 25 | 7:35 PM |
Mark M. |
hopefully it works for SurfaceView as well, if you're supporting Android 4.0 and below
|
Brent |
but the resulting picture is different from what i see in the preview even accounting for e masking. (I'm not supporting below 4.0).
|
Brent |
*the masking
|
Mark M. |
different in what way?
|
Brent |
I take a picture of an object, and have it fill the preview widthwise, but the picture has space on the sides
|
Brent |
as if it actually took a wider view than the preview indicated.
|
Mark M. |
oh, well, that's rather likely to be the case
|
Mark M. |
the preview aspect ratio and the picture aspect ratio are almost never the same
|
Brent |
i did that test in CWAC Demo from your repo, too, same outcome.
|
Brent |
OH
|
Brent |
so i have to make them the same?
|
Mark M. |
you can't "make them the same", as that's determined by camera hardware, not you
|
Mark M. |
the available sizes for the preview and the picture do not all have to have the same aspect ratio
|
Brent |
so... can i account for that in my cropping then?
|
Mark M. |
well, that depends
|
Brent |
i can find out what the aspect ratios are and do some adjustment?
|
Brent |
will that differ from device to device, though?
|
Mark M. |
my suggestion for the cropping is to chop off an equal amount on both ends of the longer side
|
Mark M. |
let's suppose, for example, that the picture is landscape, and so the longer side is the horizontal axis
|
Brent |
the longer side is not the only side on which I'm seeing extra space in preview vs. taken picture
|
Mark M. |
understood
|
Brent |
ok
|
Brent |
please proceed :)
|
Mark M. |
the cropping to make things square will take care of only that side that is being cropped
|
Nov 25 | 7:40 PM |
Brent |
ok. is the other side hopeless?
|
Mark M. |
I have no idea how you would ensure that the preview exactly matches the picture, as even beyond aspect ratios, the bitmaps are determined by the camera hardware, not you
|
Mark M. |
for all we know, the camera will return real previews and images of clowns for the picture
|
Brent |
ye of little faith :)
|
Mark M. |
no, I have plenty of faith in the power of clowns
|
Brent |
fair enough
|
Brent |
i asked a question about all of this on SO.
|
Mark M. |
I think I might have even seen that one
|
Brent |
I got one answer. Can you take a quick look and see if you think it's reasonable?
|
Mark M. |
got a link?
|
Brent |
I have been trying to implement the answer, but having trouble. Yes:
|
Brent | |
Mark M. |
well I didn't see that one
|
Brent |
i thought maybe not, since I thought you might respond
|
Mark M. |
in the future, use commonsware-cwac as the tag
|
Brent |
if you had
|
Brent |
ok
|
Mark M. |
as is noted in the project README
|
Brent |
didn't notice that. will do next time
|
Mark M. |
"in getPictureSize() must pick one of the resolution with same ratio as your preview size. " -- that is overly optimistic
|
Mark M. |
in theory, it would
|
Mark M. |
sorry
|
Mark M. |
in theory, it would work
|
Mark M. |
in practice, there's nothing to guarantee that there is such a match
|
Brent |
hmm. seems weird.
|
Brent |
but not entirely surprising
|
Nov 25 | 7:45 PM |
Mark M. |
with respect to the rest, let's just say that's why my next library is going to be a lot simpler and aim for really simple scenarios
|
Brent |
apparently the makers of the Instagram app have accomplished what I'm trying to do
|
Mark M. |
yes, and they have a whole team working on this, and more money than either you or I have
|
Brent |
speak for yourself (no, you're right, it's true)
|
Mark M. |
so I have no doubt that there's ways of doing this sort of thing, but it's not my cup of tea
|
Brent |
ok
|
Mark M. |
to put it another way, if more than 1% of your app functionality is tied up in using the camera, my library (current and future) isn't really what you're looking for
|
Brent |
ok. if i could capture the preview and use that, I'd be fine, I think, but i saw in another SO answer from you that that's not available
|
Mark M. |
it's not exposed by my library
|
Brent |
do you know if I can get it from the Android camera API?
|
Mark M. |
collecting preview frames via a callback is certainly possible
|
Brent |
ok
|
Mark M. |
Vine, for example, actually doesn't record a video -- they stitch together a video from preview frames
|
Brent |
yeah, I think i saw other SO posts explaining how to do it
|
Mark M. |
there's a "preview callback" hook in android.hardware.Camera
|
Mark M. |
biggest headache, IIRC, is that the previews come in YUV, not JPEG
|
Brent |
ok. i guess that's what I'll go for, to avoid the differences between preview and taken picture.
|
Brent |
i think the SO answers address how to handle the YUV
|
Brent |
i thought they also say there are other possible formats?
|
Brent |
anyway, not your problem
|
Mark M. |
I don't think we have a ton of control over preview frames in the android.hardware.Camera API
|
Mark M. |
android.hardware.camera2 has some more power here, for compatible devices
|
Mark M. |
also note that the raw preview frames won't be square, unless you happen to choose a square preview size (which may not exist on any given device)
|
Nov 25 | 7:50 PM |
Brent |
I'd turn them into something i could crop
|
Brent |
so I'd use my mask to make a square preview
|
Brent |
then capture the whole preview (not square)
|
Brent |
(so the first step would be to show a square preview to the user)
|
Brent |
and then crop the preview and show it in another activity
|
Brent |
that's what I'm thinking at this point
|
Mark M. |
sounds reasonable
|
Brent |
sounds somewhat straightforward, but i had no idea what i was getting myself into when I started this
|
Brent |
so who knows what clowns will jump out at me now
|
Brent |
ok, well, I guess I can let you go, unless you have any other nuggets of wisdom to share (aside from "get out of Android programming" :)
|
Brent |
(I know you'll probably stay here, but I'll leave and stop bombarding you with questions)
|
Mark M. |
well, it's a quiet chat room tonight
|
Mark M. |
if you have questions, go right ahead
|
Nov 25 | 7:55 PM |
Brent |
well, I'd love to try to implement this right now and have you hold my hand while i do it, but I'm not nearly adept enough to do anything that fast :)
|
Brent |
I'm trying to think of something else to ask you about, but can't off the top of my head
|
Mark M. |
no worries
|
Mark M. |
there will be more office hours chats in the future :-)
|
Brent |
yeah, though maybe not this quiet. Can we schedule another Thanksgiving right after your next one?
|
Mark M. |
sorry, not my department
|
Brent |
your next office hours are not for another couple of weeks?
|
Brent |
is that right?
|
Brent |
i don't have the schedule in front of me.
|
Mark M. |
no, I have a 7:30pm US Eastern one scheduled for next Tuesday
|
Mark M. |
though I just added that to the calendar yeseterday
|
Brent |
oh, ok, that's good
|
Brent |
here's something else i can ask you about.
|
Brent |
I'm using Ion, having learned about it from your book
|
Brent |
here's an SO question I asked about it that has me kind of worried:
|
Brent | |
Brent |
bit nervous about his changing the API, though of course I can just stick with one library version
|
Mark M. |
well, changing APIs between major versions is perfectly reasonable
|
Nov 25 | 8:00 PM |
Mark M. |
obviously, the bigger the change, the bigger the headache
|
Brent |
yeah, i suppose it can't be avoided
|
Mark M. |
my book sample is on an old Ion due to bugs in Ion, where I was having difficulty using a newer version
|
Mark M. |
but I do need to update it sometime
|
Brent |
i guess I'm more concerned about the x.+ gradle dependency
|
Mark M. |
my general rule is to only use + on the patchlevel (e.g., 21.1.+)
|
Mark M. |
as any library author who puts a breaking API change in a patchlevel should be slapped with a trout
|
Brent |
well, i think in his readme he says use 2.+ now.
|
Mark M. |
that's his opinion :-)
|
Mark M. |
authors are welcome to make their own suggestions
|
Mark M. |
and you, the developer, need to make the choice that you're most comfortable with
|
Brent |
yeah. sure. no rules set in stone.
|
Brent |
yes. i'll probably just stick with something fixed.
|
Brent |
presumably he recommends 2.+ because he wouldn't make breaking changes without going to version 3, but no, I'm not sure I'm comfortable with that, and it probably doesn't matter much
|
Mark M. |
so long as you check back from time to time to see if an update (with bug fixes, etc.) is worth taking on
|
Mark M. |
the value of + is in the automatic upgrading
|
Mark M. |
if you manually check frequently enough, you don't need automatic upgrading
|
Nov 25 | 8:05 PM |
Brent |
Right. I don't really understand how the gradle dependency stuff works. Does something just get downloaded once to my project?
|
Mark M. |
that depends on whether or not you are using the + wildcard
|
Brent |
right. i guess the + tells it to check
|
Mark M. |
if you have compile "com.foo:bar:1.2.3", that version will be downloaded on the first build
|
Mark M. |
and you'll stick with that until you edit the build.gradle file
|
Brent |
makes sense
|
Mark M. |
if you have compile "com.foo:bar:1.2.+", then Gradle will check for updates on the first build of each day
|
Brent |
i see
|
Mark M. |
and download the latest if your project has an older one
|
Mark M. |
there's a command-line switch you can use to force a dependency check (--force-dependencies?)
|
Brent |
ok. well, I'm about ready to wrap up. any quick advice on becoming a better Android dev? I'm the only Android dev for a small company, making apps for their clients.
|
Brent |
not working with more experienced people much
|
Mark M. |
that's a rather broad question
|
Brent |
I've been taking the Udacity course
|
Brent |
i know
|
Brent |
so don't worry about being able to provide much
|
Brent |
or anything
|
Mark M. |
yeah, I don't have a great way to answer that across the board
|
Brent |
right. different for everyone. i'll keep at it and with time I learn
|
Brent |
ok. well, i really appreciate your time tonight and all the work you've done with your book and otherwise.
|
Nov 25 | 8:10 PM |
Mark M. |
happy to be useful!
|
Brent |
have a good night and a happy Thanksgiving!
|
Mark M. |
you too!
|
Brent |
Thanks. Bye.
|
Brent | has left the room |
Nov 25 | 8:15 PM |
EGHDK | has entered the room |
Mark M. |
hello, EGHDK
|
Mark M. |
how can I help you today?
|
EGHDK |
I made a custom adapter extends array adapter but I got an error that there is no default constructor. What tells a class that there is no default when the docs show that there are a bunch
|
Mark M. |
there may be "a bunch", but none may be a default constructor
|
Nov 25 | 8:20 PM |
Mark M. |
"The default constructor is the no-argument constructor automatically generated unless you define another constructor"
|
Mark M. | |
EGHDK |
If I made the array adapter class how would I specify that one of them is default?
|
EGHDK |
Oh. Hmm... That's interesting.
|
Mark M. |
most likely, the right answer is that you implement a constructor, chaining to the superclass constructor
|
EGHDK |
So another activity being killed question. I know I've tried to comprehend this multiple times with you. But let me try to shape the question this way. What events would happen for the bundle in onCreate to not be null?
|
Mark M. |
1. configuration change (e.g., screen rotation)
|
Mark M. |
2. process is terminated, but the user returns to your app while it is still in the recent-tasks list
|
Mark M. |
those would be the big ones
|
EGHDK |
There would be a valid bundle even if the process is killed?
|
Mark M. |
in scenario #2 above, yes
|
Mark M. |
the reason why a Bundle is used is that a Bundle can be passed across process boundaries
|
Mark M. |
and so a core OS process maintains the state of the activities in the back stack for each task that is in the recent-tasks list
|
EGHDK |
How? I thought if the process is killed all 4 possible components are dead.
|
Mark M. |
they are
|
Nov 25 | 8:25 PM |
EGHDK |
Oh
|
Mark M. |
however, processes can be created as well as killed
|
Mark M. |
if we did not create them, there would be nothing *to* kill
|
EGHDK |
So the activitymanager holds onto bundles for us?
|
Mark M. |
and, if the user elects to go back into an app, where that app still has a task on the recent-tasks list, Android will effectively resume the task
|
Mark M. |
well, I can't say whether it is literally activitymanager
|
Mark M. |
something in a core OS process does
|
EGHDK |
Gotcha. Okay. I didn't know that. So I can have activityA go to activityB then go home and force close the app. Then go to recents and the bundle will be valid for both activities?
|
Mark M. |
yes
|
Mark M. |
well, actually, no, due to the "force close" bit
|
Mark M. |
if you mean "Force Stop" -- the button in Settings -- that wipes out the recent-tasks entry
|
EGHDK |
Force close clears the entry?
|
EGHDK |
Oh ok thanks
|
Mark M. |
but if the process is terminated more naturally (e.g., low-memory reclamation), or even through DDMS, Activity B will get its Bundle back when Android restores the task
|
Mark M. |
and, if the user presses BACK, then Activity A will be created and get its Bundle back
|
EGHDK |
So if my activity is open and I open a ton of other activities what will happen? Will I get an oom? Or will it start to kill earlier activities?
|
Mark M. |
Activities are not "killed"
|
Mark M. |
processes are killed
|
Nov 25 | 8:30 PM |
EGHDK |
Destroyed?
|
Mark M. |
the only reason an activity is destroyed is because something called finish() on it, whether programmatically (e.g., you actually call finish()) or based on user input (e.g., user presses BACK)
|
Mark M. |
if you keep creating new activities, you will eventually get an OutOfMemoryError, as you will run out of heap space
|
EGHDK |
Okay, out of time. May follow up next time. On a train now so I decided to give mobile commonsware a chance. Hahaha thanks again
|
Mark M. |
the next chat will be next Tuesday, also at 7:30pm US Eastern
|
EGHDK |
Happy holidays
|
Mark M. |
you too!
|
EGHDK | has left the room |
Mark M. | turned off guest access |