How to pass asynctask to another activity in android? - android

I'm try to writing an online game with a socket connection.
So I use asynctask to make a socket connection.
SocketServer.java
public class SocketServer{
private MyCustomListener listener;
private String ip = "127.0.0.1";
private int port = 4444;
#SuppressWarnings("unused")
private Context context;
private SocketAsync socketAsync;
private String dataInput, username;
public SocketServer(Context context) {
this.context = context;
}
public void setOnRecieveMsgListener(MyCustomListener listener) {
this.listener = listener;
}
public void connect() {
socketAsync = new SocketAsync();
socketAsync.execute();
}
public void sentData(String x, String y, String z) {
dataInput = null;
JSONObject object = new JSONObject();
// JSON Encode
socketAsync.sentJSON(object);
}
private class SocketAsync extends AsyncTask<Void, Void, String> {
private Socket socket;
private PrintWriter printWriter;
#Override
protected String doInBackground(Void... params) {
try {
socket = new Socket(InetAddress.getByName(ip),port);
OutputStreamWriter streamOut = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
printWriter = new PrintWriter(streamOut);
streamOut.flush();
BufferedReader streamIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
Looper.prepare();
while(socket.isConnected()) {
try {
dataInput = streamIn.readLine();
listener.onRecieveMessage(new MyListener(dataInput));
}
catch(Exception e) {}
}
Looper.loop();
}
catch(Exception e) {}
return null;
}
public void sentJSON(JSONObject object) {
if(socket.isConnected()) {
try {
printWriter.println(object.toString());
printWriter.flush();
}
catch(Exception e) {}
}
}
}
}
Login.class
public class Login extends Activity implements MyCustomListener {
JSONObject object;
SocketServer socketserver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
socketserver = new SocketServer(this);
socketserver.setOnRecieveMsgListener(this);
socketserver.connect();
button();
}
private void button() {
Button loginBt = (Button)findViewById(R.id.login_bt);
final EditText un = (EditText)findViewById(R.id.username);
final EditText ps = (EditText)findViewById(R.id.password);
final String[] logindata = new String[2];
loginBt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
logindata[0] = un.getText().toString();
logindata[1] = ps.getText().toString();
socketserver.setUsername(logindata[0]);
socketserver.sentData("SERVER", "TEST", "login");
}
});
}
private void toMainScreen() {
Intent x = new Intent(this,Main.class);
startActivity(x);
}
#Override
public void onRecieveMessage(MyListener ml) {
try {
JSONObject json = new JSONObject(ml.getMsgStr());
System.out.println(json.getString("content"));
if(json.getString("content").equals("TRUE")) {
toMainScreen();
}
else
Toast.makeText(getApplicationContext(), "Login Fail", Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
Log.e("## JSON DECODE", e.toString());
e.printStackTrace();
}
}
}
Main.class
public class Main extends Activity implements MyCustomListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//do some thing
}
#Override
public void onRecieveMessage(MyListener ml) {
System.out.println("MAIN : " + ml.getMsgStr());
}
}
so how can I pass object "socketserver" from login class to main class?
or is there an other way to do something like this?
sorry for my poor english.

You should not try to pass an instance of SocketServer around. One of it's properties is context which means you should not used it outside the original context it was created in (i.e. activity it was created in) or you'll have memory leaks.
Your SocketServer class needs IP and port. This is the kind of information that you should pass between activities and then use that to create another instance of your SocketServer class.

Related

Problems with AsyncTask class and UDP communication

I am trying to send messages through the UDP communication of an android phone a UDP host, according to the buttons on the screen send a specific message, I have a UDP_Service class where I instantiate the datagramsocket and do the corresponding sending:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class UDP_Service {
private int server_port;
DatagramSocket skt;
private InetAddress local;
private String msge;
private String st;
private int msge_lenght;
private byte[] byteMsge;
private byte[] resp;
private int j;
public UDP_Service(){
try {
skt = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
// st = null;
}
}
public void setIP(String ip){
try {
local = InetAddress.getByName(ip);
} catch (UnknownHostException e) {
// st = null;
}
}
public void setPort(int np){
server_port = np;
}
public void setMsge(String msj){
msge = msj;
msge_lenght = msge.length();
byteMsge = msge.getBytes();
resp = new byte[1024];
}
public void Enviar(){
try {
skt = new DatagramSocket();
DatagramPacket pqtEnvio = new DatagramPacket(byteMsge, msge_lenght,
local, server_port);
skt.send(pqtEnvio);
DatagramPacket pqtResp = new DatagramPacket(resp, resp.length);
skt.receive(pqtResp);
st = new String(pqtResp.getData(),0,pqtResp.getLength());
//skt.close();
} catch (Exception e) {
// st = null;
}
}
public void close() {
skt.close();
}
public String getRespuesta(){
return st;
}
public int getCont() {
return j;
}
public void setCont(int x) {
j = x;
}
}
The method "Enviar()" I invoke it from an AsyncTask, however it only works once, I open the application from the phone and press any button and effectively the corresponding message is sent, but when I press another button no longer nothing happens. The onPostExecute () method of the AsyncTask is not running,I can not see the corresponding toast.
Here the AsyncTask
public class MainActivity extends AppCompatActivity {
String msje[];
String resp[];
int port;
UDP_Service UDP_Serv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
UDP_Serv = new UDP_Service();
//UDP_A = new UDP_Async();
msje = new String[9];
resp = new String[8];
}
public void UDP_Client(String mje, int pt, String ip, int c)
{
//UDP_A = new UDP_Async();
UDP_Serv.setMsge(mje);
UDP_Serv.setPort(pt);
UDP_Serv.setIP(ip);
UDP_Serv.setCont(c);
new UDP_Async().execute();
Toast.makeText(MainActivity.this, mje, Toast.LENGTH_SHORT).show();
}
public class UDP_Async extends AsyncTask < Void, Void, Boolean > {
private String st;
private int j;
#Override
protected Boolean doInBackground(Void...params) {
UDP_Serv.Enviar();
st = UDP_Serv.getRespuesta();
j = UDP_Serv.getCont();
//return st;
return true;
}
#Override
protected void onPostExecute(Boolean result) {
//super.onPostExecute(result);
if (result) {
if (!st.equals(null)) {
resp[j] = st;
actualizarUI(j);
}
Toast.makeText(MainActivity.this, "TAREA FINALIZADA!", Toast.LENGTH_SHORT).show();
}
}
}
}

TCP/IP client receiving and sending between various Android activities

I need help to understand how to make a connection to a tcp client on Android with a server, the connection itself is not the problem, but rather the exchange between the activities.
I will try to explain with the attached image.
I need to start a connection to a server using TCP / IP sockets. After a search for the net I found several examples, but all using a single activity, but I need it to work as follows:
1 - Let's say in the main activity I start the connection by clicking on CONNECT.
2 - But then I need to click the ACTIVITY_A button to open another activity while keeping the connection that has already been opened in the main activity, and continue sending and receiving information in its ACTIVITY_A.
3 - Back to ACTIVITY_A, click on ACTIVITY_B doing the same process above.
I am lost between which solution to use and how to use, asynctask, thread, singleton, intent, context.
You can use Android Service for network connectivity. Also please look at Android Networking official doc. Also there are a lot library for performing network requests (like Robospice)
I edited the previous message to inform how I solved it, it may not be ideal but it is working.
Act_Main
public class Act_Main extends AppCompatActivity implements Singleton.OnReceiveListener{
private Singleton sing;
String ip = "192.168.4.1";
int porta = 23;
Button btConectar, btActivityA, btActivityB;
TextView txtStatus;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_main);
btConectar = (Button) findViewById(R.id.btConectarID);
btActivityA = (Button) findViewById(R.id.btActivityAID);
btActivityB = (Button) findViewById(R.id.btActivityBID);
txtStatus = (TextView) findViewById(R.id.txtStatusID);
}
public void conectar (View view){
sing = Singleton.getInstance(ip, porta, this);
}
public void openActivityA(View view) {
Intent it = new Intent(Act_Main.this, Activity_A.class);
startActivity(it);
}
public void openActivityB(View view) {
Intent it = new Intent(Act_Main.this, Activity_B.class);
startActivity(it);
}
#Override
public void onReceive(String dataRx) {
// Trata a informação recebida aqui.
txtStatus.setText(dataRx);
}
}
Singleton
public class Singleton {
private static Singleton instancia = null;
private static OnReceiveListener orl = null;
private boolean running;
private static Client client;
private Singleton() {
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
public static interface OnReceiveListener {
public void onReceive(String dataRx);
}
public static Singleton getInstance(String _ip, int _port, OnReceiveListener listener) {
if (instancia == null) {
client = new Client(_ip, _port);
client.execute();
instancia = new Singleton();
}
orl = listener;
return instancia;
}
public void sendMsg(String str) {
client.sendMessage(str);
}
private static class Client extends AsyncTask<Void, String, Void> {
String dstAddress;
int dstPort;
String response = "";
BufferedReader in;
PrintWriter out;
String incomingMessage;
private boolean running;
Client(String addr, int port) {
dstAddress = addr;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
running = true;
// Cria um objeto PrintWriter para enviar mensagens ao servidor.
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
// Cria um objeto BufferedReader para receber mensagens do servidor.
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.d(TAG, "In/Out created");
while (running) {
incomingMessage = in.readLine();
if (incomingMessage != null) {
publishProgress(incomingMessage);
}else{
running = false;
}
incomingMessage = null;
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
out.close();
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onProgressUpdate(String... params) {
orl.onReceive(params[0]);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
private void sendMessage(String message) {
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
Log.d(TAG, "Sent Message: " + message);
}
}
}
}
Activity_A
public class Activity_A extends AppCompatActivity implements Singleton.OnReceiveListener {
private Singleton sing;
String ip = "192.168.4.1";
int porta = 23;
Button btVoltar, btEnviar;
TextView txtRx, txtTx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
btEnviar = (Button) findViewById(R.id.btEnviarID);
btVoltar = (Button) findViewById(R.id.btVoltarID);
txtRx = (TextView) findViewById(R.id.txtRxID);
txtTx = (TextView) findViewById(R.id.txtTxID);
sing = Singleton.getInstance(ip, porta, this);
}
#Override
public void onReceive(String dataRx) {
txtRx.setText(dataRx);
}
public void Enviar (View view){
sing.sendMsg(txtTx.getText().toString());
}
public void Voltar(View view) {
this.finish();
}
}
Activity_B
public class Activity_B extends AppCompatActivity implements Singleton.OnReceiveListener {
private Singleton sing;
String ip = "192.168.4.1";
int porta = 23;
Button btVoltar, btEnviar;
TextView txtRx, txtTx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
btEnviar = (Button) findViewById(R.id.btEnviarID);
btVoltar = (Button) findViewById(R.id.btVoltarID);
txtRx = (TextView) findViewById(R.id.txtRxID);
txtTx = (TextView) findViewById(R.id.txtTxID);
sing = Singleton.getInstance(ip, porta, this);
}
#Override
public void onReceive(String dataRx) {
txtRx.setText(dataRx);
}
public void Enviar (View view){
sing.sendMsg(txtTx.getText().toString());
}
public void Voltar(View view) {
this.finish();
}
}
Evidently it is not finished, but it is a beginning.
Thank you to those who have responded.

Android Intent after onpostexecute fails to start

I have a registration system. The registration is working fine. My main problem is: I would like to start MainActivity.java after logging in. After sending the login data to the Server, the Server checks in Database if it matches and sends out an int (0 for unmatched) and (1 for success). This works great as well. But if i want to start the Intent after onPostExecute Method it gives out an Error:
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.app.Activity.startActivityForResult
...
This is my StartPage which exectues my AsyncTask Class. And receives success or unmatched in the Method getLoginMessage().
public class LoginPage extends Activity {
String userName;
String password;
String sendProtocolToServer;
static String matched = null;
static String unmatched;
static Context myCtx;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loginpage);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Button login = (Button) findViewById(R.id.loginBtn);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handleLogin();
}
});
Button register = (Button) findViewById(R.id.registerBtn);
register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent openMainActivityRegister = new Intent(
"com.example.fotosharing.REGISTERPAGE");
startActivity(openMainActivityRegister);
}
});
}
private void handleLogin() {
EditText editTextBox = (EditText) findViewById(R.id.EditTextUser);
EditText passwordTextBox = (EditText) findViewById(R.id.EditTextPassword);
userName = editTextBox.getText().toString();
password = passwordTextBox.getText().toString();
if (!userName.equals("") && !password.equals("")) {
sendProtocolToServer = "login" + "#" + userName + "#" + password;
ConnectToServer cts = new ConnectToServer(sendProtocolToServer);
cts.execute();
} else {
Toast.makeText(this, "Fill in Username and Password to login",
Toast.LENGTH_LONG).show();
}
}
public void getLoginMessage(String receivedMessage) {
if (receivedMessage.equals("success")) {
Intent openMainActivity = new Intent(
"com.example.fotosharing.TIMELINEACTIVITY");
openMainActivity.clone();
startActivity(openMainActivity);
}
if (receivedMessage.equals("unmatched")) {
Toast.makeText(this, "Password or username incorrect.", Toast.LENGTH_LONG).show();
}
}
}
This is my Async-Task class which receives Data from my Java-Server, and checks if it was an successful or an unmatched login. In onPostExecute im calling a Method in the LoginPage.class, which handles the Intent (here comes the Error).
public class ConnectToServer extends AsyncTask<Void, Void, String> {
public Context myCtx;
static Socket socket;
String sendStringToServer;
int protocolId = 0;
private static DataOutputStream DOS;
private static DataInputStream DIS;
StringBuffer line;
int j = 1;
String value;
static String res = null;
public ConnectToServer(String sendStringToServer) {
this.sendStringToServer = sendStringToServer;
}
public ConnectToServer(int i) {
this.protocolId = i;
}
public ConnectToServer() {
}
public ConnectToServer(Context ctx) {
this.myCtx = ctx;
}
protected String doInBackground(Void... arg0) {
try {
socket = new Socket("192.168.1.106", 25578);
DOS = new DataOutputStream(socket.getOutputStream());
if (protocolId == 1) {
DOS.writeUTF("pictureload");
protocolId = 0;
} else {
DOS.writeUTF(sendStringToServer);
}
res = receive();
// DOS.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("RES: " + res);
return res;
}
public String receive() {
String receiveResult = null;
if (socket.isConnected()) {
try {
BufferedReader input = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
DIS = new DataInputStream(socket.getInputStream());
int msg_received = DIS.readInt();
System.out.println("SERVER: " + msg_received);
if (msg_received == 1) {
receiveResult = "success";
System.out.println("IF (success): " + receiveResult);
}
if (msg_received == 0) {
receiveResult = "unmatched";
System.out.println("ELSE IF (unmatched): "
+ receiveResult);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// ***** return your accumulated StringBuffer as string, not current
// line.toString();
return receiveResult;
}
protected void onPostExecute(String result1) {
if (result1 != null) {
if (result1.equals("success") || result1.equals("unmatched")) {
sendToLoginPage(result1);
}
}
}
private void sendToLoginPage(String result1) {
System.out.println("sendtologi " + result1);
LoginPage lp = new LoginPage();
lp.getLoginMessage(result1);
}
}
This is the class I want to start when it was a successful login.
What am I doing wrong?
public class MainActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
ActionBar actionbar = getSupportActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.setBackgroundDrawable(new ColorDrawable(Color.BLACK));
actionbar.setStackedBackgroundDrawable(new ColorDrawable(Color.parseColor("#91d100")));
ActionBar.Tab Frag1Tab = actionbar.newTab().setText("Home");
ActionBar.Tab Frag2Tab = actionbar.newTab().setText("Share Photo");
Fragment Fragment1 = new TimelineActivity();
Fragment Fragment2 = new CameraActivity();
Frag1Tab.setTabListener(new MyTabsListener(Fragment1));
Frag2Tab.setTabListener(new MyTabsListener(Fragment2));
actionbar.addTab(Frag1Tab);
actionbar.addTab(Frag2Tab);
}
}
You cannot just create instance of your activity with new keyword, like this:
private void sendToLoginPage(String result1) {
System.out.println("sendtologi " + result1);
LoginPage lp = new LoginPage();
lp.getLoginMessage(result1);
}
This is wrong and it is probably why you are getting error. Code you posted is quite complex, so i am not sure if there are any other problems.
This is how it should be done:
So... Since you probably have ConnectToServer asyncTask in separate file, you need pass events or data to your LoginPage activity. For this purpose, you should use event listener, like this:
First, create interface that will represent communication between your ConnectToServer and your LoginPage.
public interface LoginResultListener {
public void getLoginMessage(String receivedMessage);
}
Now, make your LoginPage activity implement this interface:
public class LoginPage extends Activity implements LoginResultListener {
...
}
Now, update your ConnectToServer asyncTask, so that it uses LoginResultListener to communicate login result to your activity, like this:
public class ConnectToServer extends AsyncTask<Void, Void, String> {
private LoginResultListener listener;
...
public void setListener(LoginResultListener listener) {
this.listener = listener;
}
...
private void sendToLoginPage(String result1) {
System.out.println("sendtologi " + result1);
//THIS IS WHERE YOU DID WRONG
listener.getLoginMessage(result1);
}
...
}
Now finally, when you create new ConnectToServer async task from your activity, you need to set listener that will handle events when user logs in. Since you implemented this interface in your activity, you will send your activity object as listener parameter, see below:
ConnectToServer cts = new ConnectToServer(sendProtocolToServer);
// THIS IS IMPORTANT PART - 'this' refers to your LoginPage activity, that implements LoginResultListener interface
cts.setListener(this);
cts.execute();

pass parameters to asyntask

I have a problem, is that I use to control a thread AsynTask and I call AsynTask only once, but now I want to do is to call more than once, but of course for that I have to spend a few parameters, but do not know how to do, I've tried thousands ways but does not work. Here I leave my code:
public class leer_registros extends Activity {
TextView text, depurar;
EditText reg,ip;
Button boton;
float resultado;
AccionesScada accionesScada = new AccionesScada();
InetAddress addr = null; //direccion del esclavo
int port = Modbus.DEFAULT_PORT;//puerto por defecto 502
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.lblRegistro);
ip = (EditText) findViewById(R.id.txtIp);
reg = (EditText) findViewById(R.id.txtReg);
depurar = (TextView) findViewById(R.id.txtdepurar);
boton = (Button)findViewById(R.id.btnVerRegistro);
depurar.setTextColor(Color.RED);
}
public class conectar extends AsyncTask<Void,Void,Void>{
int m;
int startReg;
int count;
String dirIP;
String dirReg;
public conectar(String aux,String aux1) {
this.dirIP=aux;
this.dirReg=aux1;
try {
//IP address;
//aux1 = ip.getText().toString();
addr = InetAddress.getByName(dirIP);
//aux = reg.getText().toString();
startReg = Integer.decode(dirReg).intValue();
depurar.setText(dirIP);
//Reg = startReg[0];
} catch (Exception e) {
Log.d("MODBUS","IP error", e);
}
}
protected Void doInBackground(Void... urls) {
m = accionesScada.conectar(addr, port);
resultado = accionesScada.LeerRegistro(startReg, count);
return null;
}
protected void onPostExecute(Integer bytes) {
if(m==1){
depurar.setText("conectado!!!");
depurar.setTextColor(Color.GREEN);
}
String resul = String.valueOf(resultado);
text.setText(resul);
}
}
public void verRegistro(View v) {
final Handler handler = new Handler();
Timer timer = new Timer();
//IP address;
final String aux = ip.getText().toString();
final String aux1 = reg.getText().toString();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
try{
depurar.setText(aux1);
/*conectar conectamos = new conectar();
conectamos.execute(aux,aux1);*/
conectar conectamos = new conectar(aux,aux1);
conectamos.execute();
}catch(Exception e){
Log.d("MODBUS", "Error Timertask");
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 1000);
}
}
I want you to pass to the function its: aux and aux1.
Please help me!.
Thanks.
Create a constructor inside Async Task to pass parameters to it. Like this
Call to Async task
new conectar(url,_payload,method,context).execute();
AsycTask with constructor
private static class Conectar extends
AsyncTask<Integer,Integer,Integer> {
private final String mUrl;
private final String mPayload;
private final HttpMethod mMethod;
private final Context mContext;
public Conectar(String url,String _payload, HttpMethod method,final Context context) {
mContext = context;
mUrl=url;
mPayload=_payload;
mMethod=method;
}
#Override
protected Integer doInBackground(Void... vParams) {
ResponseWrapper user = null;
String url = mUrl;
conectar conectamos = new conectar();
conectamos.execute(1, 2, 3);// Pass the parameter like this
// Get the parameter like this
protected Integer doInBackground(Integer... urls) {
int parameter1=urls[0];
int parameter1=urls[1];
int parameter1=urls[2];
}
Edited:-
As you declare the first Argument as Integer but you are passing String.
so change it to string and it will work for.
public class conectar extends AsyncTask<String,Integer,Integer>

Scanning ports with AsyncTask

Is it possible to scan several ports at once with AsyncTask? I am totally new to AsyncTask, so I have no clue what I am doing. Even after reading all tutorials on the internet about AsyncTask (eg Vogella etc.) I still can't understand how to make this happen.
Here is the code I have at the moment:
public class MainActivity extends Activity {
EditText et;
Button b;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.editText1);
b = (Button) findViewById(R.id.button1);
}
public void start(View view){
GetPorts task = new GetPorts();
task.execute(20,53,80,114,140);
}
private class GetPorts extends AsyncTask<Integer, Void, Vector<Integer>> {
Vector<Integer> openPorts = new Vector<Integer>();
#Override
protected Vector<Integer> doInBackground(Integer... ports) {
for(Integer port: ports){
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress("localhost", port), 500);
socket.close();
openPorts.add(port);
} catch (Exception ex) {
}
}
return openPorts;
}
}
}
the ports 20,53,80 etc are the example porst I'd like to check (there could be up to 65535 ports). I thought checking ports and adding them to Vector and then returning this Vector would be a good idea, but I have no idea how to do that. I wonder if my Vector "openPorts" is going to reset with every new port to scan, and will this AsyncTask be able to scan multiple ports at the same time?
I have created the working solution with Java SE and I'm gonna paste it here to clarify what I am after of.
Java SE code:
public class Scanner {
private final String ip;
private final int sPort, ePort, timeout, poolSize;
private Vector<Integer> openPorts = new Vector<Integer>();
private final ExecutorService es;
private Collection<Future<?>> futures = new LinkedList<Future<?>>();
public Scanner(String ip, int sPort, int ePort, int timeout, int poolSize) {
this.ip = ip;
this.sPort = sPort;
this.ePort = ePort;
this.timeout = timeout;
this.poolSize = poolSize;
es = Executors.newFixedThreadPool(this.poolSize);
}
public Vector<Integer> getPorts() {
Collections.sort(openPorts);
return openPorts;
}
public void runScanner() {
for (int startPort = sPort; startPort <= ePort; startPort++) {
futures.add(es.submit(new Check(ip, startPort, timeout)));
}
es.shutdown();
}
public void stopScanner(){
for (Future<?> future : futures) {
future.cancel(true);
}
}
private class Check implements Runnable {
private String ip;
private int port, timeout;
private Check(String ip, int port, int timeout) {
this.ip = ip;
this.port = port;
this.timeout = timeout;
}
public void run() {
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress(ip, port), timeout);
socket.close();
openPorts.add(port);
} catch (Exception ex) {
}
}
}
}
Your vector will be reset only when you instanciate a new GetPorts class (as usual).
Your code looks just fine. If your problem is to retrieve the result of the AsyncTask, you have two main ways to achieve it.
You can just call Vector<Integer> v = new GetPorts().execute(20,53,80,114,140).get(); but it's not often a proper way.
Or you can implements callback in the AsyncTask post execute callback.
#Override
protected void onPostExecute(Vector<Integer> result) {
}
Your AsyncTask should be like this:
private class GetPorts extends AsyncTask<Integer, Void, Vector<Integer>> {
public interface MyCallbackInterface {
public void myCallback(Vector<Integer> ports);
}
MyCallbackInterface listener;
Vector<Integer> openPorts = new Vector<Integer>();
public GetPorts(MyCallbackInterface listener) {
this.listener = listener;
}
#Override
protected Vector<Integer> doInBackground(Integer... ports) {
for(Integer port: ports){
try {
Socket socket = new Socket();
socket.connect(new InetSocketAddress("localhost", port), 500);
socket.close();
openPorts.add(port);
} catch (Exception ex) {
}
}
return openPorts;
}
#Override
protected void onPostExecute(Vector<Integer> result) {
listener.myCallback(result);
}
}
Then in the task caller which implements MyCallbackInterface, you can do:
new GetPorts(this).execute(20,53,80,114,140);
And doing what you want in :
#Override
public void myCallback(Vector<Integer> ports) {
}

Categories

Resources