I,自定义广播
前面所说的都是接收短信,外拨电话等都是系统所有的广播,而其实我们可以自己自定义一个广播,并且写一个广播接收者来玩玩。
1)
在按钮的点击方法中,发送自定义的广播:
1 public void click(View view){ 2 /** 3 * 发送自定义的广播 4 */ 5 Intent intent=new Intent(); 6 //设置意图的动作,要和自定义的频道要一致 7 intent.setAction("www.wangchengxiang.com"); 8 sendBroadcast(intent); 9 }
setAction方法,理解为设置意图的活动,也就是广播接收者需要接收的频道。
发送自定义广播,光代码也就这么几行,其实发送广播的方法就有好几种,且它们之间都有很大的差别。
2)
sendBroadcast(intent);
它发送的是无序广播,特点就是任何广播接收者都可以接收到这个广播。
sendOrderedBroadcast(intent, receiverPermission);
它发送的是有序广播,广播接收者会让优先级的次序依次的接收到广播。上篇在广播接收者的配置中有过优先级的配置,关于优先级,最大值为1000,最小为-1000,默认的为0.
而receiverPermission表示的是广播接收者的权限,如果不关心,写为null。
当发送的是有序广播时,比如有多个广播接收者都有接收到,如果在高优先级的广播接收者中,执行abortBroadCast()方法,那么低优先级的广播接收者将不会触发onReceive方法。
所以为了防止,有恶意的广播接收者,故意中断广播,又诞生出另一种方法,可以指定某个广播接收者一定要接收到广播。
sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras)
resultReceiver参数表示的就是一定会接收到的广播接收者,即使在高优先级的广播接收者中,中断了广播,这个广播接收者也会执行到。
那么为什么google的工程师要这么做呢?
比如打电话,就可以认为是一个广播接收者,如果有高优先级的广播接收者中断了广播,那么默认为0的电话广播接收者岂不是不能打电话,而打电话对于我们是多么的重要。
所以有的时候,这个方法会派上大用场。
II,电话监听
1)
四大组件的最后一个Service,表示的是服务之意,也引申于window下的服务。
安卓下的服务的特点:长期运行在后台,没有界面的应用程序。
服务最大的特点也是这两点,长期运行在后台,有的应用就特别适合用服务去实现,比如天气预报,它可以长期隔一段时间去服务器获取天气信息。
所以总结而来,服务可以用来做一些后台监听和获取数据等操作。
接下来就用电话监听来谈谈服务。
2)
定义一个类实现Service,并在清单文件中配置,这样一个服务类就建立。在服务类下,先了解几个方法:
onCreate,服务创建就会调用,onDestroy,服务销毁会调用。
在activity类中开启服务:
1 /** 2 * 指定开启的服务的名称。 3 * 开启服务 4 */ 5 Intent intent=new Intent(this,PhoneService.class); 6 startService(intent);
当开启服务后,就会去调用onCreate方法,我们就可以在该方法中获取到电话的状态。
要获取电话状态的变化,就需要管理电话的服务,那么如何获取管理电话的服务,这里要通过电话管理器。
TelephonyManager tm=(TelephonyManager) getSystemService(TELEPHONY_SERVICE); tm.listen(new MyListener(), PhoneStateListener.LISTEN_CALL_STATE);
第一行代码表示:获取到管理电话服务的电话管理器。
第二行代码表示当电话状态改变时(PhoneStateListener.LISTEN_CALL_STATE),会回调MyListener中的方法。
而MyListener继承自PhoneStateListener。当通话状态发生变化时,就会调用MyListener中的方法,附上MyListener代码:
1 private class MyListener extends PhoneStateListener{ 2 /** 3 * 定义一个收音机 4 */ 5 private MediaRecorder recorder; 6 /** 7 * 手机的通话状态发生变化时,会去调用 8 */ 9 @Override 10 /** 11 * state:电话状态 12 * incomingNumber:来电的电话 13 */ 14 public void onCallStateChanged(int state, String incomingNumber) { 15 try { 16 switch(state){ 17 case TelephonyManager.CALL_STATE_IDLE://通话空闲的状态 18 //结束录音操作,录制的音频文件上传到服务器 19 if(recorder!=null){ 20 recorder.stop(); 21 recorder.reset(); 22 recorder.release(); 23 } 24 break; 25 case TelephonyManager.CALL_STATE_RINGING://响铃的状态 26 System.out.println("发现来电号码:"+incomingNumber); 27 recorder = new MediaRecorder(); 28 /** 29 * 设置录制的音频源MIC:表示从话筒中获取声音。标准的手机操作系统是不支持录音的。国产的山寨机可以录制。 30 */ 31 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 32 /** 33 * OutputFormat:文件格式。THREE_GPP:3gp的格式 34 */ 35 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 36 /** 37 * AudioEncoder:声音编码的方式 38 */ 39 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 40 /** 41 * 录制的声音写到哪里,参数为文件的路径。这里写到sd卡中,当然也可以上传到服务器上。 42 */ 43 recorder.setOutputFile("/sdcard"+System.currentTimeMillis()+".3gp"); 44 /** 45 * 通知录音机准备开始录制 46 */ 47 recorder.prepare(); 48 /** 49 * 开始录制 50 */ 51 recorder.start(); 52 break; 53 case TelephonyManager.CALL_STATE_OFFHOOK://通话状态 54 /** 55 * 当手机接到电话时,HOME键,后退键,菜单键都是没效的。 56 * 只有接通或挂断,才会生效。 57 */ 58 if(recorder!=null){ 59 recorder.start(); 60 } 61 break; 62 default: 63 break; 64 } 65 } catch (Exception e) { 66 e.printStackTrace(); 67 } 68 super.onCallStateChanged(state, incomingNumber); 69 } 70 }
通过以上,就可以实现电话窃听。