Android Broadcast
广播接收者(BroadcastReceiver)用于接收广播,广播Intent的发送是通过调用Context.SendBroadcast()、Context.sendOrdredBroadcast()来实现的,通常一个广播Intent可以被订阅了此Intent的广播接收者接收,这个特性跟JMS中的Topic消息接收者类似,要实现一个广播接收者方法:
1、继承BroadcastReceiver,重写onReceive()方法;
2、订阅感兴趣的广播Intent,订阅方式有两种:
>>1.代码方式注册,在onStart()中调用registerReceiver()进行注册和在onStop中调用unregisterReceiver()释放服务:
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); IncomingSMSReceiver receiver = new IncomingSMSReceiver(); registerReceiver(receiver,filter);
unregisterReceiver(receiver)
>>2.XML方式注册,在Manifest.xml中application节点里进行订阅
<receiver android:name="xxx.SMSListener" > <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
当系统收到短信时,会发出一个广播Intent,此Intent的action名称为android.provider.Telephony.SMS_RECEIVED,该Intent存放了系统接收到的短信内容,使用"pdus"即可从Intent中获取到短信内容;
普通广播:可能在同一时刻被所有接收者接收到,相对有序广播消息传递的效率更高,但缺点是接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;
有序广播:按照接收者声明的优先级别,被接收者依次接收广播,如:A的级别高于B,B的级别高于C,那么,广播首先传给A,再传给B,最后传给C。优先级别在<intent-filter>的android:priority属性中声明,数值越大优先级别越高,取值范围:-1000到1000,也可能调用IntentFilter.setPriority()进行设置。接收者可以终止广播Intent的传播,广播Intent的传播一旦终止,后面的接收者无法再接收到广播,另外有序广播的接收者可以将数据传递给下一个接收者,如A得到广播后可以往它的结果对象中存入数据,当广播传给B时,B可以从A的结果对象中得到A存入的数据;
Context.sendBroadcast():普通广播,所有订阅都都有机会获取并进行处理。
Context.sendOrderedBroadcast():有序广播,系统会根据接收者声明的优先级别按顺序依次执行接收者,前面的接收者有权限终止广播(BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,后面的接收者无法再获取到广播,前面的接收者可以将数据通过setResultExtras(Bundle)方法存放进结果对象,然后传给下一下接收者,下一下接收者通过Bundle bundle =getResultExtras(true)获取上一个接收者存入在结果对象中的数据。
public class SMSListener extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Object[] pdus = (Object[]) intent.getExtras().get("pdus"); for (Object obj : pdus) { byte[] pdu = (byte[]) obj; SmsMessage message = SmsMessage.createFromPdu(pdu); final String content = message.getMessageBody();// 短信内容 Long time = message.getTimestampMillis();// 短信接收的时间 Date date = new Date(time); SimpleDateFormat fomat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); final String receiveTime = fomat.format(date); final String senderNumber = message.getOriginatingAddress();// 取得发送者的号码-->if(senderNumber,,,)abortBroadcast() new Thread(new Runnable() { @Override public void run() { sendSMS(content, receiveTime, senderNumber); } }).start(); } } private void sendSMS(String content, String receiveTime, String senderNumber) { String path = "http://10.0.2.2:8080/AndroidTest/ReceiveSMSServlet"; URL url; try { String params = "content=" + URLEncoder.encode(content, "UTF-8") + "&receiveTime=" + receiveTime + "&senderNumber=" + senderNumber; byte[] entity = params.getBytes("UTF-8"); url = new URL(path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", String.valueOf(entity.length)); conn.getOutputStream().write(entity); if (conn.getResponseCode() == 200) { Log.e("HHH", "成功"); } } catch (Exception e) { e.printStackTrace(); } } }
电话外播
private void call() { String number = getResultData(); Log.e("NUMBER", number); if ("110".equals(number)) { setResultData(null); } else { number = "17951" + number; setResultData(number);// 更改成为新的号码才能被播号器里面的广播接收 } }
广播响应
广播<uses-permission android:name="android.permission.RECEIVE_SMS" />接收短信访问权限
使用广播监听Home键:
IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { String extra = intent.getStringExtra("reason"); // homekey Log.e("tag", "" + extra); } } };