Office Hours — Today, September 1

Monday, August 23

Sep 1
7:55 PM
Mark M.
has entered the room
Mark M.
turned on guest access
David
has entered the room
Mark M.
howdy, David!
8:00 PM
David
Hi, I have general questions.
Mark M.
hopefully related to Android application development!
David
To test with a real android device, what do you recommend?
I mean to test Android apps.
Mark M.
ummm...something that works with your choice of carrier
are you in the US, or elsewhere?
David
I am in Dallas, TX
Mark M.
definitely pick something that works with your carrier, then
at least for your first device
David
Is unlock required?
Mark M.
if you get others and use them as WiFi only, that's cool, but it stinks to get a phone and not be able to use it as a phone
carrier unlock, no
however, depending on device/carrier, you may need a data plan, at least to get the phone set up
if your carrier uses SIMs (T-Mo or AT&T), you can borrow a SIM from somebody long enough to get the phone configured, then switch to a SIM without a data plan
David
It sounds like I don't have to buy Android Dev phone or Nexus one for development. Correct?
Mark M.
no, unless you are writing custom firmware
David
I see.
Is there any tool to design graphics for Android?
Mark M.
there isn't really 'graphics for Android'
Photoshop, the GIMP, etc. all work fine for PNGs and such
8:05 PM
David
Then, how custom graphics are integrated?
Mark M.
put them in res/drawable/ of your project, and reference them from your layouts or code
David
DroidDraw is primitive.
Mark M.
oh, if you're looking for a GUI editor, then you are out of luck
nothing for Android right now
I expect there will be more solutions over the next 12 months
David
I see.
I wonder how other developers did for graphics.
I guess this is enough for today.
Mark M.
OK
David
Bye
Mark M.
have a pleasant evening!
8:10 PM
Khye
has entered the room
Khye
hello
Joe
has entered the room
Mark M.
howdy, Khye!
and howdy, Joe!
Joe
Greetings!
Well now, them 37signals folks make nice web apps. :)
Mark M.
Khye: you ducked in first -- do you have a question?
Julius
has entered the room
Khye
I do
Mark M.
Khye: go ahead (and, howdy, Julius!)
Khye
I have an app that th emain activity displays a character while you play a game. A user can launch a subactivity from th emenu which reveals a character list
Julius
(hi Mark - and everyone)
Khye
one of the context menu options from this list is to pick a portrait for the character
so it is possible for a user to change a portrait for the character that is already loaded in the main app, but they use the back button to get back there instead of picking the character from the list. How to I tell the main app that the character is dirty and needs to update?
Mark M.
I have no idea
Khye
Main App->List Activity->Portrait Activity
8:15 PM
Mark M.
in principle, you have Portrait Activity update your model, and have Main App have some sort of registered interest in changes to that model
implementation details vary
they vary by storage (database? flat-file backed by in-memory objects? something else?)
they vary by mediator (Service? Application? Singleton? something else?)
Khye
can you elaborate on registered interest
Mark M.
take SharedPreferences, for example -- you can register an OnPreferenceChangedListener to be notified when the preferences change, and which key was changed
Khye
Sure, Ok.
Mark M.
for your model, if your mediator is a ContentProvider, MainApp would register interest via the ContentResolver in the Uri of the, um, character
if your mediator is a Service, MainApp would register some sort of callback or listener object with the Service, and the Service would notify MainApp via the listener when a character of interest changed
and so on
let me take questions from others, and we can swing back to you if you want to discuss this further
8:20 PM
Khye
ok
Mark M.
Joe: do you have a question?
Joe
Sure do! [starts typing] ...
In my app, I have a need to select a contact, and then one of their emails or phone numbers. (So far, so good.)
I have an Activity extending ListActivity ...
Evan
has entered the room
Evan
hi everyone!
Julius
(hi Evan)
Joe
Because the app must also support SDK Version 4, I check for newer or 1.6-era support ...
Then I kick off an ACTION_PICK intent to grab a contact. NOW ...
Here's where I start to get hazy. In onActivityResult, I get a result (data.getData()) … then I get the last path segment, and then I want to show that contact's phone numbers and email addresses, and pick one. Do I have to brute force it, making two cursors, walking the results, and then stuffing those into an ArrayAdapter? Or is there a more expedient way I should be using? (I feel like I'm making it more complicated than necessary.)
Mark M.
well, if nothing else, you can wrap the two Cursors each into an adapter, then combine those with my MergeAdapter
there might be a query you could use to get both types of data in one shot, but I'm skeptical
8:25 PM
Joe
That's what I was hoping, but maybe not.
But it sounds like MergeAdapter can give me a single list of items to choose from, is that correct? (So I'd use that as opposed to an ArrayAdapter.)
Mark M.
yes, it gives you a single adapter concatenating the two other adapters
Joe
… and then for THAT onActivityResult, I grab the result text and go to town.
Fantastic. I'll give it a try - thanks! (If that's in the books, my apologies - haven't reached that section just yet. :) )
Mark M.
or you use MergeCursor from the SDK, though that can get a bit tricky if the Cursors are substantially different
no, I don't think MergeAdapter is in there presently -- it's just one of the CommonsWare Android Components (CWAC)
Joe
That's another part I'm still wrestling with. The cursors. Email is easy enough:
View paste
cursor = getContentResolver().query(Email.CONTENT_URI, null, Email.CONTACT_ID + "=?", new String[] { id }, null);
Phone numbers … seem to be … different. Or I'm just misreading the SDK.
Mark M.
ContactsContract is byzantine
Joe
(CWAC - got it.)
Ooh, good word to describe it. :)
I thought it was just me.
Mark M.
and since I just flew through Istanbul, I can speak with some experience on byzantine... :-)
Joe
Excellent.
Mark M.
OK...Julius: do you have a question?
Julius
yes :)
View paste
I am receiving "database is locked" errors from time to time. I use the following process to access the database
		mReadableDb = new XXXDbHelper(this).getReadableDatabase();
I find it hard to replicate this error. I looked at your approach to accessing a database in the latest version of tutorials and saw you have something that looks like:
	helper = new XXXDbHelper(this);
and then use "helper.getReadableDatabase();" when you need to use the database. I don't really understand why I get the "database is locked" issue and I am having trouble replicating it so I'm not sure if this would help but I thought it might. Without being able to replicate the issue consistently I thought I'd ask whether the former approach (reusing mReadableDb) might create the possibility of locks occurring.
heh
uh I composed it just while watching
didn't expect it to be a paste
Mark M.
that's ok
I used to do what you're doing now
Julius
(that's where I got it from)
Mark M.
I switched to getting the database from the SQLiteOpenHelper every time you need it
Julius
:)
8:30 PM
Mark M.
for one, it'll upgrade the database from readable to writable as needed
8:30 PM
Julius
and it seems you only have to close the helper
Mark M.
correct
Julius
oh yeah
that's nicer
Mark M.
I too was running into sporadic errors otherwise, though I don't recall it being "database is locked"
anyway, I'd definitely give that a try to see if it helps
Julius
great - I have another question but will wait to see if there is time - it's less critical
thank you
Mark M.
OK
Evan: do you have a question?
Joe: do you have a question?
Josh G.
has entered the room
Mark M.
Khye: your turn again -- need any followup, or have an additional question?
(and, howdy, Josh G!)
Khye
yes
Josh G.
Howdy. /me raises his hand
Khye
it relates to teh first
8:35 PM
Khye
when I context click the list view
it launches the portrait activity and then returns teh portrait
David
has left the room
Khye
the character id isn't in the view, so I can't query the selectedItem getView
I'm phrasing this as poor as possible
Is there any way to populate a hidden variable in a view
in the way that HTML has a hidden form element
Mark M.
there is setTag() and getTag()
they let you attach an arbitrary object to a View
then get it back later
Khye
thanks. I remember reading about those in your book.
I'll take another look.
thanks
Mark M.
Joe: got a question?
actually, Josh joined late...Josh: do you have a question?
Joe
Sure! More of a reality check … I was searching for more info on our byzantine friend, ContactsContract. Found this: http://www.higherpass.com/Android/Tutorial… … wow, you weren't kidding. Does that, more or less, make sense as a plan of attack? (To extract the phone #s and emails post-1.6?)
Evan
so I'm nearing the final stages of an Android app I'm developing, and there are a few things I'm stuck-on that I haven't been able to find answers to anywhere…
Mark M.
Joe: yes, that should be OK
Josh G.
Yes, thanks. I was wondering the best way to detect one's own phone number. I read that there are a couple of different ways but that some of them didn't work in the emulator. (In fact, one of the responses I saw was from you but it didn't have a specific answer.)
Mark M.
Evan: go ahead -- sorry, missed you too
Joe
thx!
8:40 PM
Evan
thanks Mark, that's okay... mainly i'm finding myself wrestling with getting widget focus to propagate properly
and i can't for the life of me find some good information on strategies to get it working right in complex UIs
Mark M.
Josh G: not sure there's a good way to do that -- getLine1Number() is unreliable
Evan: usually, focus "just works"
Evan
i essentially have a linear layout (at the top level) with several widgets containing focusable child widgets...
heh
i feel like I'm fighting the platform!
for instance, one of the widgets is a gallery (that I really want to just treat like a horizontal listview)
Josh G.
I was afraid you'd say that. I guess I can try that and if it generates an exception, prompt the user.
Mark M.
Evan: I haven't used Gallery much, but it wouldn't surprise me if that had focus issues
have you used android:nextFocusDown and so on to help control the focus order?
Evan
i've tried that...
but with Gallery, I find it will focus the item in the list that is closest vertically beneath focused item above it (when propagating focus down)
(instead of the center item, as I would have expected)
Mark M.
actually, closest vertically would have been my guess
but, android:nextFocusDown isn't letting you override it?
8:45 PM
Evan
is there no way, as the gallery, to intercept the attempt to set focus on one of its child widgets (in the spirit that the parent--i.e. the gallery--manages the state of its child widgets? :-/)
no... I set nextFocusDown to the id of the gallery (container) widget, but it always focuses the wrong child widget instead
Mark M.
sounds like a bug in Gallery, then
Evan
i was afraid of that...
Mark M.
I do not know of a way to "intercept the attempt to set focus"
well, short of subclassing and overriding onFocusChanged()
but that only tells you when you gain or lose focus
Evan
actually--that reminds me of something interesting. I did try that, and the method actually does not get called. Yet I can propagate focus directly from a widget above the gallery to a child widget of the gallery
Mark M.
BTW, Josh, the issue with getLine1Number() isn't exceptions, it's invalid data -- my SIM will report a value for getLine1Number() which was the original phone # associated with my account, before I ported a previous number over
Evan: Gallery is a complicated beast, so I won't be surprised if there are focus-related bugs or at least under-documented effects
8:50 PM
Mark M.
we're running low on time -- anyone have any other questions?
Evan
that's just the first of many issues I'm fighting to get the gallery to do the way I want. I think I'll just write my own...
Julius
yes
should be quick
:)
View paste
I have a list which is accessing images on the (an) SDCard. The thing is that some rows have images (most) but the odd one doesn't. So I check for these currently using something like this:

String filename = getFilenameUsingCursorAndDisplayDensity(c,dd);

ImageView iv = getYYYImageView();
	if(null!=iv) {
		File yyyFile = new File(filename);
		if(yyyFile.exists())
			// show file
		else
			// show default

I'm wondering how to make this more efficient so the list isn't too jerky. It's not really bad, but it could be better and it shows up when fast scrolling.
Evan
does anyone know where I could start to look for resources that would help me develop a touch-magnifier (so that the area under the user's finger is enlarged somewhere else on the screen?)
Josh G.
Thanks Mark. I can still use that info to route around the issue.
Julius
(evan cool idea)
Evan
to allow for the otherwise-enormous pointing device of a finger to more precisely affect small widgets?
Mark M.
Evan: personally, no
Julius: are the images having to be scaled?
usually, loading images off of disk isn't too jerky
Julius
oh perhaps they are being scaled... not intentionally
I'm using:
Mark M.
you might want to play with Traceview and see where the time is being spent
Julius
iv.setImageBitmap(BitmapFactory.decodeFile(filename));
yes I've tried that a bit and haven't fully got to grips with it
I'll give it a go
8:55 PM
Julius
(I was hoping not to scale which is why I check for the display density)
Mark M.
it's just tough for me to judge what might be causing the jerky behavior
Julius
so I store the files based on display density and how they're going to be used
np
I'll have a look at traceview
thanks
bye all
Julius
has left the room
Mark M.
any last questions?
Joe
I'm good - thanks!
Josh G.
Not currently, thanks!
Khye
Mark, what would be your cutoff, in size, of moving a database from the phone to a remote server
Mark M.
um, I don't usually think of that in terms of size
it belongs on the server if the database will be used places other than the device (e.g., Web app)
Khye
or if it is updated often
Mark M.
now, a question of whether it belongs on on-board flash vs. external storage would be a closer comparison, IMHO
9:00 PM
Mark M.
I'd get nervous if the database were over 10MB and you were supporting Android 1.5/1.6-era phones
Khye
Fair enough
Mark M.
in that case, I'd try to house it on the SD card, or perhaps on a server if the SD card lack of security won't cut it
If you're sticking with Android 2.x devices, you can probably creep somewhat higher
and, with that, tonight's office hour is closed
next one is tomorrow morning, and two more next week
have a pleasant evening, all!
Khye
Thanks for your help
Joe
Thanks Mark! You too.
Khye
has left the room
Joe
has left the room
Evan
has left the room
Josh G.
has left the room
Mark M.
turned off guest access

Monday, August 23

 

Office Hours

People in this transcript

  • David
  • Evan
  • Joe
  • Josh Goldsmith
  • Julius
  • Khye
  • Mark Murphy