Office Hours — Today, November 19

Wednesday, November 14

Nov 19
9:55 AM
Mark M.
has entered the room
Mark M.
turned on guest access
Gabriele
has entered the room
Mark M.
howdy, Gabriele!
how can I help you today?
10:05 AM
Gabriele
Hi
I'm using a webviewfragment inside a viewpager, anyway it's not displayed
I don't have the code right now, have you an idea of the reason?
Mark M.
the tutorials in the book use a WebViewFragment inside of a ViewPager
Gabriele
I get a viewpager with a blank page
Mark M.
so it definitely can work
does Hierarchy View confirm that you are actually seeing a WebView?
if so, are you sure that you are telling it to load something?
Gabriele
Can i invite you on my github project?
Mark M.
um, OK
Gabriele
Which is your username?
Mark M.
commonsguy
OK, I am there
10:10 AM
Gabriele
Ok
Mark M.
does the URL in question load in a regular browser on your device?
Gabriele
Yes
I'm also viewing the progressbar working
But the fragment with the webview is not dispkayed
Displayed*
Mark M.
View paste

does Hierarchy View confirm that you are actually seeing a WebView?
Gabriele
I can't check it right now, because i'm from the tablet
10:15 AM
Peri H.
has entered the room
Mark M.
Gabriele: I do not really have a way to help you, sorry
Peri: do you have a question?
Peri H.
Hello.
Yes, returing back to the issue about creating an intent for editing a contact or a calendar event.
It seems, with all good intentions of google, that using external activities is pretty unreliable. That is, if I'm requiring that the activity do a certain thing and directly return to my app, I really can't use external activities. Do you concur?
Mark M.
I would agree with the assessment that if you are "requiring that the activity do a certain thing and directly return to my app, [you] really can't use external activities"
10:20 AM
Mark M.
you seem that the world's developers work for you
sorry, getting hostile
:: calming down ::
in theory, anything supporting startActivityForResult() should do setResult()/finish() without intervening navigation/activities
however, there is nothing obligating a developer to do that
it's even conceivable that there are good reasons for not doing that, on occasion, though I cannot think of any
Peri H.
Ok, then I will write my own contact and event editors. Do you know if it's permissible to copy the google code and use it in my app? (No, I'm not really expecting the world, I'm just trying to take advantage of what I thought google wanted me to do)
Mark M.
so long as you can abide by the Apache License 2.0, you are welcome to copy such licensed code
and AFAIK, contacts should be
haven't looked at the calendar app
Peri H.
Ok, thanks, I'll look at the license carefully.
Mark M.
yeah, calendar appears to be Apache 2.0 as well
now, you will want to change the look somewhat
Peri H.
Yes, Apache is pretty generous, I'll double check. Thanks. Second question ok?
Mark M.
Google may get irritated if they think you are trying to trick users into thinking they are in a Google app rather than yours
I seem to recall there are clauses in the Play Store agreement with respect to that
Peri H.
Good point. Well, I'
Well, I'll change the graphics anyway.
Mark M.
right
which should be sufficient
let me swing back to Gabriele, then I can take another question from you
Peri H.
Cool
Mark M.
Gabriele: do you have another question?
Gabriele
No not for now, thank you
Mark M.
OK
Peri: back to you
10:25 AM
Peri H.
Ok. Do you know if there is a persistent key for calendar events? I'm assuming that _ID is persistent, but don't see any documentation saying such.
Mark M.
beats me
Peri H.
Actually, I should say that calendar_id & _id together are the key.
Mark M.
I haven't looked at CalendarContract
Peri H.
Ok. Fair enough.
Third question?
Mark M.
go ahead -- Gabriele, chime in if you have another question at any point
Gabriele
Yes, I will tell if I need thank you
Mark M.
Peri: go ahead
Peri H.
I'm using a ListView and a CursorAdapter to generate a list of calendar events. Unlike contacts, though, there are an infinite number of them (due to recurring events). So, the cursor is created with a start and end date. You've probably seen apps that automatically expand the list when the user reaches the ends. Ok here's the question:
So, the ListView generates a callback when an end is reached. From that callback my code closes and opens a new cursor (with expanded bounds). Is this ok? In particular, the adapter that fills the list view gets recreated, but it is from the previous adapter and listview that the callback occurred. My code is doing this and appears to be working, but I'd like to hear your thoughts.
10:30 AM
Mark M.
"From that callback my code closes and opens a new cursor (with expanded bounds). Is this ok?" -- so long as it is in the background, it should work
you could consider getting a Cursor just with the next chunk of range and using my MergeAdapter to blend it in with the previous results
(or something based on my MergeAdapter concepts if it will not directly work)
Peri H.
Hmm, I like the idea of a merge adapater - that would avoid regenerating the parts the are already loaded. Probalby don't have time till after my first releast. I'll put it in my notes.
Mark M.
yeah, that's what I was thinking -- it may boost performance some
Peri H.
I don't follow your comment about "background". It's my understanding that the adapter runs a separate thread to fill the listbox. I'm not doing anythiung to affect that. Is that what you're talking about?
Mark M.
the adapter definitely does not "runs a separate thread to fill the listbox"
first, Adapter is an interface and has no actual executable code
Peri H.
Well, something is running asynch. At first when you scroll fast, some entries are grey. They get filled in a few seconds later.
Mark M.
second, responding to getView() has to be done on the main application thread, since it affects the UI
it's not my code, sorry, so I cannot comment on that
Peri H.
Ok, so what were you suggesting by "background"?
Mark M.
your specific adapter implementation might by using AsyncTask for, say, fetching imagtes
background = background thread, in this case
you should not be querying a ContentProvider on the main application thread
that comes before creating your CursorAdapter
10:35 AM
Mark M.
so, for example, an AsyncTask would query the ContentProvider in doInBackground() and set up the adapter in onPostExecute()
or, you could use the Loader framework
Peri H.
Hmm. Seems to work fine creating the cursor in the app thread. I have 700 contacts and it shows the list view (not the contents) almost instantly. I'll try it on the emulator (which is glacial) and see what happens.
10:40 AM
Peri H.
I want to go back and look at the examples. Don't you have one in your book - there's nothing about creating an async task - the cursor is created and the adapter just fills the list view with contacts.
Mark M.
it's a lousy sample
I'll make a note to rewrite it
you are (indirectly) doing disk I/O on the main application thread
which is not recommended
Peri H.
Ok, I'm warned. I'll do some research. Thanks.
Do you have time for a publishing question?
Mark M.
go ahead
Peri H.
My app uses a db. It seemed that to make the db safely persistent that it should not reside in the app's private space. So, I put it in a new folder under getExternalStoragePublicDirectory() returned path. I realize that, now, anyone can see the files (though they could anyway, if the "root" their device). Do you think I made a reasonable decision?
Mark M.
I have no idea what "safely persistent" means
internal storage works just as well, if not better, than external storage for databases
10:45 AM
Peri H.
That means, if I change the app name or provide multiple versions (one free, some not) they can all access the same db. The db won't become hidden if I need to change the app name.
Mark M.
well, you can't change the app name, except by publishing a completely different app
you are welcome to put the database on external storage, but, as you note, there are issues
Peri H.
Ok, so maybe I need to understand a different way to allow multiple versions of my app to access the same db. You don't have to take the time to explain this to me, but if you know what I should search for to read-up, please say so.
Mark M.
there is only one *version* of your app on the device at a time
if you have multiple *flavors* of your app (free vs. paid), they need to sync, not share
after all, if the user uninstalls the app that holds the database, all dependent apps are screwed
Peri H.
What does "sync" mean in this case?
Mark M.
the simplest would be "copy the data on first run of the newer app, and then have totally separate databases"
the most complex would also try to mirror all changes after that initial copy
Peri H.
Oh, I'm sure I don't want to do that. Eventually, I'll have a cloud db and sync to that, but I'm not ready for that for a while.
Mark M.
now, if your apps are truly dependent (e.g., host-and-plugin), having them all use one central DB via a ContentProvider is fine
but if the apps are logically independent, their data needs to be logically independent as well
10:50 AM
Peri H.
So, I'll use a central db. Users will be putting their "important" data in the db and I don't want to do something that makes it easy to loose it - such as uninstalling and then reinstalling the app.
Do you know of a way to protect the db from prying eyes?
Mark M.
by definition, this is impossible
even if you encrypt the database, the prying eyes will get the encryption key out of your app
Peri H.
ok. I'll live with that for now. When I have a cloud server, that problem will go away.
Mark M.
(BTW, I am assuming that by "prying eyes", you mean the user)
Peri H.
Well, more specifically, I would like to hide the schema from other people.
Mark M.
if "other people" can download and install the app, they can get to your schema, given sufficient interest in doing so
Peri H.
Yes, I agree with you. Unless I were to encrypt the whole thing with a user-supplied key. Doubt I want to go to that trouble and overhead.
10:55 AM
Peri H.
Well, Mark, that's all I have for now. I really appreciate your feedback. Working on my own as a newbie, it's hard to know when I'm missing something obvious. Thaks again.
Mark M.
you are very welcome
Peri H.
has left the room
Mark M.
and you're certainly not a newbie at this juncture
Gabriele: the chat is nearly over -- any final questions?
11:00 AM
Mark M.
OK, that is a wrap for today's chat
next one is 4pm Eastern tomorrow
have a pleasant day!
Gabriele
has left the room
Mark M.
turned off guest access

Wednesday, November 14

 

Office Hours

People in this transcript

  • Gabriele
  • Mark Murphy
  • Peri Hartman