I noticed with my clean Google Play version of ODK Collect (1.4.7, 1053), running on Android 5.1.1, that setting appearance::month-year or appearance::year in XLSForm for a date question does not do what it is supposed to. In both cases the app shows working month, date, and year spinners. I found this old issue https://code.google.com/p/opendatakit/issues/detail?id=873, issue 873, and it seems like this issue was supposed to have been fixed. Is there anything I am missing?
I noticed with my clean Google Play version of ODK Collect (1.4.7, 1053), running on Android 5.1.1, that setting appearance::month-year or appearance::year in XLSForm for a date question does not do what it is supposed to. In both cases the app shows working month, date, and year spinners. I found this old issue https://code.google.com/p/opendatakit/issues/detail?id=873, issue 873, and it seems like this issue was supposed to have been fixed. Is there anything I am missing?
I will be happy to contribute if only I can find a solution. Here is what I did:
From the current Collect code, I noticed the month and/or day visibility is set by this chunk in DateWidget.java:
This looks a lot like a hack because it is bypassing an API and going after the internals of the java class, i.e. if someone on Android decides to refactor the code and rename the class member something other than mDaySpinner then Collect's code will no longer work. In fact, it looks like something similar happened.
This is where I am getting beyond the bounds of my knowledge and experience. I tried looping through the fields of mDelegate. I can get a field that is mDaySpinner. However, Field.get(Object) gives my an IllegalArgumentException:
java.lang.IllegalArgumentException: Expected receiver of type android.widget.DatePicker$DatePickerSpinnerDelegate, but got java.lang.Class<android.widget.DatePicker$DatePickerSpinnerDelegate>
See
It seems like android.widget.DatePicker$DatePickerSpinnerDelegate is not visible to Collect, so I think I am at a dead end. But I am also not very savvy with this reflect package.
Any help on how to move forward would be appreciated.
···
#########################
Obviously this is a very small piece of ODK Collect, so maybe it is not worth it to try to fix. There are ways around it for survey creators, like single select and integer entry to take place of month and date entry. However, if it is worth it to fix it, then maybe there should be a better solution than using reflect. Perhaps Collect should use a custom set of spinners for year and month or just year. It seems like digging around Android source code with reflect is not the way to go. Perhaps Dr. Sundt has some thoughts as he was the person to contribute the current code for DateWidget.java?
This looks a lot like a hack because it is bypassing an API and going after the internals of the java class, i.e. if someone on Android decides to refactor the code and rename the class member something other than mDaySpinner then Collect's code will no longer work. In fact, it looks like something similar happened.
This is where I am getting beyond the bounds of my knowledge and experience. I tried looping through the fields of mDelegate. I can get a field that is mDaySpinner. However, Field.get(Object) gives my an IllegalArgumentException:
java.lang.IllegalArgumentException: Expected receiver of type android.widget.DatePicker$DatePickerSpinnerDelegate, but got java.lang.Class<android.widget.DatePicker$DatePickerSpinnerDelegate>
It seems like android.widget.DatePicker$DatePickerSpinnerDelegate is not visible to Collect, so I think I am at a dead end. But I am also not very savvy with this reflect package.
Any help on how to move forward would be appreciated.
#########################
Obviously this is a very small piece of ODK Collect, so maybe it is not worth it to try to fix. There are ways around it for survey creators, like single select and integer entry to take place of month and date entry. However, if it is worth it to fix it, then maybe there should be a better solution than using reflect. Perhaps Collect should use a custom set of spinners for year and month or just year. It seems like digging around Android source code with reflect is not the way to go. Perhaps Dr. Sundt has some thoughts as he was the person to contribute the current code for DateWidget.java?
Yes, this is entirely a (necessary) hack.
If there is a new public API to manage what is displayed, you can do
something like:
int version = android.os.Build.VERSION.SDK_INT; if ( version < ??? ) { //
existing hack } else { // perhaps use a public API to alter what is
displayed? } This would allow the code to adjust at runtime based upon the
Android OS version. From the description, it sounds like the newer Android
OS and/or SDK has changed this widget and the reflection hack no longer
works. I would search first for whether there was a way to avoid that via a
public API before continuing to add layers to this hack.
···
On Tue, Sep 15, 2015 at 8:26 AM, Yaw Anokwa wrote:
Sounds like reasonable progress, James. Mitch is on vacation but this
issue has been filed so hopefully he can take a look soon.
And yeah, there are good workarounds, so I'd use those until this gets
fixed.
Yaw
Need ODK services? http://nafundi.com provides form design, server
setup, professional support, and software development for ODK.
This looks a lot like a hack because it is bypassing an API and going
after the internals of the java class, i.e. if someone on Android decides
to refactor the code and rename the class member something other than mDaySpinner then Collect's code will no longer work. In fact, it looks
like something similar happened.
This is where I am getting beyond the bounds of my knowledge and
experience. I tried looping through the fields of mDelegate. I can get a
field that is mDaySpinner. However, Field.get(Object) gives my an
IllegalArgumentException:
java.lang.IllegalArgumentException: Expected receiver of type
android.widget.DatePicker$DatePickerSpinnerDelegate, but got
java.lang.Class<android.widget.DatePicker$DatePickerSpinnerDelegate>
It seems like android.widget.DatePicker$DatePickerSpinnerDelegate is not
visible to Collect, so I think I am at a dead end. But I am also not very
savvy with this reflect package.
Any help on how to move forward would be appreciated.
#########################
Obviously this is a very small piece of ODK Collect, so maybe it is not
worth it to try to fix. There are ways around it for survey creators, like
single select and integer entry to take place of month and date entry.
However, if it is worth it to fix it, then maybe there should be a better
solution than using reflect. Perhaps Collect should use a custom set of
spinners for year and month or just year. It seems like digging around
Android source code with reflect is not the way to go. Perhaps Dr. Sundt
has some thoughts as he was the person to contribute the current code for
DateWidget.java?