本程序实现的是在android 中后台启动service 监听某个函数的返回状态,如果发生改变则通过broadcast到MyReceiver然后 启动另一个类似接听电话的activity,现附上源码并加以描述。
1 MainAcitvity.java 中实现的是handleMessage(接收MyReceiver发送过来的hander对象);button2中的绑定服务(只有在按Button2后才可以绑定服务);重写OnserviceDisconnected和OnserviceConnected方法
public class MainActivity extends Activity {
private Button button1;
private Button button2;
private Binder binder;
public static final int STARTACTIVITY = 1;
public static Handler handlerstart = new Handler(){
public void handleMessage(Message msg){
if(msg.what == STARTACTIVITY){
M_arg.count++;
String s=String.valueOf(M_arg.count);
Log.e("msg2",s);
Context context = (Context)msg.obj;
Intent intent = new Intent(context,ListenCall.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
//播放音乐
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button2 = (Button)findViewById(R.id.button2);
//完成绑定对象 开始绑定
Intent intent = new Intent();
intent.setClass(MainActivity.this, SecondService.class);
//绑定服务由该函数来完成,由第二个函数可知道第二部要做什么
bindService(intent, conn, BIND_AUTO_CREATE);
//发送请求
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeString("from activity :data");//给parcel方数据
try {
//一执行transact 就会去执行secondservice的ontransact,并且将相应的四个参数传递到ontransact中
binder.transact(0, data, reply,0);
String s = reply.readString();
//Log.e("msg接收", s);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
//连接对象,重写OnserviceDisconnected和OnserviceConnected方法
ServiceConnection conn = new ServiceConnection() {
// 成功连接服务,该方法被执行。在该方法中可以通过IBinder对象取得onBind方法的返回值,一般通过向下转型
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
MainActivity.this.binder = (Binder)binder;//绑定成功之后,MyBinder()传过来的binder对象赋值给mainacitvity的binder
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
// TODO Auto-generated method stub
}
};
}
2 secondservice.java 主要是指在 MyBinder类中实现了 onTransact方法,去每隔2s去检测 checkalarm(),checkalarm是一个检测网络数据的函数。返回的参数值,如果是true的话就sendBroadcast(intent),
public class SecondService extends Service {
IBinder binder = new MyBinder();
private static final String TAG = "MyService";
byte[] datahtml;
String htmlcode;
byte[] datahtmlafter;
String htmlcodeafter;
String alarm;
String alarmafter;
String textenter;
String textenterafter;
private boolean checkalarm = false;
// 当service与activity成功调用时调用这个方法
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return binder;
}
class MyBinder extends Binder {
//定义一个action常量
private static final String MY_ACTION = "com.example.parceltest.MY_ACTION";
// data是activity 发往service的。reply是service发往activity
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply,
int flags) throws RemoteException {
// TODO Auto-generated method stub
final Handler whilehandler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
checkalarm = checkalarm();
whilehandler.postDelayed(this, 2000);//每隔2s钟
if (checkalarm) {
// 获得了这个alarm然后再每隔2s钟再检测一次是不是还是同样的alarm如果不是或者是就返回给activity
Intent intent = new Intent();
//设置avtion属性
intent.setAction(MY_ACTION);
intent.putExtra("msg", "开门");
if(M_arg.count==0){
sendBroadcast(intent);//发出广播
M_arg.count++;
}
else{
Handler delayhandler = new Handler();
delayhandler.postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
M_arg.count=0;
}
}, 33000);
}
}
//Log.e("data", s);//程序在这个地方崩掉
}
};
String s = data.readString();
reply.writeString("from service: reply");
whilehandler.postDelayed(runnable, 2000);// 打开定时器,执行操作 实现每隔2s钟重复执行checkalarm()一次
return super.onTransact(code, data, reply, flags);
}
}
public boolean checkalarm() {
try {
datahtml=getHtml();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
htmlcode = new String(datahtml,"gb2312");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
textenter = htmlcode.replaceAll("\n", "");//去掉回车符
alarm = textenter.substring(123, 137);//取出123到137位
if(alarm.equals("alarm_status=2")){//正常情况下alarm是alarm_status=0,
checkalarm = true;
Log.e("msg1", "第一次执行true");
}
else {
checkalarm = false;
Log.e("msg1", "第一次执行false");
}
return checkalarm;
}
public byte[] getHtml() throws Exception {
URL url = new URL("http://192.168.1.104:81/get_status.cgi");//我是在局域网里面试的可以访问改地址。
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
byte[] data = outStream.toByteArray();// 网页的二进制数据
outStream.close();
inStream.close();
return data;
}
// service 创建时被调用
@Override
public void onCreate() {
Log.e(TAG, "start onCreate~~~");
super.onCreate();
}
// 客户端调用startservice()方法启动service时,该方法被调用
@Override
public void onStart(Intent intent, int startId) {
Log.e(TAG, "start onStart~~~");
super.onStart(intent, startId);
}
// 当service不再使用是被调用
@Override
public void onDestroy() {
Log.e(TAG, "start onDestroy~~~");
super.onDestroy();
}
}
3 MyReceiver.java 接听广播函数在receive里面启动一个activity会存在的问题是 onReceive函数只会存在10s钟左右就会销毁解决方法是:广播里面向handler发送一个消息,在handler里面去打开一个界面。
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(final Context context, Intent intent) {
//从intent中获得信息
String msg = intent.getStringExtra("msg");
//使用toast显示
if(msg.equals("开门")){
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
//在一个普通类中启动activity http://bbs.csdn.net/topics/370005057
//在receive里面启动一个activity会存在的问题是 onReceive函数只会存在10s钟左右就会销毁
//解决方法是:广播里面向handler发送一个消息,在handler里面去打开一个界面。
/*Intent intentcall = new Intent(context, ListenCall.class);
intentcall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentcall); */
Message message = new Message();
message.what = 1;
message.obj = context;
MainActivity.handlerstart.sendMessage(message);
}
}
}
4 listencall.java中的activity,改代码的按钮部分还没有加
public class ListenCall extends Activity
{
private ImageButton accept;
private ImageButton reject;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.linsten);
accept = (ImageButton)findViewById(R.id.btn_doorbell_ok);
reject = (ImageButton)findViewById(R.id.btn_doorbell_no);
accept.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
}
});
reject.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}
}
5 放置静态变量的 M_arg.java
public class M_arg{
public static int count=0;
}
注意:1 各位可以去更改checkalarm()中的那个url,去测试一下。我的那个URL是一个网络摄像头的连接地址。
2 Layout部分代码请直接下载下面的连接。去下载整个工程。
源代码及工程下载地址:点击打开链接