当前位置:   article > 正文

android基础之四——广播与服务(一)_(1)实现发送有序广播,根据广播接收者的优先级高低依次接收广播消息; (2)使用广

(1)实现发送有序广播,根据广播接收者的优先级高低依次接收广播消息; (2)使用广

01_为什么需要广播接受者

  1. 1、电台:中央人民广播电台 93.4mhz;
  2. 2、收音机:买一个收音机,插上电池,调整到一个频道,接收广播;
  3. Android系统中内置了广播电台(系统自带的广播功能),会广播出来一些事件(电量不足、电量
  4. 充满、接收到短信、外拨电话、拨进来电话、SD状态、开机启动等),指定了接收者广播消息的客
  5. 户端软件(自己开发的应用程序)可以做一些对用户有用的事情。

02广播接受者案例ip拨号器(重点)

  1. 在拨打电话的时候,把IP电话自动的添加到目标电话号码的前面,让拨打IP电话:
  2. 1、监听到用户外拨电话的事件:
  3. 2、得到用户外拨的电话号码,然后把ip电话添加目标电话号码的前面:
  4. 3、让用户拨打已经修改后电话号码:
  5. 写广播接收者的步骤:
  6. 1、买一个收音机:
  7. public class OutCallBroadcastReceiver extends BroadcastReceiver {
  8. @Override
  9. public void onReceive(Context context, Intent intent) {
  10. }
  11. }
  12. 2、插上电池:
  13. <receiver android:name="com.itheima.ipcall.OutCallBroadcastReceiver">
  14. </receiver>
  15. 3、调整到一个频道:
  16. <receiver android:name="com.itheima.ipcall.OutCallBroadcastReceiver">
  17. <intent-filter >
  18. <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
  19. </intent-filter>
  20. </receiver>

代码:

  1. package com.itheima.ipcall;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.content.SharedPreferences;
  6. //1、监听到用户外拨电话的事件:
  7. public class OutCallBroadcastReceiver extends BroadcastReceiver {
  8. /**
  9. * 接收到广播消息后调用这个方法
  10. */
  11. @Override
  12. public void onReceive(Context context, Intent intent) {
  13. //2、得到用户外拨的电话号码,
  14. String phone = getResultData();
  15. SharedPreferences sp = context.getSharedPreferences("info", Context.MODE_PRIVATE);
  16. String ipPhone = sp.getString("ipPhone", "");
  17. //然后把ip电话添加目标电话号码的前面:
  18. phone = ipPhone + phone;
  19. // 3、让用户拨打已经修改后电话号码:
  20. setResultData(phone);
  21. }
  22. }

配置文件:

  1. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
  2. <receiver android:name="com.itheima.ipcall.OutCallBroadcastReceiver">
  3. <intent-filter >
  4. <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
  5. </intent-filter>
  6. </receiver>

03广播接受者案例短信监听器(重点)

  1. pdus:protocol data unit s 协议数据单元;
  2. 广播接收者的特点:
  3. 1、即使广播接收者没有运行,当广播消息到达的时候系统会自动的启懂广播接收者,调用onReceive方法处理
  4. 消息;
  5. 2、在android4.0版本之后的系统,强制要求带广播接收者的应用程序必须有界面,并且至少运行过一次。
  6. 3、在android4.0版本之后的系统,强制要求带广播接收者的应用程序被冻结后,就不能运行了,只能在手工
  7. 启动的时候才有效。

代码: package com.itheima.smslistener;

  1. import android.content.BroadcastReceiver;
  2. import android.content.Context;
  3. import android.content.Intent;
  4. import android.telephony.SmsMessage;
  5. public class SMSBroadcastReceiver extends BroadcastReceiver {
  6. @Override
  7. public void onReceive(Context context, Intent intent) {
  8. //得到短信数据
  9. Object[] objs = (Object[]) intent.getExtras().get("pdus");
  10. for(Object obj :objs){
  11. //obj是一条短信的byte数组
  12. SmsMessage sms = SmsMessage.createFromPdu((byte[])obj);
  13. //得到短信内容
  14. String content = sms.getMessageBody();
  15. //得到发送短信的电话号码
  16. String phone = sms.getOriginatingAddress();
  17. System.out.println("content==="+content);
  18. System.out.println("phone==="+phone);
  19. }
  20. }
  21. }

配置文件:

  1. <uses-permission android:name="android.permission.RECEIVE_SMS"/>
  2. <receiver android:name="com.itheima.smslistener.SMSBroadcastReceiver">
  3. <intent-filter>
  4. <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
  5. </intent-filter>
  6. </receiver>

04广播接受者案例sd卡状态监听(重点)

测试的时使用4.0之前的模拟器或者真机,因为4.0之后的版本上已经去调用SD插拔、移除的功能;

代码:

  1. package com.itheima.sdlistener;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.widget.Toast;
  6. public class SDBroadcastReceiver extends BroadcastReceiver {
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. String action = intent.getAction();
  10. if(action.equals("android.intent.action.MEDIA_MOUNTED")){
  11. Toast.makeText(context, "SD卡已经插上", 0).show();
  12. }
  13. if(action.equals("android.intent.action.MEDIA_UNMOUNTED")){
  14. Toast.makeText(context, "SD卡已经被拔掉", 0).show();
  15. }
  16. if(action.equals("android.intent.action.MEDIA_REMOVED")){
  17. Toast.makeText(context, "SD卡已经被移除", 0).show();
  18. }
  19. }
  20. }

配置文件:

  1. <receiver android:name="com.itheima.sdlistener.SDBroadcastReceiver">
  2. <intent-filter >
  3. <action android:name="android.intent.action.MEDIA_MOUNTED"/>
  4. <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
  5. <action android:name="android.intent.action.MEDIA_REMOVED"/>
  6. <!-- 必须加上这个数据 -->
  7. <data android:scheme="file" />
  8. </intent-filter>
  9. </receiver>

05广播接受者案例开机启动(重点)

  1. 1、让界面没法关闭,没法最小化;
  2. 2、如果支付成功,关闭当前界面;

代码:

MainActivity.java:

  1. package com.itheima.bootlistener;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.widget.Toast;
  6. public class MainActivity extends Activity {
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. }
  12. public void pay(View view) {
  13. Toast.makeText(this, "已经支付了100元", 0).show();
  14. // 支付完成后关闭当前界面
  15. finish();
  16. }
  17. @Override
  18. public void onBackPressed() {
  19. // 按返回键不执行任何操作
  20. }
  21. }

BootCompletedBroadcastReceiver.java:

  1. package com.itheima.bootlistener;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.sax.StartElementListener;
  6. public class BootCompletedBroadcastReceiver extends BroadcastReceiver {
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. Intent i = new Intent(context,MainActivity.class);
  10. //告诉Activity使用自己的任务栈来维护界面
  11. i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  12. context.startActivity(i);
  13. }
  14. }

配置文件:

  1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. <receiver android:name="com.itheima.bootlistener.BootCompletedBroadcastReceiver">
  3. <intent-filter >
  4. <action android:name="android.intent.action.BOOT_COMPLETED"/>
  5. </intent-filter>
  6. </receiver>

06广播接受者案例卸载安装(重点)

代码:

  1. package com.itheima.azxzlistener;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.widget.Toast;
  6. public class AZXZBroadcastReceiver extends BroadcastReceiver {
  7. @Override
  8. public void onReceive(Context context, Intent intent) {
  9. String action = intent.getAction();
  10. if("android.intent.action.PACKAGE_INSTALL".equals(action)){
  11. Toast.makeText(context, "有一个新软件安装了......", 0).show();
  12. }
  13. if("android.intent.action.PACKAGE_REPLACED".equals(action)){
  14. Toast.makeText(context, "有一个软件升级了......", 0).show();
  15. }
  16. if("android.intent.action.PACKAGE_REMOVED".equals(action)){
  17. Toast.makeText(context, "有一个软件被卸载了......", 0).show();
  18. }
  19. }
  20. }

配置文件:

  1. <receiver android:name="com.itheima.azxzlistener.AZXZBroadcastReceiver">
  2. <intent-filter >
  3. <action android:name="android.intent.action.PACKAGE_INSTALL"/>
  4. <action android:name="android.intent.action.PACKAGE_REMOVED"/>
  5. <action android:name="android.intent.action.PACKAGE_REPLACED"/>
  6. <!-- 必须添加这个属性 -->
  7. <data android:scheme="package"/>
  8. </intent-filter>
  9. </receiver>

07_发送自定义广播

  1. 自定义广播的代码:
  2. Intent intent = new Intent();
  3. //设置广播的事件类型
  4. intent.setAction("com.itheima.broadcast.FSZDYGB");
  5. //设置广播传递的数据
  6. intent.putExtra("info", "自定义的广播消息");
  7. //发送广播消息
  8. sendBroadcast(intent);

08_有序广播和无序广播(重点)

  1. 有序广播:当广播消息发送出去之后,可以根据广播接收者的优先级的高低,从高到低一级一级的传递消息;
  2. 无序广播:当广播消息发送出去之后,只要是指定了广播事件类型的广播接收者都可以接受到这个消息;

发送有序的广播:

  • 自定义的有序广播:

    package com.itheima.broadcast;

    import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View;

    public class MainActivity extends Activity {

    1. @Override
    2. protected void onCreate(Bundle savedInstanceState) {
    3. super.onCreate(savedInstanceState);
    4. setContentView(R.layout.activity_main);
    5. }
    6. public void send(View view ){
    7. Intent intent = new Intent();
    8. // 设置广播的事件类型
    9. intent.setAction("com.itheima.broadcast.GWYFFNTBT");
    10. // 发送有序广播消息
    11. // 发送广播的意图对象
    12. // receiverPermission 指定广播接收者的权限,只有指定了这个权限的广播接收者才能接收到这个广播消息
    13. //resultReceiver 指定哪个广播接收者最后接收到广播消息
    14. //scheduler 消息处理器
    15. //initCode初始码
    16. //initData 初始数据
    17. //extraData 传递的额外参数
    18. sendOrderedBroadcast(intent, null, new ResultBroadcastReceiver(),
    19. null, 1, "发送2014年农田补贴,每亩地补贴900元", null);
    20. }

    }

  • 自定义的广播:

    代码:

    1. package com.itheima.gov;
    2. import android.content.BroadcastReceiver;
    3. import android.content.Context;
    4. import android.content.Intent;
    5. public class TownBroadcastReceiver extends BroadcastReceiver {
    6. @Override
    7. public void onReceive(Context context, Intent intent) {
    8. //得到广播的初始数据
    9. String data = getResultData();
    10. System.out.println("我是乡级人民政府,接收到国务院发送的消息:"+data);
    11. data = "发送2014年农田补贴,每亩地补贴168元";
    12. //修改广播传递的数据
    13. setResultData(data);
    14. }
    15. }

配置文件:

  1. <receiver android:name="com.itheima.gov.ProvinceBroadcastReceiver">
  2. <intent-filter android:priority="1000">
  3. <action android:name="com.itheima.broadcast.GWYFFNTBT"/>
  4. </intent-filter>
  5. </receiver>

09_服务和进程优先级

  1. windows下的服务:没有界面,可以长期运行在后台的应用程序;
  2. Android下的服务:没有界面,可以长期运行在后台的应用程序(没有界面的activity);
  3. 进程:是运行应用程序的载体。当应用程序一启动的时候,系统自动创建一个进程,负责运行dalvik虚拟机,我们开发的应用程序试运行在dalvik虚拟机上的。
  4. Activity、BroadcastReceiver、Service、ContentProvider;
  5. 应用程序:四大组件放在一起就是一个应用程序;

解决方案:给创建的每个进程定义一个类型和优先级;

进程的生命周期: 1、当应用程序已启动的时候,进程被创建; 2、当手工结束进程,或者强制停止应用程序可以结束进程、系统内存空间不够使用,系统会自动杀死低优先级的进程;

进程的等级:

  1. Foreground process(前台进程)

    应用程序界面可见,用户正在操作,activity的onresume方法被执行了,可以相应点击事件。
    
  2. Visible process (可视进程)

    应用程序的ui界面,用户还可以看到,但是不能操作了。
    
  3. Service process (服务进程)

    应用程序没有界面,但是有一个后台的服务还处于运行状态
    
  4. Background process(后台进程)

    应用程序没有服务处于运行状态,应用程序被最小化了,activity执行了onstop方法
    
  5. Empty process (空进程)

    没有任何组件运行,所有的activity都关闭了,任务栈清空了。
    

10_服务的特点

  1. 特点:
  2. 1、服务第一次被开启的时候,系统创建一个服务对象,调用onCreate、onStartCommand;
  3. 2、服务职能被创建一次,可以被开启多次,多次开启只会调用onStartCommand;
  4. 3、停止服务调用onDestroy方法,服务只能被停止一次;
  5. 4、服务没有界面,可以长期运行在后台;
  6. 服务的应用场景:
  7. 当需要在后台运行一段程序,程序需要与服务器端通讯;

11_电话窃听器的模板代码(重点)

  1. 在后台运行一段程序,监听电话的状态,当电话铃声响起的时候,创建一个录音机;当电话接通的时候,使用录音机开始录音;当电话挂断的时候,录音机停止录音,上传录制的音频文件;
  2. 实现步骤:
  3. 1、写一个服务运行在后台;
  4. 2、在服务里写一个电话的监听器;
  5. 3、当电话铃声响起的时候,准备一个录音机;
  6. 4、当电话接通的时候,使用录音机开始录音;
  7. 5、当电话挂断的时候,录音机停止录音,上传录制的音频文件;

代码:

  1. package com.itheima.phonelistener;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.IBinder;
  5. import android.telephony.PhoneStateListener;
  6. import android.telephony.TelephonyManager;
  7. /**
  8. * 1、写一个服务运行在后台;
  9. */
  10. public class PhoneStateListenerService extends Service {
  11. @Override
  12. public IBinder onBind(Intent intent) {
  13. // TODO Auto-generated method stub
  14. return null;
  15. }
  16. @Override
  17. public void onCreate() {
  18. super.onCreate();
  19. //2、在服务里写一个电话的监听器;
  20. //得到系统提供的电话服务
  21. TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
  22. //监听电话的呼叫状态
  23. tm.listen(new MyListener(), PhoneStateListener.LISTEN_CALL_STATE);
  24. }
  25. private class MyListener extends PhoneStateListener{
  26. /**
  27. * 当电话状态发生变化时调用这个方法
  28. * state 电话状态:闲置、铃声响起、接通电话
  29. * incomingNumber 呼入的电话号码
  30. */
  31. @Override
  32. public void onCallStateChanged(int state, String incomingNumber) {
  33. super.onCallStateChanged(state, incomingNumber);
  34. switch (state) {
  35. case TelephonyManager.CALL_STATE_IDLE://闲置
  36. //5、当电话挂断的时候,录音机停止录音,上传录制的音频文件;
  37. break;
  38. case TelephonyManager.CALL_STATE_RINGING://铃声响起
  39. //3、当电话铃声响起的时候,准备一个录音机;
  40. break;
  41. case TelephonyManager.CALL_STATE_OFFHOOK://接通电话
  42. //4、当电话接通的时候,使用录音机开始录音;
  43. break;
  44. default:
  45. break;
  46. }
  47. }
  48. }

}

12_利用服务实现电话窃听器

  1. 代码:
  2. package com.itheima.phonelistener;
  3. import java.io.IOException;
  4. import android.app.Service;
  5. import android.content.Intent;
  6. import android.media.MediaRecorder;
  7. import android.os.Environment;
  8. import android.os.IBinder;
  9. import android.telephony.PhoneStateListener;
  10. import android.telephony.TelephonyManager;
  11. /**
  12. * 1、写一个服务运行在后台;
  13. */
  14. public class PhoneStateListenerService extends Service {
  15. private MediaRecorder r;
  16. @Override
  17. public IBinder onBind(Intent intent) {
  18. // TODO Auto-generated method stub
  19. return null;
  20. }
  21. @Override
  22. public void onCreate() {
  23. super.onCreate();
  24. //2、在服务里写一个电话的监听器;
  25. //得到系统提供的电话服务
  26. TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
  27. //监听电话的呼叫状态
  28. tm.listen(new MyListener(), PhoneStateListener.LISTEN_CALL_STATE);
  29. }
  30. private class MyListener extends PhoneStateListener{
  31. /**
  32. * 当电话状态发生变化时调用这个方法
  33. * state 电话状态:闲置、铃声响起、接通电话
  34. * incomingNumber 呼入的电话号码
  35. */
  36. @Override
  37. public void onCallStateChanged(int state, String incomingNumber) {
  38. super.onCallStateChanged(state, incomingNumber);
  39. switch (state) {
  40. case TelephonyManager.CALL_STATE_IDLE://闲置
  41. System.out.println("==========CALL_STATE_IDLE=========");
  42. //5、当电话挂断的时候,录音机停止录音,上传录制的音频文件;
  43. if(r != null){
  44. r.stop();
  45. r.release();
  46. r = null;
  47. }
  48. break;
  49. case TelephonyManager.CALL_STATE_RINGING://铃声响起
  50. try {
  51. System.out.println("==========CALL_STATE_RINGING=========");
  52. r = new MediaRecorder();
  53. r.setAudioSource(MediaRecorder.AudioSource.MIC);
  54. r.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
  55. r.setOutputFile(Environment.getExternalStorageDirectory()+"/info.3gp");
  56. r.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  57. //准备录音机
  58. r.prepare();
  59. } catch (Exception e) {
  60. e.printStackTrace();
  61. }
  62. break;
  63. case TelephonyManager.CALL_STATE_OFFHOOK://接通电话
  64. //4、当电话接通的时候,使用录音机开始录音;
  65. System.out.println("==========CALL_STATE_OFFHOOK=========");
  66. r.start();
  67. break;
  68. }
  69. }
  70. }
  71. }

配置文件:

  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  2. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  3. <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  4. <service android:name="com.itheima.phonelistener.PhoneStateListenerService"></service>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/902075
推荐阅读
相关标签
  

闽ICP备14008679号