JSBach
JSBach

Reputation: 446

Android SeekBar talkback, talking too much

(Android) On a music player, you update the seekbar as expected with this:

PRECISION_SEEKBAR = 100000;
((SeekBar) findViewById(R.id.seekBar2)).setMax(PRECISION_SEEKBAR);

timerSeekBarUpdate.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                final SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar);

                @Override
                public void run() {
                    if (control == null || player == null) {
                        cancel();
                        return;
                    }
                    seekBar.setProgress((int) (player.getCurrentPosition() * PRECISION_SEEKBAR / player.getDuration()));
                    ...

However, if the focus is on the seek bar, talkback steadily and nonstop gives feedback for the progress. Like "seek control 25%", "seek control 25%", "seek control 25%", "seek control 26%", "seek control 26%", "seek control 27%"

I'm missing sth but couldnot solve the problem. I have set the contentDescription to other than @null. But then it reads the content description this time without stopping.

On Spotify client, I checked, it reads the progress as "xx percent" just once. Despite saving the focus on the seekbar.

When I edit the precision for 1 or 100, then you lose the precision on the seekbar. It looks like there are a few parts in the song. You either play one or another by swiping on the seekbar.

Has anybody experienced sth like this? I couldn't find anything on google docs, stack network or somewhere else.

Upvotes: 1

Views: 2205

Answers (2)

Zhan Huang
Zhan Huang

Reputation: 23

You can just override sendAccessibilityEvent() so it ignores description updates:

@Override
public void sendAccessibilityEvent(int eventType) {
    if (eventType != AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION) {
        super.sendAccessibilityEvent(eventType);
    }
}

As Altoyyr mentioned, this has the side effect of ignore ALL description updates, including scrolling with volume buttons. So you'll need add back sending the event for volume press actions:

@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
    switch (action) {
        case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
        case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
            super.sendAccessibilityEvent(AccessibilityEvent.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
        }
    }
    return super.performAccessibilityAction(action, arguments);
}

Upvotes: 2

JDurstberger
JDurstberger

Reputation: 4255

I had the problem and found that SeekBar reads the percentage on every update.

It helped, that I update the SeekBar only when the percentage changes but still keep a high precision (in my case in ms).

@Override
public void updateSeekBar(final int currentPosInMillis, final int durationInMillis) {
    long progressPercent = calculatePercent(currentPosInMillis, durationInMillis);

    if (progressPercent != previousProgressPercent) {
        seekBar.setMax(durationInMillis);
        seekBar.setProgress(currentPosInMillis);
    }
    previousProgressPercent = progressPercent;
}

private int calculatePercent(int currentPosInMillis, int durationInMillis) {
    if(durationInMillis == 0) {
        return 0;
    }
    return (int) (((float)currentPosInMillis / durationInMillis) * 100);
} 

previousProgressPercent is initialized to -1.

Please note that this solution is not the same as Spotify does it.
Spotify overrides the message announced by the system when the SeekBar gets selected.
This has following 2 effects:

  • Updates can be made as often as you want without the percentage beeing repeated
  • When the percentage changes while the SeekBar is selected then nothing gets announced

Point 2 might me a drawback depending on what you want to achieve.

Upvotes: 1

Related Questions