My problem is I have implemented a TCP socket client in android which sends continuously "Hello" messages to the server to maintain a client-server connection and receives messages from the server.
In Android, I have initialized a boolean variable that is controlling the thread if my app is in the background I make the "AppConfig.finished" variable true inactivity on pause and on stop method to stop the socket thread and make it false when in on resume state.
But my app is consuming high CPU usage which is making my app slow, I have checked it in android's profiler. Please help me to optimize it.
The code is given below.
public class MyTcp extends Thread{
private BufferedInputStream inputStream;
private BufferedOutputStream outputStream;
private Socket MySock;
private static SocketStatus SS;
private int ConnectAttemptCount = 0;
private CheckConnectionStatus CheckStatus = null;
public boolean FirstAttempt = true;
public boolean Continue = true;
private boolean isDirectChecked = false;
String tempData = "";
private final ArrayBlockingQueue<String> Queue = new ArrayBlockingQueue<>(100);
public MyTcp(SocketStatus SS) {
MyTcp.SS = SS;
MyTcp.SS.isConnected = false;
setDaemon(true);
Thread t = new Thread(new DequeueMessageThread());
t.setName(SS.SocketName + " DequeqeMessageThread");
t.start();
setName(SS.SocketName);
}
public void Dispose() {
try {
Continue = false;
SS.isConnected = false;
if(inputStream != null) {
inputStream.close();
}
if(outputStream !=null) {
outputStream.close();
}
if(MySock != null) {
MySock.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run() {
if(!Logs.isFinished) {
try {
while (Continue) {
if (SS.isConnected) {
String fromServer = ReceiveMsg();
if (fromServer.compareTo("") != 0) {
Queue.put(fromServer);
}
ConnectAttemptCount = 0;
} else {
if (ConnectAttemptCount < SS.ConnectAttempt) {
println("run>>" + "Connection Attempt" + ConnectAttemptCount);
ConnectAttemptCount++;
Connect();
} else {
println("run>>" + "Unable To Connect to server");
break;
}
}
}
} catch (Exception e) {
println("run Exception>>" + e);
}
}
}
public void Connect() {
if(!Logs.isFinished) {
try {
if (SS.isDoQueueEmptyOnConnect) {
Queue.clear();
tempData = "";
}
if (FirstAttempt) {
FirstAttempt = false;
} else {
Utilities.println("Trying to connect with " + SS.ServerIP + " on Port " + SS.Port);
_fireStatsEvent(Status.Reconnecting, "Trying to connect with " + SS.ServerIP);
Random generator = new Random();
long wait = (long) generator.nextInt(3000) + 500;
Thread.sleep(wait);
}
MySock = (Socket) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
// Start Secure Code
return (new Socket(SS.ServerIP, SS.Port));
// End Secure Code
} catch (Exception e) {
println("Connect Exception>>" + e.toString());
}
return null;
}
});
if (MySock != null) {
SS.isConnected = true;
SocketStatus.MySock = MySock;
inputStream = new BufferedInputStream(MySock.getInputStream());
outputStream = new BufferedOutputStream(MySock.getOutputStream());
Utilities.println("Connection established with " + SS.ServerIP + " on Port " + SS.Port);
if (SocketStatus.EnablePingPong) {
if (CheckStatus != null) {
CheckStatus.Dispose();
}
SS.LastMsgTime = new Date();
CheckStatus = new CheckConnectionStatus(SS, this);
CheckStatus.setName(SS.SocketName + "Connection Status Thread");
CheckStatus.start();
}
}
} catch (Exception e) {
println("Connect>>" + e);
}
int ConnectToIPCount = 0;
if (!SS.isConnected) {
while (!SS.isConnected && ConnectToIPCount < SS.ServerIPList.size()) {
final String IP_ = SS.ServerIPList.get(ConnectToIPCount).toString();
final int Port_ = SS.Port;
println("Connect>>" + "Trying to connect with " + IP_ + " on Port " + Port_);
ConnectToIPCount++;
try {
Thread.sleep(5000);
MySock = (Socket) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
// Start Secure Code
if (!isDirectChecked) {
isDirectChecked = true;
Socket tempSock = new Socket(Proxy.NO_PROXY);
tempSock.connect(new InetSocketAddress(IP_, Port_));
return tempSock;
} else {
return (new Socket(IP_, Port_));
}
// End Secure Code
} catch (Exception e) {
println("Connect Exception>>" + e.toString());
}
return null;
}
});
if (MySock != null) {
SocketStatus.MySock = MySock;
SS.isConnected = true;
inputStream = new BufferedInputStream(MySock.getInputStream());
outputStream = new BufferedOutputStream(MySock.getOutputStream());
Utilities.println("Connection established with " + IP_ + " on port " + Port_);
if (SocketStatus.EnablePingPong) {
if (CheckStatus != null) {
CheckStatus.Dispose();
}
SS.LastMsgTime = new Date();
CheckStatus = new CheckConnectionStatus(SS, this);
CheckStatus.setName(SS.SocketName + "Connection Status Thread");
CheckStatus.start();
}
}
} catch (UnknownHostException e) {
println("Connect UnknownHostException>>" + e.toString());
} catch (IOException e) {
println("Connect IOException>>" + e.toString());
} catch (Exception e) {
println("Connect Exception>>" + e.toString());
}
}
}
}
}
public void SendMsg(String sendMsg) {
if(!Logs.isFinished) {
try {
println("SendMsg>>" + sendMsg);
if (MySock != null && MySock.isConnected()) {
try {
byte[] b = null;
b = sendMsg.getBytes();
outputStream.write(b, 0, b.length);
outputStream.flush();
} catch (SocketException | SocketTimeoutException e) {
if (MySock != null) {
MySock.close();
}
SS.isConnected = false;
} catch (Exception e) {
println("SendMsg Exception>>" + e.toString());
}
}
} catch (Exception e) {
Log.d("TCP Client SendMsg >>", "Unable To Connect to server");
}
}
}
public String ReceiveMsg() {
String recvMsg = "";
if(!Logs.isFinished) {
try {
byte[] b = new byte[8092 * 6];
int recvsz = 0;
if (MySock != null && MySock.isConnected()) {
recvsz = inputStream.read(b, 0, b.length);
if (recvsz > 0) {
try {
byte[] b2 = new byte[recvsz];
System.arraycopy(b, 0, b2, 0, b2.length);
recvMsg = (new String(b2));
if (recvMsg.length() > 0) {
SS.LastMsgTime = new Date();
}
} catch (Exception e) {
println("ReceiveMsg Exception>>" + e.toString());
}
}
}
} catch (Exception e) {
if (SS.isConnected) {
Utilities.handleException(e);
}
SS.isConnected = false;
println("ReceiveMsg Exception>>>" + e.toString());
Log.d("RESPONSE FROM SERVER", "S: Received Message: '" + e.toString() + "'");
}
}
return recvMsg;
}
public void println(String msg) {
if (SS.Debug) {
String strDateFormat1 = "HH:mm:ss";
SimpleDateFormat sdf1 = new SimpleDateFormat(strDateFormat1);
Utilities.println(SS.SocketName + " (" + sdf1.format(new Date()) + ") " + msg);
}
}
private final List<MessageRecieveListner> _listeners = new ArrayList<>();
private final List<MessageRecieveListner> _listenersStrength = new ArrayList<>();
public synchronized void addListener(MessageRecieveListner l) {
_listeners.add(l);
_listenersStrength.add(l);
}
private synchronized void _fireMessageEvent(String msg) {
MessageRecieveEvent MsgEvent = new MessageRecieveEvent(this, msg);
for (MessageRecieveListner listener : _listeners) {
listener.MessageRecieved(MsgEvent);
}
}
public synchronized void _fireStatsEvent(Status status, String msg) {
MessageRecieveEvent MsgEvent = new MessageRecieveEvent(this, status, msg);
for (MessageRecieveListner listener : _listeners) {
listener.ConnectionStatus(MsgEvent);
}
}
private class DequeueMessageThread implements Runnable {
public DequeueMessageThread() {
}
#Override
public void run() {
if(!Logs.isFinished) {
while (Continue) {
if (!Queue.isEmpty()) {
try {
String data = Queue.take().trim();
if (SS.MessageParser.length() > 0) {
if (data.lastIndexOf(SS.MessageParser) == data.length() - 1) {
_fireMessageEvent(tempData + data);
tempData = "";
} else {
if (data.indexOf(SS.MessageParser) > 0) {
String particalCompleteData = tempData + data.substring(0, data.lastIndexOf(SS.MessageParser));
tempData = data.substring(data.lastIndexOf(SS.MessageParser) + 1);
_fireMessageEvent(particalCompleteData);
Utilities.println("incomplete data");
}
}
} else {
_fireMessageEvent(data);
}
} catch (Exception ex) {
ex.printStackTrace();
Continue = false;
}
}
}
}
}
}
Related
Hai friends i am new in Socket.
Now I implement a Chat app using Socket. I am testing with single Server SA and Client CA and CB. The Socket connection, chat and disconnect are working good.
But my problem is when client(CA) disconnect from server socket server not getting instant notification. Once CA reconnect again with new name CAA server will notify CA removed, and CAA connected.
my point is server must get instant notification when client CA disconnect socket.
This is my server Activity:
public class ServerMain extends ActionBarActivity {
static final int SocketServerPORT = 8080;
TextView infoIp, infoPort, chatMsg;
String msgLog = "";
List<ChatClient> userList;
ServerSocket serverSocket;
private Timer mTimer1;
private TimerTask mTt1;
private Handler mTimerHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoIp = (TextView) findViewById(R.id.infoip);
infoPort = (TextView) findViewById(R.id.infoport);
chatMsg = (TextView) findViewById(R.id.chatmsg);
infoIp.setText(getIpAddress());
userList = new ArrayList<ChatClient>();
ChatServerThread chatServerThread = new ChatServerThread();
chatServerThread.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class ChatServerThread extends Thread {
#Override
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SocketServerPORT);
ServerMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
infoPort.setText("I'm waiting here: "
+ serverSocket.getLocalPort());
}
});
while (true) {
socket = serverSocket.accept();
ChatClient client = new ChatClient();
userList.add(client);
ConnectThread connectThread = new ConnectThread(client, socket);
connectThread.start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
private class ConnectThread extends Thread {
Socket socket;
ChatClient connectClient;
String msgToSend = "";
ConnectThread(ChatClient client, Socket socket) {
connectClient = client;
this.socket = socket;
client.socket = socket;
client.chatThread = this;
}
#Override
public void run() {
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
String n = dataInputStream.readUTF();
connectClient.name = n;
msgLog += connectClient.name + " connected#" +
connectClient.socket.getInetAddress() +
":" + connectClient.socket.getPort() + "\n";
ServerMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
chatMsg.setText(msgLog);
}
});
dataOutputStream.writeUTF("Welcome " + n + "\n");
dataOutputStream.flush();
broadcastMsg(n + " join our chat.\n");
while (true) {
if (dataInputStream.available() > 0) {
String newMsg = dataInputStream.readUTF();
msgLog += n + ": " + newMsg;
ServerMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
chatMsg.setText(msgLog);
}
});
broadcastMsg(n + ": " + newMsg);
}
if (!msgToSend.equals("")) {
dataOutputStream.writeUTF(msgToSend);
dataOutputStream.flush();
msgToSend = "";
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
userList.remove(connectClient);
ServerMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (connectClient.socket.isClosed()) {
Toast.makeText(ServerMain.this,
connectClient.name + " removed.", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(ServerMain.this,
"not removed", Toast.LENGTH_LONG).show();
}
Toast.makeText(ServerMain.this,
connectClient.name + " removed.", Toast.LENGTH_LONG).show();
msgLog += "-- " + connectClient.name + " leaved\n";
ServerMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
chatMsg.setText(msgLog);
}
});
broadcastMsg("-- " + connectClient.name + " leaved\n");
}
});
}
}
private void sendMsg(String msg) {
msgToSend = msg;
}
}
private void broadcastMsg(String msg) {
for (int i = 0; i < userList.size(); i++) {
userList.get(i).chatThread.sendMsg(msg);
msgLog += "- send to " + userList.get(i).name + "\n";
}
ServerMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
chatMsg.setText(msgLog);
}
});
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
class ChatClient {
String name;
Socket socket;
ConnectThread chatThread;
}
}
This is my Client Activity:
public class ClientMain extends ActionBarActivity {
static final int SocketServerPORT = 8080;
LinearLayout loginPanel, chatPanel;
EditText editTextUserName, editTextAddress;
Button buttonConnect;
TextView chatMsg, textPort;
EditText editTextSay;
Button buttonSend;
Button buttonDisconnect;
String msgLog = "";
Socket socket = null;
ChatClientThread chatClientThread = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginPanel = (LinearLayout) findViewById(R.id.loginpanel);
chatPanel = (LinearLayout) findViewById(R.id.chatpanel);
editTextUserName = (EditText) findViewById(R.id.username);
editTextAddress = (EditText) findViewById(R.id.address);
textPort = (TextView) findViewById(R.id.port);
textPort.setText("port: " + SocketServerPORT);
buttonConnect = (Button) findViewById(R.id.connect);
buttonDisconnect = (Button) findViewById(R.id.disconnect);
chatMsg = (TextView) findViewById(R.id.chatmsg);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonDisconnect.setOnClickListener(buttonDisconnectOnClickListener);
editTextSay = (EditText) findViewById(R.id.say);
buttonSend = (Button) findViewById(R.id.send);
buttonSend.setOnClickListener(buttonSendOnClickListener);
}
OnClickListener buttonDisconnectOnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (chatClientThread == null) {
Log.e("chatClientThread", "null");
return;
} else {
chatClientThread.disconnect();
}
}
};
OnClickListener buttonSendOnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (editTextSay.getText().toString().equals("")) {
return;
}
if (chatClientThread == null) {
return;
}
chatClientThread.sendMsg(editTextSay.getText().toString() + "\n");
}
};
OnClickListener buttonConnectOnClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
String textUserName = editTextUserName.getText().toString();
if (textUserName.equals("")) {
Toast.makeText(ClientMain.this, "Enter User Name",
Toast.LENGTH_LONG).show();
return;
}
String textAddress = editTextAddress.getText().toString();
if (textAddress.equals("")) {
Toast.makeText(ClientMain.this, "Enter Addresse",
Toast.LENGTH_LONG).show();
return;
}
msgLog = "";
chatMsg.setText(msgLog);
loginPanel.setVisibility(View.GONE);
chatPanel.setVisibility(View.VISIBLE);
chatClientThread = new ChatClientThread(
textUserName, textAddress, SocketServerPORT);
chatClientThread.start();
}
};
private class ChatClientThread extends Thread {
String name;
String dstAddress;
int dstPort;
String msgToSend = "";
boolean goOut = false;
ChatClientThread(String name, String address, int port) {
this.name = name;
dstAddress = address;
dstPort = port;
}
#Override
public void run() {
try {
socket = new Socket(dstAddress, dstPort);
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(name);
dataOutputStream.flush();
while (!goOut) {
if (dataInputStream.available() > 0) {
msgLog += dataInputStream.readUTF();
ClientMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
chatMsg.setText(msgLog);
}
});
}
if (!msgToSend.equals("")) {
dataOutputStream.writeUTF(msgToSend);
dataOutputStream.flush();
msgToSend = "";
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
final String eString = e.toString();
ClientMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(ClientMain.this, eString, Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
e.printStackTrace();
final String eString = e.toString();
ClientMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(ClientMain.this, eString, Toast.LENGTH_LONG).show();
}
});
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
ClientMain.this.runOnUiThread(new Runnable() {
#Override
public void run() {
loginPanel.setVisibility(View.VISIBLE);
chatPanel.setVisibility(View.GONE);
}
});
}
}
private void sendMsg(String msg) {
msgToSend = msg;
}
private void disconnect() {
goOut = true;
}
}
}
I have a problem in using of long touch and multi thread programming.
I have 2 button: up and down. Each of these buttons have OnTouchListener event habdler . When I touch down in each of them, a thread will run inside them in the while(HelperClass.Universal_IsTouch == true) and in every 1000 milisec run again until tuouch up raised and "HelperClass.Universal_IsTouch" make false in touch up and it exit from the while .
in the while loop a thrad run and call another class method for sending data via run another thread via socket programming . So then when up button (or down) touched down long time , data should be send to server until touched up raised.
Its working but after many sending up and down when I touch long up (or down) its sended data related to other routin instead main routin ?
this is my UP routin code :
//////////// up
btn_UP_var.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
IntruptedAllThread();
// TODO Auto-generated method s tub
if (arg1.getAction() == MotionEvent.ACTION_DOWN)
{
HelperClass.Universal_IsTouch = true;
} else if (arg1.getAction() == MotionEvent.ACTION_UP) {
HelperClass.Universal_IsTouch = false;
}
//Send a simple Move (once)
if (chkbx_AutoMove_var.isChecked()) {
Img_Stop_var.setImageResource(R.drawable.arrow_stop_play);
Is_UP_buttonTouched = 1;
HelperClass.Is_Stop_Button_Disable = false;
} else {
HelperClass.Is_Stop_Button_Disable = true;
thread_UP = new Thread(new Runnable() {
#Override
public void run() {
while (HelperClass.Universal_IsTouch == true) {
Cursor ListHoist = mDbHelper.GetallSelectedHoistData();
//mDbHelper.close();
for (ListHoist.moveToFirst(); !ListHoist.isAfterLast(); ListHoist.moveToNext()) {
String IP = ListHoist.getString(ListHoist.getColumnIndex("HoistIP"));
int PK_hoist = ListHoist.getInt(ListHoist.getColumnIndex("PK_hoist"));
HelperClass.SendDataToMICRO(mDbHelper, PK_hoist, IP, HelperClass.Selector_Move_Stop,
HelperClass.MoveDesition_Up, HelperClass.inutile, HelperClass.inutile,
HelperClass.inutile);
}
ListHoist.close();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
IntruptedAllThread();
}
}
// thread_UP.interrupt();
IntruptedAllThread();
}
});
thread_UP.start();
}
return true;
}
});
and this is my Down Code :
//////////// Down
btn_Down_var.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
// TODO Auto-generated method stub
IntruptedAllThread();
if (arg1.getAction() == MotionEvent.ACTION_DOWN)
{
HelperClass.Universal_IsTouch = true;
//txt_MovementValue_var.setText("1");
} else if (arg1.getAction() == MotionEvent.ACTION_UP)
{
HelperClass.Universal_IsTouch = false;
//txt_MovementValue_var.setText("0");
}
//Send a simple Move (once)
if (chkbx_AutoMove_var.isChecked()) {
Img_Stop_var.setImageResource(R.drawable.arrow_stop_play);
Is_UP_buttonTouched = 0;
HelperClass.Is_Stop_Button_Disable = false;
} else {
HelperClass.Is_Stop_Button_Disable = true;
thread_Down = new Thread(new Runnable() {
#Override
public void run() {
while (HelperClass.Universal_IsTouch == true) {
Cursor ListHoist = mDbHelper.GetallSelectedHoistData();
for (ListHoist.moveToFirst(); !ListHoist.isAfterLast(); ListHoist.moveToNext()) {
String IP = ListHoist.getString(ListHoist.getColumnIndex("HoistIP"));
int PK_hoist = ListHoist.getInt(ListHoist.getColumnIndex("PK_hoist"));
HelperClass.SendDataToMICRO(mDbHelper, PK_hoist, IP, HelperClass.Selector_Move_Stop,
HelperClass.MoveDesition_Down, HelperClass.inutile, HelperClass.inutile,
HelperClass.inutile);
}
ListHoist.close();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
IntruptedAllThread();
}
}
//thread_Down.interrupt();
IntruptedAllThread();
}
});
thread_Down.start();
}
return true;
}
});
this is IntruptedAllThread()
public void IntruptedAllThread() {
if (thread_UP != null) {
thread_UP.interrupt();
thread_UP = null;
}
if (thread_Down != null) {
thread_Down.interrupt();
thread_Down = null;
}
}
and this is my thread to send data socket :
//This get each hoist data and change it to
//Int array to send to micro
public static void SendDataToMICRO(dbAdapter mDbHelper, int HoistID, final String Server_IP, int firstByte_KindType, int secoundByte_KindofMove,
int ValueOfMove, int valueOfsetting, int MaxOrMinValue) {
// mDbHelper = new dbAdapter(G.context);
// mDbHelper.createDatabase();
// mDbHelper.open();
Server_Port = mDbHelper.GetPortNumber();
//mDbHelper.close();
final String Concatinate_values = firstByte_KindType + Spliter + secoundByte_KindofMove +
Spliter + ValueOfMove + Spliter + valueOfsetting + Spliter + MaxOrMinValue;
//Sent Routin
////Connect To server
Thread thread = null;
thread = new Thread(new Runnable() {
#Override
public void run() {
DataOutputStream outputStream = null;
BufferedReader inputStream = null;
Socket socket;
socket = new Socket();
try {
socket.connect(new InetSocketAddress(Server_IP, Server_Port), 10);
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
Thread.currentThread().interrupt();
}
////Make Read Line
try {
outputStream = new DataOutputStream(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (IOException e1) {
//Finished Socket
ShutDown(socket);
}
if (outputStream == null) {
//
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
//Write Message
try {
String message = Concatinate_values + "\n";
outputStream.write(message.getBytes());
outputStream.flush();
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
catch (IOException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
try {
if (socket != null) {
socket.close();
}
}
catch (IOException e) {
e.printStackTrace();
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
Thread.currentThread().interrupt();
}
});
thread.start();
}
result
My application starts a thread A to save some data. In this thread I call the function startRecording(audioFile.getAbsolutePath());
But I get the following error:
start called in an invalid state: 16; at android.media.MediaRecorder.start(Native Method)
This error does not occur everytime, but sometimes I get this error report from my application.
Below, there's my code.
public void startRecording(String outputPath) {
if (recorder == null) {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setAudioSamplingRate(RECORDER_SAMPLERATE_22050);
recorder.setOutputFile(outputPath);
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
recorder.start();
SampleRecordThread thread = new SampleRecordThread(outputPath);
thread.start();
}
private class SampleRecordThread extends Thread {
private volatile boolean running = true;
public void exit() {
running = false;
}
#Override
public void run() {
while (running) {
try {
Thread.sleep(10 * 1000);//to record 10 seconds sound
} catch (InterruptedException e) {
e.printStackTrace();
}
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
// upload the data to cloud
if (isWifiActive && isInstallationSaved) {
.....
record.saveInBackground();
}
break;
}
}
I think you try recording while previous recorder not stopped and released
You can use my class
public class AudioRecordManager {
public interface OnAudioRecordCallback {
void onComplete(String path);
void onFailed(int code);
}
private OnAudioRecordCallback onAudioRecordCallback;
public void setOnAudioRecordCallback(OnAudioRecordCallback onAudioRecordCallback) {
this.onAudioRecordCallback = onAudioRecordCallback;
}
private MediaRecorder myRecorder;
private String outputFile;
private AudioRecordThread audioRecordThread;
public AudioRecordManager() {
audioRecordThread = new AudioRecordThread();
}
private AudioRecordThread audioRecordThread;
public void startRecord() {
if(audioRecordThread == null || !audioRecordThread.isRunning()){
new Thread(audioRecordThread).start();
}
}
public void stopRecord() {
if(audioRecordThread!=null && audioRecordThread.isRunning()) {
audioRecordThread.stopRecording();
}
}
class AudioRecordThread implements Runnable {
private boolean isRunning;
private boolean isStop;
private long startTime;
private void startRecord() {
isRunning = true;
isStop = false;
File folder = new File(Content.AUDIO_DIR);
if (!folder.exists()) {
boolean b = folder.mkdirs();
}
startTime = System.currentTimeMillis();
outputFile = folder.getPath() + "/rec_" + startTime + ".mp3";
myRecorder = new MediaRecorder();
myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myRecorder.setOutputFile(outputFile);
try {
myRecorder.prepare();
myRecorder.start();
startTime = System.currentTimeMillis();
} catch (Exception e) {
e.printStackTrace();
}
}
private void stopRecord() {
final long stopTime = System.currentTimeMillis();
try {
if(System.currentTimeMillis() - startTime < 500){
try{
Thread.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
}
myRecorder.stop();
myRecorder.release();
myRecorder = null;
} catch (Exception e) {
myRecorder = null;
e.printStackTrace();
}
if (stopTime - startTime > 1000) {
if (onAudioRecordCallback != null) {
onAudioRecordCallback.onComplete(outputFile);
}
} else {
File current = new File(outputFile);
current.delete();
if (onAudioRecordCallback != null) {
onAudioRecordCallback.onFailed(2);
}
}
isRunning = false;
}
#Override
public void run() {
startRecord();
while (!isStop) {
try {
Thread.sleep(30);
} catch (Exception e) {
e.printStackTrace();
}
}
stopRecord();
}
public void stopRecording() {
isStop = true;
}
public boolean isRunning() {
return isRunning;
}
}
}
I'm creating an application that gets the get the homestatus from a server in json but this happens on another thread. this isn't a problem when i try to set most Items on the ui because i can set them in a static void. but when i try to create a new switch and space i can't call 'this' to create a new.
code for getting the homestatus:
public void loadHomeStatus()
{
if(socket != null) {`enter code here`
if (socket.isConnected()) {
Log.d("BtnUpdate","already connected");
return;
}
}
swAlarm = (Switch) findViewById(R.id.swAlarmState);
tvTemperature = (TextView) findViewById(R.id.tvTemprateur);
tvHumidity = (TextView) findViewById(R.id.tvHumidity);
llDevices = (LinearLayout) findViewById(R.id.llDevices);
new Thread() {
public void run() {
try
{
busyConnecting = true;
Log.d("loadHomeStatus","trying to connect to: " + host + ":" + port);
socket = new Socket(host, port);
uiConnected();
Log.d("loadHomeStatus","Connected");
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
DataInputStream is = new DataInputStream(socket.getInputStream());
os.writeBytes(password);
Log.d("Connect", "send: " + password);
while (socket.isConnected()) {
byte[] data = new byte[500];
int count = is.read(data);
String recieved = new String(data).trim();
Log.d("loadHomeStatus","recieved " + recieved );
if(recieved.toLowerCase() == "failed")
{
Log.d("loadHomeStatus","failed to log in");
}
else
{
try
{
homeStatus = new Gson().fromJson(recieved, HomeStatus.class);
uiLoadStatus();
} catch (Exception e)
{
Log.d("Error", e.toString());
}
}
}//end of while loop
Log.w("loadHomeStatus", "end connection thread ");
//ends thread
Thread.currentThread().interrupt();
return;
}
catch (UnknownHostException e)
{
e.printStackTrace();
Log.w("loadHomeStatus", "no Failed to connect: " + host + "-" + 8001);
}
catch (IOException e)
{
e.printStackTrace();
Log.w("loadHomeStatus", "no Failed to connect: " + host + "-" + 8001);
}
Log.w("loadHomeStatus","Connection ended");
socket = null;
busyConnecting = false;
uiDisconnected();
}
}.start();
}`
Code for setting ui
public static void uiLoadStatus()
{
if (homeStatus != null)
{
try {
tvTemperature.post(new Runnable()
{
public void run()
{
//Log.d("uiLoadStatus to string",homeStatus.toString());
tvTemperature.setText(homeStatus.temperature + "°C");
tvHumidity.setText(homeStatus.humidity + "%");
}
});
}
catch(Exception e)
{
Log.d("uiLoadStatus status fragment", e.toString());
}
try {
swAlarm.post(new Runnable()
{
public void run() {
swAlarm.setChecked(homeStatus.alarmState);
}
});
}
catch (Exception e)
{
Log.d("uiLoadStatus alarm fragment", e.toString());
}
}
try {
llDevices.post(new Runnable()
{
public void run() {
uiLoadDevices(); //this gives and error because it's not static
}
});
}
catch (Exception e)
{
Log.d("uiLoadStatus alarm fragment", e.toString());
}
}
public void uiLoadDevices()
{
for (int i = 0; i < homeStatus.lstDevices.size(); i++) {
String deviceAdd = homeStatus.lstDevices.get(i);
Space mySpace = new Space(this);
Switch mySwitch = new Switch(this);
mySpace.setMinimumHeight(50);
mySwitch.setText(homeStatus.getName(deviceAdd));
mySwitch.setChecked(homeStatus.getState(deviceAdd));
mySwitch.setTextSize(18);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.LEFT;
llDevices.addView(mySpace, lp);
llDevices.addView(mySwitch, lp);
}
}
You should use AsyncTask and put the network interaction part in the doInBackground() method. To update the UI components, implement those logics in the onPostExecute() method
uiLoadStatus is a static method (not sure why or if it has to be without looking at all of your code) and therefore you cannot call non-static methods from within it, such as uiLoadDevices
I would advise taking a look at your code and update your uiLoadStatus to not be static if at all possible. Abusing static can lead to sloppy code.
i have a problem. I want to stop an httpconnection after x seconds, how can i do that? I thought something like a timertask that executes a httpconnection.close() after x seconds or something like that. Here is my code where i use my connection.
public void run() {
boolean hasCoverage = (RadioInfo.getState() == RadioInfo.STATE_ON)
&& (RadioInfo.getSignalLevel() != RadioInfo.LEVEL_NO_COVERAGE);
if (hasCoverage) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
popup = new MyPopup("Cargando Incidentes...");
UiApplication.getUiApplication().pushModalScreen(popup);
}
});
try {
HttpConnection conn = null;
String URL = "anypage.php";
conn = (HttpConnection) Connector.open(URL);
InputStream contentIn = conn.openInputStream();
byte[] data = new byte[400];
int length = 0;
StringBuffer raw = new StringBuffer();
while (-1 != (length = contentIn.read(data))) {
raw.append(new String(data, 0, length));
str = raw.toString();
}
} catch (Exception e) {
e.printStackTrace();
mainScreen.add(new RichTextField(
"Error ThreadIncidentesConnection: " + e.toString()));
}
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
try {
String datos[] = mainScreen.split(str, "ENDOFPAGE");
// mainScreen.add(new RichTextField(""+datos[0]));
datos[0] = datos[0].substring(2, datos[0].length());
mainScreen.vecRegistro = mainScreen
.split(datos[0], "$");
mainScreen.insertoEnBd();
mainScreen.insertoEnTablaDatosBD(_act);
UiApplication.getUiApplication().popScreen(popup);
} catch (Exception e) {
e.printStackTrace();
mainScreen.add(new RichTextField(
"Error ThreadIncidentes.run: " + e.toString()));
}
}
});
} else {
mainScreen.add(new RichTextField("No hay conexión disponible."));
}
}