MediaRecorder.start() throwing IllegalStateException - java

I have read similar threads and haven't found an answer which would solve my problem.
I am writing an app with 2 different MediaRecorders. One for noise detection and another one for recording. What I want to do is - when the first MediaRecorder detects noise levels above 4.0 (I am using Google's SoundMeter class for detection) it will initiate another MediaRecorder and start recording. If the soundlevels stay below 4.0 for 10 seconds, then stop recording and keep listening. All of this is done in an AsynTask, in an endless while(true) loop, which will be broken, only if a corresponding button is clicked.
The detection is working fine, but the IllegalStateException is thrown when start() is called on the recording MediaRecorder.
Here is the AsyncTask:
private class NoiseDetection extends AsyncTask {
double currentSoundInputLevel;
#Override
protected Object doInBackground(Object[] params) {
int i = 0;
soundMeter = new SoundMeter();
try {
soundMeter.start();
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("error", e.getMessage());
}
if(isCancelled()){
soundMeter.stop();
if(currentlyRecording) {
soundRecorder.stop();
}
break;
}
currentSoundInputLevel = soundMeter.getAmplitudeEMA();
if(!currentlyRecording && currentSoundInputLevel > 4.0){
soundRecorder = new SoundRecorder();
try {
soundRecorder.start(getFileNameString());
currentlyRecording = true;
} catch (IOException e) {
Log.e("error", e.getMessage());
}
} else if(currentlyRecording && currentSoundInputLevel < 4.0) {
i++;
if(i > 10) {
soundRecorder.stop();
}
}
}
return null;
}
}
And here is the SoundRecorder:
public class SoundRecorder {
private MediaRecorder mRecorder = null;
public void start(String fileName) throws IOException {
if (mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mRecorder.setOutputFile(Environment.getExternalStorageDirectory().getPath() + "/" + fileName);
mRecorder.prepare();
mRecorder.start();
}
}
public void stop() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
}
The exception is thrown on mRecorder.start();.
I think the problem lies within the idea of doing everything in this while loop, but I haven't come up with a better idea of achieving the forementioned goal.
Also, I have tried different OutputFormats and AudioEncoders without success. (reference to https://stackoverflow.com/a/23065021/1826152)
Another note, which could be of use, is the fact that the file is actually created in the sdcard dir.
The phone I am using for development is a Nexus 5. The permissions in android manifest are the following:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Update:
Right now I have tried to remove the SoundRecorder operations from the while loop by creating a RecordingHandler. The new code for the doInBackground() is as follows:
protected Object doInBackground(Object[] params) {
int i = 0;
soundMeter = new SoundMeter();
RecordingHandler recordingHandler = null;
try {
soundMeter.start();
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
if(isCancelled()){
soundMeter.stop();
if(currentlyRecording && recordingHandler != null){
recordingHandler.kill();
}
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("error", e.getMessage());
}
if(!currentlyRecording && soundMeter.getAmplitudeEMA() > 4.0){
recordingHandler = new RecordingHandler(deviceId);
currentlyRecording = true;
recordingHandler.run();
}
}
return null;
}
and the RecordingHandler itself is the following:
public class RecordingHandler implements Runnable {
SoundRecorder soundRecorder;
SoundMeter soundMeter;
String deviceID;
boolean isKilled = false;
public RecordingHandler(String deviceID){
this.soundRecorder = new SoundRecorder();
this.soundMeter = new SoundMeter();
this.deviceID = deviceID;
}
#Override
public void run() {
int i = 0;
try {
soundMeter.start();
soundRecorder.start(getFileNameString());
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
if(isKilled){
break;
}
if(soundMeter.getAmplitudeEMA() < 4.0){
i++;
if(i > 10){
break;
}
} else {
i = 0;
}
}
soundMeter.stop();
soundRecorder.stop();
EavesDrop.currentlyRecording = false;
}
public void kill(){
this.isKilled = true;
}
private String getFileNameString() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
return deviceID + "_" + sdf.format(new Date());
}
}
Now the IllegalStateException is thrown from the Recordinghandler - on the line soundMeter.start();.
Considering that this soundMeter object is basically not handled in a loop anymore, should eliminate the though that the while loop was the culprit. Is there something that I am missing? Could the problem be in having multiple MediaRecorders working at the same time? As you can see, now it is the SoundMeter, not the SoundRecorder which is throwing the exception. Actually - whichever start() call I place first in the RecordingHandler, throws the same IllegalStateException.
The question might be connected to Android: Two instances of Media recorder at same time, which unfortunately has no answers.
Any further help would be greatly appreciated!

Okay, it seems I cracked the problem. The problem seems to be in having multiple instances of MediaRecorder working at the same time. What I did, was that I now don't use separate classes for detection and recording, so that the recorder now does it's own detection.
At first I initiate the inital SoundMeter which listens until it gets input over level 4.0. Then I stop the initial SoundMeter and make a new SoundMeter (with different output directory), which starts recording and records until the levels have been below 4.0 for apprixamtely 10 seconds. Then the second SoundMeter is stopped and the background task can start the initial SoundMeter again.
Here is the code which solved my problem,
AsyncTask:
protected Object doInBackground(Object[] params) {
int i = 0;
soundMeter = new SoundMeter();
RecordingHandler recordingHandler = null;
try {
soundMeter.start("/dev/null");
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
if(isCancelled()){
soundMeter.stop();
if(currentlyRecording && recordingHandler != null){
recordingHandler.kill();
}
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("error", e.getMessage());
}
if(!currentlyRecording && soundMeter.getAmplitudeEMA() > 4.0){
soundMeter.stop();
recordingHandler = new RecordingHandler(deviceId);
currentlyRecording = true;
recordingHandler.run();
} else if(!currentlyRecording && !soundMeter.isRunning()){
try {
soundMeter.start("/dev/null");
} catch (IOException e) {
Log.e("error", e.getMessage());
}
}
}
return null;
}
}
And the RecordingHandler.run():
#Override
public void run() {
int i = 0;
try {
soundMeter.start(getFileNameString());
} catch (IOException e) {
Log.e("error", e.getMessage());
}
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e("error", e.getMessage());
}
if(isKilled){
break;
}
if(soundMeter.getAmplitudeEMA() < 4.0){
i++;
if(i > 10){
break;
}
} else {
i = 0;
}
}
soundMeter.stop();
EavesDrop.currentlyRecording = false;
}
The documentation at http://developer.android.com/reference/android/media/MediaRecorder.html , under the release() method documentation, it talks about multiple instances not being suppported on some devices. So it might be a specific device related problem.

Related

In android FlashLight and SOS FlashLight is not working together

I am trying to build a Flashlight app with SOS features. Both features are working individually. But when I want to start the flashlight blinking it blinks but didn't work smoothly. Suppose :
Case 1: If I progress the seek bar flash starts to blinking that's good but if I want to change the seek bar progress during the Flash blinking, progress act like frizzed.
Case 2: during flash blinking, I can't stop the flash immediately.
Case 3: Individually both are working.
I have used threading for blinking the Flashlight. I am giving some code below. My motive is to build a flashlight with an SOS feature.
//When progress seekbar for SOS Flashlight
private void seekbarFunc(int val) {
String myString = "010101010101010101";
long blinkDelay = val + 500; //Delay in ms
new Thread(new Runnable() {
#Override
public void run() {
}
}).start();
for (int i = 0; i < myString.length(); i++) {
if (myString.charAt(i) == '0') {
Utilities.startFlashlight(this, mPreference);
} else {
Utilities.stopFlashlight(this, mPreference);
}
try {
thread.sleep(blinkDelay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// FlashLlight turned on by this method
private static boolean flashLightOn(Context context) {
try {
if (mCameraManager == null) {
initCameraManagerInstance(context);
}
String cameraId = mCameraManager.getCameraIdList()[0];
mCameraManager.setTorchMode(cameraId, true);
// Sending broadcast to update the UI
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(ACTION_UPDATE_UI));
} catch (CameraAccessException e) {
Log.e(TAG, "flashLightOn(): " + e);
return false;
}
return true;
}
//FlashLight turned off by this method
private static boolean flashLightOff(Context context) {
try {
if (mCameraManager == null) {
initCameraManagerInstance(context);
}
String cameraId = mCameraManager.getCameraIdList()[0];
mCameraManager.setTorchMode(cameraId, false);
// Sending broadcast to update the UI
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent(ACTION_UPDATE_UI));
} catch (CameraAccessException e) {
Log.e(TAG, "flashLightOff(): " + e);
return false;
}
return true;
}

How to call CallBack(); function again after executing successfully?

I have a project that deals with RFID Cards, After tapping the card on the RF Reader, It records the data and needs to run the RFCard Reader again. But my problem is after I tapped the card, The next card that will be tapped is can't read due to the CallBack(); hasn't run again.
I have tried this, after 3-5 times, the reader has stopped.
class myCallbackThread extends Thread{
#Override
public void run(){
try{
//my code of saving will be here...
myCallbackThread myCallbackThread = new myCallbackThread();
myCallbackThread.start();
}catch (Throwable e){
e.printStackTrace();
}
}
}
It This full code is a CallBack(); function. My problem is how can I Call it again to repeat the process after it has successfully executed?
class CallBackThread extends Thread {
#Override
public void run() {
try {
RFCardInterface.waitForCardPresent(RFCardInterface.CONTACTLESS_CARD_MODE_AUTO, 1, -1);
if (RFCardInterface.isCallBackCalled &&
RFCardInterface.notifyEvent.eventID == RFCardInterface.CONTACTLESS_CARD_EVENT_FOUND_CARD) {
IDCatcher = StringUtility.ByteArrayToString(RFCardInterface.notifyEvent.eventData,
RFCardInterface.notifyEvent.eventData.length);
IDCatcher = IDCatcher.substring(9, 21).replace(" ", "");
Log.e("IDCatcher", IDCatcher);
EventBus.getDefault().post(new EBTest2());
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
How can I achieve to make it indefinite?. Thank you
EDIT Added my EBtest2()
#Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
public void onEvent(EBTest2 ebTest2) {
Cursor c = dbhelper.getReadableDatabase().rawQuery("select is_arrived,is_closed from trans_settings order by _id desc limit 1", null);
if (c != null && c.moveToFirst()) {
try {
String is_arrived = c.getString(0);
String is_closed = c.getString(1);
if (is_arrived.equals("0") && is_closed.equals("0")) {
SearchEmp();
} else if (is_arrived.equals("1") && is_closed.equals("0")) {
SearchEmp_isArrived();
} else if (is_arrived.equals("1") && is_closed.equals("1")) {
SearchEmp_isClosed();
}
} catch (Throwable e) {
e.printStackTrace();
}
c.close();
}
}

Flash not being turned off on button press(Flashlight App)

I have 3 buttons on the UI. On, Off and SOS(flash at repeated intervals). If I press On and then the Off button the flash turns off as expected.But if I press SOS(it flashes as expected at regular intervals) and then Off it refuses to stop flashing. The code is as follows:
SOSbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
SOSon = true;
startSOS();
onSOSPress();
} catch (Exception ex) {
throw ex;
}
}
});
void onSOSPress() {
try {
Flashlight flashlight=new Flashlight();
SOSon = true;
flashlight.Flashthread = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < System.currentTimeMillis(); i++) {
while (!FlashThreadStop) {
if (FlashOn) {
myParameters.setFlashMode(Parameters.FLASH_MODE_OFF);
try {
myCamera.setParameters(myParameters);
}
catch (Exception ex)
{
//logger.log(Level.SEVERE, "an exception was thrown", ex);
}
myCamera.stopPreview();
FlashOn = false;
} else {
TurnOnFlash();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
flashlight.Flashthread.start();
} catch (Exception ex) {
throw ex;
}
}
and the TurnOff mechanism is as follows:
off.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (FlashOn) {
// turn off flash
TurnOffFlash();
}
}
});
private void TurnOffFlash() {
if (FlashOn) {
if (myCamera == null || myParameters == null) {
return;
}
myParameters = myCamera.getParameters();
myParameters.setFlashMode(Parameters.FLASH_MODE_OFF);
myCamera.setParameters(myParameters);
myCamera.stopPreview();
FlashOn = false;
}
}
void endSOS(){
FlashThreadStop=true;
}
void startSOS(){
FlashThreadStop=false;
}
EDIT: The method onSOSPress() has been updated to reflect the working SOS mode(OFF button works now)
Your TurnOffFlash method does not cover flash blinking very well. You are not stopping the thread so it continues flashing back and forth. You need to add one line to cover that part as well:
Flashthread.interrupt();
This way you'll keep your functionality turning off the flash, and if the thread is running the SOS mode, you'll stop it as well.
Side note: You're failing to follow the common Java nomenclature where methods and variables start with a lowercase letter and use camelCase.

Service Socket Disconnect on Background->Foreground switch

I am writing an IRC Client. The socket connection to the IRC Server is handled via a service. I have managed to stabilize all the UI elements of the Activities in question during the orientation change, but somehow the socket that is maintained by the service is being closed during the change.
Here is what I believe to be the relevant code. Please let me know if you need to see more.
//This is the Service in question
public class ConnectionService extends Service{
private BlockingQueue<String> MessageQueue;
public final IBinder myBind = new ConnectionBinder();
public class ConnectionBinder extends Binder {
ConnectionService getService() {
return ConnectionService.this;
}
}
private Socket socket;
private BufferedWriter writer;
private BufferedReader reader;
private IRCServer server;
private WifiManager.WifiLock wLock;
private Thread readThread = new Thread(new Runnable() {
#Override
public void run() {
try {
String line;
while ((line = reader.readLine( )) != null) {
if (line.toUpperCase().startsWith("PING ")) {
SendMessage("PONG " + line.substring(5));
}
else
queueMessage(line);
}
}
catch (Exception e) {}
}
});
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(MessageQueue == null)
MessageQueue = new LinkedBlockingQueue<String>();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
return myBind;
}
#Override
public boolean stopService(Intent name) {
try {
socket.close();
wLock.release();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return super.stopService(name);
}
#Override
public void onDestroy()
{//I put this here so I had a breakpoint in place to make sure this wasn't firing instead of stopService
try {
socket.close();
wLock.release();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onDestroy();
}
public void SendMessage(String message)
{
try {
writer.write(message + "\r\n");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public String readLine()
{
try {
if(!isConnected())
return null;
else
return MessageQueue.take();
} catch (InterruptedException e) {
return "";
}
}
public boolean ConnectToServer(IRCServer newServer)
{
try {
//create a new message queue (connecting to a new server)
MessageQueue = new LinkedBlockingQueue<String>();
//lock the wifi
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "LockTag");
wLock.acquire();
server = newServer;
//connect to server
socket = new Socket();
socket.setKeepAlive(true);
socket.setSoTimeout(60000);
socket.connect(new InetSocketAddress(server.NAME, Integer.parseInt(server.PORT)), 10000);
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//run basic login scripts.
if(server.PASS != "")
SendMessage("PASS " + server.PASS);
//write nickname
SendMessage("NICK " + server.NICK);
//write username login
SendMessage("USER " + server.NICK + " 0 * :Fluffy IRC");
String line;
while ((line = reader.readLine( )) != null) {
if (line.indexOf("004") >= 0) {
// We are now logged in.
break;
}
else if (line.indexOf("433") >= 0) {
//change to alt Nick
if(!server.NICK.equals(server.ALT_NICK) && !server.ALT_NICK.equals(""))
{
server.NICK = server.ALT_NICK;
SendMessage("NICK " + server.NICK);
}
else
{
queueMessage("Nickname already in use");
socket.close();
return false;
}
}
else if (line.toUpperCase().startsWith("PING ")) {
SendMessage("PONG " + line.substring(5));
}
else
{
queueMessage(line);
}
}
//start the reader thread AFTER the primary login!!!
CheckStartReader();
if(server.START_CHANNEL == null || server.START_CHANNEL == "")
{
server.WriteCommand("/join " + server.START_CHANNEL);
}
//we're done here, go home everyone
} catch (NumberFormatException e) {
return false;
} catch (IOException e) {
return false;
}
return true;
}
private void queueMessage(String line) {
try {
MessageQueue.put(line);
} catch (InterruptedException e) {
}
}
public boolean isConnected()
{
return socket.isConnected();
}
public void CheckStartReader()
{
if(this.isConnected() && !readThread.isAlive())
readThread.start();
}
}
//Here are the relevant portions of the hosting Activity that connects to the service
//NOTE: THE FOLLOWING CODE IS PART OF THE ACTIVITY, NOT THE SERVICE
private ConnectionService conn;
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
conn = ((ConnectionService.ConnectionBinder)service).getService();
Toast.makeText(main_tab_page.this, "Connected", Toast.LENGTH_SHORT)
.show();
synchronized (_serviceConnWait) {
_serviceConnWait.notify();
}
}
#Override
public void onServiceDisconnected(ComponentName name) {
conn = null;
}
};
#Override
protected void onSaveInstanceState(Bundle state){
super.onSaveInstanceState(state);
state.putParcelable("Server", server);
state.putString("Window", CurrentTabWindow.GetName());
unbindService(mConnection);
}
#Override
protected void onDestroy()
{
super.onDestroy();
if(this.isFinishing())
stopService(new Intent(this, ConnectionService.class));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_tab_page);
localTabHost = (TabHost)findViewById(R.id.tabHostMain);
localTabHost.setup();
localTabHost.setOnTabChangedListener(new tabChange());
_serviceConnWait = new Object();
if(savedInstanceState == null)
{//initial startup, coming from Intent to start
//get server definition
server = (IRCServer)this.getIntent().getParcelableExtra(IRC_WINDOW);
server.addObserver(this);
AddTabView(server);
startService(new Intent(this, ConnectionService.class));
}
else
{
server = (IRCServer)savedInstanceState.getParcelable("Server");
String windowName = savedInstanceState.getString("Window");
//Add Needed Tabs
//Server
if(!(windowName.equals(server.GetName())))
AddTabView(server);
//channels
for(IRCChannel c : server.GetAllChannels())
if(!(windowName.equals(c.GetName())))
AddTabView(c);
//reset each view's text (handled by tabChange)
if(windowName.equals(server.GetName()))
SetCurrentTab(server.NAME);
else
SetCurrentTab(windowName);
ResetMainView(CurrentTabWindow.GetWindowTextSpan());
//Rebind to service
BindToService(new Intent(this, ConnectionService.class));
}
}
#Override
protected void onStart()
{
super.onStart();
final Intent ServiceIntent = new Intent(this, ConnectionService.class);
//check start connection service
final Thread serverConnect = new Thread(new Runnable() {
#Override
public void run() {
if(!BindToService(ServiceIntent))
return;
server.conn = conn;
conn.ConnectToServer(server);
server.StartReader();
if(server.START_CHANNEL != null && !server.START_CHANNEL.equals(""))
{
IRCChannel chan = server.FindChannel(server.START_CHANNEL);
if(chan != null)
{
AddTabView(chan);
}
else
{
server.JoinChannel(server.START_CHANNEL);
chan = server.FindChannel(server.START_CHANNEL);
AddTabView(chan);
}
}
}
});
serverConnect.start();
}
private boolean BindToService(Intent ServiceIntent)
{
int tryCount = 0;
bindService(ServiceIntent, mConnection, Context.BIND_AUTO_CREATE);
while(conn == null && tryCount < 10)
{
tryCount++;
try {
synchronized (_serviceConnWait) {
_serviceConnWait.wait(1500);
}
}
catch (InterruptedException e) {
//do nothing
}
}
return conn != null;
}
Im not entirely certain what I am doing wrong there. Obviously there's something I'm missing, haven't found yet, or haven't even thought to check. What happens though is that after the orientation change my Send command gives me this message and nothing happens:
06-04 22:02:27.637: W/System.err(1024): java.net.SocketException: Socket closed
06-04 22:02:27.982: W/System.err(1024): at com.fluffyirc.ConnectionService.SendMessage(ConnectionService.java:90)
I have no idea when the socket is getting closed, or why.
Update
I have changed the code so that rather than binding to the service and using that to start it, instead I call startService and stopService at appropriate points as well as binding to it, on the thought that the service was being destroyed when the binding was lost. This is working exactly like it was before I changed it. The socket still closes on an orientation change, and I have no idea why.
Update :- Code and description
I added the code changes recently made for Start/Stop service and START_STICKY. I also recently read a very good article explaining how the orientation change process flow works and why its NOT a bad idea to add the android:configChanges="orientation|screenSize" line to your manifest. So this fixed the orientation issue, but its still doing the same thing if I put the activity into background mode, and then bring it back to the foreground. That still follows the same Save/Destroy/Create process that the orientation does without that manifest line...and it still closes my socket, and I still don't know why.
I do know that it doesn't close the socket until the re-create process...I know this because the message queue will display messages that were received while the app was in the background, but once I bring it back forward it closes the socket and nothing else can be sent or received.
'Socket closed' means that you closed the socket and then continued to use it. It isn't a 'disconnect'.
You need to put something into that catch block. Never just ignore an exception. You might get a surprise when you see what the exception actually was.
NB Socket.isConnected() doesn't tell you anything about the state of the connection: only whether you have ever connected the Socket. You have, so it returns true.

Why on double click android client received data?

When I click the first time on login button, data send to server and server received data in return on first click data not show on android client screen. When I pressed login button again it again send data and then it show data on client screen... plz help me. Why data is received on secind click i want my data recived on my first click?
Here is the code :
Client tcpip code...
public class SockProg {
private Socket socket;
DataOutputStream dataOutputStream;
DataInputStream dataInputStream;
String data;
String serverip = "192.168.1.7";
int serverport = 4444;
public void connetToServer(){
try {
socket = new Socket(serverip, serverport);
Log.i("AsyncTank", "doInBackgoung: Created Socket");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (socket.isConnected()) {
try {
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void writeToStream(String message) {
try {
if (socket.isConnected()){
dataOutputStream.writeUTF(message.toString());
} else {
Log.i("AsynkTask", "writeToStream : Cannot write to stream, Socket is closed");
}
} catch (Exception e) {
Log.i("AsynkTask", "writeToStream : Writing failed");
}
}
public String readFromStream() {
String ret = null;
try {
if (socket.isConnected()) {
Log.i("AsynkTask", "readFromStream : Reading message");
ret=dataInputStream.readUTF();
Log.i("AsynkTask", "readFromStream : read "+ret);
} else {
Log.i("AsynkTask", "readFromStream : Cannot Read, Socket is closed");
}
} catch (Exception e) {
Log.i("AsynkTask", "readFromStream : Reading failed"+e.getClass());
}
return ret;
}
public void CloseSockets(){
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
here is the code of sychronized thread
public class TCP implements Runnable {
String data;
SockProg sp;
Thread thh;
private static String rdata;
public TCP(SockProg spr, String val) {
sp = spr;
data = val;
thh = new Thread(this);
thh.start();
}
#Override
public void run() {
synchronized(sp) { // synchronized block
//rdata= sp.DataSendRecive(data);
sp.connetToServer();
sp.writeToStream(data);
rdata=sp.readFromStream();
sp.CloseSockets();
}
}
public static String getData(){
return rdata;
}
}
here is code of Login Activity...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
msg = (TextView) findViewById(R.id.msg_log);
login = (Button) findViewById(R.id.btn_login);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// try{
txtph = (EditText) findViewById(R.id.txt_phnum);
txtpass = (EditText) findViewById(R.id.txt_pass);
ph = txtph.getText().toString();
pass = txtpass.getText().toString();
int ch = 0;
if (ph.equals("") || ph == null) {
msg.setText("Please Enter Mobile Number....\n");
ch++;
}
if (pass.equals("") || pass == null) {
if (ch == 0) {
msg.setText("Please Enter your Password....\n");
} else {
msg.append("Please Enter your Password....\n");
}
ch++;
}
if (ch == 0) {
ArrayList<String> ph_pass = new ArrayList<String>();
ph_pass.add(0, "LoginAccount");
ph_pass.add(1, ph);
ph_pass.add(2, pass);
SockProg sp=new SockProg();
TCP t=new TCP(sp, ph_pass.toString());
data=t.getData();
msg.setText(data);
}
}
});
}
This looks like a classic case of asynchronous coding delay. The TCP class is a runnable and therefor when it is called the first time (the first click on the login button) it starts running, but the Thread does not have enough time to finish
rdata=sp.readFromStream();
in the run() method, therefor data=t.getData(); does not return anything useful. The second click, provides the runnable with enough time populate the rdata with some data and therefor your program works.
When working with asynchrounous code, you need a better way to wait for code to complete what it is doing.
Why is rdata a static type? Make it non-static and then change the getData() method like this:
public synchronized String getData()

Categories