1

Hi I am building an app which requires the user to press buttons (total 8 buttons). These buttons used to send strings to the server onclick . The problem here I'm having is when i press any of the button after connecting to the server it sends the string as it should but the 2nd time nothing happens. I was suggested to use doInBackground() from AsyncTask, to run keep running the socket and write to it each time the buttons are pressed. But i am unable to do so. What should I do ? I don't know where is the problem. Here I'm putting my code.

This is my Activity

public class Acontroller extends Activity {

Button bForward;
Button bBackward;
Button bRight;
Button bLeft;
Button bSelect;
Button bStart;
Button bB;
Button bA;
Socket s;
DataOutputStream os;
String ip;

// MyAppActivity ip = new MyAppActivity();
MyThread start = new MyThread();

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    setContentView(R.layout.nesskin);

    bForward = (Button) findViewById(R.id.bForward);
    bBackward = (Button) findViewById(R.id.bBackward);
    bRight = (Button) findViewById(R.id.bRight);
    bLeft = (Button) findViewById(R.id.bLeft);
    bSelect = (Button) findViewById(R.id.bSelect);
    bStart = (Button) findViewById(R.id.bStart);
    bA = (Button) findViewById(R.id.bA);
    bB = (Button) findViewById(R.id.bB);

    Bundle gotIP = getIntent().getExtras();
    ip = gotIP.getString("ipAddress");


//  start.doInBackground(ip);
    //start.execute(ip);
    // sock.start();

}

protected void onStart() {
    // TODO Auto-generated method stub
    super.onStart();

    bForward.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub

            start.execute(ip);
        }
    });

And from the thread.

public class MyThread extends AsyncTask <String, Void, String>{


Socket s;
DataOutputStream os;
String ip;
String cmd;


  @Override
  protected void onPreExecute() {
      Log.i("AsyncTask", "onPreExecute");
  }



@Override
protected String doInBackground(String... params) {
    int port = 2222;


    // TODO Auto-generated method stub

    if(s.isConnected()){
        try {
            os.writeUTF("forward");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }else{



    try {
    s= new Socket(ip, port);
    os = new DataOutputStream(s.getOutputStream());
    os.writeUTF("forward");

    }catch(Exception e){

        e.printStackTrace();
    }


    finally{
          if (s!= null){
           try {
            s.close();
           } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           }
          }

          if (os != null){
           try {
            os.close();
           } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           }
          }
    }


}


    return null;
}

My objective is as many times the user clicks the buttons the respective strings must be send to the server. Here is my server code I'm using PC as server.

public class Server


public static void main(String[] args) throws AWTException {
    String msg_received = null;
    String fw = "forward";
    String bw = "backward";
    String l = "left";
    String r = "right";
    String se = "select";
    String st = "start";
    String a = "a";
    String b = "b";
    String fin = "finish";
//  Boolean finish = (msg_received.equal(fin));
    Robot robot = new Robot();

    try {
        ServerSocket ss = new ServerSocket(2222);
        System.out.println("Server Started...");

        while (true) {
            Socket s = ss.accept();

            System.out.println("Connection Request Received");

            DataInputStream DIS = new DataInputStream(s.getInputStream());
            msg_received = DIS.readUTF();
            System.out.println(msg_received);
            // s.close();
            // ss.close();

            if (msg_received.equals(fw)) {
                // tu yeh kerna

                robot.keyPress(KeyEvent.VK_UP);
                robot.keyRelease(KeyEvent.VK_UP);

            }

Please help me it really important to me. Thanks in advance.

user1422066
  • 29
  • 1
  • 7

1 Answers1

1

You can't re-use an AsyncTask. You have to create a new object and call execute.

Replace

start.execute();

with

start = new MyThread(); start.execute(ip);

or if you can get away with removing the instance when it's done, then you can just do this:

(new MyThread()).start();

EDIT:

To send parameters to AsyncTask, do this:

start.execute(ip, cmd, param3, param4, param5);

in doInBackground collect the parameters like so:

protected Void doInBackground(String... params)
{
   String ipParam = params[0];
   String cmdParam = params[1];
   String thirdParam = params[2];
   String fourthParam = params[3];
   String fifthParam = params[4];
}

You can pass as many Strings as you want into params and it will automatically create a new array containing all the parameters at runtime. Just note that if you only pass in two, then the params size will only be two. If you pass in 100 parameters, then params will be 100 units in size.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • the code in myThread class is fine? and how do i pass my string which is to be sent to socket? by using just start.execute() ? what is the way to write on the socket as many times i want then close is when i want to exit the app? – user1422066 May 28 '12 at 16:43
  • Oh, I see. You're keeping the socket open in your AsyncTask. If you need it open throughout the entire life of the app, then you need to move it out and close it in `onPause()`. HOWEVER, it would most likely be best open it in `doInBackground` and close it in the `onPostExecute()` method of AsyncTask. Do all cleanup in that method. The string can be sent as a parameter when you call `execute()`. If you're retrieving it, then you need to either keep the reference to the AsyncTask until you collect it, or store it somewhere. – DeeV May 28 '12 at 17:04
  • I can't comment on the correctness of the socket code as I personally haven't done network coding much in my apps, and I don't have them with me right now. Your problem was that the `AsyncTask` was only running once, and I know this is the reason. – DeeV May 28 '12 at 17:06
  • on execute i want to send the string ip and the string cmd. cmd is defined in the activity class. – user1422066 May 28 '12 at 17:46
  • Now i want to ask is there a way that when the user presses and hold the button for any specific time will it increment a variable according to the duration the button is pressed ? so that i can use it in a loop ? or is there a method using which i can get the delay or duration of the button pressed and hold? – user1422066 May 30 '12 at 11:13
  • Create an `OnTouchListener` that posts to a `Handler` on even `ACTION_DOWN`. The `Handler` calls `postDelayed` to itself. Remove all the callbacks to the `Handler` on `ACTION_UP`. http://developer.android.com/reference/android/os/Handler.html – DeeV May 30 '12 at 12:19
  • would touchlistener work fine if i already have onclick on buttons? i mean im using one button both for onclick and ontouch ? – user1422066 May 30 '12 at 15:39
  • It would take work to get them to work properly usually. I think `onClick` activates on ACTION_UP. It would be best (or maybe easier) to use `onTouch` to handle everything. You have to decide yourself when the "click" event should fire. – DeeV May 30 '12 at 15:42
  • ok just made a while loop like while (action == MotionEvent.ACTION_DOWN){ and here im executing the thread and then break; } well i doesnt work when i press and hold any idea ? – user1422066 May 30 '12 at 19:51
  • I think it would be best to make another question regarding making long press. That topic is out of scope of this answer. – DeeV May 31 '12 at 13:27
  • http://stackoverflow.com/questions/10824867/android-executing-the-thread-in-a-loop-with-ontouchlistener – user1422066 May 31 '12 at 14:18