android藍芽聊天開發(5)簡單藍芽聊天
阿新 • • 發佈:2019-01-09
執行截圖:我的裝置設定的使用者名稱是:是。可以改的
mainActivity:
package com.lmj.bluetoothchat; import java.util.ArrayList; import android.app.AlertDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private static final int REQUES_SELECT_BT_CODE = 0x1001; // 使能請求碼 private static final int REQUES_BT_ENABLE_CODE = 0x1002; private static final String TAG = MainActivity.class.getName(); private ListView mListView; private EditText mET; private BluetoothAdapter mBluetoothAdapter; private BluetoothDevice mRemoteDevice; private ArrayAdapter<String> mAdapter; // 聊天內容儲存物件 private ArrayList<String> mChatContent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //使用主介面 佈局 setContentView(R.layout.activity_main); // UI初始化 mListView = (ListView) findViewById(R.id.listView1); mET = (EditText) findViewById(R.id.editText1); mChatContent = new ArrayList<String>(); // ListView的Adapter mAdapter = new ArrayAdapter<String>(this, // 項顯示佈局 android.R.layout.simple_list_item_1, // 顯示的資料來源 mChatContent); mListView.setAdapter(mAdapter); // 開啟藍芽裝置 openBtDevice(); } /** * 使用者點擊發送按鈕 * @param v */ public void onSendClick(View v){ String msg = mET.getText().toString().trim(); if(msg.length() <= 0){ Toast.makeText(this, "訊息不能為空", Toast.LENGTH_SHORT).show(); return; } // 將使用者輸入的訊息新增到ListView中去顯示 mChatContent.add(mBluetoothAdapter.getName() + ":" + msg); // 更新ListView顯示 mAdapter.notifyDataSetChanged(); // 將傳送訊息任務提交給後臺服務 TaskService.newTask(new Task(mHandler, Task.TASK_SEND_MSG, new Object[]{msg})); // 清空輸入框 mET.setText(""); } private boolean openBtDevice(){ // 獲得藍芽匹配器 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 藍芽裝置不被支援 if (mBluetoothAdapter == null) { Log.e(TAG, "Your device is not support Bluetooth!"); Toast.makeText(this, "該裝置沒有藍芽裝置", Toast.LENGTH_LONG).show(); return false; } // 使能藍芽裝置 if (!mBluetoothAdapter.isEnabled()) { // 隱式Intent Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUES_BT_ENABLE_CODE); }else{ // 如果藍芽裝置已經使能,直接啟動後臺服務 startServiceAsServer(); } return true; } private void startServiceAsServer() { // Android非同步通訊機制Handler,UI執行緒不能執行耗時操作,應該交給子執行緒去做, // 子執行緒不允許去更新UI控制元件,必須要用到Handler機制(AsyncTask) TaskService.start(this, mHandler); // 向後臺服務提交一個任務,作為伺服器端監聽遠端 裝置連線 TaskService.newTask(new Task(mHandler, Task.TASK_START_ACCEPT, null)); } private Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case Task.TASK_SEND_MSG: Toast.makeText(MainActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show(); break; case Task.TASK_RECV_MSG: // 獲得遠端裝置傳送的訊息 mChatContent.add(msg.obj.toString()); mAdapter.notifyDataSetChanged(); break; case Task.TASK_GET_REMOTE_STATE: setTitle(msg.obj.toString()); break; default: break; } } }; // 當startActivityForResult啟動的 畫面結束的時候,該方法被回撥 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // if(requestCode == REQUES_BT_ENABLE_CODE && resultCode == RESULT_OK){ // 作為藍芽服務端啟動後臺服務 startServiceAsServer(); }else if(requestCode == REQUES_SELECT_BT_CODE && resultCode == RESULT_OK){ mRemoteDevice = data.getParcelableExtra("DEVICE"); if(mRemoteDevice == null) return; // 提交連線使用者選擇的裝置物件,自己作為客戶端 TaskService.newTask(new Task(mHandler,Task.TASK_START_CONN_THREAD, new Object[]{mRemoteDevice})); } } //重寫onCreateOptionsMenu,併為每個item新增一個監聽 //參考文章https://www.cnblogs.com/linfenghp/p/5464016.html @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()){ case R.id.change_name: AlertDialog.Builder dlg = new AlertDialog.Builder(this); final EditText devNameEdit = new EditText(this); dlg.setView(devNameEdit); dlg.setTitle("請輸入使用者名稱"); dlg.setPositiveButton("設定", new OnClickListener() { public void onClick(DialogInterface dialog, int which) { if(devNameEdit.getText().toString().length() != 0) // 設定藍芽裝置名 mBluetoothAdapter.setName(devNameEdit.getText().toString()); } }); dlg.create(); dlg.show(); break; case R.id.scann_device: // 掃描周圍藍芽裝置 startActivityForResult(new Intent(this, SelectDeviceActivity.class), REQUES_SELECT_BT_CODE); break; } return true; } @Override protected void onDestroy() { // 停止服務 TaskService.stop(this); super.onDestroy(); } }
SelectDeviceActivity:
package com.lmj.bluetoothchat; import java.util.ArrayList; import java.util.Set; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; public class SelectDeviceActivity extends Activity implements OnClickListener, OnItemClickListener { private final String TAG = "MainActivity"; private static final int REQUEST_ENABLE_CODE = 0x1003; private BluetoothAdapter mBluetoothAdapter; private Button mScanBtn; private ListView mDevList; private ArrayAdapter<String> adapter; private ArrayList<String> mArrayAdapter = new ArrayList<String>(); private ArrayList<BluetoothDevice> mDeviceList = new ArrayList<BluetoothDevice>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 請求顯示進度條 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.bt_list); initView(); // 開啟並查詢藍芽裝置 openAndFindBTDevice(); // 用來接收到裝置查詢到的廣播和掃描完成的廣播 IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); // 動態註冊廣播接收器 // 用來接收掃描到的裝置資訊 registerReceiver(mReceiver, filter); } private void openAndFindBTDevice(){ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { Log.e(TAG, "Your device is not support Bluetooth!"); return; } if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_CODE); }else{ findBTDevice(); } } private void initView(){ mDevList = (ListView) findViewById(R.id.scanDevList); mDevList.setOnItemClickListener(this); mScanBtn = (Button) findViewById(R.id.scanDevBtn); mScanBtn.setOnClickListener(this); adapter = new ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, mArrayAdapter); mDevList.setAdapter(adapter); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // 掃描到新的藍芽裝置 if (BluetoothDevice.ACTION_FOUND.equals(action)) { // 獲得藍芽裝置物件 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //防止裝置物件新增重複 if(mDeviceList.contains(device)){ return; } mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); System.out.println(device.getName() + "\n" + device.getAddress()); mDeviceList.add(device); adapter.notifyDataSetChanged(); }else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){ // 掃描完成,關閉顯示進度條 setProgressBarIndeterminateVisibility(false); } } }; @Override public void onClick(View v) { if(!mBluetoothAdapter.isDiscovering()){ mBluetoothAdapter.startDiscovery(); setProgressBarIndeterminateVisibility(true); } } private void findBTDevice(){ // 用來儲存已經配對的藍芽裝置物件 Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { // 將已經配對裝置資訊新增到ListView中 mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); mDeviceList.add(device); } } adapter.notifyDataSetChanged(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == REQUEST_ENABLE_CODE){ if(resultCode == RESULT_OK){ System.out.println("裝置開啟成功"); findBTDevice(); }else{ System.out.println("裝置開啟失敗"); } } } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(mReceiver); } @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { String targetDev = mArrayAdapter.get(arg2); System.out.println(targetDev); Intent data = new Intent(); data.putExtra("DEVICE", mDeviceList.get(arg2)); // 當用於點選某項裝置時,將該裝置物件返回給呼叫者(MainActivity) setResult(RESULT_OK, data); this.finish(); } }
Task‘:
package com.lmj.bluetoothchat; import android.os.Handler; public class Task { /** * 請求等待藍芽連線(作為伺服器) */ public static final int TASK_START_ACCEPT = 1; /** * 請求連線遠端藍芽裝置(作為客戶端) */ public static final int TASK_START_CONN_THREAD = 2; /** * 傳送訊息任務 */ public static final int TASK_SEND_MSG = 3; /** * 獲得藍芽執行狀態 */ public static final int TASK_GET_REMOTE_STATE = 4; /** * 接收到聊天訊息 */ public static final int TASK_RECV_MSG = 5; // 任務ID private int mTaskID; // 任務引數列表 public Object[] mParams; private Handler mH; public Task(Handler handler, int taskID, Object[] params){ this.mH = handler; this.mTaskID = taskID; this.mParams = params; } public Handler getHandler(){ return this.mH; } public int getTaskID(){ return mTaskID; } }
TaskService:
package com.lmj.bluetoothchat;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.UUID;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
public class TaskService extends Service {
private final String TAG = "TaskService";
private TaskThread mThread;
private BluetoothAdapter mBluetoothAdapter;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private boolean isServerMode = true;
private static Handler mActivityHandler;
// 任務佇列
private static ArrayList<Task> mTaskList = new ArrayList<Task>();
/**
* 用於被外部元件啟動服務
*
* @param c
* ,上下文物件
* @param handler
* ,Activity上的Handler物件,用於更新UI
*/
public static void start(Context c, Handler handler) {
mActivityHandler = handler;
// 顯式啟動服務
Intent intent = new Intent(c, TaskService.class);
c.startService(intent);
}
/**
* 關閉服務
*
* @param c
*/
public static void stop(Context c) {
Intent intent = new Intent(c, TaskService.class);
c.stopService(intent);
}
/**
* 提交任務
*
* @param target
* 目標任務
*/
public static void newTask(Task target) {
synchronized (mTaskList) {
// 將任務新增到任務佇列中
mTaskList.add(target);
}
}
@Override
public void onCreate() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "Your device is not support Bluetooth!");
return;
}
// 啟動服務執行緒
mThread = new TaskThread();
mThread.start();
super.onCreate();
}
private Handler mServiceHandler = new Handler() {
@Override
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case Task.TASK_GET_REMOTE_STATE:
android.os.Message activityMsg = mActivityHandler
.obtainMessage();
activityMsg.what = msg.what;
if (mAcceptThread != null && mAcceptThread.isAlive()) {
activityMsg.obj = "等待連線...";
} else if (mCommThread != null && mCommThread.isAlive()) {
activityMsg.obj = mCommThread.getRemoteName() + "[線上]";
} else if (mConnectThread != null && mConnectThread.isAlive()) {
activityMsg.obj = "正在連線:"
+ mConnectThread.getDevice().getName();
} else {
activityMsg.obj = "未知狀態";
// 重新等待連線
mAcceptThread = new AcceptThread();
mAcceptThread.start();
isServerMode = true;
}
mActivityHandler.sendMessage(activityMsg);
break;
default:
break;
}
super.handleMessage(msg);
}
};
/**
* 任務處理執行緒
* @author Micheal
*
*/
private class TaskThread extends Thread {
private boolean isRun = true;
private int mCount = 0;
/**
* 停止 執行緒
*/
public void cancel() {
isRun = false;
}
@Override
public void run() {
Task task;
while (isRun) {
// 獲得第一個任務開始執行
if (mTaskList.size() > 0) {
synchronized (mTaskList) {
task = mTaskList.get(0);
doTask(task);
}
} else {
try {
Thread.sleep(200);
mCount++;
} catch (InterruptedException e) {
}
if (mCount >= 50) {
mCount = 0;
android.os.Message handlerMsg = mServiceHandler
.obtainMessage();
handlerMsg.what = Task.TASK_GET_REMOTE_STATE;
mServiceHandler.sendMessage(handlerMsg);
}
}
}
}
}
/**
* 任務處理
* @param task
*/
private void doTask(Task task) {
switch (task.getTaskID()) {
case Task.TASK_START_ACCEPT:
// 作為伺服器接收等待客戶端執行緒
mAcceptThread = new AcceptThread();
mAcceptThread.start();
isServerMode = true;
break;
case Task.TASK_START_CONN_THREAD:
if (task.mParams == null || task.mParams.length == 0) {
break;
}
BluetoothDevice remote = (BluetoothDevice) task.mParams[0];
// 作為客戶端去連線遠端伺服器
mConnectThread = new ConnectThread(remote);
mConnectThread.start();
isServerMode = false;
break;
case Task.TASK_SEND_MSG:
boolean sucess = false;
if (mCommThread == null || !mCommThread.isAlive()
|| task.mParams == null || task.mParams.length == 0) {
Log.e(TAG, "mCommThread or task.mParams null");
} else {
sucess = mCommThread.write((String) task.mParams[0]);
}
if (!sucess) {
android.os.Message returnMsg = mActivityHandler.obtainMessage();
returnMsg.what = Task.TASK_SEND_MSG;
returnMsg.obj = "訊息傳送失敗";
mActivityHandler.sendMessage(returnMsg);
}
break;
}
synchronized (mTaskList) {
mTaskList.remove(task);
}
}
@Override
public void onDestroy() {
super.onDestroy();
mThread.cancel();
}
// UUID號,表示不同的資料協議
private final String UUID_STR = "00001101-0000-1000-8000-00805F9B34FB";
/**
* 等待客戶端連線執行緒
* @author [email protected]
*/
private class AcceptThread extends Thread {
private final BluetoothServerSocket mServerSocket;
private boolean isCancel = false;
public AcceptThread() {
Log.d(TAG, "AcceptThread");
BluetoothServerSocket tmp = null;
try {
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
"Bluetooth_Chat_Room", UUID.fromString(UUID_STR));
} catch (IOException e) {
}
mServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
while (true) {
try {
// 阻塞等待
socket = mServerSocket.accept();
} catch (IOException e) {
if (!isCancel) {
try {
mServerSocket.close();
} catch (IOException e1) {
}
// 異常結束時,再次監聽
mAcceptThread = new AcceptThread();
mAcceptThread.start();
isServerMode = true;
}
break;
}
if (socket != null) {
// 管理已經連線的客戶端
manageConnectedSocket(socket);
try {
mServerSocket.close();
} catch (IOException e) {
}
mAcceptThread = null;
break;
}
}
}
public void cancel() {
try {
Log.d(TAG, "AcceptThread canceled");
isCancel = true;
isServerMode = false;
mServerSocket.close();
mAcceptThread = null;
if (mCommThread != null && mCommThread.isAlive()) {
mCommThread.cancel();
}
} catch (IOException e) {
}
}
}
/**
* 作為客戶端連線指定的藍芽裝置執行緒
*
* @author [email protected]
*/
private class ConnectThread extends Thread {
private final BluetoothSocket mSocket;
private final BluetoothDevice mDevice;
public ConnectThread(BluetoothDevice device) {
Log.d(TAG, "ConnectThread");
// 伺服器監聽執行緒不為空,將其結束掉開始作為客戶端
if (mAcceptThread != null && mAcceptThread.isAlive()) {
mAcceptThread.cancel();
}
// 如果裝置已經連線執行緒存在,則結束它
if (mCommThread != null && mCommThread.isAlive()) {
mCommThread.cancel();
}
BluetoothSocket tmp = null;
mDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(UUID
.fromString(UUID_STR));
} catch (IOException e) {
Log.d(TAG, "createRfcommSocketToServiceRecord error!");
}
mSocket = tmp;
}
public BluetoothDevice getDevice() {
return mDevice;
}
public void run() {
// 取消裝置掃描
mBluetoothAdapter.cancelDiscovery();
try {
// 連線遠端伺服器裝置
mSocket.connect();
} catch (IOException connectException) {
Log.e(TAG, "Connect server failed");
try {
mSocket.close();
} catch (IOException closeException) {
}
// 連線伺服器失敗,則自己作為伺服器監聽
mAcceptThread = new AcceptThread();
mAcceptThread.start();
isServerMode = true;
return;
} // Do work to manage the connection (in a separate thread)
manageConnectedSocket(mSocket);
}
public void cancel() {
try {
mSocket.close();
} catch (IOException e) {
}
mConnectThread = null;
}
}
private ConnectedThread mCommThread;
private void manageConnectedSocket(BluetoothSocket socket) {
// 啟動子執行緒來維持連線
mCommThread = new ConnectedThread(socket);
mCommThread.start();
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mSocket;
private final InputStream mInStream;
private final OutputStream mOutStream;
private BufferedWriter mBw;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "ConnectedThread");
mSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mInStream = tmpIn;
mOutStream = tmpOut;
// 獲得遠端裝置的輸出快取字元流
mBw = new BufferedWriter(new PrintWriter(mOutStream));
}
public OutputStream getOutputStream() {
return mOutStream;
}
public boolean write(String msg) {
if (msg == null)
return false;
try {
mBw.write(msg + "\n");
mBw.flush();
System.out.println("Write:" + msg);
} catch (IOException e) {
return false;
}
return true;
}
public String getRemoteName() {
return mSocket.getRemoteDevice().getName();
}
public void cancel() {
try {
mSocket.close();
} catch (IOException e) {
}
mCommThread = null;
}
public void run() {
// 將上線提示資訊寫入到遠端裝置中
write(mBluetoothAdapter.getName() + "已經上線");
android.os.Message handlerMsg;
String buffer = null;
// 獲得遠端裝置的快取字元輸入流
BufferedReader br = new BufferedReader(new InputStreamReader(
mInStream));
while (true) {
try {
// 讀取遠端裝置的一行資料
buffer = br.readLine();
System.out.println("收到:" + buffer);
if (buffer == null)
continue;
if (mActivityHandler == null) {
return;
}
buffer = mSocket.getRemoteDevice().getName() + ":" + buffer;
// 通過Activity更新到UI上
handlerMsg = mActivityHandler.obtainMessage();
handlerMsg.what = Task.TASK_RECV_MSG;
handlerMsg.obj = buffer;
mActivityHandler.sendMessage(handlerMsg);
} catch (IOException e) {
try {
mSocket.close();
} catch (IOException e1) {
}
mCommThread = null;
if (isServerMode) {
// 檢查遠端裝置狀態
handlerMsg = mServiceHandler.obtainMessage();
handlerMsg.what = Task.TASK_GET_REMOTE_STATE;
mServiceHandler.sendMessage(handlerMsg);
// 重新啟動服務端連線執行緒
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
break;
}
}
}
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
介面佈局:
main—activity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
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
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/editText1"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
/>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:onClick="onSendClick"
android:text="Send" />
</RelativeLayout>
menu/main:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/scann_device"
android:orderInCategory="100"
android:title="掃描周圍裝置"/>
<item
android:id="@+id/change_name"
android:orderInCategory="100"
android:title="修改使用者名稱"/>
</menu>
bt——list
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/scanDevBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onScannClick"
android:text="Scann bt devices" />
<ListView
android:id="@+id/scanDevList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>