Today I write a program.It works successfully and is almost finished.But I found when I close the Socket,BufferedReaderandPrintWriter,the program always shows ANR.I feel confused about that.Is there any sequence to close the program??
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
try {
mPrintWriter.println("192.168.2.131;"+mSocket.getLocalAddress().toString().replace("/", "")+";byebye");
mPrintWriter.close();
mBufferedReader.close();
mSocket.close();
net_.interrupt(); //This is the thread to send and receive data.
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This is my question and I want to eliminate this bug to keep my program perfect.Thanks
Read this Android - how do I investigate an ANR?
And maybe try something like that
#Override
public void onClick(DialogInterface dialog, int which) {
thread = new Thread(new Runnable() {
#Override
public void run() {
try {
mPrintWriter.println("192.168.2.131;"+mSocket.getLocalAddress().toString().replace("/", "")+";byebye");
} catch (IOException e) {
e.printStackTrace();
} finally{
mPrintWriter.close();
mBufferedReader.close();
}
try{
net_.interrupt();
}catch (IOException e) {
e.printStackTrace();
}finally{
mSocket.close();
}
}
});
thread .start();
}
And at the end of your app you should join that thread
thread.join();
Related
I have an App that is receiving a video file from another App that is working as a Server. While the App is saving the file received on the socket, the video stream starts playing the file (which is under construction). In the code sample, after I press the btnStream, I press the btnPlay and App runs successfully. However, if the playing rate is greater than the download rate, an error will occur. I want to avoid this case. So I need to have a listener on the Video Playing that will pause the videoview when it predicts that this error will occur. I know a solution where if I know the video size, I can counter the bytes received and monitor how many seconds have been buffered and see if the videoview should pause or not. However, is it possible to do it without knowing the video file size? Or having two threads that depends on each other? Thanks.
Note: the VideoView used is a custom one where it can play FileDescriptor.
btnStream.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String s = etURL.getText().toString();
String ip = "10.0.0.24";
int port = 7878;
mct= new VideoDownloadTask(ip,port);
mct.execute();
}});
final MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(mVideoView);
Button btnPlay = (Button) findViewById(R.id.button2);
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
mVideoView.setVideoFD((new FileInputStream(new File("/sdcard/tempVideo.mp4")).getFD()));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mVideoView.seekTo(0);
mVideoView.start();
}
});
}
public class VideoDownloadTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
Socket socket=null;
VideoDownloadTask(String addr, int port){
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
socket = new Socket(InetAddress.getByName(dstAddress), dstPort);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
if(socket!=null)socket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
File f = new File("/sdcard/tempVideo.mp4");
try {
f.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DataInputStream in=null;
try {
in = new DataInputStream (socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileOutputStream videoFile = null;
try {
videoFile = new FileOutputStream(f);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int len;
byte buffer[] = new byte[8192];
try {
while((len = in.read(buffer)) != -1) {
videoFile.write(buffer, 0, len);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
videoFile.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
Toast.makeText(getApplicationContext(), "Done Downloading File",
Toast.LENGTH_LONG).show();
super.onPostExecute(result);
}
}
}
I applied a simple solution that resolved the problem. I am sharing it if anyone is having the same problem. The solution was simply to add an error listener to the videoView that will block the error popups and pauses the video.
mVideoView.setOnErrorListener(new OnErrorListener(){
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
statusText.setText("ERROR PLAYING VIDEO");
mVideoView.pause();
return true;
}
});
pDialog = new ProgressDialog(PlayVideoActivity.this);
pDialog.setTitle("Gajacharitra");
pDialog.setMessage("Buffering video...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
try {
// Start the MediaController
mediacontroller.setAnchorView(mVideoView);
// Get the URL from String VideoURL
Uri video = Uri.parse(mVideoURL);
mVideoView.setMediaController(mediacontroller);
mVideoView.setVideoURI(video);
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
pDialog.dismiss();
mVideoView.start();
}
});
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
mVideoView.pause();
pDialog.dismiss();
Toast.makeText(PlayVideoActivity.this, "Can't play this video.", Toast.LENGTH_LONG).show();
finish();
return true;
}
});
} catch (Exception e) {
/*Log.e("Error", e.getMessage());
e.printStackTrace();*/
pDialog.dismiss();
Toast.makeText(PlayVideoActivity.this, "Can't play this video.", Toast.LENGTH_LONG).show();
finish();
}
I have a problem, I have a for loop and a ProgressDialog and would like to see something like (10/5) where 10 is the total items to be processed by and for the 5 elements are currently being developed. I have this code.
new Thread(new Runnable() {
public void run() {
for(int i=0; i<adapter.getTotalItems().size(); i++) {
try {
index = i;
progressDialog = ProgressDialog.show(MyClass.this,adapter.getTotalItems().size()+"/"+index, );
MyClass.this.runOnUiThread(new Runnable() {
public void run() {
progressDialog.cancel();
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(1*2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
MyClass.this.runOnUiThread(new Runnable() {
public void run() {
progressDialog.dismiss();
}
});
}
}).start();
Don´t cancle the ProgressDialog every Time, just Change the Title like:
mProgressDialog.setTile(adapter.getTotalItems().size()+"/"+index);
That´s it.
I've been trying to get this to work for a while. I'm trying to send a message from my phone to a simple server on my laptop. I keep getting the NetworkOnMainThreadException, I've tried making a new Thread(new Runnable() etc. and an ASynchTask but I am still getting the error and the app is force closing. I have read through 3 or 4 of the questions similar to this but none have worked for me. Here is my code:
final Button post2 = (Button) findViewById(R.id.postbutton2);
post2.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
// TODO Auto-generated method stub
#Override
public void run() {
// TODO Auto-generated method stub
message = text.getText().toString(); //Message is a string, text is an EditText.
text.setText("");
try {
clientSocket = new Socket("10.0.0.2", 4445);
printWriter = new PrintWriter(clientSocket
.getOutputStream(), true);
printWriter.write(message);
printWriter.flush();
printWriter.close();
clientSocket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
Toast.makeText(context, e.toString(),
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, e.toString(),
Toast.LENGTH_SHORT).show();
}
}
}).start();
}
});
try removing the following part from your code.
message = text.getText().toString(); //Message is a string, text is an EditText.
text.setText("");
It does not look right to do this in this thread.
You must do YourActivity.this.runOnUiThread(new Runnable() { public void run() { /* show your toast here */ });
I'm trying to create a speech recognition app where the app recieves voice and sends out stuff. I'd like everything that the onEndOfSpeech method to be called to wait a second and then do the entire voice recognition intent to start over again.
public void onEndOfSpeech() {
Log.d("Speech", "onEndOfSpeech");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}
Not sure that I am doing this correctly.
Thanks!
This is how it should be
try {
Thread.sleep(3000);
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
} catch (InterruptedException e) {
// it depends on your app logic what to do with InterruptedException, you can process it or rethrow or restore interrupted flag
}
Try this code
protected boolean _active = true;
// time to display the splash screen in ms
protected int _splashTime = 1000;
Thread splashThread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while(_active && (waited < _splashTime)) {
sleep(100);
if(_active) {
waited += 100;
}
}
} catch(InterruptedException e) {
e.printStackTrace();
mSpeechRecognizer.startListening(mSpeechRecognizerIntent);
}
I have a naive problem, but I confused: I have made application which uses Facebook SDK, and it works good on my device and emulator, and it doesn't work on customer's device. He doesn't get any error or exceptions - when he press button for authorize he will see "loading" message, but progress bar will be closed, and authorization will be canceled. What problem is it? Thank you for anything hints
private void submitExec() {
/* if (SQLiteDbWrapper.getInstance().getBookCount()==0) {
Toast.makeText(this, "A list of books is empty", Toast.LENGTH_LONG).show();
return;
}*/
SQLiteDbWrapper.getInstance().makeFacebook(this, this.getApplicationContext());
if (SQLiteDbWrapper.getInstance().getConnector().getFacebook().isSessionValid()) {
//new SubmitClass().execute();
}
else {
SessionEvents.AuthListener listener = new SessionEvents.AuthListener() {
#Override
public void onAuthSucceed() {
//MyBookDroidActivity.this.executeSubmitClass();
}
#Override
public void onAuthFail(String error) {
}
};
SessionEvents.addAuthListener(listener);
SQLiteDbWrapper.getInstance().getConnector().login();
}
}
It is function for authorizating.
public void makeFacebook(Activity activity, Context context) {
if (mConnector==null||!mConnector.getFacebook().isSessionValid()) {
mConnector=new FacebookConnector(FACEBOOK_APPID, activity, context,
new String[] {"publish_stream", "read_stream", "email"});
}
}
It is function for making FacebookConnector.
Try adding logging:
public void appendLog(String text)
{
File logFile = new File("sdcard/log.file");
if (!logFile.exists())
{
try
{
logFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try
{
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(text);
buf.newLine();
buf.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
If you can't run some kind of LogCat or collect the stacktrace on the device yourself, you may want to look into:
http://code.google.com/p/microlog4android/