У меня возникла проблема с выделением текста, когда его читает Google.Каждое устройство имеет свою собственную скорость чтения текста, из-за чего выделение текста вместе со звуком вызывает проблемы и кажется несовместимым на некоторых устройствах.
Я пробовал класс Progressive Textview, чтобы выделить предложение, когда Google начинает читать его.В этом классе мне нужно определить значение задачи запуска в числах с плавающей запятой, чтобы запустить скорость выделения.Ниже приведен код пользовательского класса:
public class ProgressTextView extends AppCompatTextView {
private SpannableTask spannableTask;
private ProgressListener progressListener;
private boolean changeColor = false;
public ProgressTextView(Context context) {
super(context);
init(null);
}
public ProgressTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(getContext().obtainStyledAttributes(attrs, R.styleable.ProgressTextView));
}
public ProgressTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(getContext().obtainStyledAttributes(attrs, R.styleable.ProgressTextView, defStyleAttr, 0));
}
private void init(@Nullable TypedArray typedArray) {
this.spannableTask = new SpannableTask(this, getText().toString());
this.spannableTask.setDefaultTextColor(this.getTextColors().getDefaultColor());
int textColor = typedArray.getColor(R.styleable.ProgressTextView_highlightTextColor, 0);
if (textColor != 0) {
this.spannableTask.setHighlightTextColor(textColor);
}
}
public void addProgressListener(ProgressListener progressListener) {
this.progressListener = progressListener;
}
public SpannableTask getSpannableTask() {
return this.spannableTask;
}
public SpannableTask getSpannableTask(String text) {
this.spannableTask = new SpannableTask(this, text);
this.spannableTask.setHighlightTextColor(getResources().getColor(R.color.yellow));
this.spannableTask.setHighlightBackgroundTextColor(getResources().getColor(R.color.black));
this.spannableTask.setDefaultTextColor(getResources().getColor(R.color.text_color));
return this.spannableTask;
}
public class SpannableTask implements Runnable {
private Handler handler = new Handler();
private SpannableString spannableString;
private String text;
private ProgressTextView spannableTextView;
private int second;
private int defaultTextColor = R.color.text_color;
private int highlightTextColor = Color.YELLOW;
private int backgroundTextColor = Color.BLACK;
public SpannableTask(ProgressTextView spannableTextView, String text) {
this.text = text;
this.spannableString = new SpannableString(text);
this.spannableTextView = spannableTextView;
initTextView(defaultTextColor,backgroundTextColor, text.length());
}
public void runTask(float second) {
this.second = ((int) (second * 1000) / text.length());
new Thread(this).run();
}
public void runTask(int second) {
this.second = second / text.length();
new Thread(this).run();
}
@Override
public void run() {
for (int i = 0; i <= text.length(); i++) {
final int value = i;
handler.postDelayed(new Runnable() {
@Override
public void run() {
changeColor = true;
initTextView(highlightTextColor,backgroundTextColor, value);
if (value == text.length() && progressListener != null) {
cancel();
progressListener.complete();
}
}
}, second * i);
}
}
private void initTextView(int color,int backgroundcolor, int length) {
if(!changeColor){
this.spannableString.setSpan(new BackgroundColorSpan(Color.WHITE), 0, length, 0);
this.spannableString.setSpan( new ForegroundColorSpan(getResources().getColor(R.color.text_color)), 0,length, 0);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append(spannableString);
this.spannableTextView.setText(spannableString);
}else{
this.spannableString.setSpan(new BackgroundColorSpan(color), 0, length, 0);
this.spannableString.setSpan( new ForegroundColorSpan(backgroundcolor), 0,length, 0);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append(spannableString);
this.spannableTextView.setText(spannableString);
}
}
public void cancel() {
changeColor =false;
initTextView(defaultTextColor,backgroundTextColor, text.length());
handler.removeCallbacksAndMessages(null);
}
public void setDefaultTextColor(int defaultTextColor) {
this.defaultTextColor = defaultTextColor;
initTextView(defaultTextColor,backgroundTextColor, text.length());
}
public void setHighlightTextColor(int highlightTextColor) {
this.highlightTextColor = highlightTextColor;
}
public void setHighlightBackgroundTextColor(int backgroundTextColor) {
this.backgroundTextColor = backgroundTextColor;
}
}
}
И в своем основном голосе «Активность» я использую GTS для чтения динамического текста
private ProgressTextView.SpannableTask target = null;
private boolean isSpeech=false;
TextToSpeech textToSpeech;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_voice);
new RetrieveFeedTask().execute("");
}
public static class RetrieveFeedTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try {
String apiUrl= "https://maps.googleapis.com/maps/api/geocode/json?latlng="+mCurrentLocation.getLatitude()+","+mCurrentLocation.getLongitude()+"&key=YOUR KEY";
URL url = new URL(apiUrl);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
return stringBuilder.toString();
}
finally{
urlConnection.disconnect();
}
}
catch(Exception e) {
return null;
}
}
protected void onPreExecute() {
}
protected void onPostExecute(String response) {
if(response != null) {
try {
AddressList addressList=new Gson().fromJson(response,AddressList.class);
List<Results> mList= addressList.getResults();
List<AddressComponent> mAddressList= mList.get(0).getAddressComponents();
StringBuilder sb = new StringBuilder();
for (AddressComponent addressComponent:mAddressList) {
if(addressComponent.getTypes().contains("street_number")){
sb.append(addressComponent.getShortName()).append(" ");
}
else if(addressComponent.getTypes().contains("route")){
sb.append(addressComponent.getShortName()).append(", ");
}
else if(addressComponent.getTypes().contains("locality")){
sb.append(addressComponent.getShortName()).append(", ");
}
else if(addressComponent.getTypes().contains("administrative_area_level_1")){
sb.append(addressComponent.getLongName());
}
}
mTxtAddress.setText(sb.toString());
textSpeech();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void textSpeech(){
textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = textToSpeech.setLanguage(Locale.ENGLISH);
if (result == TextToSpeech.LANG_MISSING_DATA ||
result == TextToSpeech.LANG_NOT_SUPPORTED) {
Toast.makeText(getApplicationContext(), "This language is not supported!",
Toast.LENGTH_SHORT);
} else {
textToSpeech.setOnUtteranceCompletedListener(VoiceActivity.this);
textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
@Override
public void onStart(String s) {
final String keyword = s;
runOnUiThread(new Runnable() {
@Override
public void run() {
if(mTxtAddress.getText().toString().equalsIgnoreCase(keyword)){
target = mTxtAddress.getSpannableTask(mTxtAddress.getText().toString());
target.runTask(3.5f);
}
}
});
}
@Override
public void onDone(final String keyword) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if(mTxtAddress.getText().toString().equalsIgnoreCase(keyword)){
target.cancel();
}
}
});
}
@Override
public void onError(String s) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "Error ", Toast.LENGTH_SHORT).show();
}
});
}
});
speak();
}
}
}
});
}
private void speak() {
mPlayer.stop();
isSpeech=true;
String text = mTxtEmer.getText().toString();
HashMap<String, String> params = new HashMap<String, String>();
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,text);
textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, mTxtAddress.getText().toString());
textToSpeech.speak(mTxtAddress.getText().toString(), TextToSpeech.QUEUE_ADD, params);
} else {
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, mTxtAddress.getText().toString());
textToSpeech.speak(mTxtAddress.getText().toString(), TextToSpeech.QUEUE_ADD, params);
}
}