I can send udp and received udp, the problem that I had face now is when i need to automatic sending data from client to server(to prove that the client is alive), the the server cannot received the data. but when I send the alive status via Button event. it worked.
here's my code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
establishConnection();
/* Working */
Button send = new Button(this);
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new Thread(new Runnable() {
#Override
public void run() {
DatagramPacket receivePacket = null;
byte[] command = (room+":Alive").getBytes();
try {
receivePacket = new DatagramPacket(command, command.length, InetAddress.getByName(UrlColletion.hostAddress), 8084);
} catch (UnknownHostException e) {
e.printStackTrace();
}
java.lang.System.out.println("Sending");
try {
serverSocket1.send(receivePacket);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
});
/* Not Working*/
final Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
DatagramPacket receivePacket = null;
byte[] command = (room + ":Alive").getBytes();
try {
receivePacket = new DatagramPacket(command, command.length, InetAddress.getByName(UrlColletion.hostAddress), 8084);
} catch (UnknownHostException e) {
e.printStackTrace();
}
java.lang.System.out.println("Sending");
try {
serverSocket1.send(receivePacket);
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
// TODO: handle exception
} finally {
//also call the same runnable to call it at regular interval
handler.postDelayed(this, 5000);
}
}
};
handler.post(runnable);
setContentView(send);
}
DatagramSocket serverSocket1;
void establishConnection(){
try {
serverSocket1 = new DatagramSocket(7070);
serverSocket1.setReuseAddress(true);
} catch (SocketException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
#Override
public void run() {
boolean isOpen = true;
while(isOpen) {
byte []message = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(message, 1024);
try {
serverSocket1.receive(receivePacket);
} catch (IOException e) {
e.printStackTrace();
}
String text = new String(message, 0, receivePacket.getLength());
System.out.println(text);
}
serverSocket1.close();
}
}).start();
}
the code above is tested. when it send via handler, the server cannot received any data, while button, it can.
Additional information, the code is working on emulator, but when it comes on phone, the problem comes out. so it means on emulator the udp is sending successfully, but on phone, no.
Try to disable battery optimization or maybe implement a wakelock.
https://developer.android.com/training/scheduling/wakelock
Intent intent = new Intent();
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
startActivity(intent);
Don't know why but i just an thread on that.
final Handler handler = new Handler(Looper.getMainLooper());
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
new Thread(new Runnable() {
#Override
public void run() {
DatagramPacket receivePacket = null;
byte[] command = (room + ":Alive").getBytes();
try {
receivePacket = new DatagramPacket(command, command.length, InetAddress.getByName(UrlColletion.hostAddress), 8084);
} catch (UnknownHostException e) {
e.printStackTrace();
}
java.lang.System.out.println("Sending");
try {
serverSocket1.send(receivePacket);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} catch (Exception e) {
// TODO: handle exception
} finally {
//also call the same runnable to call it at regular interval
handler.postDelayed(this, 5000);
}
}
};
handler.post(runnable);
Related
i Use Socket To communicate between android and wifi its return me OutOfMemory Error When i Trying to disconnect 3 seconds after Sending Data
i have an interface to handle data:
public interface SocketConnections {
public void onSocketConnectionChanged(boolean isConnected, Socket socket);
public void onMessageRecieved(String Message);
public void onMessageSent();
}
SocketClass
public class connectSocket implements Runnable {
public Socket socket;
private DataOutputStream out;
private InputStream in;
private SocketConnections connections;
private static final String TAG = "connectSocket";
public connectSocket(SocketConnections connections) {
this.connections = connections;
}
#Override
public void run() {
connect();
}
private void connect() {
disconnect();
try {
try {
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
socket = new Socket(wsConfig.HOST_ADDRESS, wsConfig.PORT_NUMBER);
socket.setTcpNoDelay(true);
socket.setKeepAlive(true);
if (socket.isConnected()) {
connections.onSocketConnectionChanged(true, socket);
Log.i(TAG, "Connected");
while (socket.isConnected()) {
out = new DataOutputStream(socket.getOutputStream());
in = socket.getInputStream();
String S;
if (in != null) {
while (true) {
byte[] content = new byte[1024];
try {
Thread.sleep(2000);
int bytesRead = in.read(content);
if (bytesRead == -1) {
break;
}
byte[] x = Arrays.copyOfRange(content, 0, bytesRead);
Log.i(TAG, "run: " + x.length);
S = Util.fromByteArrayToHexString(x);
connections.onMessageRecieved(S);
} catch (Exception e) {
}
}
}
}
}
} catch (Exception e) {
connections.onSocketConnectionChanged(false, socket);
e.printStackTrace();
}
}
}).start();
} catch (Exception ignored) {
}
} catch (Exception ignored) {
}
}
public void sendData(final byte[] S) {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(100);
out.write(S);
out.flush();
connections.onMessageSent();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
public void disconnect() {
if (socket != null && socket.isConnected()) {
try {
socket.close();
connections.onSocketConnectionChanged(false, socket);
// Toast.makeText(G.context, "سیستم به سرور متصل نیست.", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
i want to add 3 seconds delay after sending data and Disconnect
like this
public void sendData(final byte[] S) {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(100);
out.write(S);
out.flush();
connections.onMessageSent();
Thread.sleep(3000);
disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
its return me out of memory error and force close what should i do?
ok so i found my problem and solved it. i'm not sure but i think when i'm trying to sleep thread inside other thread its some how its going to stop itself before start or i don't know whats happens there but when i put sleep in other method and call that in my first thread its works fine. if some one know about it tell us
I'm trying to respond to multicast DatagramPackets on my phone. This is the part of the code that keeps causing the ANR:
private void multicastLoop() {
String res = Build.FINGERPRINT + "\n";
final InetAddress group;
final MulticastSocket socket;
final DatagramPacket response;
try {
group = InetAddress.getByName("239.255.255.127");
socket = new MulticastSocket(port);
socket.setLoopbackMode(true);
socket.setSoTimeout(1000);
socket.joinGroup(group);
response = new DatagramPacket(res.getBytes(), res.length(), group, port);
} catch (IOException e) {
e.printStackTrace();
return;
}
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while(isRunning) {
try {
byte[] data = new byte[1024];
DatagramPacket dm = new DatagramPacket(data, data.length);
socket.receive(dm);
if (Arrays.equals(dm.getData(), "someone there".getBytes())) {
socket.send(response);
}
} catch (SocketTimeoutException e) {
continue;
} catch (IOException e) {
e.printStackTrace();
}
}
try {
socket.leaveGroup(group);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.run();
}
The method multicastLoop is called in the onCreate of the Service, after setting isRunning = true; Why does this Thread cause an ANR error? The TCP-Server-Thread is running without problems (while (isRunning) {...})
You need to call t.start(); instead of t.run();
t.run() will just execute the Runnable on the current thread (the UI) which causes the ANR.
hi am new to programming. am starting a thread by using onClick(View v).it works fine. now i want to repeat the "button click" by without clicking the button again. Am searching for about 5 hours. but i didn't get any answer. i user button.performClick(); but nothing happened. i want to restart my thread.
Receiver:
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (!connected) {
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
connectPhones = (Button) findViewById(R.id.connect_phones);
connectPhones.setPressed(false);
connectPhones.invalidate();
Handler handler1 = new Handler();
Runnable r1 = new Runnable() {
public void run() {
connectPhones.performClick();
connectPhones.setPressed(true);
connectPhones.invalidate();
connectPhones.setPressed(false);
connectPhones.invalidate();
}
};
handler1.postDelayed(r1, 1000);
}
}
}
};
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
Socket socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
connected = true;
final String path = "/sdcard/all.png";
File file = new File(path);
ObjectInputStream reader = new ObjectInputStream(socket.getInputStream());
int nRead = 0;
byte[] data = new byte[socket.getReceiveBufferSize()];
FileOutputStream fileOutputStream = new FileOutputStream( path );
// while(connected == true){
while( (nRead = reader.read(data)) != -1 ){
fileOutputStream.write( data, 0, nRead );
fileOutputStream.flush();
data = new byte[socket.getReceiveBufferSize()];
}
fileOutputStream.close();
//}
handler.post(new Runnable() {
#Override
public void run() {
Bitmap bitmap = BitmapFactory.decodeFile(path);
image.setImageBitmap(bitmap);
image.postInvalidate();
}
});
file.delete();
reader.close();
//connectPhones.performClick();
/* while (connected) {
try {
Log.d("ClientActivity", "C: Sending command.");
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
.getOutputStream())), true);
// WHERE YOU ISSUE THE COMMANDS
out.println("Hey Server!");
Log.d("ClientActivity", "C: Sent.");
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}*/
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
}
connected = false;
}
}
}
For your purpose I have created one example code. This code is working perfectly. You can try this. You can write your code below to //DOWNLOAD FILE HERE comment.
public class MainActivity extends Activity {
boolean connected = false;
Button button_example = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_example = (Button) findViewById(R.id.button1);
button_example.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "button clicked called", Toast.LENGTH_SHORT).show();
System.out.println("bb message called");
if (!connected) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
connected = true;
// DOWNLOAD FILE HERE.
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
connected = false;
button_example.performClick();
}
});
}
});
thread.start();
}
}
});
}
Add this in your onClick method:
btn = (Button) findViewById(R.id.yourButton);
btn.setPressed(false);
btn.invalidate();
Handler handler1 = new Handler();
Runnable r1 = new Runnable() {
public void run() {
btn.performClick();
btn.setPressed(true);
btn.invalidate();
btn.setPressed(false);
btn.invalidate();
}
};
handler1.postDelayed(r1, 1000);
I have a simple connection activity:
package com.example.conn08;
import ...;
public class MainActivity extends Activity
{
public static Socket clientSocket;
public static DataOutputStream outToServer;
public static PrintWriter outTest;
public static BufferedReader inToServer;
With PrintWriter outTest I test server's availability:
If the user has no Internet, or the server doesn't work, I put Thread on a pause with Boolean shouldContinue.
private Thread mThread;
private final Object lock = new Object();
private Boolean shouldContinue = true;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mThread = new Thread(new Runnable()
{
public void run()
{
while (true)
{
synchronized(lock)
{
try
{
lock.wait(); // lock the Thread
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
while (shouldContinue)
{
try
{
final String data = inToServer.readLine();
if (data != null)
{
Log.v("data", data);
runOnUiThread(new Runnable()
{
#Override
public void run()
{
String put[] = data.split("#");
//Data parsing
}
});
}
}
catch (IOException e)
{
e.printStackTrace();
}
Check on availability of the server:
try {
if(clientSocket.getInputStream().read() == -1)
{
Log.v("Connection: ", "lost");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
mThread.start();
Connect();
}
public void Connect()
{
shouldContinue = true;
try
{
clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress("localhost", 15780), 30000);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inToServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
outTest = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(clientSocket.getOutputStream())), true);
synchronized(lock)
{
lock.notify();
}
sendUTF("3#kokoko"); //send the message!
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void sendUTF(String str)
{
try
{
byte[] buf = str.getBytes("UTF-8");
outToServer.write(buf, 0, buf.length);
outToServer.writeBytes("\n");
outToServer.flush();
}
catch (IOException e)
{
e.printStackTrace();
outServ.setText("Нет соединения!");
}
}
}
Problem in that when I don't use the
if(clientSocket.getInputStream().read() == -1)
And send data to server like here:
sendUTF("3#kokoko");
All is fine, but if I use it, on server I see this message like
"#kokoko" - I lose the first character of the message and my socket is crushed! Help me please
I want to implement a client-server chat application in android. tried this code. but it only sends data to server and will not get any data.
The application must transfer data continuously.
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try
{
socket = new Socket("192.168.50.11", 2001);
out = new PrintWriter(socket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.print("hello!");
out.flush();
this.reciveThread = new Thread(new reciveClass());
this.reciveThread.start();
}
catch (Exception e)
{
Log.d(appTag, e.toString());
}
}
class reciveClass implements Runnable
{
public void run()
{
try
{
String readed;
while (true)
{
try
{
if ((readed = reader.readLine()) != null)
{
final String read = readed;
handler.post(new Runnable()
{
#Override
public void run()
{
TextView tv = (TextView) findViewById(R.id.messageText);
tv.setText(tv.getText() + "\n" + read);
}
});
}
}
catch (Exception ee)
{
Log.d(appTag, ee.toString());
}
Thread.sleep(100);
}
}
catch (Exception e)
{
}
}
}
Where is the problem?
thanks.