Office Hours — Today, April 5

Yesterday, April 4

Mark M.
has entered the room
Mark M.
turned on guest access
Daniel B.
has entered the room
Bruce F.
has entered the room
Mark M.
howdy, Daniel and Bruce!
Bruce F.
Hello.
Mark M.
Daniel, you narrowly got in first -- do you have a question?
OK
Daniel B.
Hi Yup. I am using a Loader to populate a spinner, is there a way to know when its finished loading, so that I can decide to hide the spinner if its empty and show a button to add something?
Mark M.
Bruce: do you have a question?
Daniel B.
right now, I am putting code in the onF
Mark M.
Daniel: your LoaderCallbacks will be called with onLoadFinished()
Daniel B.
onLoadFinished, but i think this is not best to do it
Mark M.
why not?
you need that method anyway
to populate the Spinner
Apr 5
7:30 PM
Daniel B.
don't know why I thought it was wrong. So its ok to put UI stuff in onLoadFinished, like changing visibility, or updating ActionBar titles, etc?
Mark M.
sure, that's pretty much the point of that callback :-)
Daniel B.
right, thanks.
Mark M.
Bruce: do you have a question?
Koen H.
has entered the room
Bruce F.
No, I just signed up, I thought I would take a look.
Mark M.
ah, OK
Koen H.
Hello!
Mark M.
this is mostly for Q&A
howdy, Koen!
Koen: do you have a question?
Koen H.
Hi Mark. I do have a question, yes.
It's something that's been bugging me for months, and I don't get it fixed:
when I make a backup of my database in my app, it never backs up ALL of the records!
Mark M.
how are you making the backup?
Koen H.
eum, 2 seconds, wait
Mark M.
that's a mighty long two seconds :-)
Koen H.
View paste (8 more lines)
    public void backupDataBase() throws IOException{
    	//Open your local db as the input stream
    	InputStream myInput = new FileInputStream(new File(DatabaseHelper.DB_PATH + DatabaseHelper.DB_NAME));
 
    	// Path to the just created empty db
//	    String outFileName = Environment.getExternalStorageDirectory() + "/" + myContext.getResources().getString(R.string.backup_dir) + "/" + String.format(DB_BACKUP_NAME, Calendar.getInstance());
    	FileUtil.makeDirectory(myContext, "Backup");
	    String outFileName = Preferences.GetRootDirectory(myContext) + "/Backup/" + String.format(DB_BACKUP_NAME, Calendar.getInstance());

    	//Open the empty db as the output stream
    	OutputStream myOutput = new FileOutputStream(outFileName);
 
    	//transfer bytes from the inputfile to the outputfile
    	byte[] buffer = new byte[1024];
    	int length;
...
scottt
has entered the room
7:35 PM
Mark M.
is your database closed at the time?
scottt
greetings
Mark M.
(btw, howdy, scottt!)
Koen H.
That's the question I've been asking myself a 1000 times ... I "think" so.
But I'm not sure, as there is a contentprovider on it
Ron T.
has entered the room
Ron T.
Hello to all!
Mark M.
well, you rarely close a database with a content provider by default
Koen H.
and sometimes I think that contentprovider is keeping the connection open
Mark M.
(btw, howdy Ron -- you are behind scottt in queue)
Koen H.
so, how should I fix this?
Mark M.
you would need to come up with some out-of-band communication to the content provider, indicating "yo, please close the DB" and, later perhaps, "yo, you can reopen the db now"
you would need to make sure you have no outstanding Cursors from that content provider as well
Koen H.
but how can I let the contentprovider now that he has to release the db?
Mark M.
what is your minSdkVersion?
Koen H.
4, but 7 is ok for me too
Mark M.
yeah, I was aiming for 11, when call() was added for this sort of thing
Koen H.
hmm
Mark M.
here are two choices:
1. hack it into the existing API (e.g., query() on some magic Uri is the close-the-db command)
2. since a ContentProvider is a natural singleton, stick a reference to it in a static data member, and call your own custom method on it
Koen H.
ok
Mark M.
with an eye towards perhaps migrating to call() in, say, late 2013
Koen H.
and once in the contentprovider, how do I close the db?
7:40 PM
Mark M.
call close() on it
Koen H.
ok
Mark M.
try that and see if it helps
Koen H.
ok, tx, I'll give it a try
would it help
Mark M.
it is conceivable that you are doing a backup mid-transaction or something
Koen H.
if I use the loaders?
Mark M.
well, anything that's a separate thread than your backup code
scottt: your turn -- do you have a question?
scottt
just lurking today, thanks. with all these participants, it's looking like a good day to watch.
Mark M.
yeah, it's quite the party today
Ron: do you have a question?
Ron T.
I've successfully built an activity with the WebView. The .loadUrl works fine and loads up my web page. I have orientation logic in the onPause and onDestroy to issue .stopLoading so that the subsequent onCreate reloads everything. I have a Web Client so that I can display spinners as the loading occurs. All that works fine. I have another Activity with a menu item that issues an intent to load the standalone browser with another URL. That works fine as well but... I noticed that an orientation change in the standalone default browser redraws the page instantaneously whereas my WebView activity has to recall the .loadUrl. Is is possible for my activity using the WebView to handle orientation changes as fast as the standalone browser?
Mark M.
keeping your same WebView across the orientation changes would help
not sure if it is a complete solution
that's something I need to do some experimentin' on myself
Ron T.
Doesn't it all get destroyed?
Mark M.
well, that depends on how you do it
normally, yes
are you using fragments, by any chance?
Ron T.
No, the app is targeted to 2.2
Mark M.
well, that wouldn't preclude fragments, via the Android Support package
but, regardless
Ron T.
Yeah, I just read about it over the weekend.
Any tips to point me in right direction?
Mark M.
the caveman approach is to use android:configChanges="orientation|keyboardHidden", and to handle all configuration changes yourself
Ron T.
Yeah, I read about that too!
7:45 PM
Mark M.
a slightly more sophisticated approach, though potentially dicey, is to remove the WebView from your old activity's layout, returning the WebView from onRetainNonConfigurationInstance(), and attaching it to the new activity's layout
I have not tried this
Ron T.
I'll research it and see what I can come up with.
I just wanted to make sure it wasn't something simple I had missed. Thanks!
Mark M.
this stuff is covered in the rotation chapter in _The Busy Coder's Guide to Android Development_
and a mostly rewritten chapter on it will appear in the next Omnibus update
Daniel: do you have another question?
Ron T.
I will look there. That is all I have for tonight. I'll observe for awhile
Daniel B.
Hmm yes
Iam using the ActionBar, and have several tabs, which when clicked display a different fragment. But once the screen rotates, the tab goes back to the first one, and when you click any of the other tabs, the contents do not change. Any reason why this is?
Mark M.
I have no idea
I have not seen that problem
Daniel B.
so if I was selected tab 2, and rotated the device, its back on Tab 1, with content from Tab 2, but clicking Tab, 1 or 3 don't change it.
Mark M.
it sounds like your FragmentTransactions are getting a bit messed up somehow
Daniel B.
don't really wish to disable rotation if I can avoid it
Mark M.
in terms of the selected tab, you may need to track that yourself via onSaveInstanceState()
and restore it in onRestoreInstanceState()
also, bear in mind that Android will automatically restore any fragments you have in your activity during a configuration change
7:50 PM
Mark M.
in theory, if the tab is the right one and the content is the right one, everything should then work after the configuration change
Daniel B.
right so track what tab was selected in saveInstanceState, and restore it on restore?
Mark M.
right
Koen: do you have another question?
Koen H.
not immediately ... :)
Mark M.
OK
if anyone has a question, chime in
Daniel B.
is the same approach used to restore what tab is selected on activity resume? after displaying another activity and returning to it? (sorry to butt in)
Koen H.
yea, have one :)
ok, I'll wait, no prob
Mark M.
Daniel: if needed, yes
Koen: go ahead
Koen H.
ok, suppose I want to enable extensions/plug-ins in my note-app ... what would be the best approach?
Mark M.
that's impossible to answer in the abstract
and I don't know if the "state of the art" is refined enough to specify a "best approach"
Koen H.
I thought so ... but any directions where I can read more about it?
Mark M.
well, I discuss a couple of plugin approaches in _The Busy Coder's Guide to Advanced Android Development_, in the "Integration and Introspection" chapter
I am not aware of too much written on the subject
Koen H.
I saw that :) but I'm not there yet :)
7:55 PM
Mark M.
and I plan to expand my coverage later this year
the chapters in the Advanced Android book, on the whole, can be read out of order
Koen H.
ok
scottt
not a question, but I'm getting really excited about next month's AndDevCon. I'll finally get to see Mr CommonsGuy present live (as opposed to just hear)
Mark M.
well, for all you know, it could be my robot stunt double
Koen H.
:)
Mark M.
but, yes, AnDevCon III should be good
excellent set of presentations
scottt
that might be OK. robots are cool. so says my LEGO robot addicted 7yo
Koen H.
one more Q: do you know how I could put an activity on top of the caller-window, without blocking access to the buttons in the caller?
Mark M.
Koen: that should be impossible
only one activity can have the foreground input, and that will be whatever is on top
you can create an activity that *shows* the buttons of the other activity, but they will be untappable
Koen H.
and how does an app like Thruttle (the name might not be correct) do it?
Mark M.
read the Tapjacking chapter in the Advanced Android book
and note that it is now somewhat limited on Android 4.0
Koen H.
they overlay the caller with small dialogs, and you can still tap the caller buttons
Mark M.
(thank heavens)
scottt
i heard about a couple of apps (when listening to a recent All About Android podcast) that do some sort of minimal windowing.
Mark M.
they are using the same technique as outlined in the Tapjacking chapter
Koen H.
http://thrutu.com/ (that's the correct name)
8:00 PM
Mark M.
yes
that's not an activity, or a dialog
it's a system alert window
Koen H.
aha
Mark M.
and, pre-ICS, Thrutu (and anyone else using this technique) can spy on everything the user does
hence the term "tapjacking"
Koen H.
so to get a system alert window, you have to use the tapjacking method?
Mark M.
the system alert window enables tapjacking
Ron T.
has left the room
Mark M.
if anyone has any questions, chime in
8:05 PM
Daniel B.
Is there a way to generate a second field in a listView that comes from another query? And is it possible to give your listView column headings?
Mark M.
taking your second part first
the only simple way to do that is to fix the sizes of your "columns" and have some TextView labels *outside* the ListView as the headers
I seem to recall seeing some blog posts where people had cooked up a more sophisticated mechanism that did not require fixed-width columns, but I do not have a reference handy
in terms of the rows in the ListView, you can put in them whatever you want
Daniel B.
so say I wished to grab a list of all categories, then in the same item of the list view in another textview I have result of a query that displays number of items in that category? its possible to do that?
Mark M.
sure
Daniel B.
how would I go about that?
Mark M.
most likely, you will have to subclass your adapter and take over row constructions
based on the position, part of your data is in your adapter and part of your data is somewhere else, that you would have to look up by one means or another
and, in your overridden getView() or bindView(), you would update the widgets as needed
8:10 PM
Daniel B.
Ok thanks I'll look into it.
8:15 PM
scottt
i apologize if i missed this in the newsletters, but about this omnibus book, is the idea to combine _all_ of the books, and just have one going forward?
Mark M.
yes
scottt
i think i like that better. it'll be easier to keep track of updates. especially with change bars
Mark M.
yup
basically, I'm optimizing for digital, whereas before, I was effectively optimizing for print
scottt
i remember you mentioning a disagreement with apress about a premature ICS update...
Mark M.
yes
I am no longer involved with _Beginning Android_
scottt
is this a way of moving away from them permanently
(nm, i typed too slow)
Mark M.
well, most of my "optimization for print" was for the other books
Koen H.
has left the room
Mark M.
I can't print _The Busy Coder's Guide to Android Development_ as an introductory text
scottt
"can't"? part of the previous agreement with apress?
Mark M.
correct
8:20 PM
scottt
i saw somewhere that you do onsite training. how's that part of your biz going?
Mark M.
it is doing OK
runs a bit hot and cold
scottt
i've been doing mostly tutorials for meetups lately. it seems to draw in the attendance
Mark M.
that makes sense
scottt
former coworkers keep telling me to start offering them as part of my biz. i could do the introductory stuff, but would need to have someone else to hand-off the more advanced stuff to
Mark M.
the key is sales
which is why I tend to partner with existing training firms who have sales forces
8:25 PM
scottt
i've had a couple contact me. i'm not so interested in traveling to do it, so it pretty much kills their enthusiam
Mark M.
yeah, on-site delivery is pretty important for most corporate customers
scottt
yeah. the tampa tech community is pretty vibrant, but prob not enough to sustain a fulltime training biz
Mark M.
well, if you all don't mind, I would like to close the chat a bit early, as I am decidedly under the weather
next one is 10am Eastern on Tuesday
Daniel B.
Thanks :) I'm going now anyway.
scottt
np. take care
Daniel B.
has left the room
Mark M.
have a pleasant evening, all!
Bruce F.
thank you
Bruce F.
has left the room
scottt
has left the room
Mark M.
turned off guest access

Yesterday, April 4

 

Office Hours

People in this transcript

  • Bruce Forkush
  • Daniel Bell
  • Koen Hoorelbeke
  • Mark Murphy
  • Ron Thomas
  • scottt