android實現(xiàn)手機與單片機藍牙模塊通信
本文實例為大家分享了android實現(xiàn)手機與單片機藍牙模塊通信的具體代碼,供大家參考,具體內(nèi)容如下
我是參考原博客的內(nèi)容去寫的,由于原博客寫的不全,少了關(guān)鍵的幾個類,然后我就憑借自己扎實的功底補出來了,現(xiàn)在藍牙工作正常,能發(fā)能收!在看這邊文章之前你要先了解一下藍牙的工作狀態(tài),我的代碼里面可能解釋的不是很詳細,但是我自己是能看懂的!
package com.example.fsl.bluetooth;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TextView status;
private StringBuilder mstringbuilder;
private static final UUID MY_UUID=UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//沒有用到
BluetoothReceiver receiver;
BluetoothAdapter mBtAdapter;
BluetoothSocket mBtSocket;
private BlueToothTool client;
private ListView mListView;
private List<String> ListDevice;
private ArrayAdapter<String> mAdapter;
private Button mbutton;
private EditText editText;
private ProgressBar progressBar;
private LoopProgressBar loopProgressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=(Toolbar)findViewById(R.id.toolbar);
status=(TextView)findViewById(R.id.textView2);
mListView=(ListView)findViewById(R.id.listView);
mbutton=(Button)findViewById(R.id.button);
editText=(EditText)findViewById(R.id.editText);
progressBar=(ProgressBar)findViewById(R.id.progressBar);
progressBar.setVisibility(View.INVISIBLE);
loopProgressBar=(LoopProgressBar)findViewById(R.id.loop);
ListDevice=new ArrayList<String>();
mstringbuilder=new StringBuilder();
setSupportActionBar(toolbar);
enablebluetooth();
mbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BlueToothTool.WriteTask W=client.new WriteTask(editText.getText().toString());
W.start();
}
});
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mBtAdapter.cancelDiscovery();//停止搜索
progressBar.setVisibility(View.INVISIBLE);
String str = ListDevice.get(position);
String macAdress = str.split("\\|")[1];
BluetoothDevice device = mBtAdapter.getRemoteDevice(macAdress);
client=new BlueToothTool(device,handler);
try{
client.connect();
}catch (Exception e){
e.printStackTrace();
}
}
});
}
/**
*開啟藍牙且被發(fā)現(xiàn)
*/
private void enablebluetooth(){
mBtAdapter=BluetoothAdapter.getDefaultAdapter();
/**
*if(!mBtAdapter.isEnabled()){這里可以先使能,可以在REQUEST_DISCOVERABLE處使能,這樣的話可以連使能和請求被發(fā)現(xiàn)一塊完成
// mBtAdapter.enable();
Intent enableIntent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent,REQUEST_ENABLE);
}
else {
show("藍牙已開啟");
}*/
Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivityForResult(enable, REQUEST_DISCOVERABLE);
}
/**
* 銷毀事件,注銷廣播
*/
@Override
protected void onDestroy() {
unregisterReceiver(receiver);
super.onDestroy();
}
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BlueToothTool.CONNECT_FAILED:
show("連接失敗");
try {
client.connect();
} catch (Exception e) {
Log.e("TAG", e.toString());
}
break;
case BlueToothTool.CONNECT_SUCCESS:
show("連接成功");
mListView.setVisibility(View.INVISIBLE);
break;
case BlueToothTool.READ_FAILED:
show("讀取失敗");
break;
case BlueToothTool.WRITE_FAILED:
show("寫入失敗");
break;
case BlueToothTool.DATA:
mstringbuilder.append(msg.obj.toString());
show(mstringbuilder.toString());
break;
}
}
};
/**
* 請求響應結(jié)果
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
/**
*case REQUEST_ENABLE:
if(requestCode!= Activity.RESULT_OK){
show("藍牙未開啟");
}
else
show("藍牙已開啟");
break;*/
case REQUEST_DISCOVERABLE:
if(resultCode==Activity.RESULT_CANCELED){
show("藍牙未開啟");
}
else
show("藍牙已開啟");
break;
default:
break;
}
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.menu,menu);
return true;
}
private static final int REQUEST_ENABLE=1;
private static final int REQUEST_DISCOVERABLE=2;
/**
* 注冊廣播事件
*/
@Override
public void onResume(){
super.onResume();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
receiver = new BluetoothReceiver();
registerReceiver(receiver, filter);
filter=new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver,filter);
}
/**
* 廣播
*/
private class BluetoothReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String str = device.getName() + "|" + device.getAddress();
if (ListDevice.indexOf(str) == -1)// 防止重復添加
ListDevice.add(str); // 獲取設備名稱和mac地址
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
showDevices();
}
else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
progressBar.setVisibility(View.INVISIBLE);
show("已停止尋找");
}
}
};
/**
* 菜單欄點擊事件
* @param item
* @return
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.search:
if(!mBtAdapter.isEnabled()){
show("藍牙未開啟");
}
else {
mBtAdapter.startDiscovery();
show("正在尋找設備");
progressBar.setVisibility(View.VISIBLE);
}
break;
case R.id.about:
Toast.makeText(MainActivity.this,"關(guān)于我們",Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
private void showDevices() {
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
ListDevice);
mListView.setAdapter(mAdapter);
}
/**
* 更新UI方法
* @param string
*/
private void show(final String string){
runOnUiThread(new Runnable() {
@Override
public void run() {
status.setText(string);
}
});
}
}
然后我的讀任務和寫任務以及連接任務是在另一個類里面實現(xiàn)的,也就是BlueToothTool類,這個類一個原博客是沒有寫的,只是MainActivity中用到了這個類的一些方法,但是沒有給出,所以就讓一些同學很蛋疼。我看完之后是自己補全的這個類!
package com.example.fsl.bluetooth;
import android.app.Notification;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.logging.LogRecord;
/**
* Created by Fsl on 2017/12/22.
*/
public class BlueToothTool {
private BluetoothDevice device;
private Handler mhandler;
BluetoothSocket socket;
static final int CONNECT_FAILED=1;
static final int CONNECT_SUCCESS=5;
static final int READ_FAILED=2;
static final int WRITE_FAILED=3;
static final int DATA=4;
private boolean isConnect=false;
public BlueToothTool(BluetoothDevice device,Handler handler){
this.device=device;
this.mhandler=handler;
}
/**
*開辟連接線程任務
*/
public void connect(){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
BluetoothSocket tmp = null;
Method method;
try {
method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
tmp = (BluetoothSocket) method.invoke(device, 1);
} catch (Exception e) {
setState(CONNECT_FAILED);
Log.e("TAG", e.toString());
}
socket = tmp;
try {
socket.connect();
isConnect = true;
setState(CONNECT_SUCCESS);
Readtask readtask = new Readtask(); //連接成功后開啟讀取數(shù)據(jù)的線程
readtask.start();
} catch (Exception e) {
setState(CONNECT_FAILED);
Log.e("TAG", e.toString());
}
}
});
new Thread(thread).start();
}
/**
*開辟線程讀任務
*/
public class Readtask extends Thread{
@Override
public void run(){
byte[] buffer = new byte[1024];
int bytes;
InputStream inputStream ; //建立輸入流讀取數(shù)據(jù)
while (true) {
try {
inputStream = socket.getInputStream();
if ((bytes = inputStream.read(buffer)) > 0) {
byte[] buf_data= new byte[bytes];
for (int i = 0; i < bytes; i++) {
buf_data[i] = buffer[i];
}
String s = new String(buf_data);
Message msg = mhandler.obtainMessage();
msg.what = DATA;
msg.obj = s;
mhandler.sendMessage(msg);
}
} catch (IOException e) {
setState(READ_FAILED);
Log.e("TAG", e.toString());
break;
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
Log.e("TAG", e.toString());
}
}
}
}
/**
*開辟線程寫任務
*/
public class WriteTask extends Thread{
private String srt;
public WriteTask(String str){
this.srt=str;
}
@Override
public void run(){
OutputStream outputStream=null;
byte[] st=srt.getBytes();
try{
outputStream=socket.getOutputStream();
outputStream.write(st);
}catch (Exception e){
setState(WRITE_FAILED);
e.printStackTrace();
}
}
}
private void setState(int mes){
Message message=new Message();
message.what=mes;
mhandler.sendMessage(message);
}
/**
*下面這個方法目前還沒有用到
*/
private byte[] getHexBytes(String message) {
int len = message.length() / 2;
char[] chars = message.toCharArray();
String[] hexStr = new String[len];
byte[] bytes = new byte[len];
for (int i = 0, j = 0; j < len; i += 2, j++) {
hexStr[j] = "" + chars[i] + chars[i + 1];
bytes[j] = (byte) Integer.parseInt(hexStr[j], 16);
}
return bytes;
}
}
以上就是我的藍牙與單片機連接通信的全過程,順便說一下,這個連接是自動連接的,不需要什么秘鑰什么的,直接搜索到HC-05藍牙直接就可以確定連接,親測有效。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Kotlin之在Gradle中無參(no-arg)編譯器插件的使用詳解
這篇文章主要介紹了Kotlin之在Gradle中無參(no-arg)編譯器插件的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11
Android開發(fā)必知 九種對話框的實現(xiàn)方法
App中少不了與用戶交互的各種dialog,以此達到很好的用戶體驗,下面給大家介紹Android開發(fā)必知 九種對話框的實現(xiàn)方法,有需要的朋友可以參考下2015-08-08
Android基礎之使用Fragment適應不同屏幕和分辨率(分享)
以下是對Fragment的使用進行了詳細的分析介紹,需要的朋友可以過來參考下2013-07-07
react native android6+拍照閃退或重啟的解決方案
android 6+權(quán)限使用的時候需要動態(tài)申請,那么在使用rn的時候要怎么處理拍照權(quán)限問題呢?本文提供的是一攬子rn操作相冊、拍照的解決方案,需要的朋友可以參考下2017-11-11
Android采取BroadcastReceiver方式自動獲取驗證碼
這篇文章主要介紹了Android采取BroadcastReceiver方式自動獲取驗證碼,感興趣的小伙伴們可以參考一下2016-08-08
Android應用的Material設計的布局兼容性的一些要點總結(jié)
這篇文章主要介紹了Android應用的Material設計的布局兼容性的一些要點總結(jié),文中還給了一個RecyclerView布局管理的例子,需要的朋友可以參考下2016-04-04
淺析Android Studio 3.0 升級各種坑(推薦)
本文是小編給大家收藏整理的關(guān)于Android Studio 3.0 升級后遇到的一些坑,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2017-11-11
Android實現(xiàn)點擊切換視圖并跳轉(zhuǎn)傳值
這篇文章主要為大家詳細介紹了Android實現(xiàn)點擊切換視圖并跳轉(zhuǎn)傳值,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-01-01

