Android Service和Activity基于串口蓝牙模块的双向通信【第二篇】
2012-08-09 16:20
435 查看
一直以来都想利用手机来控制一些东西,比如电灯,电风扇等家电或者智能小车等.
驱动蓝牙模块可以在Activity中直接调用,也可以在多线程下直接使用,但这样会存在一个缺陷:当你按下手机的Home或者Back键的时候.程序退出了,下次你重新启动软件的时候又需要重新建立蓝牙的链接了.
为了克服以上问题,我把蓝牙模块的调用放到Service里面使用.首先对Service说明下:(来源于http://tianrui-wang-163-com.iteye.com/blog/983099)
Service介绍
Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。
由于没有可视化界面,Service都是从其它程序组件中启动、停止和控制,这些组件包括其它的Service、Activity和Broadcast Receiver。如果你的应用程序正常且不间断的运行,而不直接依赖于用户输入,Service是你最佳的选择。
Service生命周期
服务常用生命周期回调方法如下:
onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onDestroy()该方法在服务被终止时调用。
Service对象不能自己启动,需要通过某个Activity、Service或者其他Context对象来启动。启动的方法有两种,Context.startService和Context.bindService()。两种方式的生命周期是不同的,具体如下所示。
Context.startService方式的生命周期:
启动时,startService –> onCreate() –> onStart()
停止时,stopService –> onDestroy()
Context.bindService方式的生命周期:
绑定时,bindService -> onCreate() –> onBind()
解绑定时,unbindService –>onUnbind() –> onDestory()
Service实现
定义一个Service只需要如下两步:
第一步:继承Service类
public class SMSService extends Service { } 这里可以选择要实现的方法
第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:
<service android:name=".SMSService" ”></service>
好了,废话少说,下面从我的代码直接开始:
[java]
view plaincopyprint?
package com.lxx;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Service;
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.IBinder;
import android.util.Log;
public class MyService extends Service{
public boolean threadFlag = true;
MyThread myThread;
CommandReceiver cmdReceiver;//继承自BroadcastReceiver对象,用于得到Activity发送过来的命令
/**************service 命令*********/
static final int CMD_STOP_SERVICE = 0x01;
static final int CMD_SEND_DATA = 0x02;
static final int CMD_SYSTEM_EXIT =0x03;
static final int CMD_SHOW_TOAST =0x04;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private InputStream inStream = null;
public boolean bluetoothFlag = true;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static String address = "00:19:5D:EE:9B:8F"; // <==要连接的蓝牙设备MAC地址
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
//前台Activity调用startService时,该方法自动执行
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
cmdReceiver = new CommandReceiver();
IntentFilter filter = new IntentFilter();//创建IntentFilter对象
//注册一个广播,用于接收Activity传送过来的命令,控制Service的行为,如:发送数据,停止服务等
filter.addAction("android.intent.action.cmd");
//注册Broadcast Receiver
registerReceiver(cmdReceiver, filter);
doJob();//调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
this.unregisterReceiver(cmdReceiver);//取消注册的CommandReceiver
threadFlag = false;
boolean retry = true;
while(retry){
try{
myThread.join();
retry = false;
}catch(Exception e){
e.printStackTrace();
}
}
}
public class MyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
connectDevice();//连接蓝牙设备
while(threadFlag){
int value = readByte();
if(value != -1){
DisplayToast(value + "");
}
try{
Thread.sleep(50);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
public void doJob(){
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
DisplayToast("蓝牙设备不可用,请打开蓝牙!");
bluetoothFlag = false;
return;
}
if (!mBluetoothAdapter.isEnabled()) {
DisplayToast("请打开蓝牙并重新运行程序!");
bluetoothFlag = false;
stopService();
showToast("请打开蓝牙并重新运行程序!");
return;
}
showToast("搜索到蓝牙设备!");
threadFlag = true;
myThread = new MyThread();
myThread.start();
}
public void connectDevice(){
DisplayToast("正在尝试连接蓝牙设备,请稍后····");
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
DisplayToast("套接字创建失败!");
bluetoothFlag = false;
}
DisplayToast("成功连接蓝牙设备!");
mBluetoothAdapter.cancelDiscovery();
try {
btSocket.connect();
DisplayToast("连接成功建立,可以开始操控了!");
showToast("连接成功建立,可以开始操控了!");
bluetoothFlag = true;
} catch (IOException e) {
try {
btSocket.close();
bluetoothFlag = false;
} catch (IOException e2) {
DisplayToast("连接没有建立,无法关闭套接字!");
}
}
if(bluetoothFlag){
try {
inStream = btSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
} //绑定读接口
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
} //绑定写接口
}
}
public void sendCmd(byte cmd, int value)//串口发送数据
{
if(!bluetoothFlag){
return;
}
byte[] msgBuffer = new byte[5];
msgBuffer[0] = cmd;
msgBuffer[1] = (byte)(value >> 0 & 0xff);
msgBuffer[2] = (byte)(value >> 8 & 0xff);
msgBuffer[3] = (byte)(value >> 16 & 0xff);
msgBuffer[4] = (byte)(value >> 24 & 0xff);
try {
outStream.write(msgBuffer, 0, 5);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public int readByte(){//return -1 if no data
int ret = -1;
if(!bluetoothFlag){
return ret;
}
try {
ret = inStream.read();
} catch (IOException e) {
e.printStackTrace();
}
return ret;
}
public void stopService(){//停止服务
threadFlag = false;//停止线程
stopSelf();//停止服务
}
public void showToast(String str){//显示提示信息
Intent intent = new Intent();
intent.putExtra("cmd", CMD_SHOW_TOAST);
intent.putExtra("str", str);
intent.setAction("android.intent.action.lxx");
sendBroadcast(intent);
}
public void DisplayToast(String str)
{
Log.d("Season",str);
}
//接收Activity传送过来的命令
private class CommandReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.intent.action.cmd")){
int cmd = intent.getIntExtra("cmd", -1);//获取Extra信息
if(cmd == CMD_STOP_SERVICE){
stopService();
}
if(cmd == CMD_SEND_DATA)
{
byte command = intent.getByteExtra("command", (byte) 0);
int value = intent.getIntExtra("value", 0);
sendCmd(command,value);
}
}
}
}
}
以下主要对代码部分进行详细的说明:
1.为了方便Activity和Service简历起良好的通信关系,需要在各自发送的数据进行命令的解释,这些命令在两者之间是一致的,能够相互读懂对方发送过来的数据.
[java]
view plaincopyprint?
/**************service 命令*********/
static final int CMD_STOP_SERVICE = 0x01;//停止服务
static final int CMD_SEND_DATA = 0x02;//发送数据
static final int CMD_SYSTEM_EXIT =0x03;//退出程序
static final int CMD_SHOW_TOAST =0x04;//界面上显示toast
为了能够接收到数据,首先得把这个Receiver注册:
[java]
view plaincopyprint?
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("android.intent.action.lxx")){
Bundle bundle = intent.getExtras();
int cmd = bundle.getInt("cmd");
if(cmd == CMD_SHOW_TOAST){
String str = bundle.getString("str");
showToast(str);
}
else if(cmd == CMD_SYSTEM_EXIT){
System.exit(0);
}
}
}
}
3.Activity传送数据到Service:
Activity上有一个按钮,点击一下就可以发送数据到蓝牙串口模块,工作原理是这样的:界面上实现按钮的点击事件
[java]
view plaincopyprint?
public class SendButtonClickListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
byte command = 45;
int value = 0x12345;
sendCmd(command,value);
}
}
Service中
[java]
view plaincopyprint?
//前台Activity调用startService时,该方法自动执行
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
cmdReceiver = new CommandReceiver();
IntentFilter filter = new IntentFilter();//创建IntentFilter对象
//注册一个广播,用于接收Activity传送过来的命令,控制Service的行为,如:发送数据,停止服务等
filter.addAction("android.intent.action.cmd");
//注册Broadcast Receiver
registerReceiver(cmdReceiver, filter);
doJob();//调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
//前台Activity调用startService时,该方法自动执行
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
cmdReceiver = new CommandReceiver();
IntentFilter filter = new IntentFilter();//创建IntentFilter对象
//注册一个广播,用于接收Activity传送过来的命令,控制Service的行为,如:发送数据,停止服务等
filter.addAction("android.intent.action.cmd");
//注册Broadcast Receiver
registerReceiver(cmdReceiver, filter);
doJob();//调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
通过以上步骤就可以建立起蓝牙模块发送数据到Activity,Activity也可以发送数据到蓝牙模块了;
本例子的源码:
http://download.csdn.net/source/3557026
博文转自:http://blog.csdn.net/cen616899547/article/category/1133607
驱动蓝牙模块可以在Activity中直接调用,也可以在多线程下直接使用,但这样会存在一个缺陷:当你按下手机的Home或者Back键的时候.程序退出了,下次你重新启动软件的时候又需要重新建立蓝牙的链接了.
为了克服以上问题,我把蓝牙模块的调用放到Service里面使用.首先对Service说明下:(来源于http://tianrui-wang-163-com.iteye.com/blog/983099)
Service介绍
Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。
由于没有可视化界面,Service都是从其它程序组件中启动、停止和控制,这些组件包括其它的Service、Activity和Broadcast Receiver。如果你的应用程序正常且不间断的运行,而不直接依赖于用户输入,Service是你最佳的选择。
Service生命周期
服务常用生命周期回调方法如下:
onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onDestroy()该方法在服务被终止时调用。
Service对象不能自己启动,需要通过某个Activity、Service或者其他Context对象来启动。启动的方法有两种,Context.startService和Context.bindService()。两种方式的生命周期是不同的,具体如下所示。
Context.startService方式的生命周期:
启动时,startService –> onCreate() –> onStart()
停止时,stopService –> onDestroy()
Context.bindService方式的生命周期:
绑定时,bindService -> onCreate() –> onBind()
解绑定时,unbindService –>onUnbind() –> onDestory()
Service实现
定义一个Service只需要如下两步:
第一步:继承Service类
public class SMSService extends Service { } 这里可以选择要实现的方法
第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:
<service android:name=".SMSService" ”></service>
好了,废话少说,下面从我的代码直接开始:
[java]
view plaincopyprint?
package com.lxx;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.app.Service;
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.IBinder;
import android.util.Log;
public class MyService extends Service{
public boolean threadFlag = true;
MyThread myThread;
CommandReceiver cmdReceiver;//继承自BroadcastReceiver对象,用于得到Activity发送过来的命令
/**************service 命令*********/
static final int CMD_STOP_SERVICE = 0x01;
static final int CMD_SEND_DATA = 0x02;
static final int CMD_SYSTEM_EXIT =0x03;
static final int CMD_SHOW_TOAST =0x04;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private InputStream inStream = null;
public boolean bluetoothFlag = true;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static String address = "00:19:5D:EE:9B:8F"; // <==要连接的蓝牙设备MAC地址
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
//前台Activity调用startService时,该方法自动执行
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
cmdReceiver = new CommandReceiver();
IntentFilter filter = new IntentFilter();//创建IntentFilter对象
//注册一个广播,用于接收Activity传送过来的命令,控制Service的行为,如:发送数据,停止服务等
filter.addAction("android.intent.action.cmd");
//注册Broadcast Receiver
registerReceiver(cmdReceiver, filter);
doJob();//调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
this.unregisterReceiver(cmdReceiver);//取消注册的CommandReceiver
threadFlag = false;
boolean retry = true;
while(retry){
try{
myThread.join();
retry = false;
}catch(Exception e){
e.printStackTrace();
}
}
}
public class MyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
connectDevice();//连接蓝牙设备
while(threadFlag){
int value = readByte();
if(value != -1){
DisplayToast(value + "");
}
try{
Thread.sleep(50);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
public void doJob(){
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
DisplayToast("蓝牙设备不可用,请打开蓝牙!");
bluetoothFlag = false;
return;
}
if (!mBluetoothAdapter.isEnabled()) {
DisplayToast("请打开蓝牙并重新运行程序!");
bluetoothFlag = false;
stopService();
showToast("请打开蓝牙并重新运行程序!");
return;
}
showToast("搜索到蓝牙设备!");
threadFlag = true;
myThread = new MyThread();
myThread.start();
}
public void connectDevice(){
DisplayToast("正在尝试连接蓝牙设备,请稍后····");
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
DisplayToast("套接字创建失败!");
bluetoothFlag = false;
}
DisplayToast("成功连接蓝牙设备!");
mBluetoothAdapter.cancelDiscovery();
try {
btSocket.connect();
DisplayToast("连接成功建立,可以开始操控了!");
showToast("连接成功建立,可以开始操控了!");
bluetoothFlag = true;
} catch (IOException e) {
try {
btSocket.close();
bluetoothFlag = false;
} catch (IOException e2) {
DisplayToast("连接没有建立,无法关闭套接字!");
}
}
if(bluetoothFlag){
try {
inStream = btSocket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
} //绑定读接口
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
} //绑定写接口
}
}
public void sendCmd(byte cmd, int value)//串口发送数据
{
if(!bluetoothFlag){
return;
}
byte[] msgBuffer = new byte[5];
msgBuffer[0] = cmd;
msgBuffer[1] = (byte)(value >> 0 & 0xff);
msgBuffer[2] = (byte)(value >> 8 & 0xff);
msgBuffer[3] = (byte)(value >> 16 & 0xff);
msgBuffer[4] = (byte)(value >> 24 & 0xff);
try {
outStream.write(msgBuffer, 0, 5);
outStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public int readByte(){//return -1 if no data
int ret = -1;
if(!bluetoothFlag){
return ret;
}
try {
ret = inStream.read();
} catch (IOException e) {
e.printStackTrace();
}
return ret;
}
public void stopService(){//停止服务
threadFlag = false;//停止线程
stopSelf();//停止服务
}
public void showToast(String str){//显示提示信息
Intent intent = new Intent();
intent.putExtra("cmd", CMD_SHOW_TOAST);
intent.putExtra("str", str);
intent.setAction("android.intent.action.lxx");
sendBroadcast(intent);
}
public void DisplayToast(String str)
{
Log.d("Season",str);
}
//接收Activity传送过来的命令
private class CommandReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("android.intent.action.cmd")){
int cmd = intent.getIntExtra("cmd", -1);//获取Extra信息
if(cmd == CMD_STOP_SERVICE){
stopService();
}
if(cmd == CMD_SEND_DATA)
{
byte command = intent.getByteExtra("command", (byte) 0);
int value = intent.getIntExtra("value", 0);
sendCmd(command,value);
}
}
}
}
}
[java] view plaincopyprint? package com.lxx; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class BroadcastActivity extends Activity { /** Called when the activity is first created. */ TextView myTextView; Button sendButton; MyReceiver receiver; IBinder serviceBinder; MyService mService; Intent intent; int value = 0; /**************service 命令*********/ static final int CMD_STOP_SERVICE = 0x01; static final int CMD_SEND_DATA = 0x02; static final int CMD_SYSTEM_EXIT =0x03; static final int CMD_SHOW_TOAST =0x04; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myTextView = (TextView)findViewById(R.id.myTextView); myTextView.setText("Season"); sendButton = (Button)findViewById(R.id.sendButton); sendButton.setOnClickListener(new SendButtonClickListener()); intent = new Intent(BroadcastActivity.this,MyService.class); startService(intent); } public class SendButtonClickListener implements OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub byte command = 45; int value = 0x12345; sendCmd(command,value); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); if(receiver!=null){ BroadcastActivity.this.unregisterReceiver(receiver); } } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); receiver = new MyReceiver(); IntentFilter filter=new IntentFilter(); filter.addAction("android.intent.action.lxx"); BroadcastActivity.this.registerReceiver(receiver,filter); } public void showToast(String str){//显示提示信息 Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show(); } public class MyReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if(intent.getAction().equals("android.intent.action.lxx")){ Bundle bundle = intent.getExtras(); int cmd = bundle.getInt("cmd"); if(cmd == CMD_SHOW_TOAST){ String str = bundle.getString("str"); showToast(str); } else if(cmd == CMD_SYSTEM_EXIT){ System.exit(0); } } } } public void sendCmd(byte command, int value){ Intent intent = new Intent();//创建Intent对象 intent.setAction("android.intent.action.cmd"); intent.putExtra("cmd", CMD_SEND_DATA); intent.putExtra("command", command); intent.putExtra("value", value); sendBroadcast(intent);//发送广播 } } package com.lxx; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class BroadcastActivity extends Activity { /** Called when the activity is first created. */ TextView myTextView; Button sendButton; MyReceiver receiver; IBinder serviceBinder; MyService mService; Intent intent; int value = 0; /**************service 命令*********/ static final int CMD_STOP_SERVICE = 0x01; static final int CMD_SEND_DATA = 0x02; static final int CMD_SYSTEM_EXIT =0x03; static final int CMD_SHOW_TOAST =0x04; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myTextView = (TextView)findViewById(R.id.myTextView); myTextView.setText("Season"); sendButton = (Button)findViewById(R.id.sendButton); sendButton.setOnClickListener(new SendButtonClickListener()); intent = new Intent(BroadcastActivity.this,MyService.class); startService(intent); } public class SendButtonClickListener implements OnClickListener{ @Override public void onClick(View v) { // TODO Auto-generated method stub byte command = 45; int value = 0x12345; sendCmd(command,value); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); if(receiver!=null){ BroadcastActivity.this.unregisterReceiver(receiver); } } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); receiver = new MyReceiver(); IntentFilter filter=new IntentFilter(); filter.addAction("android.intent.action.lxx"); BroadcastActivity.this.registerReceiver(receiver,filter); } public void showToast(String str){//显示提示信息 Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show(); } public class MyReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if(intent.getAction().equals("android.intent.action.lxx")){ Bundle bundle = intent.getExtras(); int cmd = bundle.getInt("cmd"); if(cmd == CMD_SHOW_TOAST){ String str = bundle.getString("str"); showToast(str); } else if(cmd == CMD_SYSTEM_EXIT){ System.exit(0); } } } } public void sendCmd(byte command, int value){ Intent intent = new Intent();//创建Intent对象 intent.setAction("android.intent.action.cmd"); intent.putExtra("cmd", CMD_SEND_DATA); intent.putExtra("command", command); intent.putExtra("value", value); sendBroadcast(intent);//发送广播 } }
以下主要对代码部分进行详细的说明:
1.为了方便Activity和Service简历起良好的通信关系,需要在各自发送的数据进行命令的解释,这些命令在两者之间是一致的,能够相互读懂对方发送过来的数据.
[java]
view plaincopyprint?
/**************service 命令*********/
static final int CMD_STOP_SERVICE = 0x01;//停止服务
static final int CMD_SEND_DATA = 0x02;//发送数据
static final int CMD_SYSTEM_EXIT =0x03;//退出程序
static final int CMD_SHOW_TOAST =0x04;//界面上显示toast
[java] view plaincopyprint? //接收Activity传送过来的命令 private class CommandReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals("android.intent.action.cmd")){ int cmd = intent.getIntExtra("cmd", -1);//获取Extra信息 if(cmd == CMD_STOP_SERVICE){ stopService(); } if(cmd == CMD_SEND_DATA) { byte command = intent.getByteExtra("command", (byte) 0); int value = intent.getIntExtra("value", 0); sendCmd(command,value); } } } } //接收Activity传送过来的命令 private class CommandReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals("android.intent.action.cmd")){ int cmd = intent.getIntExtra("cmd", -1);//获取Extra信息 if(cmd == CMD_STOP_SERVICE){ stopService(); } if(cmd == CMD_SEND_DATA) { byte command = intent.getByteExtra("command", (byte) 0); int value = intent.getIntExtra("value", 0); sendCmd(command,value); } } } }
为了能够接收到数据,首先得把这个Receiver注册:
[java]
view plaincopyprint?
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction().equals("android.intent.action.lxx")){
Bundle bundle = intent.getExtras();
int cmd = bundle.getInt("cmd");
if(cmd == CMD_SHOW_TOAST){
String str = bundle.getString("str");
showToast(str);
}
else if(cmd == CMD_SYSTEM_EXIT){
System.exit(0);
}
}
}
}
[java] view plaincopyprint? public class MyThread extends Thread{ @Override public void run() { // TODO Auto-generated method stub super.run(); connectDevice();//连接蓝牙设备 while(threadFlag){ int value = readByte();//从蓝牙模块读取一个字节的数据,解释命令用 if(value != -1){ DisplayToast(value + ""); } try{ Thread.sleep(50); }catch(Exception e){ e.printStackTrace(); } } } } public class MyThread extends Thread{ @Override public void run() { // TODO Auto-generated method stub super.run(); connectDevice();//连接蓝牙设备 while(threadFlag){ int value = readByte();//从蓝牙模块读取一个字节的数据,解释命令用 if(value != -1){ DisplayToast(value + ""); } try{ Thread.sleep(50); }catch(Exception e){ e.printStackTrace(); } } } }
3.Activity传送数据到Service:
Activity上有一个按钮,点击一下就可以发送数据到蓝牙串口模块,工作原理是这样的:界面上实现按钮的点击事件
[java]
view plaincopyprint?
public class SendButtonClickListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
byte command = 45;
int value = 0x12345;
sendCmd(command,value);
}
}
[java] view plaincopyprint? public void sendCmd(byte command, int value){ Intent intent = new Intent();//创建Intent对象 intent.setAction("android.intent.action.cmd"); intent.putExtra("cmd", CMD_SEND_DATA); intent.putExtra("command", command); intent.putExtra("value", value); sendBroadcast(intent);//发送广播 } public void sendCmd(byte command, int value){ Intent intent = new Intent();//创建Intent对象 intent.setAction("android.intent.action.cmd"); intent.putExtra("cmd", CMD_SEND_DATA); intent.putExtra("command", command); intent.putExtra("value", value); sendBroadcast(intent);//发送广播 }
Service中
[java]
view plaincopyprint?
//前台Activity调用startService时,该方法自动执行
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
cmdReceiver = new CommandReceiver();
IntentFilter filter = new IntentFilter();//创建IntentFilter对象
//注册一个广播,用于接收Activity传送过来的命令,控制Service的行为,如:发送数据,停止服务等
filter.addAction("android.intent.action.cmd");
//注册Broadcast Receiver
registerReceiver(cmdReceiver, filter);
doJob();//调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
//前台Activity调用startService时,该方法自动执行
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
cmdReceiver = new CommandReceiver();
IntentFilter filter = new IntentFilter();//创建IntentFilter对象
//注册一个广播,用于接收Activity传送过来的命令,控制Service的行为,如:发送数据,停止服务等
filter.addAction("android.intent.action.cmd");
//注册Broadcast Receiver
registerReceiver(cmdReceiver, filter);
doJob();//调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
通过以上步骤就可以建立起蓝牙模块发送数据到Activity,Activity也可以发送数据到蓝牙模块了;
本例子的源码:
http://download.csdn.net/source/3557026
博文转自:http://blog.csdn.net/cen616899547/article/category/1133607
相关文章推荐
- Android Service和Activity基于串口蓝牙模块的双向通信【第二篇】
- Android Service和Activity基于串口蓝牙模块的双向通信【第二篇】
- Android Service和Activity基于串口蓝牙模块的双向通信【第二篇】
- Android Service和Activity基于串口蓝牙模块的双向通信
- Android Service和Activity基于串口蓝牙模块的双向通信
- Android蓝牙开发与蓝牙模块进行通讯(基于eclipse)
- android手机通过串口蓝牙透传模块与AVR单片机通信实例。。。蓝牙服务程序案例
- android蓝牙和串口模块的通信
- Android通过JNI实现与C语言的串口通讯操作蓝牙硬件模块
- 用Android手机通过蓝牙模块HC-06连接Arduino串口输出
- android中activity与service的双向通信
- Android蓝牙通信——与蓝牙模块进行通信传输数据
- Android4_SRC_分析~ActivityManagerService~图解(一)
- Android——Activity、Service、Broadcast,超时时间报ANR
- Android与服务器端数据交互(基于SOAP协议整合android+webservice)
- Android TabActivity中的子Tab Activity 无法正常 bindService 之 解决方法
- Android4.42-Setting源代码分析之蓝牙模块Bluetooth(下)
- 自定义的Android service 监控正在运行的Activity
- 【转】Android TabActivity无法正常bindService解决方法
- Android解析ActivityManagerService(一)AMS启动流程和AMS家族