java - 如何在 Base 适配器中停止文本到语音

标签 java android text-to-speech

我有一个自定义 ListViewBaseAdapter .在这个习惯ListView当用户单击任何特定文本时,它会说出文本,但问题是当任何用户单击后退按钮时如何停止来自 BaseAdapter 的文本.我知道如何停止 Activity但不知道如何停止 BaseAdapter当用户按下后退按钮时。这是我的代码:

package bible.swordof.God;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Vibrator;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.zip.Inflater;

import es.dmoral.toasty.Toasty;
import petrov.kristiyan.colorpicker.ColorPicker;

import static android.content.Context.MODE_PRIVATE;

public class BaseAdopter extends BaseAdapter implements  TextToSpeech.OnInitListener{
    public BaseAdopter(Context context, List<String> versenumber, List<String> verseid, List<String> verselist, List<String> refernce) {
        this.context = context;
        this.versenumber = versenumber;
        this.verseid = verseid;
        this.verselist = verselist;
        this.refernce = refernce;
    }

ALLVERSE allverse;
    ArrayList<String> colors;
    private Context context;
    private List<String> versenumber;
    private List<String>verseid;
    private List<String> verselist;
    private List<String> refernce;
    TextToSpeech textToSpeech;
    private DatabaseHelper mDBHelper;
    private SQLiteDatabase mDb;
    @Override
    public int getCount() {
        return versenumber.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        View view=inflater.inflate(R.layout.versedisplayrow,parent,false);



        textToSpeech = new TextToSpeech(context, this);



        final TextView verseno;
     final TextView verselistview;
     ImageView share;
     ToggleButton addfavoruite;
     ImageView speakverse;
final  LinearLayout linearLayout;
     verseno=(TextView)view.findViewById(R.id.versenumber);
      verseno.setText(versenumber.get(position));
      verselistview=(TextView)view.findViewById(R.id.verse);
      verselistview.setText(verselist.get(position));
      addfavoruite=(ToggleButton)view.findViewById(R.id.adbookmark);
     linearLayout=(LinearLayout)view.findViewById(R.id.layout);
     share=(ImageView)view.findViewById(R.id.share);
     speakverse=(ImageView)view.findViewById(R.id.speak);

if(DefaultSettings.nightmode(context)){

    linearLayout.setBackgroundColor(Color.parseColor("#363437"));

    verselistview.setTextColor(Color.parseColor("#ffffff"));

    verseno.setTextColor(Color.parseColor("#ffffff"));
}
speakverse.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        singleverse(verselist.get(position).toString());

    }
});




int a=position+1;
        colors=new ArrayList<>();
        colors.add("#e0e0eb");
        colors.add("#ccffff");
        colors.add("#ffe6ff");
        colors.add("#ffffcc");
        colors.add("#ccffcc");
        colors.add("#e6f2ff");

        SharedPreferences sharedPreferences=context.getSharedPreferences("DATA",MODE_PRIVATE);


        int getverse=sharedPreferences.getInt("versenumber",1);



        if(a==getverse){
            if(DefaultSettings.highlight(context)){
                DefaultSettings.color(context);

                linearLayout.setBackgroundColor(DefaultSettings.colorpicked);
            }


        }



        if(Checkisfavourite("favourite","id",verseid.get(position)))
        {
            if(verseid.get(position).equals(verseid.get(position))){

             addfavoruite.setChecked(true);

            }else {

                addfavoruite.setChecked(false);
            }
        }



        addfavoruite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if(isChecked){
            mDBHelper = new DatabaseHelper(context);
            mDb = mDBHelper.getWritableDatabase();
            ContentValues contentValues=new ContentValues();
            contentValues.put("id",verseid.get(position));
            contentValues.put("bookname",refernce.get(position));
            contentValues.put("versenumber",versenumber.get(position));
            contentValues.put("verse",verselist.get(position));
            long check=mDb.insert("favourite",null,contentValues);
            Toasty.success(context, "Added in favouite", Toast.LENGTH_SHORT, true).show();
        }
        else {
            mDBHelper = new DatabaseHelper(context);
            mDb = mDBHelper.getWritableDatabase();
            long delete= mDb.delete("favourite","id=?",new String[]{verseid.get(position)});
            Toasty.error(context, "Remove in favouite", Toast.LENGTH_SHORT, true).show();
        }
    }
});
        share.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toasty.info(context, "Sharing a verse.", Toast.LENGTH_SHORT, true).show();
                Intent sendIntent = new Intent();
                sendIntent.setAction(Intent.ACTION_SEND);
                sendIntent.putExtra(Intent.EXTRA_TEXT, refernce.get(position) + ":" + versenumber.get(position) + '\n'   + verselist.get(position) +


                        +'\n' +'\n' +'\n' +"https://play.google.com/store/apps/details?id=bible.swordof.God");
                sendIntent.setType("text/plain");
                context.startActivity(sendIntent);
            }
        });






  /*    linearLayout.setOnLongClickListener(new View.OnLongClickListener() {


            @Override
            public boolean onLongClick(View v) {

                //Toasty.success(activity, "PICK COLOR", Toast.LENGTH_SHORT, true).show();
                Vibrator vibe = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
                vibe.vibrate(100);


                mDBHelper = new DatabaseHelper(context);
                mDb = mDBHelper.getWritableDatabase();
                ContentValues contentValues=new ContentValues();
                contentValues.put("verseid",colors.get(position));
                final long check=mDb.insert("highlight",null,contentValues);


                //id get




                //postion
                //Toast.makeText(activity, ""+getItemId(position), Toast.LENGTH_SHORT).show();

                ColorPicker colorPicker = new ColorPicker(context);


                colorPicker.setColors(colors).setColumns(4).setTitle("HIGHLIGHT VERSE").setRoundColorButton(true).setOnChooseColorListener(new ColorPicker.OnChooseColorListener() {
                    @Override
                    public void onChooseColor(int position, int color) {


                       linearLayout.setBackgroundColor(Color.parseColor(colors.get(position)));
                    }

                    @Override
                    public void onCancel() {

                    }
                }).show();






                return false;
            }
        });
*/






     return view;



    }

    public boolean Checkisfavourite(String TableName,  String dbfield, String fieldValue) {

        mDBHelper = new DatabaseHelper(context);
        mDb = mDBHelper.getReadableDatabase();
        String Query = "Select * from " + TableName + " where " + dbfield + " = " + fieldValue;
        Cursor cursor = mDb.rawQuery(Query, null);
        if(cursor.getCount() <= 0){
            cursor.close();

            // Toast.makeText(activity, "false", Toast.LENGTH_SHORT).show();
            return false;
        }else {

            // Toast.makeText(activity, "TRUE", Toast.LENGTH_SHORT).show();

        }
        cursor.close();


        return true;
    }

    public boolean colorcheck(String TableName,  String dbfield, String fieldValue) {

        mDBHelper = new DatabaseHelper(context);
        mDb = mDBHelper.getReadableDatabase();
        String Query = "Select * from " + TableName + " where " + dbfield + " = " + fieldValue;
        Cursor cursor = mDb.rawQuery(Query, null);
        if(cursor.getCount() <= 0){
            cursor.close();

            // Toast.makeText(activity, "false", Toast.LENGTH_SHORT).show();
            return false;
        }else {

            // Toast.makeText(activity, "TRUE", Toast.LENGTH_SHORT).show();

        }
        cursor.close();


        return true;
    }


    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) {

            int result = textToSpeech.setLanguage(Locale.US);

            // tts.setPitch(5); // set pitch level

            // tts.setSpeechRate(2); // set speech speed rate

            if (result == TextToSpeech.LANG_MISSING_DATA
                    || result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.e("TTS", "Language is not supported");
            } else {

            }

        } else {
            Log.e("TTS", "Initilization Failed");
        }

    }
    private void singleverse(String text) {
        DefaultSettings.speed(context);
        textToSpeech.setPitch(DefaultSettings.pitchvalue);
        textToSpeech.setSpeechRate(DefaultSettings.speedvalue);
        textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
    }

public  void  stop(){
        if (textToSpeech != null) {
        textToSpeech.stop();
        textToSpeech.shutdown();

    }
}

}

最佳答案

主要问题是您的 TextToSpeech 对象属于您的 BaseAdapter,而它应该属于父 Activity 。

我不会将它放在适配器中并在每次用户单击某个项目时调用它,而是将它放在父 Activity 中并使用“接口(interface)回调”在用户单击时向父 Activity 发送消息一个项目,发回字符串说话。此回调关系的工作方式与您已经在使用的 TextToSpeech.OnInitListener 回调完全相同。

一旦 TTS 属于父 Activity,您就可以像往常一样使用 Activity 生命周期函数来控制 TTS 的关闭。

如果您学习并理解以下内容,您应该能够将其合并到您的代码中并获得有效的解决方案:

对您的自定义 BaseAdapter 进行以下更改:

// Remove the TextToSpeech object from this class.

public class MyBaseAdapter {

// add this interface definition to your adapter
public interface SpeechClickSubscriber {
    void stringNeedsToBeSpoken(String verse);
}

// add this property (the subscriber)
private SpeechClickSubscriber speechClickSubscriber;

// *add* this functionality to your adapter's existing constructor
MyBaseAdapter(SpeechClickSubscriber parent) {
    speechClickSubscriber = parent;
}

//...

// change this section of code in your getView() method
speakverse.setOnClickListener(new View.OnClickListener()

{
    @Override
    public void onClick (View v){

    // change this...
    // singleverse(verselist.get(position).toString());

    // to this:
    speechClickSubscriber.stringNeedsToBeSpoken(verselist.get(position).toString());

}
});

// ...


}

对您的 MainActivity(或您的父 Activity 是什么)进行这些更改:

// add the SpeechClickSubscriber implementation
public class MainActivity extends AppCompatActivity implements  MyBaseAdapter.SpeechClickSubscriber, TextToSpeech.OnInitListener {

MyBaseAdapter adapter;
TextToSpeech textToSpeech;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // using app context is better and less error prone.
    textToSpeech = new TextToSpeech(getApplicationContext(), this);


}

// *add* this method to this activity (this is the answer to your question)
@Override
protected void onStop() {
    super.onStop();
    stopTTS();
}

// use this method as your "onStart()" method...
// this will help prevent any user input processing until the tts is initialized.
private void start_Activity_Because_TTS_Has_Initialized() {

    adapter = new MyBaseAdapter(this);

}


// *MOVE* this method from your base adapter to this (parent) activity:
@Override
public void onInit(int status) {
    if (status == TextToSpeech.SUCCESS) {

        int result = textToSpeech.setLanguage(Locale.US);

        // tts.setPitch(5); // set pitch level

        // tts.setSpeechRate(2); // set speech speed rate

        if (result == TextToSpeech.LANG_MISSING_DATA
                || result == TextToSpeech.LANG_NOT_SUPPORTED) {
            Log.e("TTS", "Language is not supported");
        } else {

        }

    } else {
        Log.e("TTS", "Initilization Failed");
    }

}

// *move* and *rename* this method from your adapter to the parent activity:
// from:

/*
private void singleverse(String text) {
    DefaultSettings.speed(context);
    textToSpeech.setPitch(DefaultSettings.pitchvalue);
    textToSpeech.setSpeechRate(DefaultSettings.speedvalue);
    textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
} */

// to:

@Override
public void stringNeedsToBeSpoken(String verse) {

    Log.i("XXX","stringNeedsToBeSpoken() was called because the user clicked an item.");
    Log.i("XXX","This method is being called because this activity subscribes to the callback we created and added to our base adapter.");

    //DefaultSettings.speed(context);  // <----------------- I don't know what this does.
    // I'm assuming that DefaultSettings is a static class you have made.
    textToSpeech.setPitch(DefaultSettings.pitchvalue);
    textToSpeech.setSpeechRate(DefaultSettings.speedvalue);
    textToSpeech.speak(verse, TextToSpeech.QUEUE_FLUSH, null);
}



public  void  stopTTS(){
    if (textToSpeech != null) {
        textToSpeech.stop();
        textToSpeech.shutdown();

    }
}


}

关于java - 如何在 Base 适配器中停止文本到语音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57230420/

相关文章:

java - 如何将两个字符串和一个 List<byte[]> 聚合为一个 byte[],然后提取它们

android - GIT merge 的机制是什么?

android - 将 Firebase uri 转换为位图时出现 FileNotFound 异常?

delphi - SAPI 与 Dephi : Async speech doesn't work

Java8 Stream List<Map<String,Object>> 分组依据和计数值

java - 如何在应用程序关闭时禁用 Android LocationListener

java - 如何使用 Java 驱动程序检索现有 MongoDB 集合的 validator ?

android - 最好将数据传递给另一个 Activity 或对 sqlite 执行两个查询

android - 在我的应用程序中显示文本转语音的设置

google-chrome - chrome.tts.speak字符数限制