简体   繁体   中英

Android Button Can Be Click Once Only

I'm creating an on and off app controller for a led which is connected to my arduino microcontroller. Everythings seems to be okay already except for the bottons, both in ON and OFF. It works but it can only be click once. I have read some forums related with my problem and one of it said to remove static from some statements I have but I cannot remove it since there will be errors then.

Here are some of my codes in my MainActivity.java:

//@@@@@@@@@@for the controller    
        btn_d1_on = (Button) findViewById(R.id.device1_on);
        btn_d1_off = (Button) findViewById(R.id.device1_off);

//@@@@@@@@@@for the controller
        btn_d1_on.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v)
            {
                //sendData("1");
                //Toast msg = Toast.makeText(getBaseContext(), "The device is now On", Toast.LENGTH_SHORT);
                //msg.show()
                btn_d1_on.setEnabled(false);
                try {
                    sendData("1");
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

        //@@@@@@@@@@for the controller
        btn_d1_off.setOnClickListener(new OnClickListener()
        {
            public void onClick(View v)
            {
                //sendData("0");
                //Toast msg = Toast.makeText(getBaseContext(), "The device is now On", Toast.LENGTH_SHORT);
                //msg.show();
                btn_d1_off.setEnabled(false);
                try {
                    sendData("0");
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });

  private void sendData(String message) throws IOException
  //public void sendData(String message)
  {
      byte[] msgBuffer = message.getBytes();

      Log.d(tagStateCTRL, "...Sending data: " + message + "...");

      //outStream.write(msgBuffer);
      BluetoothCommandService.write(msgBuffer);
  }

While here is my BluetoothCommandService.java where write(byte[] out) was change into public static void write(byte[] out) instead of public void write(byte[] out) ...

import java.util.UUID;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
//import android.widget.Button;

public class BluetoothCommandService {

    private final BluetoothAdapter BTAdapter;
    private final Handler bluetoothHandler;
    private static int connectionState;
    private ConnectThread connectThread;
    //private ConnectedThread connectedThread;
    public static ConnectedThread connectedThread;
    //***Added 12/27/13
    private AcceptThread mainAcceptThread;

    //connection states of the Bluetooth
    public static final int stateNothing = 0; //doing nothing
    public static final int stateListen = 1; //listening for incoming connections
    public static final int stateConnecting = 2; //initiating an outgoing connection
    public static final int stateConnected = 3;

    //constants that indicate command to computer
    public static final int exitCMD = -1;
    public static final int VOL_UP = 1;
    public static final int VOL_DOWN = 2;

    private static final boolean D = true;
    private static final String tagState = "BluetoothCommandService";

    //universally unique identifier (UUID)
    //The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination
    //private static final UUID myUUID = UUID.fromString("04c6093b-0000-1000-8000-00805f9b34fb");
     private static final UUID myUUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
    // ---------> ************* fa87c0d0-afac-11de-8a39-0800200c9a66  ***************** <-----------------
    //********************** HC-05 UUID; try this w/ the HC-05 present ***********************************

    //Name for the SDP (don;t know what is it) record when creating server socket
    private static final String name = "BluetoothCommand";
    private static final String BluetoothCommandService = null;







    public BluetoothCommandService(Context context, Handler handler) { // context == UI Activity Context && handler == send message back to the UI Activity
        BTAdapter = BluetoothAdapter.getDefaultAdapter();
        connectionState = stateNothing;
        bluetoothHandler = handler;
    }

    private  synchronized void setState(int state) { // state == current connection state; an integer
        if (D) Log.d(tagState, "setState() " + connectionState + " -> " + state);
        connectionState = state;

        //Give the new state to the Handler so that the UI Activity can update
        //bluetoothHandler.obtainMessage(what, arg1, arg2)
        bluetoothHandler.obtainMessage(MainActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();        
    }

    public synchronized int getState() { //return the current connection state
        return connectionState;
    }

    public synchronized void start() {
        if (D) Log.d(tagState, "start");

        // Cancel any thread attempting to make a connection
        if (connectThread != null) 
        {
            connectThread.cancel();
            connectThread = null;
        }

        // Cancel any thread currently running a connection
        if (connectedThread != null)
        {
            connectedThread.cancel();
            connectedThread = null;
        }

        //********************************************************
        //****Added 12/27/13
        // Start the thread to listen on a BluetoothServerSocket
        if (mainAcceptThread == null) 
        {
            mainAcceptThread = new AcceptThread();
            mainAcceptThread.start();
        }

        setState(stateListen);
    }

    //device == the BluetoothDevice to connect
    public synchronized void connect(BluetoothDevice device) {
        if (D) Log.d(tagState, "connect to: " + device);

        // Cancel any thread attempting to make a connection
        if (connectionState == stateConnecting) {
            if (connectThread != null)
            {
                connectThread.cancel(); 
                connectThread = null;
            }
        }

        // Cancel any thread currently running a connection
        if (connectedThread != null) 
        {
            connectedThread.cancel(); 
            connectedThread = null;
        }

     // Cancel the accept thread because we only want to connect to one device
        if (mainAcceptThread != null) 
        {
            mainAcceptThread.cancel(); 
            mainAcceptThread = null;
        }

        // Start the thread to connect with the given device
        connectThread = new ConnectThread(device);
        connectThread.start();
        setState(stateConnecting);
    }

    public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
        if (D) Log.d(tagState, "connected");

        // Cancel the thread that completed the connection
        if (connectThread != null) 
        {
            connectThread.cancel(); 
            connectThread = null;
        }

        // Cancel any thread currently running a connection
        if (connectedThread != null) 
        {
            connectedThread.cancel(); 
            connectedThread = null;
        }

        //*********************************************
        //****Added 12/27/13
        // Cancel the accept thread because we only want to connect to one device
        if (mainAcceptThread != null) 
        {
            mainAcceptThread.cancel(); 
            mainAcceptThread = null;
        }

        // Start the thread to manage the connection and perform transmissions
        connectedThread = new ConnectedThread(socket);
        connectedThread.start();

        // Send the name of the connected device back to the UI Activity
        Message msg = bluetoothHandler.obtainMessage(MainActivity.MESSAGE_DEVICE_NAME);
        Bundle bundle = new Bundle();
        bundle.putString(MainActivity.DEVICENAME, device.getName());
        msg.setData(bundle);
        bluetoothHandler.sendMessage(msg);

        setState(stateConnected);
    }

    public synchronized void stop() {
        if (D) Log.d(tagState, "stop");

        if (connectThread != null) 
        {
            connectThread.cancel(); 
            connectThread = null;
        }

        if (connectedThread != null) 
        {
            connectedThread.cancel(); 
            connectedThread = null;
        }

        //*****************************************
        //****Added 12/27/13
        if (mainAcceptThread != null) 
        {
            mainAcceptThread.cancel(); 
            mainAcceptThread = null;
        }

        setState(stateNothing);
    }

    public static void write(byte[] out) {
        // Create temporary object
        ConnectedThread r;
        // Synchronize a copy of the ConnectedThread
        //synchronized (this) {
        //synchronized (ConnectedThread) {
          //  if (connectionState != stateConnected) return;
            r = connectedThread;
        //}
        // Perform the write unsynchronized
        r.write(out);
    }

    public void write(int out) {
        // Create temporary object
        ConnectedThread r;
        // Synchronize a copy of the ConnectedThread
        synchronized (this) {
            if (connectionState != stateConnected) return;
            r = connectedThread;
        }
        // Perform the write unsynchronized
        r.write(out);
    }

    private void connectionFailed() {
        setState(stateListen);

        // Send a failure message back to the Activity
        Message msg = bluetoothHandler.obtainMessage(MainActivity.MESSAGE_TOAST);
        Bundle bundle = new Bundle();
        bundle.putString(MainActivity.TOAST, "Unable to connect device");
        msg.setData(bundle);
        bluetoothHandler.sendMessage(msg);
    }

    /**
     * Indicate that the connection was lost and notify the UI Activity.
     */
    private void connectionLost() {
            setState(stateListen);
            // Send a failure message back to the Activity
            Message msg = bluetoothHandler.obtainMessage(MainActivity.MESSAGE_TOAST);
            Bundle bundle = new Bundle();
            bundle.putString(MainActivity.TOAST, "Device connection was lost");
            msg.setData(bundle);
            bluetoothHandler.sendMessage(msg);
    }


    //ConnectThread runs while attempting to amke an outgoing connection w/ device
    //private class ConnectThread extends Thread {
        //private final BluetoothSocket connectThread_socket;
        //private final BluetoothDevice connectThread_device;

    public class ConnectThread extends Thread {
        public final BluetoothSocket connectThread_socket;
        public final BluetoothDevice connectThread_device;

        public ConnectThread(BluetoothDevice device) {
            connectThread_device = device;
            BluetoothSocket tmp = null;

            //Get a BluetoothSocket for a connection w/ the given BT device
            //try {
                //tmp = device.createRfcommSocketToServiceRecord(myUUID);} //ready to start a secure outgoing connection to this remote device using SDP lookup of uuid

            //catch (IOException e) {
                //Log.e(tag, msg, tr)
                //Log.e(tagState, "create() failed", e);}

            //Added 12/28/13
            Method m;
            try {
                    m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
                    tmp = (BluetoothSocket) m.invoke(device, 1);

            } catch (SecurityException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
            } catch (NoSuchMethodException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
            } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            } catch (InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            } 


            connectThread_socket = tmp;
        }

        public void run() {
            Log.i(tagState, "BEGIN ConnectThread");
            setName("ConnectThread");

            // Always cancel discovery because it will slow down a connection
            BTAdapter.cancelDiscovery();

            // Make a connection to the BluetoothSocket
            try {
                // This is a blocking call and will only return on a
                // successful connection or an exception
                connectThread_socket.connect();}
            catch (IOException e) {
                connectionFailed();
                // Close the socket
                try {
                    connectThread_socket.close();
                } catch (IOException e2) {
                    Log.e(tagState, "Unable to close() socket during connection failure", e2);
                }
                // Start the service over to restart listening mode
                BluetoothCommandService.this.start();
                return;
            }

            // Reset the ConnectThread because we're done
            synchronized (BluetoothCommandService.this) {
                connectThread = null;
            }

            // Start the connected thread
            connected(connectThread_socket, connectThread_device); //ERROR: will still create "connected"
        }

        public void cancel() {
            try {
                connectThread_socket.close();
            } catch (IOException e) {
                Log.e(tagState, "close() of connect socket failed", e);
            }
        }

    }


    //ConnectedThread runs while theres a connection w/ other remote device
    ///private class ConnectedThread extends Thread {
        //private final BluetoothSocket connectedThread_socket;
        //private final InputStream connectedThread_inStream;
        //private final OutputStream connectedThread_outStream;

    public class ConnectedThread extends Thread {
        public final BluetoothSocket connectedThread_socket;
        public final InputStream connectedThread_inStream;
        public final OutputStream connectedThread_outStream;


        public ConnectedThread(BluetoothSocket socket) {
            Log.d(tagState, "create ConnectedThread");
            connectedThread_socket = socket;

            InputStream tmpIn = null;
            OutputStream tmpOut = null;

         // Get the BluetoothSocket input and output streams
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(tagState, "temp sockets not created", e);
            }

            connectedThread_inStream = tmpIn;
            connectedThread_outStream = tmpOut;
        }

        public void run() {
            Log.i(tagState, "BEGIN ConnectedThread");
            byte[] buffer = new byte[1024]; // WALA JUD KO KASABOT ANI MAN :D
                                            //buffer == the bytes to write
                                            //buffer store for the stream

            // Keep listening to the InputStream while connected
            while (true) {
                try {
                    // Read from the InputStream
                    int bytes = connectedThread_inStream.read(buffer);

                    // Send the obtained bytes to the UI Activity
                    bluetoothHandler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1, buffer) //WA KO KASABOT SA SYNTAX YOT!!!!! >_<
                            .sendToTarget();
                } catch (IOException e) {
                    Log.e(tagState, "disconnected", e);
                    connectionLost(); //ERROR: will still create "private void CONNECTIONLOST"
                    break;
                }
            }
        }

        public void write(byte[] buffer) {
            try {
                connectedThread_outStream.write(buffer);

                // Share the sent message back to the UI Activity
//                mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
//                        .sendToTarget();
            } catch (IOException e) {
                Log.e(tagState, "Exception during write", e);
            }
        }

        public void write(int out) {
            try {
                connectedThread_outStream.write(out);

                // Share the sent message back to the UI Activity
//                mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
//                        .sendToTarget();
            } catch (IOException e) {
                Log.e(tagState, "Exception during write", e);
            }
        }

        public void cancel() {
            try {
                connectedThread_outStream.write(exitCMD);
                connectedThread_socket.close();
            } catch (IOException e) {
                Log.e(tagState, "close() of connect socket failed", e);
            }
        }


    }

    //*************************************************************************
    //*************************************************************************
    //***Added 12/27/13
    //***THis thread runs while listening for incoming connections.
    //***It behaves like a server-side client. It runs until a connection is accepted (or until cancelled).
    private class AcceptThread extends Thread {
        // The local server socket
        private final BluetoothServerSocket acceptThread_ServerSocket;

        public AcceptThread() {
            BluetoothServerSocket tmp = null;

            // Create a new listening server socket
            try {
                tmp = BTAdapter.listenUsingRfcommWithServiceRecord(name, myUUID);
            } catch (IOException e) {
                Log.e(tagState, "listen() failed", e);
            }
            acceptThread_ServerSocket = tmp;
        }

        public void run() {
            if (D) Log.d(tagState, "BEGIN mainAcceptThread" + this);
            setName("AcceptThread");
            BluetoothSocket socket = null;

            // Listen to the server socket if we're not connected
            while (connectionState != stateConnected) {
                try {
                    // This is a blocking call and will only return on a
                    // successful connection or an exception
                    socket = acceptThread_ServerSocket.accept();
                } catch (IOException e) {
                    Log.e(tagState, "accept() failed", e);
                    break;
                }

                // If a connection was accepted
                if (socket != null) {
                    synchronized (BluetoothCommandService.this) {
                        switch (connectionState) {
                        case stateListen:
                        case stateConnecting:
                            // Situation normal. Start the connected thread.
                            connected(socket, socket.getRemoteDevice());
                            break;
                        case stateNothing:
                        case stateConnected:
                            // Either not ready or already connected. Terminate new socket.
                            try {
                                socket.close();
                            } catch (IOException e) {
                                Log.e(tagState, "Could not close unwanted socket", e);
                            }
                            break;
                        }
                    }
                }
            }
            if (D) Log.i(tagState, "END mainAcceptThread");
        }

        public void cancel() {
            if (D) Log.d(tagState, "cancel " + this);
            try {
                acceptThread_ServerSocket.close();
            } catch (IOException e) {
                Log.e(tagState, "close() of server failed", e);
            }
        }
    }

}

I check already the LogCat but there were no related errors with this problem. Any help, suggestions, or clarifications about my problem with be so much appreciated. You will be a big help for this project. Thank you.

Add btn_d1_off.setEnabled(true);

After btn_d1_on.setEnabled(false);

In btn_d1_on.setOnClickListener(new OnClickListener()

And same in btn_d1_off.setOnClickListener(new OnClickListener()

Add btn_d1_on.setEnabled(true);

After btn_d1_off.setEnabled(false);

Hope this work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM