Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听
Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听
Android中四大组件的使用时重中之重,我这个阶段也不奢望能把他所有的原理搞懂,但是最起码的,我要把他的各种使用方法了如指掌才行
BroadcastReceiver
接收系统的广播,比如电话,短信之类的
1.IP拨号器
我们在拨打电话的时候,我们系统也会事先发送一个广播,所以我们可以用广播接收者来接收到这个广播拨打电话的时候在电话号码前面加上一些优惠的长途短号,其逻辑就是入门使用广播的一个小案例,那我们新建一个IPCall项目
我们拨打电话的时候系统发一个广播,我们接受到这个广播拿到号码修改之后再放回去,就达到了我们IP拨号的目的,我们需要新建一个Receiver
CallReceiver
package com.lgl.ipcall;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* 电话广播
* Created by lgl on 16/4/10.
*/
public class CallReceiver extends BroadcastReceiver {
//接收到广播时调用
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CallReceiver", "打电话");
}
}
这个类暂时不需要做什么。最重要的还是注册,作为四大组建,他是需要在清单文件里注册的
<!--注册广播-->
<receiver android:name=".CallReceiver">
<intent-filter>
<!--定义接收的广播-->
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
别忘了,你监听了用户的隐私,是需要权限的
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
我们先运行一下,打个电话
好的,广播我们已经抓住了,那我们可以首先获取打出去的号码
String iphone = getResultData();
Log.i("CallReceiver", "电话号码:"+iphone);
这样我们就可以拿到String类型的电话号码了
我们现在可以修改号码重新设置IP段了
//添加IP段
String newPhone = "+86" + iphone;
//把修改后的号码放回去
setResultData(newPhone);
这样我们每次打电话他都会自动帮我们添加一个字段了
完整代码
package com.lgl.ipcall;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* 电话广播
* Created by lgl on 16/4/10.
*/
public class CallReceiver extends BroadcastReceiver {
//接收到广播时调用
@Override
public void onReceive(Context context, Intent intent) {
Log.i("CallReceiver", "打电话");
String iphone = getResultData();
Log.i("CallReceiver", "电话号码:" + iphone);
//添加IP段
String newPhone = "+86" + iphone;
//把修改后的号码放回去
setResultData(newPhone);
}
}
2.短信拦截器
系统受到了一条短信后,也是会发一条广播的,所有我们可以在中间写一个广播接受者去进行我们的操作,这里,我们继续在IP拨号器这个项目中写吧,就不新建项目了,不然等下上传也麻烦
我们新建一个Class——SMSReceiver,重写他的onReceive方法,然后我们先注册
<!--注册广播-->
<receiver android:name=".SMSReceiver">
<intent-filter>
<!--定义接收的广播,被Google隐藏的权限操作-->
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
切記,权限
<uses-permission android:name="android.permission.RECEIVE_SMS" />
SMSReceiver
package com.lgl.ipcall;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
/**
* 短信拦截器
* Created by lgl on 16/4/10.
*/
public class SMSReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("收到短信");
//获取短信内容
Bundle bundle = intent.getExtras();
//返回的是一个Object数组
Object[] objects = (Object[]) bundle.get("pdus");
//遍历数组得到短信内容
for (Object object : objects) {
//把数组元素转换成短信对象
SmsMessage sms = SmsMessage.createFromPdu((byte[]) object);
//获取发件人号码
String toPhone = sms.getOriginatingAddress();
//获取短信内容
String smsContent = sms.getMessageBody();
Log.i("SMSReceiver", "发件人号码:" + toPhone + "短信内容" + smsContent);
//判断是否是拦截的号码
if (toPhone.equals("12345678910")) {
//拦截广播
abortBroadcast();
}
}
}
}
这样我们运行之下,你会发现,虽然走到拦截这一步,但是并没有阻止显示在短信收件箱里,这里,我们要注意一个优势,就是广播接收者是有优先级定义的,我们只需要在清单注册根节点的intent-filter标签里定义一个
android:priority="1000"
官方文档是说数值在-1000到1000之间,但是最高支持int的最大值的权限,int最大值是多少?自己去看API
3.监听SD卡
我们在对SD卡进行读写的时候会用到,其实也就是巩固一下对广播的使用,做那种语音助手之类的辅助软件,广播和服务还是很有用的,我们还是定义一个SDReceiver并且在清单文件注册
<!--注册广播-->
<receiver android:name=".SDReceiver">
<intent-filter>
<!--SD卡就绪广播-->
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<!--SD卡拔出广播-->
<action android:name="android.intent.action.MEDIA_REMOVED" />
<!--SD卡卸载广播-->
<action android:name="android.intent.action.MEDIA_UNMOUNTABLE" />
<data android:scheme="file"/>
</intent-filter>
</receiver>
我们现在可以监听了
SDReceiver
package com.lgl.ipcall;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* 监听SD卡
* Created by lgl on 16/4/10.
*/
public class SDReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//判断广播
String action = intent.getAction();
if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
Log.i("SDReceiver", "SD卡就绪");
} else if (action.equals(Intent.ACTION_MEDIA_REMOVED)) {
Log.i("SDReceiver", "SD卡拔出");
} else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTABLE)) {
Log.i("SDReceiver", "SD卡卸载");
}
}
}
4.流氓软件
我们监听到开机就启动这个软件,而且不让其退出,达到流氓的效果
先不让他退出,我们在MainActivity中
@Override
public void onBackPressed() {
//禁止返回键
// super.onBackPressed();
}
只要你一安装,就退出不了了,我们再设置一下开机启动,写一个监听器动的广播罢了,我们新建一个RebootReceiver,先注册吧
<!--注册广播-->
<receiver android:name=".RebootReceiver">
<intent-filter>
<!--定义接收的广播-->
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
这个也是需要权限的
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
RebootReceiver
package com.lgl.ipcall;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* 开机启动
* Created by lgl on 16/4/10.
*/
public class RebootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("RebootReceiver", "开机");
//启动
Intent i = new Intent(context, MainActivity.class);
//在Activity之外启动需要设置Flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
5.应用安装卸载监听
我们如果做手机助手或者应用的时候或许可以用得上这玩意,新建一个APPReceiver,然后去注册
<!--注册广播-->
<receiver android:name=".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>
然后我们来判断
package com.lgl.ipcall;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
/**
* Created by lgl on 16/4/10.
*/
public class APPReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//判断广播类型
String action = intent.getAction();
//获取包名
Uri appName = intent.getData();
if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
Log.i("APPReceiver", "安装" + appName);
} else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
Log.i("APPReceiver", "更新" + appName);
} else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
Log.i("APPReceiver", "卸载" + appName);
}
}
}
这样我们完全就可以监听状态了,我们以下载一个豌豆荚为例
6.自定义广播
这里,我们有特定需求的时候会用,我们先定义一个Button
<Button
android:id="@+id/btn_myreceiver"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送自定义广播" />
他的点击事件就是发送一个广播,我这里自定义一个广播名字liuguilin
case R.id.btn_myreceiver:
Intent i = new Intent();
i.setAction("liuguilin");
sendBroadcast(i);
break;
然后我们新建一个MyReceiver,注册
<receiver android:name=".MyReceiver">
<intent-filter>
<!--自定义广播-->
<action android:name="liuguilin" />
</intent-filter>
</receiver>
我们写个打印语句
7.有序广播和无序广播
这两种广播的区别
- 有序广播:接收这条广播是按优先级来的
- 无序广播:无条件直接接收
-1.发送有序广播
我们定义一个Button
<Button
android:id="@+id/btn_haveorder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送有序广播" />
然后发送一个广播
case R.id.btn_haveorder:
Intent intent = new Intent();
intent.setAction("com.lgl.good");
//有序广播并且携带数据
sendOrderedBroadcast(intent, null, null, null, 0, "自定义广播内容", null);
break;
这里我定义了三个广播,然后他们的优先级分辨是1000,600,300
<!--有序广播-->
<receiver android:name=".OrderReceiver">
<intent-filter android:priority="1000">
<action android:name="com.lgl.good"/>
</intent-filter>
</receiver>
<!--有序广播-->
<receiver android:name=".OrderReceiverTwo">
<intent-filter android:priority="600">
<action android:name="com.lgl.good"/>
</intent-filter>
</receiver>
<!--有序广播-->
<receiver android:name=".OrderReceiverThree">
<intent-filter android:priority="300">
<action android:name="com.lgl.good"/>
</intent-filter>
</receiver>
最后运行的结果
Demo下载:http://download.csdn.net/detail/qq_26787115/9486705
Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听的更多相关文章
- Android实训案例(五)——四大组件之一ContentProvider的使用,通讯录的实现以及ListView的优化
Android实训案例(五)--四大组件之一ContentProvider的使用,通讯录的实现 Android四大组件是啥这里就不用多说了,看图吧,他们之间通过intent通讯 我们后续也会一一的为大 ...
- Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局
Android实训案例(八)--单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局 阿法狗让围棋突然就被热议了,鸿洋大神也顺势出了篇五子棋单机游戏的视频,我看到了就像膜拜膜拜,就 ...
- Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!
Android实训案例(四)--关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程! 关于2048,我看到很多大神,比如医生,郭神,所以我也研究了一段时间,还好是研究 ...
- Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程
Android实训案例(九)--答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程 项目也是偷师的,决心研究一下数据库.所以写的还是很详细的,各位看官,耐着性子看完,实现结果不重要 ...
- Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!
Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...
- Android实训案例(二)——Android下的CMD命令之关机重启以及重启recovery
Android实训案例(二)--Android下的CMD命令之关机重启以及重启recovery Android刚兴起的时候,着实让一些小众软件火了一把,切水果,Tom猫,吹裙子就是其中的代表,当然还有 ...
- Android实训案例(一)——计算器的运算逻辑
Android实训案例(一)--计算器的运算逻辑 应一个朋友的邀请,叫我写一个计算器,开始觉得,就一个计算器嘛,很简单的,但是写着写着发现自己写出来的逻辑真不严谨,于是搜索了一下,看到mk(没有打广告 ...
- Android实训案例(七)——四大组件之一Service初步了解,实现通话录音功能,抽调接口
Service Service的神奇之处,在于他不需要界面,一切的操作都在后台操作,所以很多全局性(手机助手,语音助手)之类的应用很长需要这个,我们今天也来玩玩 我们新建一个工程--ServiceDe ...
- Android实训案例(七)——四大组件之中的一个Service初步了解,实现通话录音功能,抽调接口
Service Service的奇妙之处.在于他不须要界面,一切的操作都在后台操作,所以非常多全局性(手机助手,语音助手)之类的应用非常长须要这个.我们今天也来玩玩 我们新建一个project--Se ...
随机推荐
- 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多
学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...
- Android通知Notification全面剖析
通知 通知是您可以在应用的常规 UI 外部向用户显示的消息.当您告知系统发出通知时,它将先以图标的形式显示在通知区域中.用户可以打开抽屉式通知栏查看通知的详细信息. 通知区域和抽屉式通知栏均是由系统控 ...
- SQL Server 扩展事件(Extented Events)从入门到进阶(2)——在GUI中创建基础扩展事件
本文属于 SQL Server 扩展事件(Extented Events)从入门到进阶 系列 第一篇文章中提到了如何在Profiler中创建跟踪(trace),并以服务器端(server-side)跟 ...
- Apache shiro集群实现 (七)分布式集群系统下---cache共享
Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...
- pdflush的工作原理
大家知道,在linux操作系统中,写操作是异步的,即写操作返回的时候数据并没有真正写到磁盘上,而是先写到了系统cache里,随后由pdflush内核线程将系统中的脏页写到磁盘上,在下面几种情况下,系统 ...
- JBOSS EAP 6 系列一 新特性
在项目中,采用的架构是Springmvc+spring+EJB+Jpa等架构,当然服务器是Jboss,本次Jboss我们采用的是JBossEap6.2,Jboss7的新特性与Jboss4.5的大的改变 ...
- Hive-RCFile文件存储格式
在新建Hive表时,可以使用stored as rcfile来指定hive文件的存储方式为RCFile. 一.RCFile文件结构 下图是一个RCFile的文件结构形式. 从上图可以看出: 1)一张表 ...
- (一〇六)iPad开发之UIPopoverController的使用
很多App里都有一种点击显示的悬浮气泡菜单,例如下图: 在iPad上可以使用UIPopoverController实现这个功能,popoverController继承自NSObject而不是UIVie ...
- 新手学python(3):yield与序列化
1 Yield生成器 Yield是我在其他语言中没有见过的一个属性,算是python的一大特色,用好之后可以使代码更简洁.考虑一个简单的例子,文件的遍历.要遍历一个目录下的所有文件需要递归的操作.如果 ...
- Win10中virtualbox新建虚拟机不能设置64位系统解决
问题描述 在Win10中,安装virtualBox后,新建虚拟电脑时,所有的操作系统都没有64位. 解决 进入控制面板->卸载程序->启用或关闭windows功能->取消hyper- ...