NPE in ChangeCurrentByOneFromLongPressCommand (on Samsung devices w/ Android 4.3)
Solution 1:
So the Samsung NumberPicker
is slightly different from AOSP. The code for ChangeCurrentByOneFromLongPressCommand
class has some extra logic including
if (!mIsDeviceDefault) {
// ...
} else if (mDecrementButton.isShown() || mIncrementButton.isShown()) {
// ...
- where
mIsDeviceDefault
istrue
when you're using one of theTheme.DeviceDefault
themes (which is the default theme for apps starting Android 4.x) - where
mDecrementButton
andmIncrementButton
arenull
ifmHasSelectorWheel
istrue
, which happens if the layout resource ID forNumberPicker
specified by its style is one of-
DEFAULT_LAYOUT_RESOURCE_ID
/@layout/number_picker
-
TOUCHWIZ_DARK_LAYOUT_RESOURCE_ID
/@layout/tw_number_picker_dark
-
TOUCHWIZ_LIGHT_LAYOUT_RESOURCE_ID
/@layout/tw_number_picker_light
-
which suggests that this would happen all the time.
Here are all the possible styles:
<style name="Widget.NumberPicker">
<item name="orientation">1</item>
<item name="fadingEdge">2000</item>
<item name="fadingEdgeLength">50dp</item>
<item name="internalLayout">@layout/number_picker</item>
</style>
<style name="Widget.Holo.NumberPicker">
<item name="solidColor">@color/transparent</item>
<item name="internalLayout">@layout/number_picker_with_selector_wheel</item>
<item name="selectionDivider">@drawable/numberpicker_selection_divider</item>
<item name="selectionDividerHeight">2dp</item>
<item name="selectionDividersDistance">48dp</item>
<item name="internalMaxHeight">180dp</item>
<item name="internalMinWidth">64dp</item>
<item name="virtualButtonPressedDrawable">?attr/selectableItemBackground</item>
</style>
<style name="Widget.DeviceDefault.NumberPicker">
<item name="internalLayout">@layout/tw_number_picker_dark</item>
</style>
<style name="Widget.DeviceDefault.Light.NumberPicker">
<item name="internalLayout">@layout/tw_number_picker_light</item>
</style>
Source: Downloaded Android 4.3 firmware for Samsung Galaxy S3, extracted framework files using ext4 unpacker, decompiled framework.jar
and framework2.jar
using Universal Deodexer V5, explored the results including framework-res.apk
using JADX.
How to fix
After your NumberPicker
is constructed use reflection to check if ImageButton mDecrementButton
and ImageButton mIncrementButton
are null. If they are use reflection to set them each to a new ImageButton(numberPicker.getContext())
.
Only apply this logic when running on one of the affected devices (check Build
constants).