How can I pass message via Handler in Android? - java

I'm learning how work handler in Android. I did Android server and socket class. I want send some message (i.e. "New Connect") from socket to mainactivity, when somebody connect to server. I can't figure out how to pass from socket to mainactivity. (More in comments)
HttpServerActivity.java
public class HttpServerActivity extends Activity implements OnClickListener{
private SocketServer s;
private static final int READ_EXTERNAL_STORAGE = 1;
Button btn1, btn2;
// There I'm trying to send message to button, when somebody connected
Handler h = new Handler(){
#Override
public void handleMessage(Message msg){
super.handleMessage(msg);
String text = (String)msg.obj;
btn1.setText(text);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_http_server);
Button btn1 = (Button)findViewById(R.id.button1);
Button btn2 = (Button)findViewById(R.id.button2);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.http_server, menu);
return true;
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.button1) {
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE);
} else {
// I dont know figure out in this place
s = new SocketServer(h);
s.start();
}
}
if (v.getId() == R.id.button2) {
s.close();
try {
s.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case READ_EXTERNAL_STORAGE:
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// I dont know figure out in this place
s = new SocketServer(h);
s.start();
}
break;
default:
break;
}
}
}
SocketServer.java
public class SocketServer extends Thread {
private final Handler mHandler;
public SocketServer(Handler handler)
{
mHandler = handler;
}
ServerSocket serverSocket;
public final int port = 12345;
boolean bRunning;
public void close() {
try {
serverSocket.close();
} catch (IOException e) {
Log.d("SERVER", "Error, probably interrupted in accept(), see log");
e.printStackTrace();
}
bRunning = false;
}
public Handler mHandler;
public void run() {
try {
Log.d("SERVER", "Creating Socket");
serverSocket = new ServerSocket(port);
bRunning = true;
while (bRunning) {
Log.d("SERVER", "Socket Waiting for connection");
Socket s = serverSocket.accept();
Log.d("SERVER", "Socket Accepted");
// trying to send some message
String[] messageString = new String[1];
Message message = Message.obtain();
messageString[0]="OK";
message.obj = messageString;
mHandler.sendMessage(message);
OutputStream o = s.getOutputStream();
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(o));
out.write("HTTP/1.0 200 OK\n" +
"Date: Fri, 31 Dec 1999 23:59:59 GMT\n" +
"Content-Type: text/html\n" +
"Content-Length: 1354\n" +
"\n" +
"<html>\n" +
"<body>\n" +
"<h1> Connected </h1>\n" +
"</body>\n" +
"</html>");
out.flush();
while (!((tmp = in.readLine()).isEmpty()))
{
Log.d("Header", tmp);
if (tmp.startsWith("GET"))
{
getRequest = tmp;
}
}
s.close();
Log.d("SERVER", "Socket Closed");
}
}
catch (IOException e) {
if (serverSocket != null && serverSocket.isClosed())
Log.d("SERVER", "Normal exit");
else {
Log.d("SERVER", "Error");
e.printStackTrace();
}
}
finally {
serverSocket = null;
bRunning = false;
}
}
}

This is a sample of a bigger project I was involved a few years ago. You will not be able to run as it is, but I think you can see how the communication between a Service and an Activity works. Feel free to ask if anything is not clear
Service
public class BluetoothService {
private final Handler mHandler;
public BluetoothService(Context context, Handler handler) {
mHandler = handler;
}
public synchronized void Connecting(...) {
...
Message MenssageToActivity = mHandler.obtainMessage(Cliente_Bluetooth.MESSAGE_HELLO);
Bundle bundle = new Bundle();
bundle.putString(BluetoothClient.DEVICE_NAME, " Gorkatan");
MensajeParaActivity.setData(bundle);
mHandler.sendMessage(MensajeParaActivity);
...
}
}
Activity
public class BluetoothClient{
public static final int MESSAGE_HELLO = 1;
public static final int MESSAGE_BYE = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
mBluetoothService = new BluetoothService(this, mHandler);
}
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_HELLO:
String mName = null;
mName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Hello "+ mName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_BYE:
System.out.println("Bye!")
break;
}
Here it is the whole project (which has got comments and variable names in Spanish):
https://github.com/ignacio-alorre/PDF-Dispenser/tree/master/Client/Cliente_Bluetooth/src/com/cliente_bluetooth

If you plan on sending data from a thread to your handler then use obtainMessage to create a message object.
You must also use the same instance of the handler to handleMessage and sendMessage.
Here you will find a great resource explaining how to use Handler:
https://www.youtube.com/watch?v=LJ_pUlWzGsc

Related

Sending data over bluetooth to STM32F411

I am trying to send data over bluetooth to stm32f411 board. I am using HC-05 v2 bluetooth module which communicates over UART interface. When I'm sending data from computer it works perfectly- data is sent and STM's response is received over UART in RealTerm. However switching to bluetooth module and sending and receiving data from android app doesn't work as expected. For now I want to send ASCII data (for now just 0 and 1, but the goal is to send integers from 0 to 100). Perhaps it has something to do with message length or app's baud rate.
I also tried to send data as byte not byte array but it didn't work- when I sent 0 it worked fine but when I sent 1 I got 120 decimal on STM, 2 I got 128, 3 I got 248. When I tried sending the same data back to app every message started with [B# followed by usually 7 characters.
My android studio code:
public class MainActivity extends AppCompatActivity {
Button someButton;
ListView pairedDevListView;
Switch bluetoothSwitch;
BluetoothAdapter myBluetoothAdapter;
Intent bluetoothEnablingIntent;
TextView connectionStatusText;
SeekBar rightEnSeekBar, leftEnSeekBar;
SendReceive sendReceive;
BluetoothDevice[] bluetoothPairedDevArray;
int REQUEST_ENABLE_BLUETOOTH = 1;
int requestCodeForEnable;
static final int STATE_LISTENING = 1;
static final int STATE_CONNECTING = 2;
static final int STATE_CONNECTED = 3;
static final int STATE_CONNECTION_FAILED = 4;
static final int STATE_MESSAGE_RECEIVED = 5;
private static final String APP_NAME = "STM32";
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(#NonNull Message message) {
switch (message.what){
case STATE_LISTENING:
connectionStatusText.setText("Listening");
break;
case STATE_CONNECTING:
connectionStatusText.setText("Connecting");
break;
case STATE_CONNECTED:
connectionStatusText.setText("Connected");
break;
case STATE_CONNECTION_FAILED:
connectionStatusText.setText("Connection failed");
break;
case STATE_MESSAGE_RECEIVED:
byte[] readBuff = (byte[]) message.obj;
//String tempMsg = new String(readBuff, 0 , message.arg1);
String tempMsg = null;
try {
tempMsg = new String(readBuff, "ASCII");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), String.valueOf(readBuff), Toast.LENGTH_SHORT).show();
connectionStatusText.setText(tempMsg);
break;
}
return true;
}
});
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothEnablingIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
requestCodeForEnable = 1;
if(!myBluetoothAdapter.isEnabled()){
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
}
findViewByIds();
implementListeners();
}
private void findViewByIds() {
pairedDevListView = findViewById(R.id.pairedDevicesListView);
bluetoothSwitch = findViewById(R.id.btSwitch);
connectionStatusText = findViewById(R.id.statusTextView);
rightEnSeekBar = findViewById(R.id.rightSeekBar);
leftEnSeekBar = findViewById(R.id.leftSeekBar);
someButton = findViewById(R.id.button2);
}
private void implementListeners() {
//BLUETOOTH ENABLING SWITCH
bluetoothSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
if(myBluetoothAdapter == null){
Toast.makeText(getApplicationContext(),"Bluetooth is not supported on this device", Toast.LENGTH_LONG).show();
}
else{
if(!myBluetoothAdapter.isEnabled()){
startActivityForResult(bluetoothEnablingIntent, requestCodeForEnable);
}
}
}
else{
if(myBluetoothAdapter.isEnabled()){
myBluetoothAdapter.disable();
Toast.makeText(getApplicationContext(), "Bluetooth is disabled", Toast.LENGTH_LONG).show();
}
}
}
});
//CLICKING ON DEVICE FROM PAIRED DEVICE LIST
pairedDevListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ClientClass clientClass = new ClientClass(bluetoothPairedDevArray[i]);
clientClass.start();
connectionStatusText.setText("Connecting");
}
});
someButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String string = "1";
try {
sendReceive.write(string.getBytes("ASCII"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
}
//SHOWING PAIRED DEVICES WHEN SWITCH IS CHECKED
private void showPairedDevices() {
Set<BluetoothDevice> btDevices = myBluetoothAdapter.getBondedDevices();
bluetoothPairedDevArray = new BluetoothDevice[btDevices.size()];
String[] deviceNames = new String[btDevices.size()];
int index = 0;
if(btDevices.size() > 0){
for(BluetoothDevice device: btDevices){
deviceNames[index] = device.getName();
bluetoothPairedDevArray[index] = device;
index++;
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, deviceNames);
pairedDevListView.setAdapter(arrayAdapter);
}
}
//SHOWING POP UP MESSAGE
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
if(requestCode == requestCodeForEnable){
if(resultCode == RESULT_OK){
Toast.makeText(getApplicationContext(), "Bluetooth is enabled", Toast.LENGTH_LONG).show();
showPairedDevices();
}
else if(resultCode == RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "Bluetooth enabling cancelled", Toast.LENGTH_LONG).show();
}
}
}
private class ClientClass extends Thread{
private BluetoothSocket socket;
private BluetoothDevice device;
public ClientClass(BluetoothDevice device1){
this.device = device1;
try {
socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
myBluetoothAdapter.cancelDiscovery();
try {
socket.connect();
Message message = Message.obtain();
message.what = STATE_CONNECTED;
handler.sendMessage(message);
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
e.printStackTrace();
Message message = Message.obtain();
message.what = STATE_CONNECTION_FAILED;
handler.sendMessage(message);
}
}
}
private class SendReceive extends Thread {
private final BluetoothSocket bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public SendReceive(BluetoothSocket socket) {
bluetoothSocket = socket;
InputStream tempIn = null;
OutputStream tempOut = null;
try {
tempIn = bluetoothSocket.getInputStream();
tempOut = bluetoothSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
inputStream = tempIn;
outputStream = tempOut;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = inputStream.read(buffer);
handler.obtainMessage(STATE_MESSAGE_RECEIVED, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes) {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
My STM code:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
switch (atoi(&Received)) {
case 0:
size = sprintf(Data, "STOP\n\r");
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET);
break;
case 1:
size = sprintf(Data, "START\n\r");
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
break;
default:
size = sprintf(Data, "Odebrano nieznany znak: %c\n\r", Received);
break;
}
HAL_UART_Transmit_IT(&huart1, Data, size);
HAL_UART_Receive_IT(&huart1, &Received, 1);
HAL_GPIO_TogglePin(RED_LED_GPIO_Port, RED_LED_Pin);
}

Why does my service class receive null values?

I have a PlayerActivity class, and a PlayerConnect class.
Previously, I used PlayerActivity class to start a thread that would run PlayerConnect. I recently found that the thread misbehaves a little, and have been recommended to use services (for this: IntentServices).
Problem: My logs tell me that the IP, name, and init are null, null, 0, which should not be the case as they are supposed to be set before the point of starting the service. Logs also tell me that it's failing to connect to the localhost, which I think it's defaulting to because it doesn't have a set IP to try.
Am I correctly referencing the PlayerConnect class in my Intent?
PlayerActivity:
public class PlayerActivity extends AppCompatActivity {
InetAddress hostIP;
String playerName;
int playerInitiative = -1;
boolean denied = false;
boolean started = false;
PlayerConnect playerConnect;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
submit = (Button) findViewById(R.id.submit);
submit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (!(playerName.equals("")) && playerInitiative > -1) {
try {
if (!(hostIPString.equals(""))) {
hostIP = InetAddress.getByName(hostIPString);
if(!(started)) {
playerConnect = new PlayerConnect();
playerConnect.SetHostIP(hostIP);
playerConnect.SetPlayerName(playerName);
playerConnect.SetPlayerInit(playerInitiative);
denied = playerConnect.GetDenied();
started = true;
}
else {
playerConnect.SetHostIP(hostIP);
playerConnect.SetPlayerName(playerName);
playerConnect.SetPlayerInit(playerInitiative);
denied = playerConnect.GetDenied();
}
if (denied)
{
started = false;
}
else
{
Intent playerConnectIntent =
new Intent(PlayerActivity.this, playerConnect.getClass());
startService(playerConnectIntent);
}
}
}
catch (Exception e) {
Log.i("LOG", e.toString());
}
}
}
});
}
}
PlayerConnect:
public class PlayerConnect extends IntentService {
public PlayerConnect() {
super("PlayerConnect");
}
InetAddress hostIP;
String playerName;
int playerInitiative;
boolean denied = false;
#Override
public void onHandleIntent(Intent intent) {
SendPlayerData(hostIP, playerName, playerInitiative);
}
private void SendPlayerData(InetAddress IP, String name, int init) {
try {
int port = 8080;
Socket socket = new Socket();
socket.connect(new InetSocketAddress(IP, port), 3000);
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
if (socket.isConnected())
{
output.writeUTF(name);
output.writeInt(init);
output.close();
socket.close();
Log.i("LOG", "client socket connected");
}
if (socket.isClosed())
{
stopSelf();
Log.i("LOG", "client socket closed");
}
}
catch (Exception e) {
denied = true;
Log.i("LOG", e.toString());
Log.i("LOG", IP + name + init);
}
}
public void SetHostIP(InetAddress host)
{
hostIP = host;
}
public void SetPlayerName(String name)
{
playerName = name;
}
public void SetPlayerInit(int init)
{
playerInitiative = init;
}
public boolean GetDenied()
{
return denied;
}
}
greeble31 Your comment helped me a lot, so I'm making it the answer for future readers. Thank you.
No, you never want to construct a Service subclass yourself (new PlayerConnect()). That's the system's job. The one it gives you in response to a startService() call will be completely different from the one you get back from the constructor, so it won't have any of the data you added to it. You need to add your data to playerConnectIntent, and retrieve it in onHandleIntent().

Android Bluetooth Communication call write medthod

I am attempting to use the MyBluetoothService class straight from the Android tutorials and call the write method from the main activity as suggested by the text. I would just like some guidance on how to pass a string from the main activity to the write method and send it to a connected Bluetooth device.
public class MyBluetoothService {
private static final String TAG = "MY_APP_DEBUG_TAG";
private Handler mHandler; // handler that gets info from Bluetooth service
// Defines several constants used when transmitting messages between the
// service and the UI.
private interface MessageConstants {
public static final int MESSAGE_READ = 0;
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_TOAST = 2;
// ... (Add other message types here as needed.)
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private byte[] mmBuffer; // mmBuffer store for the stream
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams; using temp objects because
// member streams are final.
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating input stream", e);
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating output stream", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
mmBuffer = new byte[1024];
int numBytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs.
while (true) {
try {
// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
// Send the obtained bytes to the UI activity.
Message readMsg = mHandler.obtainMessage(
MessageConstants.MESSAGE_READ, numBytes, -1,
mmBuffer);
readMsg.sendToTarget();
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
break;
}
}
}
// Call this from the main activity to send data to the remote device.
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
// Share the sent message with the UI activity.
Message writtenMsg = mHandler.obtainMessage(
MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
writtenMsg.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Error occurred when sending data", e);
// Send a failure message back to the activity.
Message writeErrorMsg =
mHandler.obtainMessage(MessageConstants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString("toast",
"Couldn't send data to the other device");
writeErrorMsg.setData(bundle);
mHandler.sendMessage(writeErrorMsg);
}
}
// Call this method from the main activity to shut down the connection.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the connect socket", e);
}
}
}
}
this code will help you to find all the devices in the surrounding
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class DeviceList extends AppCompatActivity {
ListView blist;
Button b;
private BluetoothAdapter myBluetooth = null;
private Set<BluetoothDevice> pairedDevices;
public static String EXTRA_ADDRESS = "device_address";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_list);
b=(Button)findViewById(R.id.button);
blist=(ListView)findViewById(R.id.listView);
myBluetooth = BluetoothAdapter.getDefaultAdapter();
if(myBluetooth == null)
{
//Show a mensag. that the device has no bluetooth adapter
Toast.makeText(getApplicationContext(), "Bluetooth Device Not Available", Toast.LENGTH_LONG).show();
//finish apk
finish();
}
else if(!myBluetooth.isEnabled())
{
//Ask to the user turn the bluetooth on
Intent turnBTon = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnBTon,1);
}
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
pairedDevices();
}
});
}
private void pairedDevices()
{
pairedDevices=myBluetooth.getBondedDevices();
ArrayList list=new ArrayList();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice bt : pairedDevices)
{
list.add(bt.getName() + "\n" + bt.getAddress()); //Get the device's name and the address
}
}
else
{
Toast.makeText(getApplicationContext(), "No Paired Bluetooth Devices Found.", Toast.LENGTH_LONG).show();
}
final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
blist.setAdapter(adapter);
blist.setOnItemClickListener(myListClickListener); //Method called when the device from the list is clicked
}
private AdapterView.OnItemClickListener myListClickListener = new AdapterView.OnItemClickListener()
{
public void onItemClick (AdapterView<?> av, View v, int arg2, long arg3)
{
// Get the device MAC address, the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
// Make an intent to start next activity.
Intent i = new Intent(DeviceList.this, ledControl.class);
//Change the activity.
i.putExtra(EXTRA_ADDRESS, address); //this will be received at ledControl (class) Activity
startActivity(i);
}
};
}
this code helps to send the message to the device connected
public class ledControl extends AppCompatActivity {
Button btnOn, btnOff, btnDis;
TextView lumn;
String address = null;
private ProgressDialog progress;
BluetoothAdapter myBluetooth = null;
BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
//SPP UUID. Look for it
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent newint = getIntent();
address = newint.getStringExtra(DeviceList.EXTRA_ADDRESS); //receive the address of the bluetooth device
//view of the ledControl
setContentView(R.layout.activity_led_control);
//call the widgtes
btnOn = (Button) findViewById(R.id.button2);
btnOff = (Button) findViewById(R.id.button3);
btnDis = (Button) findViewById(R.id.button4);
lumn = (TextView) findViewById(R.id.lumn);
new ConnectBT().execute(); //Call the class to connect
//commands to be sent to bluetooth
btnOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
turnOnLed();
//method to turn on
}
});
btnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
turnOffLed(); //method to turn off
}
});
btnDis.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Disconnect(); //close connection
}
});
}
private void Disconnect()
{
if (btSocket!=null) //If the btSocket is busy
{
try
{
btSocket.close(); //close connection
}
catch (IOException e)
{ msg("Error");}
}
finish(); //return to the first layout
}
private void turnOffLed()
{
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write("F".toString().getBytes());
//Log.e("message",)
}
catch (IOException e)
{
msg("Error");
}
}
}
private void turnOnLed()
{
if (btSocket!=null)
{
try
{
//Toast.makeText(ledControl.this,"oning",Toast.LENGTH_SHORT).show();
btSocket.getOutputStream().write("O".toString().getBytes());
Log.e("message",btSocket.toString());
}
catch (IOException e)
{
msg("Error");
}
}
}
// fast way to call Toast
private void msg(String s)
{
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
private class ConnectBT extends AsyncTask<Void, Void, Void> // UI thread
{
private boolean ConnectSuccess = true; //if it's here, it's almost connected
#Override
protected void onPreExecute()
{
progress = ProgressDialog.show(ledControl.this, "Connecting...", "Please wait!!!"); //show a progress dialog
}
#Override
protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
{
try
{
if (btSocket == null || !isBtConnected)
{
myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();//start connection
}
}
catch (IOException e)
{
ConnectSuccess = false;//if the try failed, you can check the exception here
}
return null;
}
#Override
protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
{
super.onPostExecute(result);
if (!ConnectSuccess)
{
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
finish();
}
else
{
msg("Connected.");
isBtConnected = true;
}
progress.dismiss();
}
}
}

Receive message from server in TCP Client and set it in TextView

I'm having some troubles while trying to visualize the message send from the TCP Server as response to my TCP Client
Here is my Client.java code
public class Client {
public static String SERVER_IP; //server IP address
public static String ipp;
public static final int SERVER_PORT = 4444;
// message to send to the server
private String mServerMessage;
// sends message received notifications
private OnMessageReceived mMessageListener = null;
// while this is true, the server will continue running
private boolean mRun = false;
// used to send messages
private PrintWriter mBufferOut;
// used to read messages from the server
private BufferedReader mBufferIn;
/**
* Constructor of the class. OnMessagedReceived listens for the messages received from server
*/
public Client(OnMessageReceived listener) {
mMessageListener = listener;
}
/**
* Sends the message entered by client to the server
*
* #param message text entered by client
*/
public void sendMessage(String message) {
if (mBufferOut != null && !mBufferOut.checkError()) {
mBufferOut.println(message);
mBufferOut.flush();
}
}
/**
* Close the connection and release the members
*/
public void stopClient() {
mRun = false;
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mMessageListener = null;
mBufferIn = null;
mBufferOut = null;
mServerMessage = null;
}
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
//sends the message to the server
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//receives the message which the server sends back
mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//in this while the client listens for the messages sent by the server
while (mRun) {
mServerMessage = mBufferIn.readLine();
if (mServerMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(mServerMessage);
}
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
While here is the MainActivity :
public class MainActivity extends AppCompatActivity {
Server server;
static Client client;
settings Settings;
public static TextView terminale, indr, msg;
TextView log;
static String ipp;
static String trm;
static DataBaseHandler myDB;
allert Allert;
SharedPreferences prefs;
String s1 = "GAB Tamagnini SRL © 2017 \n" +
"Via Beniamino Disraeli, 17,\n" +
"42124 Reggio Emilia \n" +
"Telefono: 0522 / 38 32 22 \n" +
"Fax: 0522 / 38 32 72 \n" +
"Partita IVA, Codice Fiscale \n" +
"Reg. Impr. di RE 00168780351 \n" +
"Cap. soc. € 50.000,00 i.v. \n" + "" +
"REA n. RE-107440 \n" +
"presso C.C.I.A.A. di Reggio Emilia";
ImageButton settings, helps, allerts, home;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Utils.darkenStatusBar(this, R.color.colorAccent);
server = new Server(this);
myDB = DataBaseHandler.getInstance(this);
msg = (TextView) findViewById(R.id.msg);
log = (TextView) findViewById(R.id.log_avviso);
settings = (ImageButton) findViewById(R.id.impo);
helps = (ImageButton) findViewById(R.id.aiut);
allerts = (ImageButton) findViewById(R.id.msge);
home = (ImageButton) findViewById(R.id.gab);
terminale = (TextView) findViewById(R.id.terminal);
indr = (TextView) findViewById(R.id.indr);
final Cursor cursor = myDB.fetchData();
if (cursor.moveToFirst()) {
do {
indr.setText(cursor.getString(1));
terminale.setText(cursor.getString(2));
Client.SERVER_IP = cursor.getString(1);
trm = cursor.getString(2);
} while (cursor.moveToNext());
}
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
ipp = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
startConnection.postDelayed(runnableConnection,5000);
startMessage.postDelayed(runnableMessage,5500);
cursor.close();
server.Parti();
home.setOnClickListener(new View.OnClickListener() {
int counter = 0;
#Override
public void onClick(View view) {
counter++;
if (counter == 10) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setCancelable(true);
builder.setMessage(s1);
builder.show();
counter = 0;
}
}
});
settings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent impostazioni = new Intent(getApplicationContext(), settingsLogin.class);
startActivity(impostazioni);
}
});
helps.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent pgHelp = new Intent(getApplicationContext(), help.class);
startActivity(pgHelp);
}
});
allerts.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Server.count = 0;
SharedPreferences prefs = getSharedPreferences("MY_DATA", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.clear();
editor.apply();
msg.setVisibility(View.INVISIBLE);
Intent pgAlert = new Intent(getApplicationContext(), allert.class);
startActivity(pgAlert);
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
server.onDestroy();
}
public static class ConnectTask extends AsyncTask<String, String, Client> {
#Override
protected Client doInBackground(String... message) {
client = new Client(new Client.OnMessageReceived() {
#Override
public void messageReceived(String message) {
messageReceived(message);
}
});
client.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
Log.d("test", "response " + values[0]);
}
}
static Handler startConnection = new Handler();
static Runnable runnableConnection = new Runnable() {
#Override
public void run() {
new ConnectTask().execute("");
}
};
static Handler startMessage = new Handler();
static Runnable runnableMessage = new Runnable() {
#Override
public void run() {
final Cursor cursor = myDB.fetchData();
if (cursor.moveToFirst()) {
do {
Client.SERVER_IP = cursor.getString(1);
trm = cursor.getString(2);
} while (cursor.moveToNext());
}
if (client != null) {
client.sendMessage(ipp + "#" + trm);
}
}
};
}
So what i'm trying to do is receive message from the server and visualize it in help.java activity in a TextView called msgServer set as static.
Actually i don't know which value i have to attribute to the help.msgServer.setText() and where to put it in MainActivity.
Fixed by setting in AsyncTask in MainActivity following code:
msgServer.setTextColor(Color.parseColor("#00FF00"));
msgServer.setText("ONLINE");
in the onProgressUpdate method.
So i identified the right place from where i can get the message sent by the server, the message is contained in:
values
.

How can I send ELM327 commands to my OBDII adapter through Bluetooth?

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();
}
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);

Categories

Resources