第六天

本文深入讲解Android中的广播机制,包括广播接收者的实现原理及其应用场景,如拨号监听、SD卡状态监测、短信监听等,并探讨不同版本间的差异及有序与无序广播的特点。

1、  为什么需要广播接收(broadcastReceiver)
    [1] 想听广播必须有 :电台、有收音机、
    [2]  android系统内部已经定义好了电台,已经定义好了一些广播事件 外拨电话 sd状态 电池电量...

       [3] 使用broadcastReceiver去接收这些已经定义好的事件

        [4]   定义广播接收者的目的方便开发者进行开发
2、  广播接收者案例_ip拨号器

        [1]  创建一个类继承 broadcastReceiver

  1. public class OutGoingCallReceiver extends BroadcastReceiver
        [2]  重写onReceive()方法
  1. public void onReceive(Context context, Intent intent) {
  2. String resultData = getResultData();
  3. SharedPreferences config = context.getSharedPreferences("config", Context.MODE_PRIVATE);
  4. String ipNumber = config.getString("ipNumber", "");
  5. if(resultData.startsWith("0")){
  6. setResultData(ipNumber+resultData);
  7. }
  8. }

        [3]   在清单里面配置

           <receiver>

               <intent-filter>

                    <action/>   这个里面注册什么事件就接收什么广播

                </intent-filter>

           </receiver>

  1. <receiver android:name=".OutGoingCallReceiver">
  2. <intent-filter>
  3. <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
  4. </intent-filter>
  5. </receiver>

          [3] 在清单文件中设置权相关权限

    

  1. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

          [4]  在android studio 中不设置权限不报错,但是app会不按意愿走

3、  广播接收者案例_sd卡状态监听

           [1]  定义一个广播接收器

  1. public class SdStatusReceiver extends BroadcastReceiver
           [2]  配置清单文件  小细节:在判断SD卡是否被加载的时候,必须配合一下data的scheme属性为file
  1. <receiver android:name=".SdStatusReceiver">
  2. <intent-filter>
  3. <action android:name="android.intent.action.MEDIA_MOUNTED"/>
  4. <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
  5. <!--在获取SD卡状态的时候必须要配置data的约束-->
  6. <data android:scheme="file"/>
  7. </intent-filter>

4、  广播接收者案例_短信监听器

    [1]   定义一个类继承BroadcastReceiver

  1. public class SMSReceiver extends BroadcastReceiver
    [2]    重写onReceive方法
  1. public void onReceive(Context context, Intent intent) {
  2. //获取信息集合 使用的是pdu格式封装的信息,那么就需要SMSMessage来进行接收
  3. //必须首先获取一个信息集合,然后拿出每一条来获取一条短信息,再获取数据
  4. Object []pdus = (Object[]) intent.getExtras().get("pdus");
  5. for (Object pdu : pdus ){
  6. SmsMessage fromPdu = SmsMessage.createFromPdu((byte[]) pdu);
  7. String address = fromPdu.getOriginatingAddress();
  8. Log.d("sms",address);
  9. }
  10. }
      [3]  配置监听信息
    
  1. <receiver android:name=".SMSReceiver">
  2. <intent-filter>
  3. <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
  4. </intent-filter>
  5. </receiver>
      [4]  配置权限
    
  1. <uses-permission android:name="android.permission.RECEIVE_SMS"/>

5、  不同版本广播的特点

    [1]  在4.0以上谷歌要求 第一次安装应用必须有界面 这样广播接收者才会生效

    [2]  如果用户点击了强行终止程序的运行,那么广播接收者也不会生效

    [3]  在level 10  上面没有这些的安全设计
6、  广播接收者案例_卸载安装

    [1]  创建一个类继承BroadcastReceiver

  1. public class AppStateReceiver extends BroadcastReceiver
    [2]  重写onReceive
  1. public void onReceive(Context context, Intent intent) {
  2. String action = intent.getAction();
  3. if(action.equals("android.intent.action.PACKAGE_ADDED")){
  4. Toast.makeText(context,"应用被安装了",Toast.LENGTH_LONG).show();
  5. }else if(action.equals("android.intent.action.PACKAGE_REMOVED")){
  6. Toast.makeText(context,"应用被卸载了",Toast.LENGTH_LONG).show();
  7. }
  8. }
    [3]  配置监听事件
    
  1. <receiver android:name=".AppStateReceiver">
  2. <intent-filter>
  3. <action android:name="android.intent.action.PACKAGE_ADDED"/>
  4. <action android:name="android.intent.action.PACKAGE_REMOVED"/>
  1. <!--要使这个reveiver起作用,要配置datascheme属性-->
  1. <data android:scheme="package"/>
  2. </intent-filter>
  3. </receiver>
    

7、  广播接收者案例_开机启动

  1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. <receiver android:name=".BootCompleted">
  3. <intent-filter>
  4. <action android:name="android.intent.action.BOOT_COMPLETED"/>
  5. </intent-filter>
  6. </receiver>
  1. public class BootCompleted extends BroadcastReceiver {
  2. @Override
  3. public void onReceive(Context context, Intent intent) {
  4. Intent intent1 = new Intent(context, MainActivity.class);
  5. intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  6. context.startActivity(intent1);
  7. }
  8. }

8、  有序广播和无序广播

    [1]  通过广播发出的数据一般通过getResultData()来接收,而通过Intent发送的数据一般使用intent.getData()来接收
    [2]  有序广播可以被终止  有序广播数据可以被修改

     [3]  无序广播不可以被终止,数据不可以被修改

    [4]  有序广播会按照在清单文件中定义的priority的值来进行广播的传递,数值越高接收的速度越快,优先级就越高,如果在优先级高的广播接收者处调用abortBroadcast()那么以后的所有优先级低的广播接收者都接收不到,但是在发送者处,可以定义一个resultReceiver,这个receiver不用在清单文件中注册,拥有特权,在最后接收到,但是即使在优先级高处截断广播,还是会被resultReceiver接收到

    [5]  发送广播

  1. Intent intent = new Intent();
  2. intent.setAction("com.young.test");
  3. /*
  4. 参数说明
  5. intent 意图
  6. receiverPermission 接收者需要的权限
  7. resultReceiver 最终的接收者
  8. scheduler 一个传递Hander 不在主线程的时候使用
  9. initialCode int: An initial value for the result code. Often Activity.RESULT_OK.
  10. initialData String: An initial value for the result data. Often null.
  11. initialExtras Bundle: An initial value for the result extras. Often null.
  12. */
  13. sendOrderedBroadcast(intent,null,null,null,1,"发送数据",null);
    [6]  接收广播
    
  1. public class HPriorityReceiver extends BroadcastReceiver {
  2. @Override
  3. public void onReceive(Context context, Intent intent) {
  4. String resultData = getResultData();
  5. Log.d("HPriorityReceiver",resultData);
  6. Toast.makeText(context,"HPriorityReceiver"+resultData,Toast.LENGTH_LONG).show();
  7. }
  8. }
    [7]  特殊的广播接收者  频繁的广播接收   例如监视解锁屏等   这些不能在清单文件中注册,注册无效,需要在代码中进行动态注册
  1. screenStatueReceiver = new ScreenStatueReceiver();
  2. IntentFilter intentFilter = new IntentFilter();
  3. intentFilter.addAction(Intent.ACTION_SCREEN_ON);
  4. intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
  5. registerReceiver(screenStatueReceiver,intentFilter); //进行动态注册广播
  6. }
  7. @Override
  8. protected void onDestroy() {
  9. super.onDestroy();
  10. unregisterReceiver(screenStatueReceiver); //在activity 进行销毁的时候,进行解注册广播
  11. }

9、  样式和主题

    样式:一样作用于控件  例如 Button  TextView  是为了减少代码量

    主题:一般作用于Activity上,用于控制Activity的显示的界面效果  在清单文件中的Application和activity节点下更改
10、国际化

    在res目录下创建values-语言代码   例如  values-zh 代表中文,当手语言环境为中文的时候加载,然后将需要显示的字符串进行翻译成相对应的语言就可以了
11、常见对话框

    普通对话框   单选按钮对话框   多选按钮对话框   进度条对话框

    [1]  普通对话框

  1. AlertDialog.Builder builder = new AlertDialog.Builder(this);
  2.  
  3. builder.setTitle("警告");
  4. builder.setMessage("世界上最遥远的距离 是没有网络");
  5. builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
  6. @Override
  7. public void onClick(DialogInterface dialogInterface, int i) {
  8. Log.d("positive","点击了确定按钮");
  9. }
  10. });
  11. builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
  12. @Override
  13. public void onClick(DialogInterface dialogInterface, int i) {
  14. Log.d("negative","点击了取消按钮");
  15. }
  16. });
  17.  
  18. builder.show();
    [2]  单选对话框
  1. AlertDialog.Builder builder = new AlertDialog.Builder(this);
  2. builder.setTitle("选出你最喜欢的课程");
  3. final String [] item = new String[]{"android","java","c","c++","c#"};
  4. //-1代表没有选中的
  5. builder.setSingleChoiceItems(item, -1, new DialogInterface.OnClickListener() {
  6. @Override
  7. public void onClick(DialogInterface dialogInterface, int i) {
  8. String itemName = item[i];
  9. Toast.makeText(getApplicationContext(),itemName,Toast.LENGTH_SHORT).show();
  10. dialogInterface.dismiss();
  11. }
  12. });
  13. builder.show();
    [3]  多选对话框
  1. AlertDialog.Builder builder = new AlertDialog.Builder(this);
  2. builder.setTitle("选出你想要学习的课程");
  3. final String item[] = new String[]{"android","java","c","c++","c#"};
  4. final boolean ischeck[] = new boolean[5];
  5. builder.setMultiChoiceItems(item, null, new DialogInterface.OnMultiChoiceClickListener() {
  6. @Override
  7. public void onClick(DialogInterface dialogInterface, int i, boolean b) {
  8. ischeck[i] = b;
  9. }
  10. });
  11. builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
  12. @Override
  13. public void onClick(DialogInterface dialogInterface, int i) {
  14. for(int j = 0;j < ischeck.length;j++){
  15. if(ischeck[j]){
  16. Log.d("选中的数据",item[j]);
  17. }
  18. }
  19. }
  20. });
  21. builder.show();
    [4]  进度条对话框
  1. final ProgressDialog dialog = new ProgressDialog(this);
  2. dialog.setTitle("正在加载ing...");
  3. dialog.setMax(100);
  4. dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  5. new Thread(){
  6. public void run(){
  7. for(int i = 0;i <= 100;i++){
  8. dialog.setProgress(i);
  9. SystemClock.sleep(50);
  10. }
  11. dialog.dismiss();
  12. }
  13. }.start();
  14. dialog.show();

    
   [5]  所有的进度控件都可以在子线程更新UI

12、this和getApplicationContext的区别

    [1]  this 是Context的子类  而getApplicationContext返回的是一个Context父类。

    [2]  this返回的是具体的哪一个组件的上下文,而getApplicationContext返回的是应用的上下文

    [3]  在需要上下文的地方如果传getApplication是正确的,那么写this也一定是正确的

13、android中的动画

    [1]  帧动画

    [2]  view动画

    [3]  property 动画

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值