Office Hours — Today, March 26

Thursday, March 21

Mar 26
9:50 AM
Mark M.
has entered the room
Mark M.
turned on guest access
10:00 AM
Carlos
has entered the room
Carlos
Hi Mark
Mark M.
hello, Carlos!
how can I help you today?
Carlos
View paste

	* Situation: I have a custom ArrayAdapter who's row has a checkbox and a textview. Currently I implement onListItemClick() in the ListFragment and I have a listener for the checkbox inside the custom ArrayAdapter.
	* Question: What's the best approach to implement a listener for the checkbox?
	* 
		* The way I've been able to persist the checked/unchecked state in my data model is by having a private copy of the context (initialized in the adapter's constructor) and then using my Application context as follows:


                    MyObject temp = new MyObject(original);
                ((MyObjectApplication)mContext.getApplicationContext()).updateItem(temp);

	* The above solutions feels like a hack.  Is my solution acceptable or there is a way to implement a checkbox listener in the ListFragment just like onListItemClick?
Let me know if paste is not showing all the details.
Mark M.
do you absolutely need to treat row clicks to be different than checkbox toggling?
most lists have those operations be identical
some do not (e.g., Gmail conversation list)
Carlos
In my case, I'm using checkboxes differently from, for example, Gmail app
Mark M.
that did not really answer my question, though
Carlos
a checked checkbox means the item is completed/done and I want to be able to track that state in my data model
Jose L.
has entered the room
Mark M.
then what does onListItemClick() do differently than that?
(BTW, hello, Jose -- I will be with you shortly)
Carlos
onListItemClick is used to captured when a row is clicked so the user can edit details for that row
Mark M.
OK
10:05 AM
Jose L.
Hi guys, no prob!
Carlos
I tried to use onListItemClick for checkbox events but it didn't work for me
Mark M.
Carlos: the pattern I used in the Selection/RateList sample in the book updates a model held onto by the activity
this happens to use a RatingBar, but the same principle would hold for a CheckBox
unless you are putting your data model in a custom Application for other reasons, I definitely would not do that for just managing checked states
Carlos
Cool. I'll check your sample. I have another question, but I'll look at your code while you answer Jose's question.
Mark M.
that sample is in the book, in the Advanced ListViews chapter
OK, Jose: do you have a question?
Jose L.
Yes, I do
Mark M.
Jose: go ahead with your question
Jose L.
well, first I would like to introduce myself, you know my name already :) I started learning android 3 years ago and started working full time as an android dev 2,5 years ago here in Holland
now, the question
I have some issues with the media player
while streaming audio
Mark M.
I have limited experience with that, but I can try to help
10:10 AM
Jose L.
at some point on some devices (user complains, mainly) streaming just stop
non of the listener methods are trigegred
triggered
onerror
or something like that
it just stops
the less memory the device has, the sooner it happens
I have the media player running in a service which is started on foreground
I'm also setting this: getMediaPlayer().setAudioStreamType(AudioManager.STREAM_MUSIC);
and just setting the streaming url like this: getMediaPlayer().setDataSource(streamUrl);
so all the downloading and stuff it's handled internally by the MediaPlayer
Mark M.
all I can say is: welcome to MediaPlayer
Jose L.
I've done a prototype of the app which downloads the streaming to disk and plays from the local storage but I would rather have the media player working "natively"
Mark M.
MediaPlayer has a history of strange things like this
Jose L.
haha I know
10:15 AM
Mark M.
other than researching online or asking on StackOverflow, I do not have much in the way of advice
other than light testing of streaming, I have only used MediaPlayer for local content
I am sorry that I cannot be of greater assistance with MediaPlayer
I will be back with you shortly for another question, after I have taken another from Carlos
Carlos: do you have another question?
Jose L.
no problem, thanks anyway :)
Carlos
Mark, I review your code and it is similar to what I did :)
In my case, I did the adapter in a separate java file, but I'm basically doing what you are doing. I thought there was a better way so the adapter is not that coupled to Fragment, but anyways adapter is sort of couple to fragment implementation.
Mark M.
be careful with your row recycling, though
Carlos
My other question...
This is how I'm recycling the rows:
View paste (14 more lines)
if (view == null){
            String inflater = Context.LAYOUT_INFLATER_SERVICE;
            LayoutInflater li = (LayoutInflater)getContext().getSystemService(inflater);
            view = li.inflate(R.layout.tasks_list_row, parent, false);

            if(DEBUG) Log.d(TAG, "The holder is null");
            // cache view fields into holder
            holder = new ViewHolder();
            holder.title = (TextView)view.findViewById(R.id.taskTitleText);
            holder.isCompleted = (CheckBox)view.findViewById(R.id.taskDoneCheckBox);

            // associate the holder with the view for later lookup
            view.setTag(holder);
        }
        else{
...
Mark M.
my concern is your task variable/data member
10:20 AM
Mark M.
task.setCompleted(true); and such
I do not know where that is coming from
Carlos
I think I can remove that. I had that from one of my failed attempts to update listview data model
Mark M.
OK
just make sure that you are working with the correct model object
Carlos
It is meaninless than after I was able to get the application context and call "upateItem"
thanks for the hint on that. I forgot to remove that code
My next question had to do with AlarmManager and Intent services
Mark M.
OK
Carlos
I'm working on some task/calendar functionality and want to implement reminders.
I was reading that chapter from your book and initially it seem AlarmManager/IntentService was the way to go, but then you introduced your Wake-type implementation.
Mark M.
if you want to use a _WAKEUP alarm, you need WakefulIntentService or something like it for your results to be reliable
Carlos
Not sure if for my implementation I need to keep the phone wake. The context is this: I sent the reminder to the AlarmManager and when the due date is met I want to invoke a notification in the system bar.
So I don't really need the app to be fully running, but to just submit the user notification
Mark M.
if your "invoke a notification in the system bar" logic will be fast, you can do that just from your onReceive() of a BroadcastReceiver tied to your _WAKEUP alarm
Carlos
Based on this I know I need to do wake, but not sure if invoking the notification will take longer than onReceive
Mark M.
notifications themselves are fast
10:25 AM
Carlos
ohh ok. Awesome. Thanks for the confirmation.
Mark M.
however, if you are doing database I/O or something, that's another matter
Carlos
BTW, does your WakefulIntentService works with IntelliJ? Your commits say it got updated for Eclipse, but I coudlnt' get the sample to work because Intellij was not taking your *.jar.
Mark M.
I do not use IntelliJ
however, I have no idea why the JAR would not work
it should be no different than any other Android-aware JAR
what does "not taking your *.jar" mean?
Carlos
ok. Yeah, I haven't fully migrated to Intellij so it should have been a mistake on my part.
Ohh. I meant after creating the import library (like I do with ABS) the Wakeful class was not recognized in the receiver code.
I'll try again tonight.
Mark M.
Jose: do you have another question?
Jose L.
well
I was going to ask something related to the previous topic
but it's not something android-specific, is more java thing
Mark M.
you can ask -- whether I can help is another matter :-)
OK
Jose L.
so I did this prototype that downloads the streaming content and plays it from the local storage
10:30 AM
Jose L.
so my question is, how should I do it
if I don't want that cache to grow forever
Mark M.
you could kick off an IntentService to clean up old cache files, for some likely definition of "old"
whether you do that just on first run, or you do it every day via AlarmManager, or some other pattern, would be up to you
or, as you download new files to cache, you could find and clean out older files, or files that exceed some total amount you want to cache
Jose L.
yeah, well, that's not the case I meant
Mark M.
sorry -- what do you mean?
Jose L.
the use case I mean is (pretty extreme tho) is that the user clicks play
and leaves it like 3 days running
I would be downloading the streaming for 3 days
Mark M.
are you downloading chunks to individual files, or are you trying to read from one long file that you continuously write to?
Jose L.
the latter
yes
10:35 AM
Mark M.
other than "don't do that", I am not sure that you have other options
Jose L.
because I've checked some internet radio streaming apps and you can leave them running almost "forever"
Mark M.
when that file gets to some size, you are going to need to switch to another file, just so you can delete the first one
Jose L.
I mean, I don't know if it's even possible to keep writing on one file on one end and deleting bytes from the beginning, queue-like thing
Mark M.
not with a file
you could switch to using a ContentProvider, perhaps
Jose L.
and how could that work?
Mark M.
a ContentProvider can, in effect, publish an OutputStream to MediaPlayer
where that OutputStream is one you would write to with your incoming data
rather than writing to a file and having MediaPlayer read from the file
Jose L.
sorry I ask this funky questions, but I have been struggling with this thing for a long time and I don't know what more can I do
Mark M.
then, other than in-flight memory buffers, nothing is retained after playback
you can see samples of such "pipe" providers in my book, in the ContentProviders chapter
and I think my book's coverage of media shows using it for media playback
Jose L.
so I would have my background task pushing bytes to the content provider
Mark M.
more likely, the ContentProvider itself manages the background task
Jose L.
awesome, I will give it a try definitely
Mark M.
the difficulty with media playback is that for some file formats, MediaPlayer wants to rewind the stream, which is not possible in this case
hence, it will limit your available codecs, IIRC
I seem to recall that I covered that issue in the book as well, in the audio playback chapter
10:40 AM
Jose L.
yep, also, the third party providing the audio streaming is using (for whatever reason) a video format for the audio stream
which is causing more memory issues
(I think)
Carlos
has left the room
Mark M.
I am not sure what you will be able to do about that
Jose L.
I can't do anything, I know
I will check those chapters of your book definitely, thanks
I have to say that I bought it last week, so I didn't have the time so far to read it all
Mark M.
it is a bit long :-)
Jose L.
haha, that made me laugh out loud
"a bit"
xD
well, don't want to waste your time anymore
thanks a lot Mark
Mark M.
you are very welcome
Jose L.
I will be attending this chats whenever I can, if not to ask, to learn
Mark M.
you are welcome to do so
Jose L.
thanks
Mark M.
the number of attendees and questions varies
Jose L.
I can image
well, thanks, again, and keep up the good work!
^^
Mark M.
thanks!
10:55 AM
Mark M.
any last questions?
Jose L.
not really
thanks!
see you next time
Mark M.
the transcript will be posted on http://commonsware.com/office-hours/ shortly
the next office hours chat is Thursday at 4pm Eastern Time
have a pleasant day!
Jose L.
you too
thanks!
Jose L.
has left the room
Mark M.
turned off guest access

Thursday, March 21

 

Office Hours

People in this transcript

  • Carlos
  • Jose Luis Montes
  • Mark Murphy