Tip:
Highlight text to annotate it
X
STEPHAN LINZNER: Hello, everybody.
Welcome to this week's Android Office Hours
live here from London.
Today is the first birthday of Google Play, for those who
don't know, so I think it's a good day to
have an Android Hangout.
So this is Stephan Linzner.
MATT GAUNT: I'm Matt Gaunt.
And in the Hangout down here, we have Rich and Nick.
RICH HYNDMAN: Hey there.
Yeah, we're not in the London office today because we've
just got back from a trip to Israel, where we were at the
campus in Tel Aviv.
I'm sporting the new Campus Tel Aviv hoodie, whether you
can read it from there.
So Yossi there, in the bottom corner there, we actually sat
with him about 10 hours ago, but we just
got back to the UK.
And there was a lot of good talks on multiscreen
applications and multiscreen development over at
the campus in Israel.
What were you talking about, Nick?
NICK BUTCHER: Yeah, I went and I gave a talk on how to design
responsive applications on Android.
So hopefully, people enjoyed that, and I'll be posting my
slides online soon, so watch out for that.
RICH HYNDMAN: Absolutely.
I'll be posting mine as well.
MATT GAUNT: Sweet.
STEPHAN LINZNER: Fun.
MATT GAUNT: So as usual, no more disclaimer.
We are not announcing new features or product timelines
or anything like that.
It's purely to answer questions and help out
wherever we can.
So we've pretty much got a full house already.
So has anyone got any questions in the Hangout?
No.
STEPHAN LINZNER: No questions from the Hangout?
OK.
MATT GAUNT: Do you want to kick off
with a Moderator question?
STEPHAN LINZNER: Yes.
OK, we have a question down here on using the Crop Intent
or using a customized one.
Yeah, I think it's a difficult question because if you have
used a Crop Intent before, you might have noticed that it
will not work on all devices.
And I don't know actually how official it is, but if you
want to use it, you should make sure that you have a
fallback option to what you're doing.
So you could use the Crop Intent, but you still have to
have a fallback solution if this is not working.
NICK BUTCHER: I'd have stronger guidelines than that
and say it's actually not a documented intent.
So it's well known, but it's not actually guaranteed to be
there by the platform.
So while you could try and use it, like you're saying, it's
not guaranteed to be there.
A better approach might be to copy the functionality from
the gallery application and do it yourself.
STEPHAN LINZNER: Or do it on a server side.
Even that might be a good idea to do.
NICK BUTCHER: Well, you probably want to be able to
resize it on the client side and then choose the cropping
area, and then performing the actual crop is trivial, right?
STEPHAN LINZNER: Right.
NICK BUTCHER: I mean, all the code is there in the
[INAUDIBLE] app, it's all open source, but [INAUDIBLE]
if the OEMs modified their version of the gallery
[INAUDIBLE].
MATT GAUNT: Which is exactly what's happened with a
question like this saying, that one particular device
just doesn't work.
It comes back with something weird.
I mean, you've also got to think if you can get away with
not involving the user at all, that's also
another viable option.
I've had applications where we needed to crop an image just
to make it square, and nine times out of 10, you didn't
really need to get the user involved.
So think of a different way of doing it, I think,
is the way to go.
Should I just jump in right with the difficult one?
I'm going to do it.
So we had a question.
Can Android destroy stopped activities of an app if it's
still in the foreground?
The docs suggest it can, but Hackborn replied it wasn't
necessarily the same case.
Essentially, what Dianne Hackborn's kind of stated is
that if you have an application in the foreground
and then you keep on creating activity after activity,
essentially, you'll get to a point where you'll run out of
memory and the activities won't be cleared because the
application is in the foreground.
So essentially, the best way to get around this was to
start using fragments.
And essentially that way, you can start managing memory
itself because you're essentially able to swap out
the fragments and remove them, et cetera.
So managing things that way.
I think it's slightly ambiguous in the documentation
in terms of whether the activities will be cleared
when they're just in the background even though the
application's in the foreground or not.
I think that's where the confusion has come about.
STEPHAN LINZNER: But you have to be very careful if you're
running in the foreground and creating activity over
activity over activity.
I think this is kind of an architectural problem.
This is also why Dianne said use a fragments API because
you don't want to create a new activity every time.
Or what you can do is you can handle a task that you can use
flags like Single Tap and refresh the
views, refresh the adapters.
But I think this is how you should approach [INAUDIBLE].
But this is how you generally should approach these things.
And to know that if your application's in the
background, the framework will be able to kill your activity,
but not if you're running in the foreground.
MATT GAUNT: And that was from itai.
And originally, I posted the comment and he's rightfully
come back saying, given that it's Dianne Hackborn.
If Dianne Hackborn says it's true, then--
STEPHAN LINZNER: It probably is true.
MATT GAUNT: Definitely take her word over mine.
Next [INAUDIBLE].
When do you think the ability to reply to comments will be
added to developers?
So again, this kind of falls neatly under the, we're not
announcing new features, et cetera.
Google Play have given it to some developers, but
ultimately, I think the move to have comments be backed up
by a Google+ profile means that you could reach out to
users if you wanted to help them out directly.
But at the moment, there's no news as to what the Google
Play team are doing with that feature.
I'm going to jump straight into the next one.
By the way, if anyone has another question anywhere,
then feel free.
Stephan, have you got a question in the Moderator?
Yeah, he has somewhere.
STEPHAN LINZNER: Which one?
RICH HYNDMAN: He's linked to it as well.
Also, if anyone's got any favorite apps from the first
birthday celebrations that they've been downloading, it'd
be good to hear about them.
There's movies, books, applications, games, all for
sale at the moment in the Play Store for the first birthday.
The Play is one celebration.
STEPHAN LINZNER: Your question was the one with the UI
automator, I see.
We still don't have any news on that.
I saw you open up a different one.
It should not happen, like I said last week, but we don't
have an answer for you ready.
I'm sorry.
Should we take on the private API key question?
MATT GAUNT: Let's do it.
STEPHAN LINZNER: This is also something that's very
sensitive, I think, because you should obviously protect
your API keys.
So what should you do about it?
There's a couple of things you could do.
In general, if you want to have a read, there's a blog
post on the Android Developers Blog on securing passwords,
and maybe use some advice from there and apply it to secure
your API key.
But in general, you should think about how sensitive is
it to protect your API key in general?
Do you have to pay for your API usage, and how important
is it [INAUDIBLE] or not.
Generally, you should protect it.
In the Android system, of course, you should always use
the Flag Private to store the API key internally.
Of course, on rooted devices, this won't be accessible, so
if you really have to protect your API key, you can do some
kind of root detection.
I also posted a link on [INAUDIBLE]
class where you can do root detection last week.
This is something you can use to detect root and only run on
non-rooted devices if this is something you can do.
And you, obviously, what's your take on it?
You can do a lot of things.
MATT GAUNT: Yeah.
I think generally, you've got to think how hard do you need
to make it for someone to get the API key, and I think
that's going to be dependent on the use case, essentially.
I think the way a lot of companies will get a way
around this will be to do a combination of server side
support as well as client side, which the [INAUDIBLE]
kind of covers the client side of it.
So I think generally, there's going to be certain methods
that are going to work better than others, but generally,
it's a case of how difficult do you need to make it for
someone to then not be interested in
getting at the API key?
So it will depend on the scenario.
STEPHAN LINZNER: We'll confer and investigate on what is the
best practice to do it on different levels of
[INAUDIBLE].
RICH HYNDMAN: Also, the more recent API keys now also
require a package name to be associated with them.
So the Maps API, for example, your API key can only be used
by you because it takes your signature and
your package name.
So for our APIs, at least, we're now securing them
through that mechanism as well.
Other people's APIs may not use that, but it is actually
fine to put things like the Maps API key in plain text
inside your application.
MATT GAUNT: Yeah.
NICK BUTCHER: But other developers kind of take
advantage of that same infrastructure, right?
You have the ability to verify back end calls, so that's
exactly what the Maps API is doing.
It's a way to verify that the traffic is only coming from a
certain package.
So if you wanted to, you could route something through a
server off device, and use the Google based [INAUDIBLE] token
to verify that it's only coming from your application,
that isn't some random web traffic.
RICH HYNDMAN: Yeah, I think if you search for Cloud Endpoints
on Google+, Cloud Endpoints, you'll find
it on the API Console.
MATT GAUNT: Nice.
STEPHAN LINZNER: OK, very nice.
RICH HYNDMAN: While I'm talking about things on the
API Console, actually, it's worth mentioning that last
week, a new feature launched which now allows you, if you
use Google+ sign in on your website, to have the Install
Now button in your Android applications.
So users can install your Android application from your
website directly onto their device as if they were in the
Play Store.
You don't need to forward them to the Play Store anymore.
It's part of the Google+ sign in, as I say, and you get some
great metrics from the Google+ Platform Insights as well.
So have a look at developers.google.com/+, and
then look for Over the Air Install.
It's not actually the Install button, it's part of the sign
in process allows the user to install your application.
Kind of cool new feature.
MATT GAUNT: Added some more work for me to do to my
website now.
RICH HYNDMAN: But if you've got Google+ sign in already,
then you just need to add the app package name into the
script that's already there and turn on the API feature in
the API Console.
MATT GAUNT: Cool.
So Nick, we've got a question for you.
In the last Android Design in Action, Nick mentioned they
rarely recommend to use dialogs.
Why is that?
I think it's a useful way not only to get input data, but
also show a relatively small amount of info that doesn't
really fit anywhere in the app, so about
two to three lines.
NICK BUTCHER: Yeah, my general hatred of dialogs is just due
to their blocking nature.
It just really disrupts any flow you might have within an
application.
I just think if you can display something in lines,
two to three lines could be given in line somehow, or some
inline use in space element that you don't have to go to
through an explicit dismissal or anything like that, and I
find that's better.
MATT GAUNT: Yeah, I kind of agree.
I think one of the most obvious use cases for a dialog
is when you're in the middle of a sign in process, you've
got the username, you've got the password, and then
something fails and then it comes up with a dialog saying
something doesn't work.
It's much nicer if you just show a message above the
actual form, so that way they can edit whatever they want to
do, or retry there.
By putting up a dialog, you're almost already flagging up the
fact that something's gone wrong and blocking them from
trying again.
STEPHAN LINZNER: So you should only use it in cases where you
need the user's attention and you need the user input.
But in the other cases, I would suggest there are other
things in the framework you can use to notify the user,
tell them what's going on.
But I think dialogs interrupt user flow, as I wrote on the
Moderator, and this is why you should be really careful when
using them.
So what else do we have?
AUDIENCE: Can I ask a question, please?
MATT GAUNT: Go for it.
STEPHAN LINZNER: Of course.
AUDIENCE: Thanks.
Is it possible to detect if the app is open from a
broadcast receiver?
STEPHAN LINZNER: I don't know if it's possible from a
broadcast receiver, but what you can do is you can grant
for it to Get Tasks permission, and you can from
there get the running task.
But you have to be very careful because you're
requesting the Get Task permission.
I think there are one or two ways.
I did that on another project.
But this is one way you can detect if your application is
still there and also if it's running.
But I only recommend it in rare cases, because you're
obviously going to request this permission, and people
wondering why you're requesting--
AUDIENCE: What exactly I would like to know, I would like to
know if the app is open, if the UI is in the front, and
not just if I can find the task.
Because you know the app can be in the task but is not open
at the moment.
It's in the background.
STEPHAN LINZNER: But I think you can do it with that.
Just type in on Stack Overflow, there are a couple
of answers on that.
But if I remember correctly, you can
definitely do it from there.
AUDIENCE: I will check on that.
Thank you.
STEPHAN LINZNER: What you also can do, I think one solution
is to register a dynamic broadcast receiver, and from
then send messages which you can then receive.
This is something you also could do because this
broadcast receiver will only be active if you're running
the program and have user focus.
AUDIENCE: Thank you very much.
MATT GAUNT: So one of the questions on the Google+
stream is, do the menu items on the Action bar support the
checked state?
We tried this but it seems not to work, from Jens Hohl.
So to the best of my knowledge, it doesn't support
necessary the checked state, but what you can do is just
swap out the icon depending on the state.
So essentially, when you've created the menu, it's safe to
keep a reference to the actual menu itself and then at that
point use Find Item by Idea, I think it is, or something
along those lines, to actually get a reference to that
particular item, and then change the icon
depending on the state.
So that's the best way that I know how to do it.
If anyone else has any other comments on it?
STEPHAN LINZNER: Yeah, greetings to Jens.
I know him.
He's a very smart guy.
MATT GAUNT: Another one from Robert Rees.
Where would you suggest a new developer to start?
So I think Giovanni has already responded to the best
place to start, which is the Android
Developer Training Site.
Loads of tutorials, and just generally helps you go from
really brand new developers right through to the really
advanced stuff.
So that's probably a really safe place to start.
And just start coding.
Come and ask us questions.
Then we've got a later conversation with Andrew
Kelly, the one man moderator machine.
So one of the other questions we got on the Moderator--
by the way, has anyone else got a question in the Hangout?
No, still quiet.
So the question starts off with something we can't cover
now, which is will an update of Google Maps API include a
long press callback for Info window, something like on info
window, long click listener, or is there any workaround to
do that now?
I really need that.
So essentially, on the Maps API, you can
create a little marker.
When you think the marker, it comes up with an info window
above that.
What McCann is trying to do is when you long click on the
info window, get a difficult callback.
So Stephan, you've been kind of looking into this.
STEPHAN LINZNER: There's no out of the box solution for
this, so it's not supported.
If you read through the docs, you will see that the view
that is shown there above the marker as an info window is
actually not the real view, it's an image.
So it's not very interactive.
But there was one interesting post on Stack Overflow.
To be honest, it's a little bit hacky.
I put it in the Moderator.
So give it a try.
What he basically does is he wraps his whole layout for the
whole activity, he makes a custom layout.
And what he does, he's
intercepting touch event there.
He's overwriting on this touch event and then is looking if
the touch event actually was on the info window.
And when it was on the info window, he's going to manually
dispatch the event down to the info window.
And so the info window is, again, kind of a live view.
This is what he has successfully managed to do,
but to me, it sounds kind of hacky and you should have a
good reason to do it.
We've discussed this before.
A long press on a pop-up in a Map View, my personal opinion
is you have to have a very good reason to do it.
But if you have to do it, look at the Moderator and try to
intercept the touch events and route them yourself.
This is what you can do.
MATT GAUNT: It's one of these things, I think it's probably
messed up from the API because we intend people just to click
on it and then go through to another screen which will
actually have all the information and all the
features that you can do from that point.
So having the long click listener, I don't know.
I struggle to see a situation where the experience is going
to really benefit from having a long click, but I'd be
interested to know what you're trying to do with it, really.
STEPHAN LINZNER: OK, what else do we have?
There's a really good quality of images.
MATT GAUNT: Got another one?
STEPHAN LINZNER: There's one.
I'm just reading through the comment.
What you can do is, I don't know where you get your images
from, but what you can do is, I mean, you obviously will
know the width and the height of the image in your gallery.
And to make sure the images are always at a good quality,
just fetch a slightly bigger image from the server.
And what you also can do is then scale it down so
that it will fit.
So there are a couple of strategies.
I think optimizing images for the gallery is often done on
the server side.
So you request different representations from the
server for different devices.
But what you never should do is download very big images
and use them without sampling them down, because this will
obviously take a lot of memory.
You can download a big image if you don't have an image
scanning facility and scale it down and then put it in a
view, but what you should never do is take the big image
and put it in a gallery.
And also, recycle your views.
MATT GAUNT: So just to reference that, that was
referring to a question that we had on the Google+ stream,
that was essentially, how do you maintain good quality for
images when writing custom gallery implementation?
I think just to further what Stephan was saying, the main
approach that I've seen people take is essentially, they only
have access to really big images, and therefore when
you're doing custom gallery, the best solution that I've
seen is just to scale it down, store a reference to the full
image as well as the smaller one, and then just use the
thumbnail within the List View, and then that way,
you've still got access to the large one if you need it for
whatever reason.
But you do you have to be careful with memory management
because you're dealing with bitmaps.
STEPHAN LINZNER: And Andrew Kelly just pointed out to
Giusepppe, this is what I was talking about.
With getting the running task permission, you can refer to
running a process info and you can get the
importance from there.
This is where you can tell if you're in the foreground or
not, but still be very careful when using it.
AUDIENCE: Thank you.
MATT GAUNT: So this is a question that maybe Rich or
Nick will have a bit more insight in.
This is from Phil.
Are unstripped system libraries available for
download to assist in diagnosing Android app crashes
below the Dalvik VM?
So essentially, what Phil's got is he's got a Java
application, there's no NDK, and somewhere down in the
Dalvik VM, there's actually a cycle.
And he's kind of posted to a Google+ link, which then posts
to a Google Group conversation where someone's actually said
they've got unstripped binaries which then gives them
access to an extra set of information.
So I've posted a link to the Nexus drivers.
Not really sure if that's related or not,
but it might help.
Do you guys have any insight?
NICK BUTCHER: Nope.
RICH HYNDMAN: I'm looking through the [INAUDIBLE]
at the moment.
Sometimes you can tell.
Sometimes they've commented and you can find out
what's going on.
But on this, I can't see much at all.
MATT GAUNT: I'd be interested to know what you're doing,
Phil, to kind of cause it.
I think somewhere along the lines, there was an example of
using a bitmap in one thread, recycling it in
another, and then it--
RICH HYNDMAN: I'd try the memory allocation tools.
Run a debug off the app, collect the memory usage, and
then run it through the MAT, the Memory Analysis Tool, at
the point when it crashes and see if you can figure out from
the memory allocations what's going on.
MATT GAUNT: OK.
STEPHAN LINZNER: So our man Jens asked another question,
which I think Rich can comment on.
He's asking for suggestions on a webcast recording tool from
the device.
They want to record their app on the device and show the
video to their customers.
I think you're experienced in recording video from devices.
RICH HYNDMAN: Sure.
If you want to record it into a PC or a Mac, there's a
number of HDMI recorders.
I've used a Black Magic one.
I was using one a couple of days ago.
It works very well.
You get the 1080P and 720P streams that's already through
your Thunderbolt or USB3.
So if you have a look at Black Magic's website, they have a
few tools there that work quite well.
The only thing to be careful of is that your phone or
tablet doesn't have HTTP keys on it.
So you want to something like the Motorola Zoom, or the
Galaxy Tab, or the Transformer Prime, or the Galaxy Nexus.
All these things will work fine.
But then as soon as you go up to things like the Nexus 4 and
the Nexus 10 and some of the newer devices that support
HTTP, most recorders won't record HTTP
encrypted content, obviously.
So just be careful with that, but I'm using the one from
Black Magic and it works absolutely perfectly for me.
NICK BUTCHER: A viable attempt, if you can, is that
you use an emulator or a desktop software like
BlueStacks or something like that and use some desktop
recording software as well.
You get quite good frame rates then.
STEPHAN LINZNER: OK.
We have an interesting question, I think, from
Stephan from Berlin.
He's asking what's the best approach to migrate a phone
app, no fragments, to a tablet app.
This is an interesting question.
What's the best approach?
I think the best approach is to go over the sequential
screens on the phone and ask yourself how will you lay out
these screens on a tablet?
And after you've done that, you should probably continue
on taking each activity and refactoring out every code
that has to go from the activity to the fragment, and
put all screens in fragments.
And then after that, you're going to start rearranging it
on the tablet.
But that's what I would do, is I would think about which
activities which visible views to the user go where on a
tablet, and then I would refactor out the fragments,
and then I would do all the rearranging for the phone and
the tablet.
So you can do it step by step.
What can be very helpful when doing it is to use something
like an event bus because it allows you to
decouple things like that.
So you can still use the old code while also running a
fragment because the events tend to make code more loosely
coupled, so this is an approach I've taken on which
worked very well because you can still keep the app running
and having some fragments there.
But generally, take on the phone code, extract some
fragments, and then rearrange it for the tablet version.
MATT GAUNT: I think that sounds about right.
I think you just need to genuinely think about how you
want to chunk up the logic of the application into fragments
because obviously, you're going to want
to move them around.
And once you've figured that out, start moving those bits
of logic you already have into in the fragment.
And like Stephan said, then you're good to go.
STEPHAN LINZNER: There's a short question.
I'm a newbie.
Why don't pages like developer.android.com?
I have no links to examples.
Where can you get the sample apps?
You can get it from, if you use a [INAUDIBLE]
Android tool--
NICK BUTCHER: Sorry, actually, the important thing you missed
out when you read that link is he was talking about the
design site developer.android.com/design,
specifically on linked code stuff, so they're specifically
resources targeted mostly at designers, and they're not
supposed to be backed up by implementation steps.
STEPHAN LINZNER: You're right.
MATT GAUNT: So I think generally with this kind of
stuff, when you start looking, so if you're finding something
in the Action Bar that's mentioned in the design
guidelines.
When you actually then start looking at the documentation
for the Action Bar, you'll actually start finding guides
that'll explain how to do each particular part that will be
kind of referenced in the design guidelines.
So I think they are decoupled for a good reason, but
generally, the documentation is still there to back it up
and help you in whatever way you need to.
So I think it's quite a good way of doing it.
And like Nick said, it's one of those things, anything that
gets designers to start thinking in an Android when
they're not really used to it is good.
And scaring them off with code and certain things like that,
if they're not into that, then it's best to leave it.
NICK BUTCHER: I think it's good and bad.
I want all developers to read the Design Guide, and I could
see the benefit for having links
through to some examples.
So I can see the argument.
I get it completely where you're coming from.
But at the same time, like Matt says, we want to be
accessible to non-developers as well, to designers and
people who might get scared off by links through to all
that stuff.
So there's arguments for both sides, and this is the way
we've fallen on this argument right now.
MATT GAUNT: Andrew Kelly's asked a question.
In the absence of--
I'm going to answer this one last question.
In the absence of being able to use the Google Maps
Fragment inside an app widget, would you see any problems
using an image from static Google Maps API instead?
I like to link to periodically call location updates show
places of interest nearby.
So Stephan's linked to Android Design in Action next week,
which I believe you guys are covering widgets, Nick?
NICK BUTCHER: That was yesterday.
That went out yesterday.
MATT GAUNT: There you go.
We've already done it.
So what would you say to this?
I personally don't think it's that bad of an idea.
I think dealing with the densities, it might be a bit
of an issue, but I'm sure Andrew can deal with it.
NICK BUTCHER: It sounds doable.
I think I would just be careful about how frequently
you're going to do something like that.
RICH HYNDMAN: And of course, if you're using static images
from Google Maps, make sure you abide by all the relevant
terms and conditions put the copyrights and licenses at the
bottom of the pictures.
We have a static image generator.
NICK BUTCHER: Yeah, no cropping out the cropping.
RICH HYNDMAN: Exactly, no cropping out the logo.
STEPHAN LINZNER: Yeah, but just give it a
try and let us know.
MATT GAUNT: Yeah, it would be cool to find out
what you're up to.
So unfortunately, that is our half hour.
We have steamed through so many questions, it is untrue.
But thank you for joining us and
chatting with your questions.
If you've got any more, then stick them in the Moderator
for next week where we'll be doing another office hours.
NICK BUTCHER: Guiseppe asked where in the comments which
I'm not touching with a barge pole.
MATT GAUNT: Yeah, neither am I.
NICK BUTCHER: How long will it take for Google Air
tickets to sell out?
MATT GAUNT: You tell us.
It depends.
Anyway, thank you, everyone.
STEPHAN LINZNER: All right, guys.
See you next week.
NICK BUTCHER: Bye, guys.
RICH HYNDMAN: Bye bye.
AUDIENCE: Bye, guys.