In this Demo we will see
- Check compatibility of the device.
- Turn On/Off Bluetooth, Making it discoverable
- List Paired Devies.
- Check for Online Bluetooth Devices.
- Connect with a Device.
- Communicate between Connected Bluetooth Devices.
- Disconnect from Device.
You can download the complete Android Studio Source code at the end of the post.
Before We start with the coding, make sure you add the following permission to the AndroidManifest
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
Before we start, I have some variable declarations like this.
BluetoothAdapter mBluetoothAdapter; private static final int REQUEST_ENABLE_BT = 0; private static final int REQUEST_DISCOVERABLE_BT = 0; private static final String TAG = "Bluetooth"; ListView listView; private CoordinatorLayout coordinatorLayout; ArrayList<BluetoothDevice> devices; ArrayList<String> allDevices; private BluetoothDevice deviceToConnect; private static final UUID MY_UUID_SECURE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); private BluetoothSocket curBTSocket = null; ClientThread connectThread; DeviceConnectThread deviceConnectThread; ServerConnectThread serverConnectThread; AlertDialog alertDialogObject; ArrayAdapter<String> devicesListAdapter; LinearLayout linSendMessage; Button btnSend; EditText edtMessage;
These are some of the constants that I use in this application declared in Constants.java.
package com.coderzheaven.bluetoothdemo.constants; public class Constants { // Message types sent from the threads Handler public static final int MESSAGE_STATE_CHANGE = 1; public static final int MESSAGE_READ = 2; public static final int MESSAGE_WRITE = 3; public static final int MESSAGE_DEVICE_NAME = 4; public static final int MESSAGE_TOAST = 5; public static final int MESSAGE_SERVER_CONNECTED = 7; // Key names received from the threads Handler public static final String DEVICE_NAME = "device_name"; }
1. Get the Default Bluetooth Adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
2. To check the Compatibility of your device.
private void checkCompatibility() { // Phone does not support Bluetooth so let the user know and exit. if (mBluetoothAdapter == null) { showMessage("Your phone does not support Bluetooth"); } else { showMessage("Your phone supports Bluetooth "); } }
3. To Turn On the Bluetooth.
private void turnOn() { if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } }
4. List the Paired Bluetooth Devices.
private void getPairedDevices() { if (devices == null) devices = new ArrayList<BluetoothDevice>(); else devices.clear(); Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); if (pairedDevices.size() > 0) { for (BluetoothDevice curDevice : pairedDevices) { devices.add(curDevice); } Log.i(TAG, "Paired Number of Devices : " + pairedDevices.size()); showPairedList(); } } public void showPairedList() { List<String> tempDevices = new ArrayList<String>(); for (BluetoothDevice b : devices) { String paired = "Paired"; if (b.getBondState() != 12) { paired = "Not Paired"; } tempDevices.add(b.getName() + " - [ " + paired + " ] "); } if (allDevices == null) allDevices = new ArrayList<String>(); else allDevices.clear(); allDevices.addAll(tempDevices); if (devicesListAdapter == null) { ListView devicesList = new ListView(this); devicesList.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); devicesListAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1, allDevices); devicesList.setAdapter(devicesListAdapter); //Create sequence of items AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); dialogBuilder.setTitle("Paired/Unpaired BT Devices"); dialogBuilder.setView(devicesList); //Create alert dialog object via builder final AlertDialog alertDialogObject = dialogBuilder.create(); devicesList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { deviceToConnect = devices.get(position); devicesListAdapter = null; alertDialogObject.dismiss(); Log.i(TAG, "Connecting to device :" + deviceToConnect.getName()); showMessage("Connecting to device " + deviceToConnect.getName()); //Now this is not the server... killServerThread(); //Connect to the other device which is a server... connectAsClient(); } }); //Show the dialog alertDialogObject.show(); alertDialogObject.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { devicesListAdapter = null; } }); } else { devicesListAdapter.notifyDataSetChanged(); } }
5. List Online Non-Paired Devices.
To find the devices that are online, but not paired with your device, we will add an intent filter and register a Broadcast receiver, the Receiver will be called when each device is found.
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(bReciever, filter);
The Receiver…
private final BroadcastReceiver bReciever = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice curDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); devices.add(curDevice); } Log.i(TAG, "All BT Devices : " + devices.size()); if (devices.size() > 0) { showPairedList(); } } };
showPairedList() method will show the list of paired devices and other online Bluetooth Devices.
6. Connecting to a Device as a Client
Bluetooth connections work like any other connection. There is a server and a client, which communicate via RFCOMM sockets. On Android, RFCOMM sockets are represented as a BluetoothSocket object.
Connecting as a client is simple. Your first obtain the RFCOMM socket from the desired BluetoothDevice by calling createRfcommSocketToServiceRecord(), passing in a UUID, a 128-bit value that you create. The UUID is similar to a port number.
Once the BluetoothSocket is created, call connect() on the BluetoothSocket.
This will initialize a connection with the BluetoothDevice through the RFCOMM socket. Once our device is connected, we can use the socket to exchange data with the connected device.
Below Class will create a Client thread
package com.coderzheaven.bluetoothdemo.threads; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.os.Handler; import android.util.Log; import com.coderzheaven.bluetoothdemo.constants.Constants; import java.io.IOException; import java.util.UUID; // Client which initiates a connection // public class ClientThread extends Thread { private BluetoothSocket bTSocket = null; public static final String TAG = "ClientThread"; public BluetoothSocket connect(BluetoothAdapter bTAdapter, BluetoothDevice bTDevice, UUID mUUID, Handler mHandler) { try { bTSocket = bTDevice.createRfcommSocketToServiceRecord(mUUID); } catch (IOException e) { Log.d(TAG, "Could not create RFCOMM socket:" + e.toString()); return bTSocket; } bTAdapter.cancelDiscovery(); try { bTSocket.connect(); } catch (IOException e) { Log.d(TAG, "Could not connect: " + e.toString()); try { bTSocket.close(); } catch (IOException close) { Log.d(TAG, "Could not close connection:" + e.toString()); return bTSocket; } return bTSocket; } byte[] bytes = bTDevice.getName().getBytes(); byte[] buffer = new byte[1024]; mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME, 0, -1, bytes) .sendToTarget(); return bTSocket; } public boolean cancel() { if (bTSocket != null) { try { bTSocket.close(); } catch (IOException e) { Log.d(TAG, "Could not close connection:" + e.toString()); return false; } } return true; } }
7. Connecting as a Server
First, from your BluetoothAdapter, you must get a BluetoothServerSocket, which will be used to listen for a connection.
This is only used to obtain the connection’s shared RFCOMM socket.
Once the connection is established, the server socket is no longer need and can be closed by calling close() on it.
We then call accept() on the newly obtained BluetoothServerSocket to wait for a connection.
When the accept() call returns something that isn’t null, we assign it to our BluetoothSocket, which we can then use to exchange data with the connected device.
package com.coderzheaven.bluetoothdemo.threads; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.os.Handler; import android.util.Log; import com.coderzheaven.bluetoothdemo.constants.Constants; import java.io.IOException; import java.util.UUID; public class ServerConnectThread extends Thread{ private BluetoothSocket bTSocket; Handler mHandler; public static final String TAG = "ServerConnectThread"; public BluetoothSocket acceptConnection(BluetoothAdapter bTAdapter, UUID mUUID, Handler mHandler) { BluetoothServerSocket temp = null; this.mHandler = mHandler; try { temp = bTAdapter.listenUsingRfcommWithServiceRecord("Service_Name", mUUID); } catch (IOException e) { Log.d(TAG, "Could not get a BluetoothServerSocket:" + e.toString()); } while (true) { try { bTSocket = temp.accept(); } catch (IOException e) { Log.d(TAG, "Could not accept an incoming connection."); break; } if (bTSocket != null) { try { temp.close(); byte[] bytes0 = "Connected".getBytes(); byte[] buffer0 = new byte[1024]; mHandler.obtainMessage(Constants.MESSAGE_SERVER_CONNECTED, 0, -1, bytes0) .sendToTarget(); } catch (IOException e) { Log.d(TAG, "Could not close ServerSocket:" + e.toString()); } break; } } return bTSocket; } public void closeConnection() { if (bTSocket != null) { try { bTSocket.close(); } catch (IOException e) { Log.d(TAG, "Could not close connection:" + e.toString()); } } } }
8. Communicate between Connected Bluetooth Devices.
Reading and writing to the connection is done using streams, InputStream and OutputStream.
To read from and write to these streams, we call read() and write() respectively.
package com.coderzheaven.bluetoothdemo.threads; import android.bluetooth.BluetoothSocket; import android.os.Handler; import android.util.Log; import com.coderzheaven.bluetoothdemo.constants.Constants; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class DeviceConnectThread extends Thread { private final BluetoothSocket mSocket; private final InputStream mInStream; private final OutputStream mOutStream; Handler mHandler; public static final String TAG = "DeviceConnectThread"; public DeviceConnectThread(BluetoothSocket socket, Handler mHandler) { this.mHandler = mHandler; mSocket = 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(); tmpOut = socket.getOutputStream(); } catch (IOException e) { } mInStream = tmpIn; mOutStream = tmpOut; } public void run() { byte[] buffer = new byte[1024]; // buffer store for the stream int bytes = 0; // bytes returned from read() // Keep listening to the InputStream until an exception occurs while (true) { try { // Read from the InputStream bytes = mInStream.read(buffer); // Send the obtained bytes to the UI activity mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer) .sendToTarget(); } catch (IOException e) { Log.i(TAG, e.toString()); break; } } } /* Call this from the main activity to send data to the remote device */ public void write(byte[] bytes) { try { mOutStream.write(bytes); mHandler.obtainMessage(Constants.MESSAGE_WRITE, 0, -1, bytes) .sendToTarget(); } catch (IOException e) { Log.i(TAG, "Write Error : " + e.toString()); } } /* Call this from the main activity to shutdown the connection */ public void cancel() { try { mSocket.close(); } catch (IOException e) { } } }
In this implementation we will send a Handler object to send messages back to the UI.
Here is the Complete Activity file.
package com.coderzheaven.bluetoothdemo; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.Snackbar; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import com.coderzheaven.bluetoothdemo.constants.Constants; import com.coderzheaven.bluetoothdemo.threads.ClientThread; import com.coderzheaven.bluetoothdemo.threads.DeviceConnectThread; import com.coderzheaven.bluetoothdemo.threads.ServerConnectThread; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.UUID; public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, View.OnClickListener { String[] values = new String[]{ "Check Bluetooth Compatibility", "Turn On Bluetooth", "Make Discoverable", "Show Paired And Online BT devices", "Cancel Discovery", "Disconnect", "Turn Off Bluetooth", }; BluetoothAdapter mBluetoothAdapter; private static final int REQUEST_ENABLE_BT = 0; private static final int REQUEST_DISCOVERABLE_BT = 0; private static final String TAG = "Bluetooth"; ListView listView; private CoordinatorLayout coordinatorLayout; ArrayList<BluetoothDevice> devices; ArrayList<String> allDevices; private BluetoothDevice deviceToConnect; private static final UUID MY_UUID_SECURE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); private BluetoothSocket curBTSocket = null; ClientThread connectThread; DeviceConnectThread deviceConnectThread; ServerConnectThread serverConnectThread; AlertDialog alertDialogObject; ArrayAdapter<String> devicesListAdapter; LinearLayout linSendMessage; Button btnSend; EditText edtMessage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); coordinatorLayout = (CoordinatorLayout) findViewById(R.id .coordinatorLayout); linSendMessage = (LinearLayout) findViewById(R.id.l1); listView = (ListView) findViewById(R.id.list); btnSend = (Button) findViewById(R.id.btnSend); edtMessage = (EditText) findViewById(R.id.edtMessage); btnSend.setOnClickListener(this); ArrayAdapter<String> adapter; adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1, values); listView.setAdapter(adapter); listView.setOnItemClickListener(this); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(bReciever, filter); } @Override public void onResume() { super.onResume(); if (mBluetoothAdapter.isEnabled()) { startAsServer(); } } private void turnOn() { if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } } private void makeDiscoverable() { if (!mBluetoothAdapter.isDiscovering()) { showMessage("Making Discoverable..."); Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); startActivityForResult(enableBtIntent, REQUEST_DISCOVERABLE_BT); } } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { switch (position) { case 0: checkCompatibility(); break; case 1: turnOn(); break; case 2: makeDiscoverable(); break; case 3: startDiscovery(); break; case 4: cancelDiscovery(); break; case 5: disconnect(); break; default: turnOff(); } } private void disconnect() { if (curBTSocket != null) { try { curBTSocket.close(); } catch (IOException e) { } } } private void startDiscovery() { showMessage("Starting Discovery..."); getPairedDevices(); mBluetoothAdapter.startDiscovery(); } private void cancelDiscovery() { showMessage("Cancelling Discovery..."); unregisterReceiver(bReciever); mBluetoothAdapter.cancelDiscovery(); } private void getPairedDevices() { if (devices == null) devices = new ArrayList<BluetoothDevice>(); else devices.clear(); Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); if (pairedDevices.size() > 0) { for (BluetoothDevice curDevice : pairedDevices) { devices.add(curDevice); } Log.i(TAG, "Paired Number of Devices : " + pairedDevices.size()); showPairedList(); } } private void turnOff() { mBluetoothAdapter.disable(); } private void checkCompatibility() { // Phone does not support Bluetooth so let the user know and exit. if (mBluetoothAdapter == null) { showMessage("Your phone does not support Bluetooth"); } else { showMessage("Your phone supports Bluetooth "); } } private final BroadcastReceiver bReciever = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice curDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); devices.add(curDevice); } Log.i(TAG, "All BT Devices : " + devices.size()); if (devices.size() > 0) { showPairedList(); } } }; public void connectAsClient() { showMessage("Connecting for online Bluetooth devices..."); new Thread(new Runnable() { @Override public void run() { if (deviceToConnect != null) { if (connectThread != null) { connectThread.cancel(); connectThread = null; linSendMessage.setVisibility(View.GONE); } connectThread = new ClientThread(); curBTSocket = connectThread.connect(mBluetoothAdapter, deviceToConnect, MY_UUID_SECURE, mHandler); connectThread.start(); } } }).start(); } public void killServerThread() { if (serverConnectThread != null) { serverConnectThread.closeConnection(); serverConnectThread = null; linSendMessage.setVisibility(View.GONE); } } private void startAsServer() { showMessage("Listening for online Bluetooth devices..."); new Thread(new Runnable() { @Override public void run() { serverConnectThread = new ServerConnectThread(); curBTSocket = serverConnectThread.acceptConnection(mBluetoothAdapter, MY_UUID_SECURE, mHandler); } }).start(); } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { byte[] buf = (byte[]) msg.obj; switch (msg.what) { case Constants.MESSAGE_WRITE: // construct a string from the buffer String writeMessage = new String(buf); Log.i(TAG, "Write Message : " + writeMessage); showMessage("Message Sent : " + writeMessage); break; case Constants.MESSAGE_READ: // construct a string from the valid bytes in the buffer String readMessage = new String(buf, 0, msg.arg1); Log.i(TAG, "readMessage : " + readMessage); showMessage("Message Received : " + readMessage); break; case Constants.MESSAGE_DEVICE_NAME: // save the connected device's name String mConnectedDeviceName = new String(buf); showMessage("Connected to " + mConnectedDeviceName); linSendMessage.setVisibility(View.VISIBLE); sendMessageToDevice(); break; case Constants.MESSAGE_SERVER_CONNECTED: showMessage("CONNECTED"); Log.i(TAG, "Connected..."); linSendMessage.setVisibility(View.VISIBLE); break; } } }; public void sendMessageToDevice() { deviceConnectThread = new DeviceConnectThread(curBTSocket, mHandler); deviceConnectThread.start(); String message = edtMessage.getText().toString().trim(); if (message.length() > 0) { byte[] send = message.getBytes(); deviceConnectThread.write(send); } } public void showMessage(String message) { Snackbar snackbar = Snackbar .make(coordinatorLayout, message, Snackbar.LENGTH_LONG); View view = snackbar.getView(); view.setBackgroundColor(Color.GREEN); TextView textView = (TextView) view.findViewById(android.support.design.R.id.snackbar_text); textView.setTextColor(Color.BLACK); CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) view.getLayoutParams(); params.gravity = Gravity.BOTTOM; view.setLayoutParams(params); snackbar.show(); } public void showPairedList() { List<String> tempDevices = new ArrayList<String>(); for (BluetoothDevice b : devices) { String paired = "Paired"; if (b.getBondState() != 12) { paired = "Not Paired"; } tempDevices.add(b.getName() + " - [ " + paired + " ] "); } if (allDevices == null) allDevices = new ArrayList<String>(); else allDevices.clear(); allDevices.addAll(tempDevices); if (devicesListAdapter == null) { ListView devicesList = new ListView(this); devicesList.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); devicesListAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1, allDevices); devicesList.setAdapter(devicesListAdapter); //Create sequence of items AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); dialogBuilder.setTitle("Paired/Unpaired BT Devices"); dialogBuilder.setView(devicesList); //Create alert dialog object via builder final AlertDialog alertDialogObject = dialogBuilder.create(); devicesList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { deviceToConnect = devices.get(position); devicesListAdapter = null; alertDialogObject.dismiss(); Log.i(TAG, "Connecting to device :" + deviceToConnect.getName()); showMessage("Connecting to device " + deviceToConnect.getName()); //Now this is not the server... killServerThread(); //Connect to the other device which is a server... connectAsClient(); } }); //Show the dialog alertDialogObject.show(); alertDialogObject.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { devicesListAdapter = null; } }); } else { devicesListAdapter.notifyDataSetChanged(); } } @Override public void onClick(View v) { sendMessageToDevice(); } }
Now the layout activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/coordinatorLayout" android:fitsSystemWindows="true" tools:context="com.coderzheaven.bluetoothdemo.MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main" /> </android.support.design.widget.CoordinatorLayout>
content_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.coderzheaven.bluetoothdemo.MainActivity" tools:showIn="@layout/activity_main"> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="@+id/l1" android:layout_alignParentTop="true" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"></ListView> <LinearLayout android:id="@+id/l1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginTop="10dp" android:background="@android:color/holo_blue_bright" android:orientation="horizontal" android:visibility="gone"> <EditText android:id="@+id/edtMessage" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:hint="Enter message..." /> <Button android:id="@+id/btnSend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send" /> </LinearLayout> </RelativeLayout>
You can download the complete source code from here.
Hi there, thanks for the tutorial! I think I am halfway there but there are some details that I don’t really understand/ find it here. I tried to download the code at the given link above but it leads me to an error webpage. Is there any other way I could have the complete code for this? Thanks!!
I have updated the link…
Or you can download it from here
https://drive.google.com/uc?id=0B5PzI5GeMH-AbDJwelBZUUl2NHc