[安卓基础]学习第七天
来源:互联网 发布:机器人运动仿真软件 编辑:程序博客网 时间:2024/05/22 02:05
一、为什么需要广播接收者(broadcastReceiver)
1.有什么样的人员听广播 老人,出租车司机2.听广播必须:电台,收音机,调频道3.Android内部已经定义好了电台,已经定义好了一些广播事件,如外拨电话,短信到来等等4.使用broadcastReceiver去接收系统定义好的这些事件5.javame javase javaee6.定义广播接收者目的是为了方便安卓开发者开发
二、案例
2-1.案例——ip拨号器
360永久免费 瑞星 卡巴斯基
1.在清单文件中配置receiver,并添加用户权限
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/><application //...... <!-- 配置广播接收者 --> <receiver android:name="com.elnui.day07_caseip.OutGoingCallReceiver"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL"/> </intent-filter> </receiver></application>
2.新建一个类继承BroadcastReceiver
public class OutGoingCallReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub // 获取用户输入的ip号码在config.xml文件中 SharedPreferences sp = context.getSharedPreferences("config", 0); String number = sp.getString("ipnumber", ""); // 获取当前拨打的电话 String num = getResultData(); // 在当前号码前假17951 // 判断当前号码是不是长途号码 if(num.startsWith("0")){ // 修改拨打的号码 setResultData(number + num); } }}
3.getResultData()
Retrieve the current result data, as set by the previous receiver. Often this is null.
4.setResultData()
Change the current result data of this broadcast; only works with broadcasts sent through Context.sendOrderedBroadcast. This is an arbitrary string whose interpretation is up to the broadcaster.
5.总结
- BroadcastReceiver是一个抽象类,没有上下文
public abstract class BroadcastReceiver{}
- public void onReceive(Context context, Intent intent) {},该方法中的context就是上下文
2-2.案例——sd卡监听器
1.onReceive()方法
- intent.getAction(); //获取当前广播的事件类型 Retrieve the general action to be performed, such as ACTION_VIEW. The action describes the general way the rest of the information in the intent should be interpreted -- most importantly, what to do with the data returned by getData.
2.清单文件配置
<receiver android:name="com.elnui.day07_casesd.SdcardStateReceiver"> <intent-filter> <action android:name="android.intent.action.MEDIA_MOUNTED"/> <action android:name="android.intent.action.MEDIA_UNMOUNTED"/> <!-- 小细节,这里必须配置data,约束类型叫file,因为sd里面的数据类型是file --> <data android:scheme="file"/> </intent-filter></receiver>
说明:<intent-filter>下必须添加<data android:scheme="file"/>
3.代码
public class SdcardStateReceiver extends BroadcastReceiver{ // 当SD卡状态发生改变时调用 @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String action = intent.getAction(); if("android.intent.action.MEDIA_MOUNTED".equals(action)){ System.out.println("SD卡挂载了。"); }else if("android.intent.action.MEDIA_UNMOUNTED".equals(action)){ System.out.println("SD卡挂载了。"); } }}
2-3.案例——短信监听器
1.代码
public class SmsListerReceiver extends BroadcastReceiver { // 当短信到来的时候执行 @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub System.out.println("Receive sms.............success!!!"); // 获取发送者的号码和内容 Object []objects = (Object[]) intent.getExtras().get("pdus"); for (Object obj : objects) { // 获取SmsMessage的实例 SmsMessage smg = SmsMessage.createFromPdu((byte[])obj); String messageBody = smg.getMessageBody(); String messageAddr = smg.getOriginatingAddress(); System.out.println("___Address:" + messageAddr + ":" + messageBody); } }}
2.清单文件配置
<uses-permission android:name="android.permission.RECEIVE_SMS"/><receiver android:name="com.elnui.day07_casesms.SmsListerReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter></receiver>
3.类SmsManager
- pdu也是封装短信的一种格式
4.类SmsMessage (android.telephony包下)
通过这个API拿到短信的信息
通过静态的createFromPdu()即可获得实例
- getOriginatingAddress(); // 获取号码
- getMessageBody(); // 获取内容
2-4.卸载安装
1.代码
public class StatusReceiver extends BroadcastReceiver { // 当有新的应用被安装或者卸载时调用 @Override public void onReceive(Context context, Intent intent) { // 获取当前广播的类型 String action = intent.getAction(); if("android.intent.action.PACKAGE_INSTALL".equals(action)){ System.out.println("___PACKAGE_INSTALL"); }else if("android.intent.action.PACKAGE_REMOVED".equals(action)){ System.out.println("___PACKAGE_REMOVED"); }else if("android.intent.action.PACKAGE_ADDED".equals(action)){ System.out.println("___PACKAGE_ADDED" + intent.getData()); } }}
2.清单文件配置(此处得配置data)
<receiver android:name="com.elnui.day07_caseinstall.StatusReceiver"> <intent-filter> <action android:name="android.intent.action.PACKAGE_INSTALL"/> <action android:name="android.intent.action.PACKAGE_REMOVED"/> <action android:name="android.intent.action.PACKAGE_ADDED"/> <!-- 小细节:还需配置一个data --> <data android:scheme="package"/> </intent-filter></receiver>
android.intent.action.PACKAGE_INSTALL是谷歌工程师预留的字符段
3.getData()
intent.getData()可以拿到包名
2-5.开机启动
1.代码
public class BootReceiver extends BroadcastReceiver { // 当手机重启时调用 @Override public void onReceive(Context context, Intent intent) { // 开启Activity Intent x = new Intent(context,MainActivity.class); // 添加标记 x.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(x); }}
2.清单文件配置
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/><application> <receiver android:name="com.elnui.day07_reboot.BootReceiver"> <intent-filter > <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver></application>
3.注意
不能在广播接收者里面开启Activity,需要添加一个任务栈的标记开机启动一定要加RECEIVE_BOOT_COMPLETED权限
// 添加标记intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4.补充
在页面按返回键会调用onBackPressed()
@Override public void onBackPressed() { // TODO Auto-generated method stub super.onBackPressed(); }
三、不同版本广播的特点
四、有序广播和无序广播
4-1.无序广播
比如新闻联播,到7点就播
1.广播发送者
代码
public void click1(View v){ Intent intent = new Intent(); intent.setAction("com.elnui.custom"); intent.putExtra("name", "准时开播"); sendBroadcast(intent); }
2.广播接收者
代码
public class wuxuRecelver extends BroadcastReceiver { // 当接收到自定义的广播时执行 @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String str = intent.getStringExtra("name"); Toast.makeText(context, str, 1).show(); }}
清单文件
<receiver android:name="com.elnui.day07_recelve.wuxuRecelver"> <intent-filter > <action android:name="com.elnui.custom"/> </intent-filter> </receiver>
4-2.有序广播
类似中央发送红头文件,按照优先级进行接收
1.发送者
代码
// 点击发送有序广播 public void click1(View v){ Intent intent = new Intent(); intent.setAction("com.elnui.sendOrderBroadcast"); /** * intent 意图 * receiverPermission 接收的权限 * resultReceiver 最终的recriver * scheduler handler * initialCode 初始码 * initialData 初始化数据 * initialExtras 额外数据 * * */ sendOrderedBroadcast(intent, null, new FinalReceiver(), null, 1, "有序广播-1000", null); }
2.接收者(以其中一个为例)
代码
public class CountryReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String str = getResultData(); Toast.makeText(context, "乡_>>"+str, 1).show(); setResultData("有序广播-100"); // 终止广播 //abortBroadcast(); }}
清单文件
<!-- 省长优先级 最高优先级--> <receiver android:name="com.elnui.day07_receiver.ProvienceReceiver"> <intent-filter android:priority="1000"> <action android:name="com.elnui.sendOrderBroadcast"/> </intent-filter> </receiver> <!-- 市长优先级 --> <receiver android:name="com.elnui.day07_receiver.CityReceiver"> <intent-filter android:priority="100"> <action android:name="com.elnui.sendOrderBroadcast"/> </intent-filter> </receiver> <!-- 乡长优先级 --> <receiver android:name="com.elnui.day07_receiver.CountryReceiver"> <intent-filter android:priority="10"> <action android:name="com.elnui.sendOrderBroadcast"/> </intent-filter> </receiver> <!-- 村民优先级 --> <receiver android:name="com.elnui.day07_receiver.PeopleReceiver"> <intent-filter android:priority="1"> <action android:name="com.elnui.sendOrderBroadcast"/> </intent-filter> </receiver>
3.最终接收者
public class FinalReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String str = getResultData(); Toast.makeText(context, "报告_>>"+str, 1).show(); }}
说明:最终接收者无需再清单文件中配置
4.abortBroadcast()
终止广播
5.有序和无序广播的区别
- 无序广播不可以被终止,调用abortBroadcast()会在日志文件中打印警告
- 无序广播数据不可以修改
五、特殊广播接收者
操作特别频繁的广播事件,比如屏幕的锁屏和解锁,电池电量的变化。这种事件的广播在清单文件注册无效
5-1.注册广播接收者的两种方式
1. 使用代码动态注册 Context.registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 动态去注册广播接收者 ScreenReceiver sc = new ScreenReceiver(); /* * <action android:name="android.intent.action.SCREEN_OFF"/> <action android:name="android.intent.action.SCREEN_ON"/> * */ IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("android.intent.action.SCREEN_OFF"); intentFilter.addAction("android.intent.action.SCREEN_ON"); registerReceiver(sc, intentFilter); }}
04-16 10:24:40.719: E/ActivityThread(2270): android.app.IntentReceiverLeaked:
Activity com.elnui.day07_broadcast.MainActivity has leaked IntentReceiver com.elnui.day07_broadcast.ScreenReceiver@b0fc74e8
that was originally registered here. Are you missing a call to unregisterReceiver()?
注意,当Activity销毁的时候,要取消注册广播接收者unregisterReceiver()
2. 在清单文件通过receiver节点静态注册
六、样式和主题
6-1.样式
样式的作用一般在控件上,样式的作用范围比较窄
6-2.主题
主题一般作用在Activity或者Application节点下,作用范围相抵较大
6-3.二者定义的方式一样
七、国际化
i18n
在res目录下创建不同国家语言环境的目录即可,如values-ch,values-en..
八、常见对话框
8-1.Toast
8-2.普通对话框
public void click1(View v){ // 通过Builder构建器来构造 AlertDialog.Builder builder = new Builder(this); builder.setTitle("警告"); // 标题 builder.setMessage("世界上最遥远的距离是没有网络"); //内容 builder.setPositiveButton("确定", new OnClickListener() { public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub System.out.println("___点击了确定按钮"); } }); // builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub System.out.println("___点击了取消按钮"); } }); // builder.show(); }
8-3.单选对话框
// 点击,弹出一个单选对话框 public void click2(View v){ // 通过Builder构建器来构造 AlertDialog.Builder builder = new Builder(this); builder.setTitle("请选择课程"); items = new String[] {"安卓","IOS","C","C++","C#"}; builder.setSingleChoiceItems(items, 0, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub System.out.println("___点击了单选按钮"); // 取出选择的内容 String str = items[which]; Toast.makeText(getApplicationContext(), str, 1).show(); // 关闭单选框 dialog.dismiss(); } }); builder.show(); }
8-4.多选对话框
// 点击,弹出一个多选对话框 public void click3(View v){ // 通过Builder构建器来构造 AlertDialog.Builder builder = new Builder(this); builder.setTitle("请选择水果"); final String frults[] = new String[] {"苹果","西瓜","桔子","榴莲","哈密瓜"}; checkedItems = new boolean[] {true,false,false,false,false}; builder.setMultiChoiceItems(frults, checkedItems, new OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { // TODO Auto-generated method stub } }); builder.setPositiveButton("确定", new OnClickListener() { StringBuffer sb = new StringBuffer(); @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub // 把选中的条目数据取出来 for (int i = 0; i < checkedItems.length; i++) { if(checkedItems[i]){ String frult = frults[i]; sb.append(frult + "-"); } } Toast.makeText(getApplicationContext(), sb.toString(), 1).show(); // 关闭单选框 dialog.dismiss(); } }); builder.show(); }
8-5.进度条对话框
PrograssBar
与进度相关的控件,都可以在子线程更新UI
// 点击,弹出进度条对话框 public void click4(View v){ final ProgressDialog dialog = new ProgressDialog(this); dialog.setTitle("正在玩命加载。。。。"); // 设置进度条样式 dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); // 线程 new Thread(){ @Override public void run() { // TODO Auto-generated method stub // 设置最大进度 dialog.setMax(100); for (int i = 0; i < 100; i++) { // 设置进度 dialog.setProgress(i); // 延时 SystemClock.sleep(50); if(dialog.getProgress() == 99){ dialog.dismiss(); } } super.run(); } }.start();; // 最后show() dialog.show(); }
九、两种上下文的区别
9-1.getApplicationContext()
返回的对象是Context对象【父类】
9-2.this
最终继承Context对象【子类】注意: 对话框只能用this
十、安卓中的动画
10-1.帧动画
- 加载一系列的图片资源
- The AnimationDrawable class is the basis for Drawable animations.
res/drawable/my_animation.xml - 在android2.3之前的手机上需要用兼容性写法,使用线程
<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true"> <item android:drawable="@drawable/girl_1" android:duration="200" /> <item android:drawable="@drawable/girl_2" android:duration="200" /> <item android:drawable="@drawable/girl_3" android:duration="200" /> <item android:drawable="@drawable/girl_4" android:duration="200" /> <item android:drawable="@drawable/girl_5" android:duration="200" /> <item android:drawable="@drawable/girl_6" android:duration="200" /> <item android:drawable="@drawable/girl_7" android:duration="200" /> <item android:drawable="@drawable/girl_8" android:duration="200" /> <item android:drawable="@drawable/girl_9" android:duration="200" /> <item android:drawable="@drawable/girl_10" android:duration="200" /> <item android:drawable="@drawable/girl_11" android:duration="200" /></animation-list>
onCreat()
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView rocketImage = (ImageView)findViewById(R.id.iv); // 设置背景资源 rocketImage.setBackgroundResource(R.drawable.my_animation); // 获取AnimationDraw类型 AnimationDrawable rocketAnimation = (AnimationDrawable) rocketImage.getBackground(); // 开启动画 rocketAnimation.start(); }
10-2.View动画(补间动画)
10-3.属性动画
笔记:
笔记一:Android TextView 文字居中
两种方法
- 在xml文件设置:Android:gravity=”center”
- 在程序中设置:m_TxtTitle.setGravity(Gravity.CENTER);
android:gravity和android:layout_gravity的区别在于前者对控件内部操作,后者是对整个控件操作
阅读全文
0 0
- [安卓基础]学习第七天
- 安卓学习第七天
- 安卓学习第七天:View
- 安卓实习第七天
- JavaWeb基础学习第七天
- 安卓--第七天--fragment的实现
- 黑马程序员----基础学习第七天
- 基础加强第七天
- Java 基础 第七天
- JAVA基础第七天
- java基础第七天
- Android基础第七天
- C#基础第七天
- [安卓基础]学习第一天
- [安卓基础]学习第三天
- [安卓基础]学习第五天
- [安卓基础]学习第八天
- [安卓基础]学习第九天
- 如何在 Git 里撤销(几乎)任何操作
- eclipse使用心得
- JavaScript中关于事件绑定、冒泡、捕获和执行顺序
- poj 2443 bitset 或 状态压缩
- USACO-Section1.1 Broken Necklace [动态规划]
- [安卓基础]学习第七天
- 归并排序
- 最长回文串
- 【七日牧函】来一场爱心大冒险
- python的web开发框架django学习笔记
- 排序--折半插入排序
- BANANAPI 修改启动直接进入系统
- FAQ停用词表
- QT源程序与编译方式