广播

  • 广播的概念

    • 现实:电台通过发送广播发布消息,买个收音机,就能收听
    • Android:系统在产生某个事件时发送广播,应用程序使用广播接收者接收这个广播,就知道系统产生了什么事件。
      Android系统在运行的过程中,会产生很多事件,比如开机、电量改变、收发短信、拨打电话、屏幕解锁

IP拨号器

原理:接收拨打电话的广播,修改广播内携带的电话号码

  • 定义广播接收者接收打电话广播

    public class CallReceiver extends BroadcastReceiver {

      //当广播接收者接收到广播时,此方法会调用@Overridepublic void onReceive(Context context, Intent intent) {//拿到用户拨打的号码String number = getResultData();//修改广播内的号码setResultData("17951" + number);}
    

    }

  • 在清单文件中定义该广播接收者接收的广播类型

      <receiver android:name="com.itheima.ipdialer.CallReceiver"><intent-filter ><action android:name="android.intent.action.NEW_OUTGOING_CALL"/></intent-filter></receiver>
    
  • 接收打电话广播需要权限

      <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
    
  • 即使广播接收者的进程没有启动,当系统发送的广播可以被该接收者接收时,系统会自动启动该接收者所在的进程


短信拦截器

系统收到短信时会产生一条广播,广播中包含了短信的号码和内容

  • 定义广播接收者接收短信广播

      public void onReceive(Context context, Intent intent) {//拿到广播里携带的短信内容Bundle bundle = intent.getExtras();Object[] objects = (Object[]) bundle.get("pdus");for(Object ob : objects ){//通过object对象创建一个短信对象SmsMessage sms = SmsMessage.createFromPdu((byte[])ob);System.out.println(sms.getMessageBody());System.out.println(sms.getOriginatingAddress());}
    

    }

  • 系统创建广播时,把短信存放到一个数组,然后把数据以pdus为key存入bundle,再把bundle存入intent

  • 清单文件中配置广播接收者接收的广播类型,注意要设置优先级属性,要保证优先级高于短信应用,才可以实现拦截

      <receiver android:name="com.itheima.smslistener.SmsReceiver"><intent-filter android:priority="1000"><action android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter></receiver>
    
  • 添加权限

      <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    
  • 4.0以后广播接收者安装以后必须手动启动一次,否则不生效

  • 4.0以后广播接收者如果被手动关闭,就不会再启动了


监听SD卡状态

  • 清单文件中定义广播接收者接收的类型,监听SD卡常见的三种状态,所以广播接收者需要接收三种广播

       <receiver android:name="com.itheima.sdcradlistener.SDCardReceiver"><intent-filter ><action android:name="android.intent.action.MEDIA_MOUNTED"/><action android:name="android.intent.action.MEDIA_UNMOUNTED"/><action android:name="android.intent.action.MEDIA_REMOVED"/><data android:scheme="file"/></intent-filter></receiver>
    
  • 广播接收者的定义

      public class SDCardReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 区分接收到的是哪个广播String action = intent.getAction();if(action.equals("android.intent.action.MEDIA_MOUNTED")){System.out.println("sd卡就绪");}else if(action.equals("android.intent.action.MEDIA_UNMOUNTED")){System.out.println("sd卡被移除");}else if(action.equals("android.intent.action.MEDIA_REMOVED")){System.out.println("sd卡被拔出");}}}
    

勒索软件

  • 接收开机广播,在广播接收者中启动勒索的Activity

  • 清单文件中配置接收开机广播

      <receiver android:name="com.itheima.lesuo.BootReceiver"><intent-filter ><action android:name="android.intent.action.BOOT_COMPLETED"/></intent-filter></receiver>
    
  • 权限

      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    
  • 定义广播接收者

      @Overridepublic void onReceive(Context context, Intent intent) {//开机的时候就启动勒索软件Intent it = new Intent(context, MainActivity.class);        context.startActivity(it);}
    
  • 以上代码还不能启动MainActivity,因为广播接收者的启动,并不会创建任务栈,那么没有任务栈,就无法启动activity

  • 手动设置创建新任务栈的flag

      it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    

监听应用的安装、卸载、更新

原理:应用在安装卸载更新时,系统会发送广播,广播里会携带应用的包名

  • 清单文件定义广播接收者接收的类型,因为要监听应用的三个动作,所以需要接收三种广播

      <receiver android:name="com.itheima.app.AppReceiver"><intent-filter ><action android:name="android.intent.action.PACKAGE_ADDED"/><action android:name="android.intent.action.PACKAGE_REPLACED"/><action android:name="android.intent.action.PACKAGE_REMOVED"/><data android:scheme="package"/></intent-filter></receiver>
    
  • 广播接收者的定义

      public void onReceive(Context context, Intent intent) {//区分接收到的是哪种广播String action = intent.getAction();//获取广播中包含的应用包名Uri uri = intent.getData();if(action.equals("android.intent.action.PACKAGE_ADDED")){System.out.println(uri + "被安装了");}else if(action.equals("android.intent.action.PACKAGE_REPLACED")){System.out.println(uri + "被更新了");}else if(action.equals("android.intent.action.PACKAGE_REMOVED")){System.out.println(uri + "被卸载了");}}
    

广播的两种类型

  • 无序广播:所有跟广播的intent匹配的广播接收者都可以收到该广播,并且是没有先后顺序(同时收到)
  • 有序广播:所有跟广播的intent匹配的广播接收者都可以收到该广播,但是会按照广播接收者的优先级来决定接收的先后顺序
    • 优先级的定义:-1000~1000
    • 最终接收者:所有广播接收者都接收到广播之后,它才接收,并且一定会接收
    • abortBroadCast:阻止其他接收者接收这条广播,类似拦截,只有有序广播可以被拦截

#Service

  • 就是默默运行在后台的组件,可以理解为是没有前台的activity,适合用来运行不需要前台界面的代码
  • 服务可以被手动关闭,不会重启,但是如果被自动关闭,内存充足就会重启
  • startService启动服务的生命周期
    • onCreate-onStartCommand-onDestroy
  • 重复的调用startService会导致onStartCommand被重复调用

进程优先级

  1. 前台进程:拥有前台activity(onResume方法被调用)
  2. 可见进程:拥有可见activity(onPause方法被调用)
  3. 服务进程:不到万不得已不会被回收,而且即便被回收,内存充足时也会被重启
  4. 后台进程:拥有后台activity(activity的onStop方法被调用了),很容易被回收
  5. 空进程:没有运行任何activity,很容易被回收

电话窃听器

  • 电话状态:空闲、响铃、接听

  • 获取电话管理器,设置侦听

      TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
    
  • 侦听对象的实现

      class MyPhoneStateListener extends PhoneStateListener{//当电话状态改变时,此方法调用@Overridepublic void onCallStateChanged(int state, String incomingNumber) {// TODO Auto-generated method stubsuper.onCallStateChanged(state, incomingNumber);switch (state) {case TelephonyManager.CALL_STATE_IDLE://空闲if(recorder != null){recorder.stop();recorder.release();}break;case TelephonyManager.CALL_STATE_OFFHOOK://摘机if(recorder != null){recorder.start();}break;case TelephonyManager.CALL_STATE_RINGING://响铃recorder = new MediaRecorder();//设置声音来源recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置音频文件格式recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);recorder.setOutputFile("sdcard/haha.3gp");//设置音频文件编码recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);try {recorder.prepare();} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}break;}}}
    

服务两种启动方式

  • startService:服务被启动之后,跟启动它的组件没有一毛钱关系
  • bindService:跟启动它的组件同生共死
  • 绑定服务和解绑服务的生命周期方法:onCreate->onBind->onUnbind->onDestroy

找领导办证

  • 把服务看成一个领导,服务中有一个banZheng方法,如何才能访问?

  • 绑定服务时,会触发服务的onBind方法,此方法会返回一个Ibinder的对象给MainActivity,通过这个对象访问服务中的方法

  • 绑定服务

      Intent intent = new Intent(this, BanZhengService.class);bindService(intent, conn, BIND_AUTO_CREATE);
    
  • 绑定服务时要求传入一个ServiceConnection实现类的对象

  • 定义这个实现类

      class MyServiceconn implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {zjr = (PublicBusiness) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {  }
    

    }

  • 创建实现类对象

       conn = new MyServiceconn();
    
  • 在服务中定义一个类实现Ibinder接口,以在onBind方法中返回

      class ZhongJianRen extends Binder implements PublicBusiness{public void QianXian(){//访问服务中的banZheng方法BanZheng();} public void daMaJiang(){}
    

    }

  • 把QianXian方法抽取到接口PublicBusiness中定义


两种启动方法混合使用

  • 用服务实现音乐播放时,因为音乐播放必须运行在服务进程中,可是音乐服务中的方法,需要被前台Activity所调用,所以需要混合启动音乐服务
  • 先start,再bind,销毁时先unbind,在stop

使用服务注册广播接收者

  • Android四大组件都要在清单文件中注册

  • 广播接收者比较特殊,既可以在清单文件中注册,也可以直接使用代码注册

  • 有的广播接收者,必须代码注册

    • 电量改变
    • 屏幕锁屏和解锁
  • 注册广播接收者

      //创建广播接收者对象receiver = new ScreenOnOffReceiver();//通过IntentFilter对象指定广播接收者接收什么类型的广播IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_SCREEN_OFF);filter.addAction(Intent.ACTION_SCREEN_ON);//注册广播接收者registerReceiver(receiver, filter);
    
  • 解除注册广播接收者

      unregisterReceiver(receiver);
    
  • 解除注册之后,广播接收者将失去作用

本地服务:服务和启动它的组件在同一个进程

远程服务:服务和启动它的组件不在同一个进程

  • 远程服务只能隐式启动,类似隐式启动Activity,在清单文件中配置Service标签时,必须配置intent-filter子节点,并指定action子节点

AIDL

  • Android interface definition language
  • 安卓接口定义语言
  • 作用:跨进程通信
  • 应用场景:远程服务中的中间人对象,其他应用是拿不到的,那么在通过绑定服务获取中间人对象时,就无法强制转换,使用aidl,就可以在其他应用中拿到中间人类所实现的接口

支付宝远程服务

  1. 定义支付宝的服务,在服务中定义pay方法
  2. 定义中间人对象,把pay方法抽取成接口
  3. 把抽取出来的接口后缀名改成aidl
  4. 中间人对象直接继承Stub对象
  5. 注册这个支付宝服务,定义它的intent-Filter

需要支付的应用

  1. 把刚才定义好的aidl文件拷贝过来,注意aidl文件所在的包名必须跟原包名一致
  2. 远程绑定支付宝的服务,通过onServiceConnected方法我们可以拿到中间人对象
  3. 把中间人对象通过Stub.asInterface方法强转成定义了pay方法的接口
  4. 调用中间人的pay方法

五种前台进程

  1. activity执行了onresume方法,获得焦点
  2. 拥有一个跟正在与用户交互的activity绑定的服务
  3. 拥有一个服务执行了startForeground()方法
  4. 拥有一个正在执行onCreate()、onStart()或者onDestroy()方法中的任意一个的服务
  5. 拥有一个正在执行onReceive方法的广播接收者

两种可见进程

  1. activity执行了onPause方法,失去焦点,但是可见
  2. 拥有一个跟可见或前台activity绑定的服务

Android入门笔记08相关推荐

  1. Android入门笔记之更改手机屏幕方向

    Android入门笔记之更改手机屏幕方向 <1>简介 通过一个按钮组来改变横屏竖屏显示. <2>关键步骤 主要通过android.app.activity.getRequest ...

  2. ESP32 入门笔记08:1.54寸(240*240)彩色TFT 显示高清IPS LCD 屏幕 SPI接口

    目录 1.屏幕规格 2.原理图 3.程序实现 3.1引脚定义 3.2Adafruit_GFX / Arduino_ST7789版 3.3TFT_eSPI库版 3.3.1配置TFT_eSPI a.选择屏 ...

  3. Android Studio 基础入门笔记

    Android Studio 基础入门笔记 Android Studio 基础入门笔记 为什么选择使用 Android Studio 而不是EclipseADT 安卓配置JDK AS如何更新 常规的 ...

  4. Android 插件化原理入门笔记

    Android开发笔记 onGithub 笔记,参考7.2中所列参考文章所写,DEMO地址在PluginTestDemoApplication 1.综述 2015年是Android插件化技术突飞猛进的 ...

  5. Android入门自学笔记

    Android入门 前几个月要去作物联网项目,花了一个月入门android本文写于物联网大赛后 Android入门所需书籍 <android第一行代码>-----入门必看书.这本书实例和理 ...

  6. MyBatis-学习笔记08【08.动态SQL】

    Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...

  7. ROS入门笔记(七):详解ROS文件系统

    ROS入门笔记(七):详解ROS文件系统 文章目录 01 Catkin编译系统 1.1 Catkin特点 1.2 Catkin工作原理 1.3 使用`catkin_make`进行编译 02 Catki ...

  8. go web框架_golang微服务框架go-micro 入门笔记2.2 micro工具之微应用利器micro web

    micro web micro 功能非常强大,本文将详细阐述micro web 命令行的功能 阅读本文前你可能需要进行如下知识储备 golang分布式微服务框架go-micro 入门笔记1:搭建go- ...

  9. Android开发笔记(序)写在前面的目录

    知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入 ...

  10. Android开发笔记(一百一十六)网络学习资源

    知名网站 本系列的开发笔记,对Android开发来说只是沧海一瓢,还有更多的技术等待我们去汲取.下面列出几个常用的开发网站,供初学者上路: 首先当然是国内首屈一指的技术网站csdn啦,csdn提供了众 ...

最新文章

  1. ​kdevelop用法_weixin_44594953的博客-CSDN博客_kdevelop​
  2. 科大星云诗社动态20210217
  3. 记录下UIButton的图文妙用和子控件的优先显示
  4. [COGS58] 延绵的山峰
  5. 20140625 程序 进程 线程 物理存储器
  6. c++ 每半个小时打印一次_有了3D打印机,后期该如何维护呢
  7. Promise机制(持续更新中)
  8. 温故而知新:查看端口占用情况以及DOS中的管道操作/重定向操作
  9. XP照片缩略图和照片本身显示不一致,如何解决防范?
  10. 15.3 实时时钟芯片DS1302介绍
  11. java 追加文件换行_java 追加换行txt
  12. typora主题配置:公众号一键排版
  13. meanshift算法通俗讲解
  14. D. Lizard Era: Beginning
  15. 海康威视监控下载下来的mp4格式的视频,小类别MPEG-PS格式,这种格式在浏览器中没法播放,跪求播放方法。
  16. mysql子查询返回多于1行_mysql – 子查询返回超过1行
  17. 3.识别AP版本与胖转瘦
  18. Python:python镜像源汇总及使用
  19. 我的一加5刷机基本步骤
  20. vs code 不能正确补全结构体成员变量的解决方法

热门文章

  1. 数据bag中的激光雷达数据和相机数据分割出来
  2. Advances in adversarial attacks and defenses in computer vision: A survey论文解读
  3. FM、LFM、AFM、NFM、DeepFM、 Deep Cross Network
  4. Storm目录树、任务提交、消息容错、通信机制
  5. C#的GC机制(来自网摘复制,未整理)
  6. 字符串输入控制:与空格、回车的输入相关的几种函数
  7. 了解:shell脚本+脚本优化+脚本注入+正则表达式
  8. 开源大数据周刊-第74期
  9. 资金流学习 - 关注点
  10. 编程十年 (3):初识计算机