android service 通过broadcast通知Myreceiver 启动activity

	本程序实现的是在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部分代码请直接下载下面的连接。去下载整个工程。

源代码及工程下载地址:点击打开链接



你可能感兴趣的:(android)