Выделение текста при чтении с использованием текста Google в речь - PullRequest
1 голос
/ 26 сентября 2019

У меня возникла проблема с выделением текста, когда его читает 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);

        }
    }
...