当prinln加速度计事件值时应用程序崩溃
Posted
技术标签:
【中文标题】当prinln加速度计事件值时应用程序崩溃【英文标题】:App crash when prinln accelerometer event value 【发布时间】:2017-01-08 10:42:36 【问题描述】:我开发了一个 PC 远程应用程序,该应用程序能够使用 android 加速度计传感器移动光标鼠标。我使用 java.io.PrintWriter 从 onSensorChanged 读取加速度计事件值并发送到服务器,但应用程序崩溃。请帮忙。 error log Code
Context context;
ToggleButton toggleButton2;
private ToggleButton toggleButton1;
Button nextButton;
Button previousButton;
TextView mousePad;
TextView returnedText;
TextView textViewX;
TextView textViewY;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private boolean isConnected=false;
private boolean mouseMoved=false;
private Socket socket;
private PrintWriter out;
private float initX =0;
private float initY =0;
private float disX =0;
private float disY =0;
private SpeechRecognizer speech = null;
private Intent recognizerIntent;
private String LOG_TAG = "VoiceRecognitionActivity";
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
context = this;
returnedText = (TextView) findViewById(R.id.returnedText);
toggleButton1 = (ToggleButton) findViewById(R.id.toggleButton1);
toggleButton2 = (ToggleButton) findViewById(R.id.toggleButton2);
nextButton = (Button)findViewById(R.id.nextButton);
previousButton = (Button)findViewById(R.id.previousButton);
textViewX = (TextView) findViewById(R.id.textViewX);
textViewY = (TextView) findViewById(R.id.textViewy);
nextButton.setOnClickListener(this);
previousButton.setOnClickListener(this);
mousePad = (TextView)findViewById(R.id.mousePad);
mousePad.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
if(isConnected && out!=null)
switch(event.getAction())
case MotionEvent.ACTION_DOWN:
//save X and Y positions when user touches the TextView
initX =event.getX();
initY =event.getY();
mouseMoved=false;
break;
case MotionEvent.ACTION_MOVE:
disX = event.getX()- initX; //Mouse movement in x direction
disY = event.getY()- initY; //Mouse movement in y direction
/*set init to new position so that continuous mouse movement
is captured*/
initX = event.getX();
initY = event.getY();
if(disX !=0|| disY !=0)
out.println(disX +","+ disY); //send mouse movement to server
mouseMoved=true;
break;
case MotionEvent.ACTION_UP:
//consider a tap only if usr did not move mouse after ACTION_DOWN
if(!mouseMoved)
out.println(Constants.MOUSE_LEFT_CLICK);
return true;
);
speech = SpeechRecognizer.createSpeechRecognizer(this);
speech.setRecognitionListener(this);
recognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE,
"en");
recognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,
this.getPackageName());
recognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
recognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
toggleButton1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
if (isChecked)
speech.startListening(recognizerIntent);
else
speech.stopListening();
);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
@Override
public boolean onCreateOptionsMenu(Menu menu)
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
int id = item.getItemId();
if(id == R.id.action_settings)
Intent i = new Intent(getApplicationContext(), SetIP.class);
startActivity(i);
finish();
//noinspection SimplifiableIfStatement
if(id == R.id.action_connect)
Intent intent = getIntent();
String ipadd = intent.getStringExtra("ipaddress");
ConnectPhoneTask connectPhoneTask = new ConnectPhoneTask();
connectPhoneTask.execute(ipadd);
return true;
return super.onOptionsItemSelected(item);
@Override
public void onClick(View v)
switch (v.getId())
case R.id.playPauseButton:
out.println(Constants.MOUSE_RIGHT_CLICK);
break;
case R.id.nextButton:
if (isConnected && out!=null)
out.println(Constants.NEXT);
break;
case R.id.previousButton:
if (isConnected && out!=null)
out.println(Constants.PREVIOUS);
break;
@Override
public void onDestroy()
super.onDestroy();
if(isConnected && out!=null)
try
out.println("exit");
socket.close();
catch (IOException e)
Log.e("remotedroid", "Error in closing socket", e);
@Override
public void onResume()
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
@Override
protected void onPause()
super.onPause();
if (speech != null)
speech.destroy();
Log.i(LOG_TAG, "destroy");
mSensorManager.unregisterListener(this);
public void onStop()
super.onStop();
mSensorManager.unregisterListener(this);
public void onAccuracyChanged(Sensor sensor, int accuracy)
// can be safely ignored for this demo
public void onSensorChanged(SensorEvent event)
float x = event.values[0];
float y = event.values[1];
textViewX.setText(Float.toString(x));
textViewY.setText(Float.toString(y));
Log.i(LOG_TAG, x+","+y);
if ((x = null) && (y = null))
try
out.println(String.valueOf(x)+","+String.valueOf(y));
catch (IOException e)
Log.e("remotedroid", "huhuhu", e);
@Override
public void onBeginningOfSpeech()
Log.i(LOG_TAG, "onBeginningOfSpeech");
@Override
public void onBufferReceived(byte[] buffer)
Log.i(LOG_TAG, "onBufferReceived: " + buffer);
@Override
public void onEndOfSpeech()
Log.i(LOG_TAG, "onEndOfSpeech");
toggleButton1.setChecked(false);
@Override
public void onError(int errorCode)
String errorMessage = getErrorText(errorCode);
Log.d(LOG_TAG, "FAILED " + errorMessage);
toggleButton1.setChecked(false);
@Override
public void onEvent(int arg0, Bundle arg1)
Log.i(LOG_TAG, "onEvent");
@Override
public void onPartialResults(Bundle arg0)
Log.i(LOG_TAG, "onPartialResults");
@Override
public void onReadyForSpeech(Bundle arg0)
Log.i(LOG_TAG, "onReadyForSpeech");
@Override
public void onResults(Bundle results)
Log.i(LOG_TAG, "onResults");
ArrayList<String> matches = results
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
String text = "";
for (String result : matches)
text = result;
out.println(text);
returnedText.setText(text);
@Override
public void onRmsChanged(float rmsdB)
Log.i(LOG_TAG, "onRmsChanged: " + rmsdB);
public static String getErrorText(int errorCode)
String message;
switch (errorCode)
case SpeechRecognizer.ERROR_AUDIO:
message = "Audio recording error";
break;
case SpeechRecognizer.ERROR_CLIENT:
message = "Client side error";
break;
case SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS:
message = "Insufficient permissions";
break;
case SpeechRecognizer.ERROR_NETWORK:
message = "Network error";
break;
case SpeechRecognizer.ERROR_NETWORK_TIMEOUT:
message = "Network timeout";
break;
case SpeechRecognizer.ERROR_NO_MATCH:
message = "No match";
break;
case SpeechRecognizer.ERROR_RECOGNIZER_BUSY:
message = "RecognitionService busy";
break;
case SpeechRecognizer.ERROR_SERVER:
message = "error from server";
break;
case SpeechRecognizer.ERROR_SPEECH_TIMEOUT:
message = "No speech input";
break;
default:
message = "Didn't understand, please try again.";
break;
return message;
public class ConnectPhoneTask extends AsyncTask<String,Void,Boolean>
@Override
protected Boolean doInBackground(String... params)
boolean result = true;
try
InetAddress serverAddr = InetAddress.getByName(params[0]);
socket = new Socket(serverAddr, Constants.SERVER_PORT);//Open socket on server IP and port
catch (IOException e)
Log.e("remotedroid", "Error while connecting", e);
result = false;
return result;
@Override
protected void onPostExecute(Boolean result)
isConnected = result;
Toast.makeText(context,isConnected?"Connected to server!":"Error while connecting",Toast.LENGTH_LONG).show();
try
if(isConnected)
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);
catch (IOException e)
Log.e("remotedroid", "Error while creating OutWriter", e);
Toast.makeText(context,"Error while connecting",Toast.LENGTH_LONG).show();
【问题讨论】:
你的代码中out
在哪里初始化?
请附上问题代码。
我只声明了私有的PrintWriter; (我是新手对不起)
这就是问题所在,您必须在使用之前启动out
变量。查看错误日志,它清楚地指出NullPointerException
在out
变量上
@codePG 你能举个例子如何启动变量。
【参考方案1】:
确保在使用out
变量之前启动它。查看您的代码,使用
if(isConnected && out!=null)
// Your code to use out
// out.println(.......);
上面的if
条件将检查变量是否为空并且连接是否已经建立。
在ConnectPhoneTask
类中,onPostExecuted
方法是启动out
变量的地方,确保与手机建立连接。
//This is where the variable is initiated already in your code
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);
所以out
变量只能在建立连接后使用一次。
请看下面的例子,
public void onSensorChanged(SensorEvent event)
float x = event.values[0];
float y = event.values[1];
textViewX.setText(Float.toString(x));
textViewY.setText(Float.toString(y));
Log.i(LOG_TAG, x+","+y);
if(isConnected && out!=null)
out.println(String.valueOf(x) + "," + String.valueOf(y));
【讨论】:
非常感谢@codePG。我的代码现在正在运行。以上是关于当prinln加速度计事件值时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章