2024年4月27日发(作者:尉迟晔)
上次成功实现了通过笔记本电脑蓝牙来控制智能小车机器人的运动,但是通过电脑控制毕竟
不方便,于是乎~本人打算将控制程序移植到手机上。
目前主流的手机操作系统有塞班、安卓(Android)、Windows Mobile,对比了一下,首先,
塞班是用C++写的,这么多门语言我唯独看到C++就头大···,放弃了···,Windows Moblie
其实和之前发的电脑端程序基本是一样的,也就没什么意思了,最后决定选择目前正火的
Android手机作为控制平台。
Android是个开源的应用,使用Java语言对其编程。于是这次的开发我选用Eclipse作为开
发工具,用Java语言开发手机端的控制程序,由于之前对Android的蓝牙通信这块涉及不
多,一开始感觉有点小茫然,而网上也少有这方面的例程,有少数人做出了类似的东西,但
是只传了个视频装X!雪特····
经过几天的研究,最终确定了手机蓝牙通信其实就是Socket编程,再经过一番编写和调试,
昨晚终于大功告成!
这是视频:
下面开始介绍Android手机端控制程序的编写:
首先打开Eclipse,当然之前的Java开发环境和安卓开发工具自己得先配置好,这里就不多
说了,网上教程一大摞。
然后新建一个Android项目,修改布局文件,代码如下:
android:id="@+id/widget0" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="/apk/res/android" >
这个布局文件的效果就是如视频中所示的手机操作界面。
然后是权限声明,这一步不能少,否则将无法使用安卓手机的蓝牙功能。
权限声明如下:
打开文件,修改代码如下:
package="" android:versionCode="1" android:versionName="1.0"> /> android:label="@string/app_name">
其中红色、加粗部分就是要添加的权限声明。
然后编写Activity中的执行代码,这些代码的作用就是发送指令,控制小车的运动。
代码如下:
package ;
import ty;
import ;
import ption;
import Stream;
import ;
import ty;
import othAdapter;
import othDevice;
import othSocket;
import Interface;
import kListener;
import ;
import ;
import ;
import Event;
import ;
import ;
import ;
public class ThinBTClient extends Activity {
private static final String TAG = "THINBTCLIENT";
private static final boolean D = true;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
Button mButtonF;
Button mButtonB;
Button mButtonL;
Button mButtonR;
Button mButtonS;
private static final UUID
ring("00001101-0000-1000-8000-00805F9B34FB");
MY_UUID =
private static String address = "00:11:03:21:00:43"; // <==要连接的蓝牙设备MAC
地址
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
te(savedInstanceState);
setContentView();
//前进
mButtonF=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = ion();
switch(action)
{
case _DOWN:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "1";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case _UP:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
message = "0";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//后退
mButtonB=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = ion();
switch(action)
{
case _DOWN:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "3";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case _UP:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
message = "0";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//左转
mButtonL=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = ion();
switch(action)
{
case _DOWN:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "2";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case _UP:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
message = "0";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//右转
mButtonR=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = ion();
switch(action)
{
case _DOWN:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "4";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case _UP:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
message = "0";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//停止
mButtonS=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(ion()==_DOWN)
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
String message = "0";
byte[] msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
return false;
}
});
if (D)
Log.e(TAG, "+++ ON CREATE +++");
mBluetoothAdapter = aultAdapter();
if (mBluetoothAdapter == null) {
xt(this, "Bluetooth
_LONG).show();
finish();
return;
}
is not available.",
if (!led()) {
xt(this, "Please enable your Bluetooth and re-run
this program.", _LONG).show();
finish();
return;
}
if (D)
Log.e(TAG, "+++ DONE IN ON CREATE, GOT LOCAL BT ADAPTER +++");
}
@Override
public void onStart() {
t();
if (D) Log.e(TAG, "++ ON START ++");
}
@Override
public void onResume() {
me();
if (D) {
Log.e(TAG, "+ ON RESUME +");
Log.e(TAG, "+ ABOUT TO ATTEMPT CLIENT CONNECT +");
}
BluetoothDevice device = oteDevice(address);
try {
btSocket = RfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Socket creation failed.", e);
}
Discovery();
try {
t();
Log.e(TAG, "ON RESUME: BT connection established, data transfer
link open.");
} catch (IOException e) {
try {
();
} catch (IOException e2) {
Log .e(TAG,"ON RESUME: Unable to close socket during
connection failure", e2);
}
}
// Create a data stream so we can talk to server.
if (D)
Log.e(TAG, "+ ABOUT TO SAY SOMETHING TO SERVER +");
/* try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
String message = "1";
byte[] msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
*/
}
@Override
public void onPause() {
e();
if (D)
Log.e(TAG, "- ON PAUSE -");
if (outStream != null) {
try {
();
} catch (IOException e) {
Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);
}
}
try {
();
} catch (IOException e2) {
Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);
}
}
@Override
public void onStop() {
();
if (D)Log.e(TAG, "-- ON STOP --");
}
@Override
public void onDestroy() {
roy();
if (D) Log.e(TAG, "--- ON DESTROY ---");
}
}
可以看到,在这个程序中我直接把小车蓝牙模块的MAC地址给写进去了,其实更合理一点
应该让程序运行后搜索周围蓝牙设备,然后选择需要连接的设备,获取它的MAC地址再连
接,但是我为了图省事,就直接把我的小车的蓝牙MAC给定死了(反正也没那么多小车让
我遥控~~~),这样一打开程序,手机将自动连接智能小车。
好了,手机端的开发到此介绍完毕~希望能为需要者提供一点帮助。
下一步是打算增加红外避障功能、超声波测距功能,机械手臂,如果有机会,以后再安装上
火控系统发射钻天猴~
最后在此感谢侯金龙童鞋提供了他心爱的Android手机~
,不过估计时间不太允许了······
2024年4月27日发(作者:尉迟晔)
上次成功实现了通过笔记本电脑蓝牙来控制智能小车机器人的运动,但是通过电脑控制毕竟
不方便,于是乎~本人打算将控制程序移植到手机上。
目前主流的手机操作系统有塞班、安卓(Android)、Windows Mobile,对比了一下,首先,
塞班是用C++写的,这么多门语言我唯独看到C++就头大···,放弃了···,Windows Moblie
其实和之前发的电脑端程序基本是一样的,也就没什么意思了,最后决定选择目前正火的
Android手机作为控制平台。
Android是个开源的应用,使用Java语言对其编程。于是这次的开发我选用Eclipse作为开
发工具,用Java语言开发手机端的控制程序,由于之前对Android的蓝牙通信这块涉及不
多,一开始感觉有点小茫然,而网上也少有这方面的例程,有少数人做出了类似的东西,但
是只传了个视频装X!雪特····
经过几天的研究,最终确定了手机蓝牙通信其实就是Socket编程,再经过一番编写和调试,
昨晚终于大功告成!
这是视频:
下面开始介绍Android手机端控制程序的编写:
首先打开Eclipse,当然之前的Java开发环境和安卓开发工具自己得先配置好,这里就不多
说了,网上教程一大摞。
然后新建一个Android项目,修改布局文件,代码如下:
android:id="@+id/widget0" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="/apk/res/android" >
这个布局文件的效果就是如视频中所示的手机操作界面。
然后是权限声明,这一步不能少,否则将无法使用安卓手机的蓝牙功能。
权限声明如下:
打开文件,修改代码如下:
package="" android:versionCode="1" android:versionName="1.0"> /> android:label="@string/app_name">
其中红色、加粗部分就是要添加的权限声明。
然后编写Activity中的执行代码,这些代码的作用就是发送指令,控制小车的运动。
代码如下:
package ;
import ty;
import ;
import ption;
import Stream;
import ;
import ty;
import othAdapter;
import othDevice;
import othSocket;
import Interface;
import kListener;
import ;
import ;
import ;
import Event;
import ;
import ;
import ;
public class ThinBTClient extends Activity {
private static final String TAG = "THINBTCLIENT";
private static final boolean D = true;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
Button mButtonF;
Button mButtonB;
Button mButtonL;
Button mButtonR;
Button mButtonS;
private static final UUID
ring("00001101-0000-1000-8000-00805F9B34FB");
MY_UUID =
private static String address = "00:11:03:21:00:43"; // <==要连接的蓝牙设备MAC
地址
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
te(savedInstanceState);
setContentView();
//前进
mButtonF=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = ion();
switch(action)
{
case _DOWN:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "1";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case _UP:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
message = "0";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//后退
mButtonB=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = ion();
switch(action)
{
case _DOWN:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "3";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case _UP:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
message = "0";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//左转
mButtonL=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = ion();
switch(action)
{
case _DOWN:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "2";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case _UP:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
message = "0";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//右转
mButtonR=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
String message;
byte[] msgBuffer;
int action = ion();
switch(action)
{
case _DOWN:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
message = "4";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
case _UP:
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
message = "0";
msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
break;
}
return false;
}
});
//停止
mButtonS=(Button)findViewById();
ouchListener(new hListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(ion()==_DOWN)
try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.",
e);
}
String message = "0";
byte[] msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
return false;
}
});
if (D)
Log.e(TAG, "+++ ON CREATE +++");
mBluetoothAdapter = aultAdapter();
if (mBluetoothAdapter == null) {
xt(this, "Bluetooth
_LONG).show();
finish();
return;
}
is not available.",
if (!led()) {
xt(this, "Please enable your Bluetooth and re-run
this program.", _LONG).show();
finish();
return;
}
if (D)
Log.e(TAG, "+++ DONE IN ON CREATE, GOT LOCAL BT ADAPTER +++");
}
@Override
public void onStart() {
t();
if (D) Log.e(TAG, "++ ON START ++");
}
@Override
public void onResume() {
me();
if (D) {
Log.e(TAG, "+ ON RESUME +");
Log.e(TAG, "+ ABOUT TO ATTEMPT CLIENT CONNECT +");
}
BluetoothDevice device = oteDevice(address);
try {
btSocket = RfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Socket creation failed.", e);
}
Discovery();
try {
t();
Log.e(TAG, "ON RESUME: BT connection established, data transfer
link open.");
} catch (IOException e) {
try {
();
} catch (IOException e2) {
Log .e(TAG,"ON RESUME: Unable to close socket during
connection failure", e2);
}
}
// Create a data stream so we can talk to server.
if (D)
Log.e(TAG, "+ ABOUT TO SAY SOMETHING TO SERVER +");
/* try {
outStream = putStream();
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Output stream creation failed.", e);
}
String message = "1";
byte[] msgBuffer = es();
try {
(msgBuffer);
} catch (IOException e) {
Log.e(TAG, "ON RESUME: Exception during write.", e);
}
*/
}
@Override
public void onPause() {
e();
if (D)
Log.e(TAG, "- ON PAUSE -");
if (outStream != null) {
try {
();
} catch (IOException e) {
Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e);
}
}
try {
();
} catch (IOException e2) {
Log.e(TAG, "ON PAUSE: Unable to close socket.", e2);
}
}
@Override
public void onStop() {
();
if (D)Log.e(TAG, "-- ON STOP --");
}
@Override
public void onDestroy() {
roy();
if (D) Log.e(TAG, "--- ON DESTROY ---");
}
}
可以看到,在这个程序中我直接把小车蓝牙模块的MAC地址给写进去了,其实更合理一点
应该让程序运行后搜索周围蓝牙设备,然后选择需要连接的设备,获取它的MAC地址再连
接,但是我为了图省事,就直接把我的小车的蓝牙MAC给定死了(反正也没那么多小车让
我遥控~~~),这样一打开程序,手机将自动连接智能小车。
好了,手机端的开发到此介绍完毕~希望能为需要者提供一点帮助。
下一步是打算增加红外避障功能、超声波测距功能,机械手臂,如果有机会,以后再安装上
火控系统发射钻天猴~
最后在此感谢侯金龙童鞋提供了他心爱的Android手机~
,不过估计时间不太允许了······