Exception: java.lang.NumberFormatException
Opened this issue · 1 comments
This error likely occurs in RingonePreference because I used my own key, rather than a resolvable URI. Error reports from my app's users show this crash only happening on Android 10 (so far).
I confirmed in the Android source code that this issue is fixed in Android 11. In RingtoneManager.getRingtonePosition(Uri)
, they put a try-catch for NumberFormatException, and return -1 rather than throwing: https://github.com/AndroidSDKSources/android-sdk-sources-for-api-level-30/blob/1479eb7a294ab2f740f99d19c6b33b4de67c99a5/android/media/RingtoneManager.java#L514
In Android 10, that try-catch does not exist in RingtoneManager, so it crashes by default instead: https://github.com/AndroidSDKSources/android-sdk-sources-for-api-level-29/blob/815d70abfebfcd8a80015c9da50e8a76c12bba2b/android/media/RingtoneManager.java
In order to make RingtonePreferenceDialogFragmentCompat.java
more robust for pre-Android 11, a similar try-catch-NumberFormatException could be added to surround line 248 (selectedIndex = ringtoneManager.getRingtonePosition(ringtoneUri);
)
Example code:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
selectedIndex = ringtoneManager.getRingtonePosition(ringtoneUri);
} else {
try {
selectedIndex = ringtoneManager.getRingtonePosition(ringtoneUri);
} catch (NumberFormatException e) {
selectedIndex = -1;
}
}
Do you agree with this fix? Any proposed changes?
Stacktrace:
Exception: java.lang.NumberFormatException: For input string: "alert_connected"
at java.lang.Long.parseLong(Long.java:594)
at java.lang.Long.parseLong(Long.java:636)
at android.content.ContentUris.parseId(ContentUris.java:89)
at android.media.RingtoneManager.getRingtonePosition(RingtoneManager.java:513)
at com.takisoft.preferencex.RingtonePreferenceDialogFragmentCompat.createCursor(RingtonePreferenceDialogFragmentCompat.java:248)
at com.takisoft.preferencex.RingtonePreferenceDialogFragmentCompat.onPrepareDialogBuilder(RingtonePreferenceDialogFragmentCompat.java:101)
at androidx.preference.PreferenceDialogFragmentCompat.onCreateDialog(PreferenceDialogFragmentCompat.java:154)
at com.takisoft.preferencex.RingtonePreferenceDialogFragmentCompat.onCreateDialog(RingtonePreferenceDialogFragmentCompat.java:171)
at androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:419)
at androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1485)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2181)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2004)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1959)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1861)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7562)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
I've had some thoughts about it before and it might be necessary to change the RingtonePreference completely as it needs to consider the scoped storage for the custom ringtones as well. Also, JCenter is sunsetting, so the whole project will be migrated to Maven Central.