Android Studio点击按钮播报位置却循环重复的问题求助
问题描述
我有一个按钮,点击后会在两个TextView(textview3显示纬度X,textview21显示经度Y)中显示当前位置,同时希望通过TextToSpeech播报该位置。但现在遇到的问题是文本转语音会一直循环播报位置,只有关闭程序才能停止,不知道怎么修复。
MainActivity2 定位处理代码
ImageButtonLoc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (ActivityCompat.checkSelfPermission(MainActivity2.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity2.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQ_LOC_CODE); } else { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, MainActivity2.this); //locationManager.removeUpdates(MainActivity.this); } //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, // 0, 0, MainActivity.this); //locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER., 0, 0 , MainActivity.this); } }); } //energopoietai apo to kleisimou tou dangerous permissions @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQ_LOC_CODE && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, MainActivity2.this); } } @Override public void onLocationChanged(@NonNull Location location) { //sintetagmenes sto text x=location.getLatitude(); y=location.getLongitude(); textView3.setText(String.format("Your current location is:X=%.2f",x)); textView21.setText(String.format(" and Y=%.2f",y)); textspeech.speak("Your current location is:"+"X="+String.format("%.2f",x)+","+" "+"Y="+String.format("%.2f",y)); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(@NonNull String provider) { } @Override public void onProviderDisabled(@NonNull String provider) { }
textspeech 类代码
public class textspeech { private TextToSpeech tts; TextToSpeech.OnInitListener initListener=new TextToSpeech.OnInitListener() { @Override public void onInit(int status) { if(status==TextToSpeech.SUCCESS){ tts.setLanguage(Locale.US); } } }; //prepei na ftiaksume constructor moni mas gt h mixani omilias dn // mporei na energopoithi moni ths h klasi prepei na energopoiithoi apo contex public textspeech(Context context){ tts=new TextToSpeech(context, initListener); } //methodos gia na tn kalume public void speak(String message){ tts.speak(message,TextToSpeech.QUEUE_ADD, null,null); } }
修复方案
问题根源
- 定位更新持续触发:设置
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ...)时,参数0,0表示只要位置有任何微小变化就会触发onLocationChanged,导致不断调用播报方法。 - 语音队列叠加:
textspeech.speak方法用了TextToSpeech.QUEUE_ADD,每次触发都会把新的播报内容加到队列里,旧内容未播完新内容又进入,造成循环播报。
具体修复步骤
1. 控制定位更新逻辑
如果只需要点击按钮时获取一次位置,在拿到位置后立即移除监听:
@Override public void onLocationChanged(@NonNull Location location) { // 获取并显示位置 x=location.getLatitude(); y=location.getLongitude(); textView3.setText(String.format("Your current location is:X=%.2f",x)); textView21.setText(String.format(" and Y=%.2f",y)); // 播报位置 textspeech.speak("Your current location is: X="+String.format("%.2f",x)+", Y="+String.format("%.2f",y)); // 移除定位监听,避免持续触发 locationManager.removeUpdates(this); }
如果需要持续更新但不想每次都播报,可以添加标记控制播报时机(比如只播报一次,或位置变化超过阈值时播报):
private boolean hasReportedLocation = false; // 类成员变量 @Override public void onLocationChanged(@NonNull Location location) { x=location.getLatitude(); y=location.getLongitude(); textView3.setText(String.format("Your current location is:X=%.2f",x)); textView21.setText(String.format(" and Y=%.2f",y)); // 仅播报一次 if(!hasReportedLocation){ textspeech.speak("Your current location is: X="+String.format("%.2f",x)+", Y="+String.format("%.2f",y)); hasReportedLocation = true; } }
2. 修改语音队列模式
把QUEUE_ADD改成QUEUE_FLUSH,新的播报内容会替换队列中未播放的内容,避免叠加:
// 在textspeech类的speak方法中修改 public void speak(String message){ tts.speak(message,TextToSpeech.QUEUE_FLUSH, null,null); }
3. 避免重复注册定位监听
在按钮点击时先移除旧的监听,再添加新的,防止重复触发:
ImageButtonLoc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (ActivityCompat.checkSelfPermission(MainActivity2.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(MainActivity2.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQ_LOC_CODE); } else { // 先移除旧监听,防止重复注册 locationManager.removeUpdates(MainActivity2.this); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, MainActivity2.this); } } });
内容的提问来源于stack exchange,提问作者anastasia papaioannou
相关产品推荐
相关产品推荐

