Reputation: 126
My App is voice streaming between two android phones.
this code is listening part(server side)
but i face this error
android.view.ViewRootImpl$CalledFromWrongThreadException
i put the cat logs.have a look
please give me your best help.
thanks in advance.
code :
package com.example.encryptechatresiving;
import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.view.Menu;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
@SuppressLint("NewApi") public class MainActivity extends Activity {
private Button receiveButton,stopButton;
private TextView recive;
private EditText port;
public static DatagramSocket socket;
private AudioTrack speaker;
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_OUT_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean status = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiveButton = (Button) findViewById (R.id.receive_button);
stopButton = (Button) findViewById (R.id.stop_button);
recive= (TextView) findViewById(R.id.receive_label);
//recive.setText("Created...!");
receiveButton.setOnClickListener(receiveListener);
stopButton.setOnClickListener(stopListener);
//receiveButton.setText("Start Reciving...!");
//stopButton.setText("Stop Reciving...!");
port=(EditText) findViewById(R.id.editText1);
//port.setText("1234");
AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
sampleRate =Integer.parseInt( audioManager.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
}
private final OnClickListener stopListener = new OnClickListener() {
@Override
public void onClick(View v) {
status = false;
//recive.setText("Recoder Stop...!");
speaker.release();
Log.d("VR","Speaker released");
}
};
private final OnClickListener receiveListener = new OnClickListener() {
@Override
public void onClick(View arg0) {
status = true;
// recive.setText(" before Start ");
startReceiving();
}
};
public void startReceiving() {
Thread receiveThread = new Thread (new Runnable() {
@Override
public void run() {
try {
int port_num=Integer.parseInt(port.getText().toString());
DatagramSocket socket = new DatagramSocket(port_num);
Log.d("VR", "Socket Created");
//minimum buffer size. need to be careful. might cause problems. try setting manually if any problems faced
int minBufSize =256; //AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
byte[] buffer = new byte[4096]; //256
speaker = new AudioTrack(AudioManager.STREAM_VOICE_CALL,sampleRate,channelConfig,audioFormat,16000,AudioTrack.MODE_STREAM);
//AudioTrack.MODE_STREAM,
speaker.play();
// recive.setText("hear anything...?");
while(status == true) {
try {
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
Log.d("VR", "Packet Received");
//reading content from packet
buffer=packet.getData();
Log.d("VR", "Packet data read into buffer");
//sending data to the Audiotrack obj i.e. speaker
speaker.write(buffer, 0, minBufSize);
Log.d("VR", "Writing buffer content to speaker");
} catch(IOException e) {
Log.e("VR","IOException");
}
}
} catch (SocketException e) {
Log.e("VR", "SocketException");
}
}
});
receiveThread.start();
}
}
Logs:
05-23 22:56:10.646: D/VR(789): Socket Created
05-23 22:56:10.746: W/dalvikvm(789): threadid=13: thread exiting with uncaught exception (group=0x40a71930)
05-23 22:56:10.807: E/AndroidRuntime(789): FATAL EXCEPTION: Thread-77
05-23 22:56:10.807: E/AndroidRuntime(789): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
05-23 22:56:10.807: E/AndroidRuntime(789): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:823)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.view.View.requestLayout(View.java:15473)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.view.View.requestLayout(View.java:15473)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.view.View.requestLayout(View.java:15473)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.view.View.requestLayout(View.java:15473)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:318)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.view.View.requestLayout(View.java:15473)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.widget.TextView.checkForRelayout(TextView.java:6452)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.widget.TextView.setText(TextView.java:3696)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.widget.TextView.setText(TextView.java:3554)
05-23 22:56:10.807: E/AndroidRuntime(789): at android.widget.TextView.setText(TextView.java:3529)
05-23 22:56:10.807: E/AndroidRuntime(789): at com.example.encryptechatresiving.MainActivity$3.run(MainActivity.java:113)
05-23 22:56:10.807: E/AndroidRuntime(789): at java.lang.Thread.run(Thread.java:856)
05-23 22:56:10.897: W/ActivityManager(291): Force finishing activity com.example.encryptechatresiving/.MainActivity
05-23 22:56:10.906: W/WindowManager(291): Failure taking screenshot for (246x410) to layer 21010
Upvotes: 2
Views: 4007
Reputation: 740
Toast must be in UI thread .
Toast.makeText(getApplicationContext(), "Start Talking....",Toast.LENGTH_LONG).show();
Upvotes: 1
Reputation: 7132
Actually you are accessing
port.getText().toString()
from separate non-UI thread which is wrong that's why you are getting this exception. So, try to access it from main thread.
//accessing it from ui-thread
runOnUiThread(new Runnable() {
@Override
public void run() {
int port_num=Integer.parseInt(port.getText().toString());
}
});
Edit: Test the edited code if again you are getting syntax error as mentioned by you in your comments
private int port_num;
public void startReceiving() {
Thread receiveThread = new Thread (new Runnable() {
@Override
public void run() {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
port_num=Integer.parseInt(port.getText().toString());
}
});
DatagramSocket socket = new DatagramSocket(port_num);
Log.d("VR", "Socket Created");
//minimum buffer size. need to be careful. might cause problems. try setting manually if any problems faced
int minBufSize =256; //AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
byte[] buffer = new byte[4096]; //256
speaker = new AudioTrack(AudioManager.STREAM_VOICE_CALL,sampleRate,channelConfig,audioFormat,16000,AudioTrack.MODE_STREAM);
//AudioTrack.MODE_STREAM,
speaker.play();
// recive.setText("hear anything...?");
while(status == true) {
try {
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
Log.d("VR", "Packet Received");
//reading content from packet
buffer=packet.getData();
Log.d("VR", "Packet data read into buffer");
//sending data to the Audiotrack obj i.e. speaker
speaker.write(buffer, 0, minBufSize);
Log.d("VR", "Writing buffer content to speaker");
} catch(IOException e) {
Log.e("VR","IOException");
}
}
} catch (SocketException e) {
Log.e("VR", "SocketException");
}
}
});
receiveThread.start();
}
Upvotes: 2
Reputation: 7214
You cannot show a Toast
message from a background Thread
. so replace
Toast.makeText(getApplicationContext(), "Start Talking....",Toast.LENGTH_LONG).show();
with
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Toast.makeText(context, "Running background", Toast.LENGTH_SHORT).show();
}
});
This runs your Toast
on UI Thread
.
Upvotes: 0