1

So i'm making a OBDII Bluetooth app were the user can send commands such as voltage (in this case) and get data from the OBDII. So far i've managed to make a Bluetooth connection with my mobile device to my OBDII adapter work and now I need to send some basic commands and displaying them in Logcat (for the moment).

The problem i'm having is that it doesn't recognize my onClick method?

Could not find method onClick(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'getValue'

I'm sure that i've missed something in my code, but I dont know what.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    Button b1;
    BluetoothAdapter mAdapter;
    FragmentHostCallback mHost;
    BTHandler btHandler;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case Constants.MESSAGE_STATE_CHANGE:
                    switch (msg.arg1) {
                        case BTHandler.STATE_CONNECTED:
                            //setContentView(R.layout.activity_connected);
                            Intent intent = new Intent(MainActivity.this, Connected.class);
                            startActivity(intent);
                            Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
                            Log.v("Log", "Connected");
                            break;
                        case BTHandler.STATE_NONE:
                            Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
                            break;
                    }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btHandler = new BTHandler(MainActivity.this, mHandler);
        b1 = (Button) findViewById(R.id.connect);
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        //init();

        if (mAdapter == null) {
            Toast.makeText(getApplicationContext(), R.string.device_not_supported, Toast.LENGTH_LONG).show();
            finish();
        } else {
            if (!mAdapter.isEnabled()) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(intent, 1);
            }
        }
        //BTHandler btHandler = new BTHandler(MainActivity.this, mHandler);
        //btHandler.connect("");
    }

    public void onClick(View v) {
        int id = v.getId();
        String sendMessage = ("AT RV");

        switch (id) {
            case R.id.connect:
                onConnect(); //Operation
                Log.v("Log", "Pressed onClick");
                break;
            case R.id.getValue:
                btHandler.write(sendMessage);
                Log.v("Log", "getValue" + sendMessage);
                break;
        }
    }

BTHandler.java

public class BTHandler {

    public static final int STATE_NONE = 0;       // we're doing nothing
    public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
    public static final int STATE_CONNECTED = 3;  // now connected to a remote device

    final ArrayList<String> devices = new ArrayList();
    private final Handler mHandler;
    private BluetoothAdapter mAdapter;
    private BluetoothDevice device;
    private ConnectThread mConnectThread;
    private ConnectedThread mConnectedThread;
    private BluetoothSocket socket;
    private String status;
    private int mState;
    private boolean connectionStatus = false;

    public BTHandler(Context context, Handler handler) { // Konstruktor
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mHandler = handler;
    }

    public void write(String s) {
        mConnectedThread.sendRawCommand(s);
    }
    /*
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) {
        }
    }
    */
    public void connect(String deviceAddress) {
        mConnectThread = new ConnectThread(deviceAddress);
        mConnectThread.start();
    }

    private void guiHandler(int what, int arg1, String obj) {
        Message msg = mHandler.obtainMessage();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.sendToTarget();
    }

    private class ConnectThread extends Thread {
        BluetoothSocket tmp = null;
        private BluetoothSocket mmSocket;

        public ConnectThread(String deviceAddress) {
            mAdapter = BluetoothAdapter.getDefaultAdapter();
            device = mAdapter.getRemoteDevice(deviceAddress);

            BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
            BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
            UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
            try {
                tmp = device.createRfcommSocketToServiceRecord(uuid);
                //socket.connect();
                //Log.v("connect", "connect");
            } catch (IOException e) {
                //e.printStackTrace();
                //Log.v("exception", "e");
            }
            mmSocket = tmp;
        }

        public void run() {
            // Cancel discovery because it will slow down the connection
            mAdapter.cancelDiscovery();
            byte[] buffer = new byte[1024]; // buffer store for the stream
            int bytes;

            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket.connect();
                Log.v("connect", "connect");
            } catch (IOException connectException) {
                // Unable to connect; close the socket and get out
                try {
                    mmSocket.close();
                    Log.v("close", "close");
                } catch (IOException closeException) {
                }
                guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
                return;
            }
            guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
        }
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        private ObdMultiCommand multiCommand;

        public ConnectedThread(BluetoothSocket socket) {
            connectionStatus = true;
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;

            try {
                RPMCommand engineRpmCommand = new RPMCommand();
                SpeedCommand speedCommand = new SpeedCommand();
                ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();

                while (!Thread.currentThread().isInterrupted()) {
                    engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
                    speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
                    voltageCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
                    // TODO handle commands result
                    Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
                    Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
                    Log.v("Log", "Voltage: " + speedCommand.getFormattedResult());
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        public void run() {
            byte[] buffer = new byte[1024];  // buffer store for the stream
            int bytes; // bytes returned from read()

            OBDcmds();
            // Keep listening to the InputStream until an exception occurs
            while (connectionStatus) {
                sendMultiCommand();
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        // CALL this to MainActivity
        public void sendRawCommand(String s) {
            try {
                //new ObdRawCommand();

            } catch (Exception e) {
            }
        }

        private void OBDcmds() { // execute commands

            try {
                new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
                new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
                new TimeoutCommand(125).run(socket.getInputStream(), socket.getOutputStream());
                new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN

            } catch (Exception e) {
                Log.v("Log", "e");
                // handle errors
            }
        }
        /*
        // Call this from the main activity to send data to the remote device
        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) {
            }
        }
        */

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
            }
        }

        public void sendMultiCommand() {
            try {
                // RUN some code here
            } catch (Exception e) {
            }
        }
    }
}

EDIT:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {...}

@Override
    protected void onCreate(Bundle savedInstanceState) {
        b1 = (Button) findViewById(R.id.connect);
        b1.setOnClickListener(this);
    }

Logcat:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.asabanov.powersupplytool, PID: 26570 java.lang.IllegalStateException: Could not find method onClick(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'getValue' at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:307) at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:266) at android.view.View.performClick(View.java:5226) at android.view.View$PerformClick.run(View.java:21266) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:168) at android.app.ActivityThread.main(ActivityThread.java:5845) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

W/System.err: com.github.pires.obd.exceptions.UnableToConnectException: Error running 01 42, response: 0142...UNABLETOCONNECT W/System.err: at java.lang.Class.newInstance(Native Method) W/System.err: at com.github.pires.obd.commands.ObdCommand.checkForErrors(ObdCommand.java:203) W/System.err: at com.github.pires.obd.commands.ObdCommand.readResult(ObdCommand.java:123) W/System.err: at com.github.pires.obd.commands.ObdCommand.run(ObdCommand.java:77) W/System.err: at com.example.asabanov.powersupplytool.BTHandler$ConnectedThread.(BTHandler.java:151) W/System.err: at com.example.asabanov.powersupplytool.BTHandler$ConnectThread.run(BTHandler.java:117) V/Log: e

EDIT:

private void onConnect() {
        ArrayList deviceStrs = new ArrayList();
        final ArrayList<String> devices = new ArrayList();

        BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
        Set pairedDevices = mAdapter.getBondedDevices();
        if (pairedDevices.size() > 0) {
            for (Object device : pairedDevices) {
                BluetoothDevice bdevice = (BluetoothDevice) device;
                deviceStrs.add(bdevice.getName() + "\n" + bdevice.getAddress());
                devices.add(bdevice.getAddress());
            }
        }

        // show list
        final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

        ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.select_dialog_singlechoice,
                deviceStrs.toArray(new String[deviceStrs.size()]));

        alertDialog.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
                String deviceAddress = devices.get(position);

                btHandler.connect(deviceAddress);
                //btHandler.write();

            }
        });
        alertDialog.setTitle("Paired devices");
        alertDialog.show();
    }
swess
  • 171
  • 19

1 Answers1

0

You should set an onClickListener for your button.

For that, you need to implement OnClickListener interface as:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

When you create the button, set its OnClickListener as follows:

b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);

This should get you to your onClick method, when the button is clicked.

Edit: i see you have two buttons. Just do the same for the other button. Don't forget to declare a member for b2, just like b1.

Button b2;



b2 = (Button)findViewById(R.id.getValue);

b2.setOnClickListener(this);
Selçuk Cihan
  • 1,979
  • 2
  • 17
  • 30
  • @swess, sorry i can't view the link. Just change your `MainActivity`'s class declaration by adding an `implements View.OnClickListener` and set `b1`'s on click listener to `MainActivity`'s instance by calling `b1.setOnClickListener(this);`. – Selçuk Cihan Mar 23 '16 at 09:36
  • but should I add `b1 = (Button) findViewById(R.id.connect); b1.setOnClickListener(this);` in my onClick method? – swess Mar 23 '16 at 09:37
  • No just add `b1.setOnClickListener(this);` right after you create your button. Basically, you will add a single line to your code in `MainActivity`'s `onCreate` where you are setting `b1`. – Selçuk Cihan Mar 23 '16 at 09:43
  • I edited the post. Look at the Logcat and see if you can make something out of it. It displays the same error message. – swess Mar 23 '16 at 09:54
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107151/discussion-between-swess-and-selcuk-cihan). – swess Mar 23 '16 at 15:21