android之旅-Intent和BroadcastReceiver(修改了网上文章很多不足,重点参考了android4高级编程)

 一、Intent作用及分类

Intent是一种消息传递机制,可以在程序内及程序间使用,主要用法为:①使用类名显式启动一个service或Activity②在①的基础上执行一个动作的intent,并进行相关处理③广播某个时间已经发生。

 二、使用Intent启动Activity

1、显式启动一个Activity

所谓显式启动,即显式指定我们要启动Activity的类名,比如我们要在Mainactivity中的Button被按下时,打开IntentActivity,就可以使用下面的代码:

<span style="white-space:pre">			</span>if(v==btn1)
			{
				Intent intent=new Intent();
				intent.setClass(MainActivity.this, IntentActivity.class);
				startActivity(intent);
			}
注意,所有的Activity都存储于一个Activity栈,当我们调用startActivity后,IntentActivity将会经过Creat start resume最终运行,并且IntentActivity会移动到Acticity栈的顶部。但是当我们按下back(或在代码执行finish())会从Activity栈栈顶依次删除Activity。

2、隐式启动Activity

隐式启动Activity即匿名启动某一恰当的程序组件来响应动作请求。如我们要隐式的启动打开联系人的Activity:

//隐式选择联系人,注意使用startActivity并不能启动界面
Intent intent=new Intent(Intent.ACTION_PICK,Uri.parse("content://contacts/people"));
startActivityForResult(intent,PICK_CONTACT_SUBACTIVITY);
3、启动Activity并捕获子Activity返回的结果

在上文我们可以看出,单纯使用startActivity MainActivity并不能得到IntentActivity进行处理后的结果。这时我们需要startActivityForResult:

但是仅仅使用这个接口还不够,我们需要一个接口来监听结构,这时,我们就需要重载MainActivity中的protected void onActivityResult(int requestCode, int resultCode, Intent data):

在MainActivity中:

<pre name="code" class="java"><pre name="code" class="java">//定义intent识别码
	 private static final int SHOW_SUBACTIVITY=1;<pre name="code" class="java">Intent intent=new Intent();
				intent.setClass(MainActivity.this, IntentActivity.class);
				//传入识别码唯一标识SHOW_SUBACTIVITY,启动intent,以便获取下一页面返回的结果
				startActivityForResult(intent, SHOW_SUBACTIVITY);

 @Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
    	super.onActivityResult(requestCode, resultCode, data);
    	if(requestCode==SHOW_SUBACTIVITY)
    	{
    		switch (resultCode) {
    		case RESULT_CANCELED:
    		{
    			Bundle bd=data.getExtras();
    			edittxt.setText(bd.getString("text"));
    			break;
    		}
    		case RESULT_OK:
    		{
    			Bundle bd=data.getExtras();
    			edittxt.setText(bd.getString("text"));
    			break;
    		}	
    		default:	
    			break;
    		}
    	}
		
	}




    

 在IntentActivity中:

switch(v.getId())
			{
			case R.id.resultcancel:
			{
				Intent intent=new Intent();
				intent.setClass(IntentActivity.this, MainActivity.class);
				intent.putExtra("text", "cancel:i am from intentactivity!and pass back me on childactivity finished!");
				setResult(RESULT_CANCELED,intent);
				finish();
				break;
			}
			case R.id.resultok:
			{
				Intent intent=new Intent();
 				intent.setClass(IntentActivity.this, MainActivity.class);
 				intent.putExtra("text", "ok: am from intentactivity!and pass back me on childactivity finished!");
 				setResult(RESULT_OK,intent);
 				finish();
 				break;
			}
			default:
				break;
			}
解析:我们在startActivityForResult(intent, SHOW_SUBACTIVITY);传入SHOW_SUBACTIVITY,其实就是一个大于0的整数,用来标识相应的Intent;为了接受Result,对onActivityResult(int requestCode, int resultCode, Intent data) 进行重写,注意,requestCode就是Intent的标识符,即为上文中的SHOW_SUNACTIVITY,resultCode即为IntentActivity中的setResult(RESULT_OK,intent);传回的Result值 -RESULT_OK,date即为setResult(RESULT_OK,intent);传回的intent。

三、使用Intent广播事件

 1、最基本的广播事件发送与接受:

广播的发送,很简单,生成一个Intent,设置Action,直接进行广播:

<span style="white-space:pre">		</span>public static final String BROAD_UI_STRING="com.example.intentbraodcast.BROAD_UI"; 
<span style="white-space:pre">		</span>Intent intent=new Intent(BROAD_UI_STRING);
		intent.putExtra("str", "update ui by broadcast!");
		sendBroadcast(intent);

广播的注册,最好在广播的发送前注册广播:

<span style="white-space:pre">		</span>//注册Broadcast Receiver
   	  	registerReceiver(new MyBroadcastReceiver, new IntentFilter(BROAD_UI_STRING));

注:上文中的 BROAD_UI_STRING就是一个自定义的独一无二的字符串,由于广播不但可用于应用程序内部交换数据,还可用于系统间应用交换数据,故一般用传统的包名前缀法来命名。

进行注册以前,我们需要实现自己的接收器,继承BroadcastReceiver即可,我们对广播出的Intent绑定的数据再次进行处理

public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
           //TODO: React to the Intent received.
        	String actionString=intent.getAction();
        	if (actionString.equals(BROAD_UI_STRING))
        	{
        		//改变下一个activity中的值
        		String str=intent.getStringExtra("str");
            	Intent newIntent=new Intent();
            	newIntent.setClass(MainActivity.this,IntentActivity.class );
            	newIntent.putExtra("str", str);
            	context.startActivity(newIntent);
        	}
        	else if(actionString.equals(LOCAL_ACTION))
        	{
        		edittxt.setText(intent.getStringExtra("str"));
        	}
        }
     }
广播的注销:在我们不再广播时,通常是界面挂起或停止时,需要对接收器进行注销:

 @Override
	protected void onPause() {
		 unregisterReceiver(receiver);
		super.onPause();
	}
需要注意的是,接收器中的处理程序需要在5秒钟内完成,否则会显示Force CLose的对话框。很多时候,我们希望当我们的应用程序在关闭时也能响应一些广播,需要在Manifest中的application节点添加一个receiver标签,指定接收器类名和过滤器标识符:

<receiver android:name=".MyBroadcastReceiver"
  <intent-filter>
    <action android:name="packagename.classname.BROAD_UI_STRING" />
  </intent-filter>
</receiver>
这样,即使我们的应用程序处于关闭状态也能响应广播。

2、有序广播

3、广播Sticky Intent,在一些教程仍出现,但在android 5.0以后会渐渐废弃,故不再讨论。

4、LocalBroadcastManager(局部广播管理器)

顾名思义,其用于局部数据的消息驱动,是一种轻量级的handler,更高效的广播模型。

操作过程与普通广播管理器类似,只不过要先获取LocalBroadcastManager:

lbm=LocalBroadcastManager.getInstance(MainActivity.this);
发送时将sendBroadcast改为lbm.sendBroadcast,注册时将registerReceiver改为lbm.registerReceiver,注销时将unregisterReceiver改为lbm.unregisterReceiver

下面为示例的全部代码,工程文件我也会放到最后:

package com.example.intentandbroadcast;

import android.R.string;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;
@SuppressWarnings("unused")
public class MainActivity extends Activity {
	 Button btn1;
	 Button btn2,btn3,btn4,btn_broad_ui,btn_local_broad;
	 EditText edittxt;
	 TextView tv;
	 LocalBroadcastManager lbm;
	 MyBroadcastReceiver receiver;
	 //定义intent识别码
	 private static final int SHOW_SUBACTIVITY=1;
	 private static final int PICK_CONTACT_SUBACTIVITY=2;
	 public static final String BROAD_UI_STRING="com.example.intentbraodcast.BROAD_UI"; 
	 public static final String LOCAL_ACTION="com.example.intentbraodcast.LOCAL_ACTION"; 
	 void getviewdefinition()
	 {
		 btn1=(Button)findViewById(R.id.btn1);
   	 	 btn2=(Button)findViewById(R.id.btn2);
   	 	 btn3=(Button)findViewById(R.id.btn3);
   	 	 btn4=(Button)findViewById(R.id.btn4);
   	 	 btn_broad_ui=(Button)findViewById(R.id.btn_broad_ui);
   	 	 edittxt=(EditText)findViewById(R.id.edittext);
   	 	 tv=(TextView)findViewById(R.id.textview);
   	 	 btn_local_broad=(Button)findViewById(R.id.btn_local_broad_ui);
   	 	 lbm=LocalBroadcastManager.getInstance(MainActivity.this);
   	 	receiver=new MyBroadcastReceiver();
	 }
	 public class OnButtonClick implements OnClickListener
	 {

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			if(v==btn1)
			{
				Intent intent=new Intent();
				intent.setClass(MainActivity.this, IntentActivity.class);
				//传入识别码唯一标识SHOW_SUBACTIVITY,启动intent,以便获取下一页面返回的结果
				startActivityForResult(intent, SHOW_SUBACTIVITY);
			}
			else if(v==btn3)
			{
				//触发外部intent打电话
				Intent intent=new Intent(Intent.ACTION_DIAL,Uri.parse("tel:13237170570"));
				startActivity(intent);
			}
			else if(v==btn4)
			{
				//隐式选择联系人,注意使用startActivity并不能启动界面
				Intent intent=new Intent(Intent.ACTION_PICK,Uri.parse("content://contacts/people"));
				startActivityForResult(intent,PICK_CONTACT_SUBACTIVITY);
			}
			else if(v==btn_broad_ui)
			{
				Intent intent=new Intent(BROAD_UI_STRING);
				intent.putExtra("str", "update ui by broadcast!");
				sendBroadcast(intent);
			}
			else if(v==btn_local_broad)
			{
				//设置本地广播,更高效:
				Intent intent=new Intent(LOCAL_ACTION);
				intent.putExtra("str", "i am created by local broadcast!");
				lbm.sendBroadcast(intent);
			}
		}
		 
	 }
	@Override
    	protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
        getviewdefinition();
        OnButtonClick btnclick=new OnButtonClick();
        btn1.setOnClickListener(btnclick);
        btn3.setOnClickListener(btnclick);
        btn4.setOnClickListener(btnclick);
        btn_broad_ui.setOnClickListener(btnclick);	
        btn_local_broad.setOnClickListener(btnclick);
    }
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		//注册Broadcast Receiver
   	  	registerReceiver(receiver, new IntentFilter(BROAD_UI_STRING));
   	  	//注册local broadcast
		lbm.registerReceiver(receiver, new IntentFilter(LOCAL_ACTION)); 
	}
	
	 @Override
	protected void onPause() {
		 unregisterReceiver(receiver);
		 lbm.unregisterReceiver(receiver);
		super.onPause();
	}
    
    @Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
    	super.onActivityResult(requestCode, resultCode, data);
    	if(requestCode==SHOW_SUBACTIVITY)
    	{
    		switch (resultCode) {
    		case RESULT_CANCELED:
    		{
    			Bundle bd=data.getExtras();
    			edittxt.setText(bd.getString("text"));
    			break;
    		}
    		case RESULT_OK:
    		{
    			Bundle bd=data.getExtras();
    			edittxt.setText(bd.getString("text"));
    			break;
    		}	
    		default:	
    			break;
    		}
    	}
		
	}
   
    
   
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
           //TODO: React to the Intent received.
        	String actionString=intent.getAction();
        	if (actionString.equals(BROAD_UI_STRING))
        	{
        		//改变下一个activity中的值
        		String str=intent.getStringExtra("str");
            	Intent newIntent=new Intent();
            	newIntent.setClass(MainActivity.this,IntentActivity.class );
            	newIntent.putExtra("str", str);
            	context.startActivity(newIntent);
        	}
        	else if(actionString.equals(LOCAL_ACTION))
        	{
        		edittxt.setText(intent.getStringExtra("str"));
        	}
        }
     }
}

package com.example.intentandbroadcast;

import java.security.PublicKey;

import com.example.intentandbroadcast.MainActivity.MyBroadcastReceiver;

import android.app.Activity;
import android.app.PendingIntent.CanceledException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;
public class IntentActivity extends Activity {
	Button cancel,ok,btn_local;
	TextView txtintentTextView;
	IntentFilter filter;
	String stickystring;
	void getdefinition()
	{
		cancel=(Button)findViewById(R.id.resultcancel);
        ok=(Button)findViewById(R.id.resultok);
        btn_local=(Button)findViewById(R.id.btn_localintent);
        txtintentTextView=(TextView)findViewById(R.id.textintent); 
	}
	public class OnBtnClick implements OnClickListener{
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			switch(v.getId())
			{
			case R.id.resultcancel:
			{
				Intent intent=new Intent();
				intent.setClass(IntentActivity.this, MainActivity.class);
				intent.putExtra("text", "cancel:i am from intentactivity!and pass back me on childactivity finished!");
				setResult(RESULT_CANCELED,intent);
				finish();
				break;
			}
			case R.id.resultok:
			{
				Intent intent=new Intent();
 				intent.setClass(IntentActivity.this, MainActivity.class);
 				intent.putExtra("text", "ok: am from intentactivity!and pass back me on childactivity finished!");
 				setResult(RESULT_OK,intent);
 				finish();
 				break;
			}
			default:
				break;
			}
			
		}
	}
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //雷区,这个启动的xml打错了 调了好久
        setContentView(R.layout.activity_intent);
        getdefinition();
		//测试startactivyforresult
        cancel.setOnClickListener(new OnBtnClick());
        ok.setOnClickListener(new  OnBtnClick());
    }
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    
}
eclipse工程地址:http://download.csdn.net/detail/tianyuan521521/8604875









郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。