Автозамена работает по принципу:
Сначала, заменить слово, которое редактируется(даже если замена происходит на тоже самое слово)
Затем добавить символ конца слова(пробел, абзац и т.п.)
Зачем так сделано не знаю.
В соответствии с этим принципом в afterTextChanged сначала попадает строка с заменённым словом и сразу же за ней строка с новым символом(afterTextChanged вызывается дважды).
И здесь есть одна тонкость. Если во время первого вызова afterTextChanged изменить содержимое editText (касается большинства наследников TextView), то второго вызова с добавлением символа конца слова не произойдёт.
А поскольку нельзя напрямую перехватывать символы от виртуальной клавиатуры(разве что подключаться к ней, но возможно ли это и как это делается я не знаю.), то узнать происходит ли обычная замена или замена в следствии конца слова не представляется возможным(во всяком случае я не нашёл способа, это не значит, что его нет).