Android09-广播和服务(一)

1.广播接受者的概念

1:BroadcastReceiver是一个抽象类,用来接收sendBroadCast发出的广播。
2:其特点是数据单向传递,可扩散。

2.ip拨号器案例

1:写一个类继承BroadCastRevceiver重写onReceive方法。
2:清单文件中注册receiver节点,通过intent-filter拦截android.intent.action.NEW_OUTGOING_CALL广播事件。
3:添加android.permission.PROCESS_OUTGOING_CALLS权限。
public class MainActivity extends Activity {

    private EditText ed_prefix;
	private SharedPreferences sp;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ed_prefix = (EditText) findViewById(R.id.ed_prefix);
        Button btn_add = (Button) findViewById(R.id.btn_add);
        
        sp = getSharedPreferences("info", MODE_PRIVATE);
        
        btn_add.setOnClickListener(new OnClickListener() {
			
        	/*
        	 * (non-Javadoc)
        	 * @see android.view.View.OnClickListener#onClick(android.view.View)
        	 * 获取数据 进行存储
        	 */
			@Override
			public void onClick(View v) {
				String prefis = ed_prefix.getText().toString();
				if(TextUtils.isEmpty(prefis)){
					Toast.makeText(getApplicationContext(), "前缀是空", Toast.LENGTH_SHORT).show();
				}else {
					Editor edit = sp.edit();
					edit.putString("prefix", prefis);
					edit.commit();
				}
			}
		});
    }

}

public class DailReceiver extends BroadcastReceiver {

	/*
	 * (non-Javadoc)
	 * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
	 * 当外拨电话时就会调用这个方法,可以在这个方法中进行电话号码的相关处理
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		SharedPreferences sp = context.getSharedPreferences("info", Context.MODE_PRIVATE);
		String number = getResultData();
		System.out.println("number" + number);
		
		String prefix = sp.getString("prefix", "100");
		//讲前缀 + 数据设置为要拨打的电话号码
		setResultData(prefix + number);
	}

}
<!-- 当intent-filter意图过滤器拦截到外拨电话是就会实例化这个类 -->
<receiver android:name="com.my.androidpro23.DailReceiver">
    <intent-filter>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
</receiver>
<!-- 外拨电话的权限 -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

3.sd卡状态监听

public class SDCardStateReveiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		if("android.intent.action.MEDIA_MOUNTED".equals(action)){
			System.out.println("挂载sd卡");
		}else if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){
			System.out.println("去掉sd卡");
		}
	}

}
<!-- sd卡状态变化的intent-filter -->
<receiver android:name="com.my.androidpro23.SDCardStateReveiver">
    <intent-filter>
        <!-- 插上sd卡的模式 -->
        <action android:name="android.intent.action.MEDIA_MOUNTED" />
        <!-- 去掉sd卡的模式 -->
        <action android:name="android.intent.action.MEDIA_UNMOUNTED" />
        <data android:scheme="file" />
    </intent-filter>
</receiver>

4.来短信监听

public class SmsReceiver extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		//读取消息内容
		Object[] objects = (Object[]) intent.getExtras().get("pdus");
		for(Object obj : objects){
			SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
			String smsContent = smsMessage.getMessageBody();
			String from = smsMessage.getOriginatingAddress();
			System.out.println("from" + from + "短信内容:" + smsContent);
		}
	}

}
<!-- 接收短信权限 -->
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<!-- 接收短信intent-filter,这个权限没有自动提示,必须手动打出来 -->
<receiver android:name="com.my.androidpro23.SmsReceiver">
    <intent-filter>
    <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

5.不同版本之间广播的特点

1:4.0之后没有运行的应用不能收到广播。
2:在应用管理器中强制停止(force stop)的应用不能收到广播。

6.应用安装和下载的监听

public class AppInstallReceiver extends BroadcastReceiver {

    /*
	 * (non-Javadoc)
	 * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
	 * 可以通过监听应用的安装和卸载来做数据分析
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		//获取安装或者卸载应用的包名
		Uri data = intent.getData();
		System.out.println(action + data);
	}

}
<!-- 应用安装和下载的intent-filter -->
<receiver android:name="com.my.androidpro23.AppInstallReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_ADDED" />
        <action android:name="android.intent.action.PACKAGE_REMOVED" />
        <data android:scheme="package" />
    </intent-filter>
</receiver>

7.系统启动监听

public class BootRecevier extends BroadcastReceiver{

	@Override
	public void onReceive(Context context, Intent intent) {
		System.out.println("开启了");
		Intent intent2 = new Intent(context,MainActivity.class);
		//系统启动时候,并没有开启该应用,没有这个应用的任务栈,所以要创建这个应用的任务栈
		intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(intent2);
	}

}
<!-- 系统启动的intent-filter -->
<receiver android:name="com.my.androidpro23.BootRecevier">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>
<!-- 监控系统系统的权限 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

8.发送无序广播

/*
	 * 发送广播 使用Intent封装数据,并且指明给谁发广播
	 */
public void sendBroadcast(View v){
    //发送广播
    Intent intent = new Intent();
    intent.setAction("com.my.android23");
    intent.putExtra("name", "zhangsan");

    sendBroadcast(intent);
}

9.有序广播

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void send(View v){
    	Intent intent = new Intent();
    	intent.setAction("com.my.OrderedBroadcast");
    	
    	//接收广告需要的权限
		String receiverPermission = null;
		//最后一个广告接受者
		BroadcastReceiver resultReceiver = new FinalBroadcastReceiver();
		//处理最终广告需要的handler,如果是null则会在主线程中进行处理
		Handler scheduler = null;
		//初始码,一般用来区分不同的广告
		int initialCode = Activity.RESULT_OK;
		//初始数据,一般使用Intent进行数据的传递,和setResultData的作用一样,可以使用getResultData取出
		String initialData = "qwer100";
		//使用Bundle也可以进行数据的封装,一般使用Intent
		Bundle initialExtras = null;
		sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras);
    }
}

public class FirstBroadcastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		//获取initialData封装的数据
		String resultData = getResultData();
		Toast.makeText(context, resultData, Toast.LENGTH_SHORT).show();
		//设置要传递的数据
		setResultData("qwer200");
		//终端要发送的广播,只有有序广播需要终端,无序广播所有的人都同时收到,不需要中断
		//abortBroadcast();
	}

}

public class SecondBroadcastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		//获取initialData封装的数据
		String resultData = getResultData();
		Toast.makeText(context, resultData, Toast.LENGTH_SHORT).show();
		//设置要传递的数据
		setResultData("qwer400");
	}

}


public class ThirdBroadcastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		//获取initialData封装的数据
		String resultData = getResultData();
		Toast.makeText(context, resultData, Toast.LENGTH_SHORT).show();
		//设置要传递的数据
		setResultData("qwer200");
	}

}

public class FinalBroadcastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		Toast.makeText(context, "最后一个接收广告", Toast.LENGTH_SHORT).show();
	}

}
<!-- 通过android:priority指定有序广告的优先级 -->
<receiver android:name="com.my.androidpro24.FirstBroadcastReceiver">
    <intent-filter android:priority="100">
        <action android:name="com.my.OrderedBroadcast" />
    </intent-filter>
</receiver>

<receiver android:name="com.my.androidpro24.SecondBroadcastReceiver">
    <intent-filter android:priority="80">
        <action android:name="com.my.OrderedBroadcast" />
    </intent-filter>
</receiver>

<receiver android:name="com.my.androidpro24.ThirdBroadcastReceiver">
    <intent-filter android:priority="60">
        <action android:name="com.my.OrderedBroadcast" />
    </intent-filter>
</receiver>

10.有序广告和无序广告的比较

1:有序广告可以通过priority设置接收顺序,无序广告大家一起收到。
2:有序广告可以通过abortBroadcast()方法中断传播,无序广告不可以中断传播。
3:有序广告通过sendOrderedBroadcast()方法发送,无序广告通过sendBroadCast()发送。
4:可以通过是否可以被中断来判断有序广告和无序广告。
5:如果无序广告被中断,则会产生出现异常BroadcastReceiver trying to return result during a non-ordered broadcast。

11.广告的动态注册和静态注册

1:四大组件中,只有广告接收者可以不在清单文件中注册。
2:静态注册在清单文件中,通过声明receiver节点,并且指定intent-filter来注册。
3:动态注册通过registerReceiver()方法注册,unregisterReceiver()方法注销。
public class MainActivity extends Activity {

    private BroadcastReceiver receiver;

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        receiver = new ScreenLightBroadcastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.intent.action.SCREEN_ON");
        filter.addAction("android.intent.action.SCREEN_OFF");
        
        //动态注册广告
        registerReceiver(receiver, filter);
    }
    
    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	//当前Activity销毁,关闭广告接收着的实例对象
    	unregisterReceiver(receiver);
    }
}

public class ScreenLightBroadcastReceiver extends BroadcastReceiver {

	@Override
	public void onReceive(Context context, Intent intent) {
		String action = intent.getAction();
		if("android.intent.action.SCREEN_OFF".equals(action)){
			System.out.println("屏幕关闭");
		}else if("android.intent.action.SCREEN_ON".equals(action)){
			System.out.println("屏幕亮了");
		}
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值