Highlighting the text as it reads using Google text to speech

大憨熊 提交于 2019-12-08 04:36:15

问题


I am facing issue in highlighting the text as the google reads it. Every device is having its own speed of reading the text due to which highlighting text along with sound cause problem and seems inconsistent in some devices.

I have tried Progressive Textview class to highlight the sentence as google start it reading. In this class, I need to define run task value in floats so as to start the highlighting speed. Bellow is the custom class code:

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;
        }
    }
}

And in my main voice Activity, I am using GTS to read the dynamic text

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);

        }
    }

来源:https://stackoverflow.com/questions/58114281/highlighting-the-text-as-it-reads-using-google-text-to-speech

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!