广播如何绑定服务android,关于android:Broadcast接收器组件不允许绑定服务。 如何从广播接收器开始文本到语音的转换?...

我的应用程序出现错误,表明BroadcastReceiver组件不允许绑定到服务。

短信到达时,我正在呼叫广播接收器,文本将转换为语音。

我的收款人打了电话。

但是我的代码给出了错误

FATAL EXCEPTION: main

Process: texttospeech.tts.com.tts, PID: 12811

java.lang.RuntimeException: Unable to start receiver texttospeech.tts.com.tts.ttsBroadcast:

android.content.ReceiverCallNotAllowedException: BroadcastReceiver

components are not allowed to bind to services

at android.app.ActivityThread.handleReceiver(ActivityThread.java:2618)

at android.app.ActivityThread.access$1700(ActivityThread.java:148)

at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1369)

at android.os.Handler.dispatchMessage(Handler.java:102)

at android.os.Looper.loop(Looper.java:135)

at android.app.ActivityThread.main(ActivityThread.java:5312)

at java.lang.reflect.Method.invoke(Native Method)

at java.lang.reflect.Method.invoke(Method.java:372)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

Caused by: android.content.ReceiverCallNotAllowedException: BroadcastReceiver components are not allowed to bind to services

at android.app.ReceiverRestrictedContext.bindService(ContextImpl.java:215)

at android.speech.tts.TextToSpeech.connectToEngine(TextToSpeech.java:800)

at android.speech.tts.TextToSpeech.initTts(TextToSpeech.java:770)

at android.speech.tts.TextToSpeech.(TextToSpeech.java:723)

at android.speech.tts.TextToSpeech.(TextToSpeech.java:702)

at android.speech.tts.TextToSpeech.(TextToSpeech.java:686)

at texttospeech.tts.com.tts.ttsBroadcast.onReceive(ttsBroadcast.java:23)

at android.app.ActivityThread.handleReceiver(ActivityThread.java:2611)

at android.app.ActivityThread.access$1700(ActivityThread.java:148)

at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1369)

at android.os.Handler.dispatchMessage(Handler.java:102)

at android.os.Looper.loop(Looper.java:135)

at android.app.ActivityThread.main(ActivityThread.java:5312)

at java.lang.reflect.Method.invoke(Native Method)

at java.lang.reflect.Method.invoke(Method.java:372)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

这是我的代码

ttsBroadcast.java

public class ttsBroadcast extends BroadcastReceiver implements TextToSpeech.OnInitListener {

private TextToSpeech tts;

private String msg;

@Override

public void onReceive(Context context, Intent intent) {

Toast.makeText(context,"sms recived",Toast.LENGTH_LONG).show();

tts = new TextToSpeech(context,this);

tts.speak(msg,TextToSpeech.QUEUE_FLUSH,null);

}

@Override

public void onInit(int i) {

tts.setLanguage(Locale.ENGLISH);

}

}

您能够解决此问题吗? 面临同样的问题。

似乎在stackoverflow.com/a/5646770/1651940上得到了回答

由于问题似乎仍然存在,因此我将添加一些行。

首先,我认为您应该有一个服务,并从BroadcastReceiver调用此服务。这可能是一种可能的实现。

广播接收器:

public class ReadMessageBroadcastReceiver extends BroadcastReceiver {

public final static String TAG ="ReadMessageBroadcastReceiver";

public ReadMessageBroadcastReceiver() {

}

@Override

public void onReceive(Context context, Intent intent) {

if(intent.getAction().equals(Actions.ACTION_TTS_READ_MESSAGE)) {

Log.v(TAG,"Read messages on tts received trough notification");

String[] unreadMessages = intent.getStringArrayExtra(Constants.EXTRA_UNREAD_MESSAGES);

if (unreadMessages != null) {

Log.v(TAG,"Read messages on tts trough notification received" + unreadMessages.length

+" total messages");

String messageNumber = context.getString(R.string.notification_message_number);

ArrayList allMessagesToRead = new ArrayList<>(unreadMessages.length);

for (int i = 0; i < unreadMessages.length; i++) {

StringBuilder stringBuilder = new StringBuilder();

stringBuilder.append(messageNumber);

stringBuilder.append("");

stringBuilder.append(i + 1);

stringBuilder.append("");

stringBuilder.append(unreadMessages[i]);

stringBuilder.append("");

allMessagesToRead.add(stringBuilder.toString());

}

Log.d(TAG,"Texts to read loud:" + allMessagesToRead);

Intent speechIntent = new Intent(context, TextToSpeechService.class);

speechIntent.putStringArrayListExtra(TextToSpeechService.TEXT_TO_READ, allMessagesToRead);

context.startService(speechIntent);

}

}

}

}

单击系统栏通知即可调用此广播接收器。接收者需要在AndroidManifest.xml上声明一个特定的动作。

(all your stuff)

android:name=".broadcastreceivers.ReadMessageBroadcastReceiver"

android:enabled="true">

您还需要在您的应用中的某处声明此操作

public static final String ACTION_TTS_READ_MESSAGE ="com.example.action.ACTION_TTS_READ_MESSAGE";

最后,您需要实现TTSService本身。我从这里使用了部分代码

public class TextToSpeechService extends Service implements TextToSpeech.OnInitListener {

public final static String TAG ="TextToSpeechService";

public static final String TEXT_TO_READ ="text";

private final String UTTERANCE_ID ="FINISHED_PLAYING";

private final int MULTI_LINE = 2;

private TextToSpeech tts;

private ArrayList texts;

private boolean isInit;

private UtteranceProgressListener utteranceProgressListener = new UtteranceProgressListener() {

@Override

public void onStart(String utteranceId) {

}

@Override

public void onDone(String utteranceId) {

if (utteranceId.equals(UTTERANCE_ID)) {

stopSelf();

}

}

@Override

public void onError(String utteranceId) {

stopSelf();

}

};

@Override

public void onCreate() {

super.onCreate();

tts = new TextToSpeech(getApplicationContext(), this);

tts.setOnUtteranceProgressListener(utteranceProgressListener);

Log.d(TAG,"onCreate");

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

Log.d(TAG,"onStartCommand");

texts = intent.getStringArrayListExtra(TTSService.TEXT_TO_READ);

if (isInit) {

speak();

}

return TextToSpeechService.START_NOT_STICKY;

}

@Override

public void onDestroy() {

if (tts != null) {

tts.stop();

tts.shutdown();

}

Log.d(TAG,"onDestroy");

super.onDestroy();

}

@Override

public void onInit(int status) {

Log.d(TAG,"onInit");

if (status == TextToSpeech.SUCCESS) {

int result = tts.setLanguage(Locale.getDefault());

if (result != TextToSpeech.LANG_MISSING_DATA

&& result != TextToSpeech.LANG_NOT_SUPPORTED) {

speak();

isInit = true;

}

}

}

private void speak() {

if (tts != null) {

// Speak with 3 parameters deprecated but necessary on pre 21 version codes

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

// This is a single message

String utteranceId = null;

if (texts.size() < MULTI_LINE) {

// If is a single message this needs to be the last one

utteranceId = UTTERANCE_ID;

}

tts.speak(texts.get(0), TextToSpeech.QUEUE_FLUSH, null, utteranceId);

if (texts.size() >= MULTI_LINE) {

for (int i = 1; i < texts.size(); i++) {

if (texts.size() - 1 == i) {

// If is the last message add the id

utteranceId = UTTERANCE_ID;

}

tts.speak(texts.get(i), TextToSpeech.QUEUE_ADD, null, utteranceId);

}

}

} else {

HashMap myHashAlarm = null;

if (texts.size() < MULTI_LINE) {

myHashAlarm = new HashMap<>();

myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE_ID);

}

tts.speak(texts.get(0), TextToSpeech.QUEUE_FLUSH, myHashAlarm);

if (texts.size() >= MULTI_LINE) {

for (int i = 1; i < texts.size(); i++) {

if (texts.size() - 1 == i) {

// If is the last message add the id

myHashAlarm = new HashMap<>();

myHashAlarm.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,

UTTERANCE_ID);

}

tts.speak(texts.get(i), TextToSpeech.QUEUE_ADD, myHashAlarm);

}

}

}

}

}

@Override

public IBinder onBind(Intent arg0) {

return null;

}

}

最后,不要忘记在AndroidManifest.xml文件中注册服务

android:name=".services.TextToSpeechService"

android:exported="false"/>

不利的一面是,我需要花太多时间才能开始(一秒到两秒之间,具体取决于手机)。好的一面,您的tts不会一直按需运行。由于在Intent上传递给服务的参数是ArrayList,因此实现了一些逻辑以找出是否是序列中的最后一条消息。如果只需要一个字符串,则可以简化实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值