Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java NullPointerException在尝试使用文字对语音大声说出文字信息时发生_Java_Android_Nullpointerexception_Sms_Text To Speech - Fatal编程技术网

Java NullPointerException在尝试使用文字对语音大声说出文字信息时发生

Java NullPointerException在尝试使用文字对语音大声说出文字信息时发生,java,android,nullpointerexception,sms,text-to-speech,Java,Android,Nullpointerexception,Sms,Text To Speech,当我试图让文本到语音在到达时说sms文本时,我遇到了一个异常,它给了我一个NullPointerException,我似乎可以弄清楚它是想让我做什么,或者错误到底在哪里。我可能有什么问题 错误日志 java.lang.RuntimeException: Unable to start receiver com.fegeley.handsfreetexting.TTS: java.lang.NullPointerException at android.app.ActivityTh

当我试图让文本到语音在到达时说sms文本时,我遇到了一个
异常,它给了我一个
NullPointerException
,我似乎可以弄清楚它是想让我做什么,或者错误到底在哪里。我可能有什么问题

错误日志

java.lang.RuntimeException: Unable to start receiver com.fegeley.handsfreetexting.TTS: java.lang.NullPointerException
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:2677)
        at android.app.ActivityThread.access$1800(ActivityThread.java:170)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:146)
        at android.app.ActivityThread.main(ActivityThread.java:5635)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
        at com.fegeley.handsfreetexting.TTS.speakText(TTS.java:52)
        at com.fegeley.handsfreetexting.TTS.onReceive(TTS.java:74)
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:2669)
        at android.app.ActivityThread.access$1800(ActivityThread.java:170)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:146)
        at android.app.ActivityThread.main(ActivityThread.java:5635)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
        at dalvik.system.NativeStart.main(Native Method)
MainActivity.java

package com.fegeley.handsfreetexting;

import android.media.AudioManager;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.view.View;
import android.widget.Toast;

import java.util.HashMap;
import java.util.Locale;


public class MainActivity extends ActionBarActivity {

TTS tts;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tts = new TTS();
    tts.giveContext(this);
}

@Override
public void onPause(){
    tts.onPause();
    super.onPause();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
package com.fegeley.handsfreetexting;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.telephony.SmsMessage;

import java.util.HashMap;
import java.util.Locale;

/**
 * Created by Kayne on 1/14/2015.
 */
public class TTS extends BroadcastReceiver {

private static Context context;
TextToSpeech tts;

public TTS(){
}

public static void giveContext(Context con){
    context = con;
}

protected void onCreate(Bundle savedInstanceState){
    tts = new TextToSpeech(context,
            new TextToSpeech.OnInitListener() {
                @Override
                public void onInit(int status) {
                    if(status != TextToSpeech.ERROR){
                        tts.setLanguage(Locale.US);
                    }
                }
            });
}

public void onPause(){
    if(tts !=null){
        tts.stop();
        tts.shutdown();
    }
}

public void speakText(String toSpeak){
    HashMap<String, String> hash = new HashMap<String,String>();
    hash.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
            String.valueOf(AudioManager.STREAM_NOTIFICATION));
    tts.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, hash);
}

@Override
public void onReceive(Context context, Intent intent) {
    //---get the SMS message passed in---
    Bundle bundle = intent.getExtras();
    SmsMessage[] msgs = null;
    String str = "";
    //if (bundle != null)
    //{
        //---retrieve the SMS message received---
        Object[] pdus = (Object[]) bundle.get("pdus");
        msgs = new SmsMessage[pdus.length];
        for (int i=0; i<msgs.length; i++){
            msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            str += "SMS from " + msgs[i].getOriginatingAddress();
            str += " :";
            str += msgs[i].getMessageBody().toString();
            str += "\n";
        //}
        //---display the new SMS message---
        speakText(str);
    }
}
}
TTS.java

package com.fegeley.handsfreetexting;

import android.media.AudioManager;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.view.View;
import android.widget.Toast;

import java.util.HashMap;
import java.util.Locale;


public class MainActivity extends ActionBarActivity {

TTS tts;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tts = new TTS();
    tts.giveContext(this);
}

@Override
public void onPause(){
    tts.onPause();
    super.onPause();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
package com.fegeley.handsfreetexting;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.telephony.SmsMessage;

import java.util.HashMap;
import java.util.Locale;

/**
 * Created by Kayne on 1/14/2015.
 */
public class TTS extends BroadcastReceiver {

private static Context context;
TextToSpeech tts;

public TTS(){
}

public static void giveContext(Context con){
    context = con;
}

protected void onCreate(Bundle savedInstanceState){
    tts = new TextToSpeech(context,
            new TextToSpeech.OnInitListener() {
                @Override
                public void onInit(int status) {
                    if(status != TextToSpeech.ERROR){
                        tts.setLanguage(Locale.US);
                    }
                }
            });
}

public void onPause(){
    if(tts !=null){
        tts.stop();
        tts.shutdown();
    }
}

public void speakText(String toSpeak){
    HashMap<String, String> hash = new HashMap<String,String>();
    hash.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
            String.valueOf(AudioManager.STREAM_NOTIFICATION));
    tts.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, hash);
}

@Override
public void onReceive(Context context, Intent intent) {
    //---get the SMS message passed in---
    Bundle bundle = intent.getExtras();
    SmsMessage[] msgs = null;
    String str = "";
    //if (bundle != null)
    //{
        //---retrieve the SMS message received---
        Object[] pdus = (Object[]) bundle.get("pdus");
        msgs = new SmsMessage[pdus.length];
        for (int i=0; i<msgs.length; i++){
            msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            str += "SMS from " + msgs[i].getOriginatingAddress();
            str += " :";
            str += msgs[i].getMessageBody().toString();
            str += "\n";
        //}
        //---display the new SMS message---
        speakText(str);
    }
}
}
package com.fegeley.handsfreetexting;
导入android.content.BroadcastReceiver;
导入android.content.Context;
导入android.content.Intent;
导入android.media.AudioManager;
导入android.os.Bundle;
导入android.speech.tts.TextToSpeech;
导入android.telephony.sms消息;
导入java.util.HashMap;
导入java.util.Locale;
/**
*由Kayne于2015年1月14日创建。
*/
公共类TTS扩展广播接收机{
私有静态语境;
texttospeechtts;
公共TTS(){
}
公共静态上下文(上下文con){
上下文=con;
}
创建时受保护的void(Bundle savedInstanceState){
tts=新文本到语音(上下文,
新的TextToSpeech.OnInitListener(){
@凌驾
公共无效onInit(int状态){
if(状态!=TextToSpeech.ERROR){
tts.setLanguage(Locale.US);
}
}
});
}
公共无效暂停(){
如果(tts!=null){
tts.stop();
tts.shutdown();
}
}
公共void speakText(字符串到speak){
HashMap hash=新的HashMap();
hash.put(TextToSpeech.Engine.KEY_PARAM_流,
字符串.valueOf(AudioManager.STREAM_通知));
tts.speak(toSpeak、TextToSpeech.QUEUE\u FLUSH、hash);
}
@凌驾
公共void onReceive(上下文、意图){
//---获取传入的SMS消息---
Bundle=intent.getExtras();
SmsMessage[]msgs=null;
字符串str=“”;
//if(bundle!=null)
//{
//---检索收到的SMS消息---
Object[]pdus=(Object[])bundle.get(“pdus”);
msgs=新SMS消息[PDU.length];

对于(int i=0;i我不知道库,但堆栈跟踪告诉我们在TTS.java的第52行出现了NullPointerException:

str += "SMS from " + msgs[i].getOriginatingAddress();
这意味着msgs[i]为空,尽管在此之前它被分配了一行:

msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
因此createFromPdu返回null。 由于createFromPdu似乎是一个框架方法,因此从bundle中检索到的PDU[i]很可能为空。 在阅读之前,请确保您已将“PDU”写入包中

问候,, Max

第52行的“tts”对象为空

您似乎正在BroadcastReceiver的“onCreate()”中初始化它

protected void onCreate(Bundle savedInstanceState){
    tts = new TextToSpeech(context,
            new TextToSpeech.OnInitListener()
请注意,BroadcastReceiver类没有任何onCreate()活动样式的回调方法。

我猜您假设系统将调用BroadcastReceiver类的onCreate(),但对于BroadcastReceiver则不是这样

protected void onCreate(Bundle savedInstanceState){
    tts = new TextToSpeech(context,
            new TextToSpeech.OnInitListener()
您可以在onReceive()中初始化“tts”对象,如下所示:

public void onReceive(Context context1, Intent intent) {
    //---get the SMS message passed in---

    tts = new TextToSpeech(context,
            new TextToSpeech.OnInitListener() {
                @Override
                public void onInit(int status) {
                    if(status != TextToSpeech.ERROR){
                        tts.setLanguage(Locale.US);
                    }
                }
            });
另外,更改MainActivity.java中的以下行

package com.fegeley.handsfreetexting;

import android.media.AudioManager;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.view.View;
import android.widget.Toast;

import java.util.HashMap;
import java.util.Locale;


public class MainActivity extends ActionBarActivity {

TTS tts;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tts = new TTS();
    tts.giveContext(this);
}

@Override
public void onPause(){
    tts.onPause();
    super.onPause();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
package com.fegeley.handsfreetexting;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.telephony.SmsMessage;

import java.util.HashMap;
import java.util.Locale;

/**
 * Created by Kayne on 1/14/2015.
 */
public class TTS extends BroadcastReceiver {

private static Context context;
TextToSpeech tts;

public TTS(){
}

public static void giveContext(Context con){
    context = con;
}

protected void onCreate(Bundle savedInstanceState){
    tts = new TextToSpeech(context,
            new TextToSpeech.OnInitListener() {
                @Override
                public void onInit(int status) {
                    if(status != TextToSpeech.ERROR){
                        tts.setLanguage(Locale.US);
                    }
                }
            });
}

public void onPause(){
    if(tts !=null){
        tts.stop();
        tts.shutdown();
    }
}

public void speakText(String toSpeak){
    HashMap<String, String> hash = new HashMap<String,String>();
    hash.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
            String.valueOf(AudioManager.STREAM_NOTIFICATION));
    tts.speak(toSpeak, TextToSpeech.QUEUE_FLUSH, hash);
}

@Override
public void onReceive(Context context, Intent intent) {
    //---get the SMS message passed in---
    Bundle bundle = intent.getExtras();
    SmsMessage[] msgs = null;
    String str = "";
    //if (bundle != null)
    //{
        //---retrieve the SMS message received---
        Object[] pdus = (Object[]) bundle.get("pdus");
        msgs = new SmsMessage[pdus.length];
        for (int i=0; i<msgs.length; i++){
            msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            str += "SMS from " + msgs[i].getOriginatingAddress();
            str += " :";
            str += msgs[i].getMessageBody().toString();
            str += "\n";
        //}
        //---display the new SMS message---
        speakText(str);
    }
}
}
删除:
tts.giveContext(this);
Add:
tts.giveContext(getApplicationContext());


此更改是为了防止receiver CallNotAllowedException

您不能在广播接收器中实例化TextToSpeech对象。您的代码

speakText(str);
onReceive
的末尾,在文本到语音的调用
onInit
之前,会调用onReceive,因此您会得到speak failed,而不是绑定到TTS引擎。
当SMS到达时,系统将实例化清单中定义的TTS对象。它与您在MainActivity中实例化的TTS无关。
当你的应用程序打开时,你没有得到
NPE
,因为
TTS
类中
static
声明
context
,你在
main活动中实例化了一个对象,因此
context
不是空的,因此你在
onCreate
中声明的
TTS
对象>onReceive
asAADTechnical建议值不为空。
当您的应用程序关闭时,在
main活动中声明的
tts
对象将被销毁,因此任何
tts
对象中的
context
成员将在不进行任何调用的情况下启动
giveContext
将为空。并且当系统实例化
tts
对象时,将不会调用
giveContext
因此,object
context
为null,类中实例化的
tts
对象为null,您将得到
NPE

您需要做的是创建一个
service
类,在该类中实例化一个TTS对象,并在
onReceive

public class SMSService extends Service
{
    // instantiate a TTS object in this class
}


事实上,我刚刚意识到,TTS.java中有16行额外的导入行,我在复制到问题时遗漏了它们,所以第52行实际上是16行。我将编辑问题以解决这个问题。哦,我没有看到查询中的不一致性,抱歉。AADTechnical的解决方案可能就是它。在应用了您的建议后,我测试了代码,当我在应用程序仍然打开的情况下收到短信时,它会给我一个错误,说“speak failed:not bound to TTS engine”,但当我在应用程序关闭的情况下收到短信时,它仍然会说“NullPointerException at TTS.java:45”,这是
public void onReceive(上下文上下文1,意图){(第45行)tts=new TextToSpeech(上下文,new TextToSpeech.OnInitListener(){@Override public void onInit(int status){if(status!=TextToSpeech.ERROR){tts.setLanguage(Locale.US);}}}};
1.当关闭应用程序并收到短信时,TTS.giveContext(getApplicationContext())无法为您提供上下文(因为应用程序可能会被终止)。您可以