I wrote a server for android. The Server works good and I succeed to send a message from app that simulate a client (SocketTest).
So I wrote a client in C# by my self.
I tried my client against SocketTest(As server of course) and it's work.
The connection step to android seems to be good, I get no exception.
But I don't see the message in my Android device.
C# code
{
public partial class sendSms : Form
{
TcpClient client;
NetworkStream ns;
public sendSms()
{
InitializeComponent();
}
private void Connect()
{
client = new TcpClient("192.168.14.76", 8080);
//client = new TcpClient("127.0.0.1", 8080);
ns = client.GetStream();
}
private void button1_Click(object sender, EventArgs e)
{
Connect();
}
private void sendBtn_Click(object sender, EventArgs e)
{
SendMessage();
}
private void SendMessage()
{
string sendMSG = msgTB.Text;
ns.Write(Encoding.UTF8.GetBytes(sendMSG), 0, sendMSG.Length);
ns.Flush();
}
}
}
Andorid Server
public class MainActivity extends AppCompatActivity {
private ServerSocket serverSocket;
Handler UiHandler;
Thread thread = null;
private TextView textView;
private static final int PORT = 8080;
private String status = null;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
textView = (TextView) findViewById(R.id.ipTextView);
UiHandler = new Handler();
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = Formatter.formatIpAddress(wifiManager.getConnectionInfo().getIpAddress());
textView.setText("Ip - " + ipAddress + ", Port - " + PORT);
// statusTxt.setText("Hello");
this.thread = new Thread(new ServerThread());
this.thread.start();
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
UiHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public String[] getPhoneAndMSG(String msg)
{
return msg.split("&");
}
class updateUIThread implements Runnable
{
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
try {
textView.setText(msg);
String[] numAndMsG = getPhoneAndMSG(msg);
// SmsManager smsManager = SmsManager.getDefault();
// Toast.makeText(getApplicationContext(), numAndMsG[0] +" " +numAndMsG[1] , Toast.LENGTH_LONG).show();
// smsManager.sendTextMessage(numAndMsG[0], null, numAndMsG[1], null, null);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "SMS Faild", Toast.LENGTH_LONG).show();
}
// textView.setText(textView.getText().toString()+"Client Says: "+ msg + "\n");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Problem solved!
string sendMSG = msgTB.Text + "\r\n";
Related
It is now over a month that I'm trying to send a string using WiFi-Direct between two android devices, but I'm still struggling hard to understand what I'm doing wrong.
I've looked around forums but they often don't give much detail on how to achieve what I want.
I also went through those two guides from the android developer's website:
Create P2P connections with Wi-Fi Direct
Wi-Fi Direct (peer-to-peer or P2P) overview
I'm using one activity - ActivityConnection - where I toggle the visibility of views depending on whether the user previously chose to send or to receive the string.
Immediatly, on the client side, discoverPeers() looks for any device with WiFi-Direct turned on and displays them on a ListView. Once the user chooses a device and presses the send button, the connection makes itself and the string is sent.
On the server side, the server is immediatly launched using my AsyncServerTask class. There, it waits for a client to connect and to retrieve its sent string.
My main problem is that, after choosing the device and tapping on the send button, the server side isn't receiving anything.
My second problem is that, sometimes, devices aren't being discovered and the listview stays empty.
Am I missing something? Or maybe doing something wrong?
Here's my current code.
I took the liberty to get rid of any line I thought to be out of context to make it easier to read.
ActivityConnection
public class ActivityConnection extends AppCompatActivity implements NewPeersListener {
public static final String CONNECTION_ACTOR = "actor";
public static final String SEND_INFO = "send";
public static final String RECEIVE_INFO = "receive";
ListView listViewDevices;
private IntentFilter intentFilter;
private WifiP2pManager manager;
private WifiP2pManager.Channel channel;
private WiFiDirectBroadcastReceiver receiver;
public List <WifiP2pDevice> listDevices;
private WifiP2pDevice selectedDevice;
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
confirm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
connectToSelectedDevice();
}
});
Intent intent = this.getIntent();
String actor = intent.getStringExtra(CONNECTION_ACTOR);
this.intentFilter = new IntentFilter();
this.intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
this.intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
this.intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
this.intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
this.manager = (WifiP2pManager) this.getSystemService(Context.WIFI_P2P_SERVICE);
this.channel = this.manager.initialize(this, this.getMainLooper(), null);
this.receiver = new WiFiDirectBroadcastReceiver(this.manager, this.channel, this);
this.listDevices = new ArrayList <> ();
if (actor.equals(SEND_INFO)) {
DeviceAdapter adapter = new DeviceAdapter(ActivityConnection.this, R.layout.device_item, this.listDevices);
this.listViewDevices.setAdapter(adapter);
this.listViewDevices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedDevice = listDevices.get(position);
}
});
this.discoverPeers();
}
else if (actor.equals(RECEIVE_INFO)) {
new ServerAsyncTask(this).execute();
}
}
#Override
protected void onResume() {
super.onResume();
this.receiver = new WiFiDirectBroadcastReceiver(this.manager, this.channel, this);
this.registerReceiver(this.receiver, this.intentFilter);
}
#Override
protected void onPause() {
super.onPause();
this.unregisterReceiver(this.receiver);
}
public void resultReceived (String result) {
Toast.makeText(ActivityConnection.this, "Received! :)", Toast.LENGTH_SHORT).show();
}
private void discoverPeers () {
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// The discovery process succeeded
}
#Override
public void onFailure(int reason) {
// The discovery process DID NOT succeed
Toast.makeText(ActivityConnection.this, "Discovery process DID NOT succeed. Please verify that WiFi-Direct is active.", Toast.LENGTH_LONG).show();
}
});
}
private void connectToSelectedDevice () {
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = this.selectedDevice.deviceAddress;
this.manager.connect(this.channel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// Send string
Intent serviceIntent = new Intent(ActivityConnection.this, TransferService.class);
serviceIntent.setAction(TransferService.ACTION_SEND_STRING);
serviceIntent.putExtra(TransferService.EXTRAS_GROUP_OWNER_ADDRESS, getMacAddress());
serviceIntent.putExtra(TransferService.EXTRAS_GROUP_OWNER_PORT, 8090);
startService(serviceIntent);
onBackPressed();
}
#Override
public void onFailure(int reason) {
Toast.makeText(ActivityConnection.this, "Connection failed. Try again.", Toast.LENGTH_SHORT).show();
}
});
}
#NonNull
private String getMacAddress () {
try {
List <NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : all) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) {
return "";
}
StringBuilder result = new StringBuilder();
for (byte b : macBytes) {
result.append(String.format("%02X:",b));
}
if (result.length() > 0) {
result.deleteCharAt(result.length() - 1);
}
return result.toString();
}
} catch (Exception e) {
}
return "02:00:00:00:00:00";
}
#Override
public void newPeers (WifiP2pDeviceList wifiP2pDeviceList) {
this.listDevices = new ArrayList <> (wifiP2pDeviceList.getDeviceList());
DeviceAdapter adapter = new DeviceAdapter(ActivityConnection.this, R.layout.device_item, this.listDevices);
this.listViewDevices.setAdapter(adapter);
}
}
WiFiDirectBroadcastReceiver
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager manager;
private WifiP2pManager.Channel channel;
private ActivityConnection activity;
private List <NewPeersListener> listeners;
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel, ActivityConnection activity) {
super();
this.manager = manager;
this.channel = channel;
this.activity = activity;
this.listeners = new ArrayList <> ();
this.listeners.add(activity);
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wi-Fi P2P is enabled
} else {
// Wi-Fi P2P is not enabled
Toast.makeText(this.activity, "Please turn on WiFi-Direct (or WiFi-P2P).", Toast.LENGTH_SHORT).show();
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// Request available peers from the wifi p2p manager.
if (this.manager != null) {
this.manager.requestPeers(this.channel, new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
for (NewPeersListener listener : listeners) {
listener.newPeers(peers);
}
}
});
}
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
// Respond to new connection or disconnections
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// Respond to this device's wifi state changing
}
}
}
ServerAsyncTask (server)
public class ServerAsyncTask extends AsyncTask<Void, Void, String> {
private ServerSocket serverSocket;
private Socket clientSocket;
private DataInputStream stream;
private WeakReference <Context> contextWeakReference;
ServerAsyncTask (Context context) {
this.contextWeakReference = new WeakReference <> (context);
}
#Override
protected String doInBackground (Void... params) {
try {
this.serverSocket = new ServerSocket(8090);
this.clientSocket = this.serverSocket.accept();
this.stream = new DataInputStream(this.clientSocket.getInputStream());
String received = this.stream.readUTF();
this.serverSocket.close();
return received;
} catch (IOException e) {
Log.e(TransferService.TAG, Objects.requireNonNull(e.getMessage()));
return null;
} finally {
if (this.stream != null) {
try {
this.stream.close();
} catch (IOException e) {
Log.e(TransferService.TAG, Objects.requireNonNull(e.getMessage()));
}
}
if (this.clientSocket != null) {
try {
this.clientSocket.close();
} catch (IOException e) {
Log.e(TransferService.TAG, Objects.requireNonNull(e.getMessage()));
}
}
if (this.serverSocket != null) {
try {
this.serverSocket.close();
} catch (IOException e) {
Log.e(TransferService.TAG, Objects.requireNonNull(e.getMessage()));
}
}
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute (String result) {
super.onPostExecute(result);
((ActivityConnection) this.contextWeakReference.get()).resultReceived(result);
}
}
TransferService (client)
public class TransferService extends IntentService {
public static final String TAG = "WIFI_DIRECT";
private static final int SOCKET_TIMEOUT = 5000;
public static final String ACTION_SEND_STRING = "sendString";
public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
public TransferService (String name) {
super(name);
}
public TransferService () {
super("TransferService");
}
#Override
protected void onHandleIntent (Intent intent) {
Context context = getApplicationContext();
if (intent.getAction().equals(ACTION_SEND_STRING)) {
String toSend = "string to send";
String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
Socket socket = null;
DataOutputStream stream = null;
try {
// Create a client socket with the host, port, and timeout information.
socket = new Socket();
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Log.d(TAG, "Client connected socket - " + socket.isConnected());
// Send string
stream = new DataOutputStream(socket.getOutputStream());
stream.writeUTF(toSend);
stream.close();
Toast.makeText(context, "Sent! :)", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Log.e(TAG, Objects.requireNonNull(e.getMessage()));
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
In the ActivityConnetion class, I was giving a MAC address instead of an IP address. I don't know why I didn't see this, nor why I did it in the first place. So I looked around this forum and found out how to get the IP address of the WiFi-Direct's group owner: Wifi Direct Group Owner Address .
To get the code running, I went into the ActivityConnetion class, delete the getMacAddress() method and replaced this line:
serviceIntent.putExtra(TransferService.EXTRAS_GROUP_OWNER_ADDRESS, getMacAddress());
with this line:
serviceIntent.putExtra(TransferService.EXTRAS_GROUP_OWNER_ADDRESS, "192.168.49.1");
As the group owner's IP is always the same, one can write it down directly. As doing so can stop working if the IP changes, I would recommend looking for the group owner's IP instead. The link above show's how to do it.
I'm doing a desktop server application in java with multiple android clients, each one with a thread. I'm using sockets to provide the communication.
Until now, clients are sending messages to the server and then do something based on server response.
But now I need that server send a message to a specific client and I don't know how.
Could you help me please?
Thanks
Server class
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException{
boolean listening = true;
try (ServerSocket serverSocket = new ServerSocket(4444)){
while(listening){
new ServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
}
}
ServerThread
import java.net.*;
import java.io.*;
public class ServerThread extends Thread {
private Socket socket = null;
public ServerThread(Socket socket) {
super("ServerThread");
this.socket = socket;
}
public void run() {
try (
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
String inputLine, outputLine;
GameProtocol gp = new GameProtocol();
outputLine = gp.processInput(null);
//System.out.println(outputLine);
//out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
//System.out.println(outputLine);
outputLine = gp.processInput(inputLine);
System.out.println(outputLine);
out.println(outputLine);
if (outputLine.equals("Bye"))
break;
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
TcpClient class
import android.util.Log;
import java.io.*;
import java.net.*;
/**
* Created by andrecorreia on 03/06/16.
*/
public class TcpClient {
public static final String SERVER_IP = "10.0.2.2"; // computer IP address
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 TcpClient(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() {
Log.i("Debug", "stopClient");
// send mesage that we are closing the connection
//sendMessage(Constants.CLOSED_CONNECTION + "Kazy");
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);
//InetAddress serverAddr = InetAddress.getLocalHost();
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket("192.168.1.92", SERVER_PORT);
try {
Log.i("Debug", "inside try catch");
//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()));
// send login name
//sendMessage(Constants.LOGIN_NAME + PreferencesManager.getInstance().getUserName());
//sendMessage("Hi");
//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);
}
}
Main Activity
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity implements OnClickListener {
public static TcpClient tcpClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ConnectTask().execute("");
// Set up click listeners for all the buttons
View playNowButton = findViewById(R.id.playNow_button);
playNowButton.setOnClickListener(this);
View optionsButton = findViewById(R.id.options_button);
optionsButton.setOnClickListener(this);
View helpButton = findViewById(R.id.help_button);
helpButton.setOnClickListener(this);
View exitButton = findViewById(R.id.exit_button);
exitButton.setOnClickListener(this);
//---------------------------------------------
}
#Override
public void onClick(View v) {
Intent i;
switch (v.getId()){
case R.id.playNow_button:
i = new Intent(this, PlayNowActivity.class);
startActivity(i);
break;
case R.id.options_button:
i = new Intent(this, OptionsActivity.class);
tcpClient.sendMessage("options");
startActivity(i);
break;
case R.id.help_button:
i = new Intent(this, HelpActivity.class);
tcpClient.sendMessage("help");
startActivity(i);
break;
case R.id.exit_button:
finish();
break;
}
}
public class ConnectTask extends AsyncTask<String,String,TcpClient> {
#Override
protected TcpClient doInBackground(String... message) {
//we create a TCPClient object and
tcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
tcpClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
/*View view = adapter.getChildView(0, 0, false, null, null);
TextView text = (TextView) view.findViewById(R.id.betChildOdd);
child2.get(0).get(0).put("OLD", text.getText().toString());
child2.get(0).get(0).put(CONVERTED_ODDS, values[0].toString());
child2.get(0).get(0).put("CHANGE", "TRUE");
adapter.notifyDataSetChanged();*/
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
The solution you suggested could be something like this?
Thanks
public class Server {
private static ArrayList<ServerThread> playerList;
private static LinkedBlockingQueue<Object> messages;
private static GameProtocol gp ;
public static void main(String[] args) throws IOException{
playerList = new ArrayList<ServerThread>();
messages = new LinkedBlockingQueue<Object>();
gp = new GameProtocol();
Thread accept = new Thread() {
public void run(){
while(true){
try{
ServerSocket serverSocket = new ServerSocket(4444);
ServerThread player = new ServerThread(serverSocket.accept(), gp);
playerList.add(player);
player.start();
}
catch(IOException e){ e.printStackTrace(); }
}
}
};
accept.setDaemon(true);
accept.start();
Thread messageHandling = new Thread() {
public void run(){
while(true){
try{
Object message = messages.take();
// Do some handling here...
System.out.println("Message Received: " + message);
}
catch(InterruptedException e){ }
}
}
};
messageHandling.setDaemon(true);
messageHandling.start();
}
}
I'm working on a OBDII reading app to read basic data such as (in this case) voltage. I've tried other apps and it works just fine to read the voltage of the OBDII adapter, so there's nothing wrong with the adapter itself.
I'm using the OBDII api from pires on github. When connection to my OBDII via Bluetooth successfully I get 0,0V and after that I get a Error saying: "Error running 01 42, response: ...UNABLETOCONNECT" (you can see this in the log cat below)
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 pPlatform = Constants.SPA;
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);
Log.v("write", "write");
}
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) {
Log.v("connectException", "e");
try {
mmSocket.close();
Log.v("close", "close");
} catch (IOException closeException) {
Log.v("closeException", "e");
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
}
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private BluetoothSocket mmSocket;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
switch (pPlatform) {
case Constants.SPA:
multiCommand = new ObdMultiCommand();
multiCommand.add(new OdbRawCommand(SPA.VOLTAGE));
break;
}
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.v("e", "e");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
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
try {
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
//System.out.println("Inside while");
// TODO handle commands result
Log.d("d", "Voltage: " + voltageCommand.getFormattedResult());
try {
voltageCommand.run(mmInStream, mmOutStream);
voltageCommand.getFormattedResult();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("inside catch before while");
}
// Get the input and output streams, using temp objects because
// member streams are final
/*
try {
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
voltageCommand.run(mmSocket.getInputStream(), mmSocket.getOutputStream());
voltageCommand.getFormattedResult();
Log.d("Log", "Voltage:" + voltageCommand.getFormattedResult());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
//ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
/*while (!Thread.currentThread().isInterrupted()) {
try {
voltageCommand.run(socket.getInputStream(), socket.getOutputStream());
voltageCommand.getCalculatedResult();
Log.d("Log", "Voltage:" + voltageCommand.getResultUnit());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(mmInStream, mmOutStream);
new LineFeedOffCommand().run(mmInStream, mmOutStream);
new TimeoutCommand(100).run(mmInStream, mmOutStream);
new SelectProtocolCommand(ObdProtocols.AUTO).run(mmInStream, mmOutStream);
//ISO_15765_4_CAN
} catch (Exception e) {
Log.v("OBDcmds", "e");
// handle errors
}
}
// CALL this to MainActivity
public void sendRawCommand(String s) {
try {
} catch (Exception e) {
Log.v("sendRawCommand", "e");
}
}
/*
// 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) {
}
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
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);
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);
b1.setOnClickListener(this);
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 voltage = ("ATRV");
switch (id) {
case R.id.connect:
onConnect(); //Operation
Log.v("Log", "Pressed onClick");
break;
case R.id.getValue:
btHandler.write(SPA.VOLTAGE);
Log.v("getValue","" + SPA.VOLTAGE);
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), R.string.enable_bluetooth, Toast.LENGTH_SHORT).show();
finish();
}
}
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();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Constants.java
public interface Constants {
int MESSAGE_STATE_CHANGE = 1;
int TOAST = 1;
int SHORT = 0;
int STATE_CONNECTED = 3;
int CONNECTION_STATUS = 1;
int MESSAGE_DEVICE_NAME = 4;
String DEVICE_NAME = "device_name";
int SPA = 1;
}
SPA.java
public interface SPA {
String VOLTAGE = "AT RV";
}
I'm making a OBDII Bluetooth Android app and i'm having some issues sending out commands. I've already made a successfully connection between my mobile device and my OBDII adapter, but when I click on another activity, the Bluetooth connection seems to quit?
When you open up the app you'll see a button that says "Connect Device". When you press that, a ListAdapter will show up with paired Bluetooth devices. Then when you have succesfully connected to the device (OBDII Adapter) it will take you to another layout where there is 3 activities that are 3 different powerplatforms for cars. This is where the problem occurs. For now, I just want to be able to read the voltage from the OBDII. But when I click my button getValue inside one of the 3 activities. I get an logcat error. And I think it's because I haven't initiated my BluetoothHandler properly. I have no idea how to do this.
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
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);
b1.setOnClickListener(this);
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 voltage = ("ATRV");
switch (id) {
case R.id.connect:
onConnect(); //Operation
Log.v("Log", "Pressed onClick");
break;
/*case R.id.getValue:
btHandler.write(voltage);
Log.v("Log", "getValue" + voltage);
break;*/
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), R.string.enable_bluetooth, Toast.LENGTH_SHORT).show();
finish();
}
}
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();
}
BTHandler:
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);
Log.v("write", "write");
}
/*
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, "");
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
}
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(socket.getInputStream(), socket.getOutputStream());
// TODO handle commands result
//Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
//Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
Log.v("Log", "Voltage: " + voltageCommand.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 command) {
try {
new OdbRawCommand(command);
} catch (Exception e) {
Log.v("sendRawCommand", "e");
}
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new TimeoutCommand(100).run(socket.getInputStream(), socket.getOutputStream());
new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN
} catch (Exception e) {
Log.v("OBDcmds", "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) {
}
}
}
}
SPA: One of the power platforms mentioned before.
public class SPA extends AppCompatActivity implements View.OnClickListener {
Button b2;
BTHandler btHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sp);
b2 = (Button) findViewById(R.id.getValue);
b2.setOnClickListener(this);
}
public void onClick(View v) {
int id = v.getId();
String voltage = ("AT RV");
switch (id) {
case R.id.getValue:
btHandler.write(voltage);
Log.v("Log", "getValue" + voltage);
break;
}
}
}
Logcat:
The reason of the error is here:
BTHandler btHandler;
and you are doing this:
btHandler.write(voltage);
but the object is null referenced....
you need to initialize the BTHandler in the oncreate...
or maybe better:
use a service so you can Bind all the activities to that...
PS:
Note that the BTHandler of the MainActivity is not the same as the one declared in the SPA Class... so although that btHandler is constructed and works in MainActivity doesnt mean it will work in other activities/classes
How to send data(string) server-to client with button?
I made several attempts, but I'm new to android programming. Therefore
waiting for your help..my expectations: just a small sample..
My goal is to send data from server to client.
enter code here public class MainActivity extends ActionBarActivity {
private TextView tvClientMsg,tvServerIP,tvServerPort;
private final int SERVER_PORT = 13003; //Define the server port
#Override
protected void onCreate(Bundle saveenter code heredInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvClientMsg = (TextView) findViewById(R.id.textViewClientMessage);
tvServerIP = (TextView) findViewById(R.id.textViewServerIP);
tvServerPort = (TextView) findViewById(R.id.textViewServerPort);
tvServerPort.setText(Integer.toString(SERVER_PORT));
getDeviceIpAddress();
new Thread(new Runnable() {
#Override
public void run() {
try {
ServerSocket socServer = new ServerSocket(SERVER_PORT);
Socket socClient = null;
while (true) {
socClient = socServer.accept();
ServerAsyncTask serverAsyncTask = new ServerAsyncTask();
serverAsyncTask.execute(new Socket[] {socClient});
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
public void getDeviceIpAddress() {
try {
for (Enumeration<NetworkInterface> enumeration = NetworkInterface
.getNetworkInterfaces(); enumeration.hasMoreElements();) {
NetworkInterface networkInterface = enumeration.nextElement();
for (Enumeration<InetAddress> enumerationIpAddr = networkInterface.getInetAddresses(); enumerationIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumerationIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress.getAddress().length == 4) {
tvServerIP.setText(inetAddress.getHostAddress());
}
}
}
} catch (SocketException e) {
Log.e("ERROR:", e.toString());
}
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
class ServerAsyncTask extends AsyncTask<Socket, Void, String> {
protected String doInBackground(Socket... params) {
String result = null;
Socket mySocket = params[0];
try {
InputStream is = mySocket.getInputStream();
PrintWriter out = new PrintWriter(
mySocket.getOutputStream(), true);
out.println("Hello from server");
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
result = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
protected void onPostExecute(String s) {
tvClientMsg.setText(s);
}
}
}