I googled it and StackoverFlow but there's not much information I can use.
And most of the answers suggest to use thread, don't open socket in main thread.
Anyway my code like this
public class Client implements Runnable {
private Socket socket;
private static ObjectOutputStream oos;
public Client() {
mPauseLock = new Object();
mPaused = false;
mFinished = false;
try {
socket = new Socket("168.131.148.50", 5001);
pw = new PrintWriter(socket.getOutputStream(), true);
oos = new ObjectOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
for (int i = 0; i < MsgQueue.getSize(); i++) {
try {
oos.writeObject(MsgQueue.get(i));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
and in MainActivity
new Thread(new Client()).start();
But still I get NetworkOnMainThreadExcpetion..
Can anybody tell me solution please?
try moving the initialization code in the constructor right before the for loop in run()
You are doing the socket call in the main thread when calling the line "new Client()", you should move all the code related to the socket creation inside the run method, you must know that only the "run" method is executed in the background thread, not the class initialization:
public class Client implements Runnable {
private Socket socket;
private static ObjectOutputStream oos;
public Client() {
mPauseLock = new Object();
mPaused = false;
mFinished = false;
}
public void run() {
try {
socket = new Socket("168.131.148.50", 5001);
pw = new PrintWriter(socket.getOutputStream(), true);
oos = new ObjectOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i = 0; i < MsgQueue.getSize(); i++) {
try {
oos.writeObject(MsgQueue.get(i));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You should read more about java before jumping into Android...
Regards!
Related
The program here shows passing a string using wi-fi. I need a solution which does not require print writer or a simple solution which helps me send two different strings while toggling the buttons
switch3.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (switch3.isChecked()) {
messsage = "S";
Log.d("On", "Button On" + messsage);
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
// client = new
// Socket(etIP.getText().toString(), port);
client = new Socket("192.168.4.1", 100);
printwriter = new PrintWriter(client
.getOutputStream(), true);
printwriter.write(messsage);
printwriter.flush();
//printwriter.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
} else {
messsage = "T";
Log.d("off", "Button off " + messsage);// etMsg.getText().toString();
// etMsg.setText("");
// port = Integer.parseInt(etPort.getText().toString());
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
// client = new
// Socket(etIP.getText().toString(), port);
//client = new Socket("192.168.4.1", 100);
printwriter = new PrintWriter(client
.getOutputStream(), true);
printwriter.write(messsage);
printwriter.flush();
//printwriter.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
});
You can send data by this way ->
try {
Socket socket = new Socket(DESTINATION_ADDRESS, DESTINATION_PORT);
// Exmp : Socket socket = new Socket("192.168.0.101", 80);
OutputStream outToServer = socket.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(SEND_STRING);
// Exmp : out.writeUTF("TEST");
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
I'm able to clear a single package name's data through this snippet. However, i want it to handle more than one package names. in other words, it should clear two more package names' data
private void clearData() {
//"com.uc.browser.en"
//"pm clear com.sec.android.app.sbrowser"
String cmd = "pm clear com.sec.android.app.sbrowser" ;
ProcessBuilder pb = new ProcessBuilder().redirectErrorStream(true)
.command("su");
Process p = null;
try {
p = pb.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// We must handle the result stream in another Thread first
StreamReader stdoutReader = new StreamReader(p.getInputStream(),
CHARSET_NAME);
stdoutReader.start();
out = p.getOutputStream();
try {
out.write((cmd + "\n").getBytes(CHARSET_NAME));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
out.write(("exit" + "\n").getBytes(CHARSET_NAME));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
p.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String result = stdoutReader.getResult();
}
}
The ProcessCommandsSU class starts an su process in which to run a list of commands, and provides an interface to deliver the output to an Activity asynchronously. Unlike the example you're following, this class will not block the UI thread. The Activity must implement the OnCommandsReturnListener interface.
public class ProcessCommandsSU extends Thread {
public interface OnCommandsReturnListener {
public void onCommandsReturn(String output);
}
private final Activity activity;
private final String[] cmds;
public ProcessCommandsSU(Activity activity, String[] cmds) {
if(!(activity instanceof OnCommandsReturnListener)) {
throw new IllegalArgumentException(
"Activity must implement OnCommandsReturnListener interface");
}
this.activity = activity;
this.cmds = cmds;
}
public void run() {
try {
final Process process = new ProcessBuilder()
.redirectErrorStream(true)
.command("su")
.start();
final OutputStream os = process.getOutputStream();
final CountDownLatch latch = new CountDownLatch(1);
final OutputReader or = new OutputReader(process.getInputStream(), latch);
or.start();
for (int i = 0; i < cmds.length; i++) {
os.write((cmds[i] + "\n").getBytes());
}
os.write(("exit\n").getBytes());
os.flush();
process.waitFor();
latch.await();
process.destroy();
final String output = or.getOutput();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
((OnCommandsReturnListener) activity).onCommandsReturn(output);
}
}
);
}
catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private class OutputReader extends Thread {
private final InputStream is;
private final StringBuilder sb = new StringBuilder();
private final CountDownLatch latch;
public OutputReader(InputStream is, CountDownLatch latch) {
this.is = is;
this.latch = latch;
}
public String getOutput() {
return sb.toString();
}
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
}
catch (IOException e) {
e.printStackTrace();
}
latch.countDown();
}
}
}
Using the class is quite simple. We first ensure that our Activity implements the interface. We then create an instance, passing the Activity and our array of commands in the constructor, and call its start() method. In the following example, it's assumed that the Activity has a TextView named textOutput to display the returned output:
public class MainActivity extends Activity
implements ProcessCommandsSU.OnCommandsReturnListener {
...
#Override
public void onCommandsReturn(String output) {
textOutput.append(output + "\n");
}
private void runCommands() {
final String[] cmds = {
"ping -c 5 www.google.com",
"pm list packages android",
"chdir " + Environment.getExternalStorageDirectory(),
"ls"
};
new ProcessCommandsSU(MainActivity.this, cmds).start();
}
}
My device is not rooted, so this was tested with the commands you see in the code above. Simply replace those commands with your pm clear commands.
I'm using a TimerTask to get the result of a Wi-Fi scan on a specific interval. I want to send the scanning results to a server.So I used AsyncTask to send the results. When I call the AsyncTask from inside the TimerTask my application crashes. Can anyone tell me why this is happening? Also in my code what is the best way to send the result to a server?
Here is my code:
public class ServerComm extends AsyncTask<String, Void, String>{
int port=9999;
String IP="192.168.2.100";
BufferedReader input;
#Override
protected String doInBackground(String... scanRes) {
// TODO Auto-generated method stub
Socket socket;
String loc="";
FileWriter writer;
File sock=new File(Environment.getExternalStorageDirectory()+"/network.txt");
try {
writer = new FileWriter(sock, true);
writer.append("in async task.\n");
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
InetAddress serverAddr = InetAddress.getByName(IP);
socket = new Socket(serverAddr, port);// socket is created
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.d("ser","socket");
// now send
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.println(scanRes);
// get the reply
loc = input.readLine();
//close
socket.close();
return loc;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return loc;
}
#Override
protected void onPostExecute(String result) {
// draw the new location on the map
}
This is the code of the TimerTask:
public void Locate()
{
if(isScanning)// if a previous scan is running cancel it
{
timer.cancel();
}
else
{
timer.schedule(new TimerTask() { // start new scanner
#Override
public void run() {
// TODO Auto-generated method stub
if(counter==numOfScans)
{
try {
writer = new FileWriter(file, true);
writer.append(RSS+" \n");
writer.append("Finished Collecting RSSIs.\n");
writer.close();
new ServerComm().execute(RSS);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
timer.cancel();
}
else // not finished
{
isScanning=true;
if(result!=null)
{
if(result.size()!=0)
{
for(int i=0;i< result.size();i++)
{
RSS=RSS+result.get(i).BSSID+" "+result.get(i).level+" ";
}//end for
counter++;
} // end of if
}//end of else
}
}
}, 0,Interval);
}
//get location
}
I solved the problem, so I'm posting the answer in case someone else faced the same problem.
The problem was the AsyncTask should not be called from TimerTask. A handler should be used to run the AsyncTask Like this:
Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
public void run() {
new ServerComm().execute(RSS);
}
});
This is solution is by arthvading on this question.
I am using FTP to upload a file. This works great. This file contains information what the app should do.
So I am doing the following:
1) Download the file with Apache FTP Client (seems to work fine)
2) Try to read out the file with a BufferedReader and FileReader.
The problem:
I get a NullPointerException while reading the file. I guess that this is a timing problem.
The code has this structure:
...
getFile().execute();
BufferedReader br = new BufferedReader(...);
How can I solve this problem?
I have to use a seperate Thread (AsyncTask) to download the file because otherwise it will throw a NetworkOnMainThread Exception.
But how can I wait until the file is completely downloaded without freezing the UI?
I cannot use the BufferedReader inside AsyncTask because I use GUI elements and I have to run the interactions on the GUI Thread, but I have no access to it from AsyncTask. RunOnUiThread does not work as well because I am inside a BroadcastReceiver.
Some code:
private class GetTask extends AsyncTask{
public GetTask(){
}
#Override
protected Object doInBackground(Object... arg0) {
FTPClient client = new FTPClient();
try {
client.connect("*****");
}
catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
client.login("*****", "*****");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream( "/sdcard/"+userID+".task" );
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
resultOk &= client.retrieveFile( userID+".task", fos );
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}/**
try {
client.deleteFile(userID+".task");
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
**/
try {
client.disconnect();
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
return null;
}
}
The Broadcastreceiver class:
public class LiveAction extends BroadcastReceiver {
...
private Context cont;
FileReader fr = null;
BufferedReader br;
#Override
public void onReceive(Context context, Intent intent)
{
cont = context;
...
new GetTask().execute();
try {
Thread.sleep(3000);
}
catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
fr = new FileReader("/sdcard/"+userID+".task");
}
catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
br = new BufferedReader(fr)
String strline = "";
try {
while ((strline = br.readLine()) != null){
if(strline.equals("taskone")){
//Some GUI Tasks
}
....
This is the relevant code.
I think the best approach would be to read the file's contents from the doInBackground inside the AsyncTask and then output an object which contains the info you need on the onPostExecute method of the async stask and then manipulate your UI.
private AsyncTask<String,Void,FileInfo> getFile(){
return new AsyncTask<String,Void,FileInfo>{
protected FileInfo doInBackground(String url){
FileInfo finfo = new FileInfo(); // FileInfo is a custom object that you need to define that has all the stuff that you need from the file you just downloaded
// Fill the custom file info object with the stuff you need from the file
return finfo;
}
protected void onPostExecute(FileInfo finfo) {
// Manipulate UI with contents of file info
}
};
}
getFile().execute();
Another option is to call another AsyncTask from onPostExecute that does the file parsing but I would not recommend it
I would try some thing like this:
private class GetTask extends AsyncTask{
LiveAction liveAction;
public GetTask(LiveAction liveAction){
this.liveAction = liveAction;
}
...
#Override
protected void onPostExecute(String result) {
liveAction.heyImDoneWithdownloading();
}
}
Ps: why the Thread.sleep(5000)?
public class LiveAction extends BroadcastReceiver {
...
public void heyImDoneWithdownloading(){
//all the things you want to do on the ui thread
}
}
I try to create a client server socket beetwen my droid(client) and my PC(server), when i am in local(over wifi) it work perfectely, but when il try over 3G i get this exception when the server try to get clientsocket.getOutputStream()
at java.lang.Thread.run(Unknown Source)
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
What's the probleme, do eny one know the solution of this?
help please :-(
The Server
public class Server {
ServerSocket serverSocket;
public LinkedBlockingQueue<CDRecCourseDisplay> recCours;
public LinkedList<ClientMail> clientMails;
static Server server;
public static Server getInstance(){
if(server == null){
server = new Server();
}
return server;
}
Server() {
// TODO Auto-generated constructor stub
try {
serverSocket = new ServerSocket(54444);
recCours = new LinkedBlockingQueue<CDRecCourseDisplay>(10);
clientMails = new LinkedList<ClientMail>();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.start();
}
private void start(){
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while (true){
try {
Socket socket = serverSocket.accept();
new Thread(new Client(socket)).start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
class Client implements Runnable{
Socket socket;
DataInputStream in;
DataOutputStream out;
public Client(Socket socket) {
// TODO Auto-generated constructor stub
this.socket = socket;
if(socket == null) return;
try {
InputStream i = socket.getInputStream();
OutputStream o = socket.getOutputStream();
in = new DataInputStream(i);
out = new DataOutputStream(o);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void run() {
// TODO Auto-generated method stub
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
out.writeUTF("Test Message");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
String buf = in.readUTF();
Log.d("MESSAGE", buf);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
}
}
and the client
class Client implements Runnable{
Socket socket;
DataInputStream in;
DataOutputStream out;
public void run() {
// TODO Auto-generated method stub
boolean conected = false;
while(!conected){
try {
Thread.sleep(500);
socket = new Socket("213.233.216.25", 54444);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
conected = true;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
Log.e("ERROR :", e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("ERROR :", e.getMessage());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.e("ERROR :", e.getMessage());
}
}
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
while(true){
try {
String buf = in.readUTF();
log.d("MESSAGE", buf);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
while(true){
try {
out.writeUTF("Test message from the phone");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
}
}
Most networks (Wifi and 3G) use NAT. NAT allows outbound connections, but prevents inbound (internet to device) connections.
When your server and device are both on the same network, as in your case, then this works as you are not traversing NAT gateway.
Rationale: what you are trying to do (connecting from internet to device) will not work in most networks.