zoukankan      html  css  js  c++  java
  • BroadcastReceiver

    1.用法(在Mainfest中静态注册):

    通过一个简单的例子来说明:

    这是主Activity:

    package com.larry.msglighter;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    
    public class MsgLighter extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_msg_lighter);
        
        Intent intent = new Intent();
        intent.getAction();
        }
    }

    这是Receiver:

    package com.larry.msglighter;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.widget.Toast;
    
    public class MyBroadcastReceiver extends BroadcastReceiver {
         
        // action 名称
        String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED" ;
     
        public void onReceive(Context context, Intent intent) {
     
           if (intent.getAction().equals( SMS_RECEIVED )) {
               // 相关处理 : 地域变换、电量不足、来电来信;
               System.out.println("JB");
               Toast.makeText(context, "来短信了", Toast.LENGTH_LONG).show();
           }
        }
    }

    这是Mainifest里要注册的receiver:

            <receiver android:name = ".MyBroadcastReceiver" >
                <intent-filter android:priority = "1000" >
                    <action android:name = "android.provider.Telephony.SMS_RECEIVED" />
                </intent-filter >
            </receiver >

    以及权限:

        <uses-permission android:name = "android.permission.RECEIVE_SMS"/>
        <uses-permission android:name = "android.permission.SEND_SMS" />

    这个简单的例子实现了当短信来了的时候toast一个“短信来了”,当然可以把toast事件改成别的想要的事件。

    值得注意的是:

    public class MsgLighter extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_msg_lighter);
        
        Intent intent = new Intent();
        intent.getAction();
        }
    }
    

      这里intent的用法,这里用了一个getAction();参数为空,然后在receiver里面用下面的代码来判断这个action到底是什么。有时候也出现了setAction(),但我还不清楚这样做有什么意义。。。既然是自己能交代Action,那何必还要让系统来判断。。

    if (intent.getAction().equals( SMS_RECEIVED )) {
               // 相关处理 : 地域变换、电量不足、来电来信;
               System.out.println("JB");
               Toast.makeText(context, "来短信了", Toast.LENGTH_LONG).show();
           }
    

      先到这。

    2.关于:

    今天发现BroadcastReceiver是不会因为APP的进程被杀死而停止侦听的。。也就是说杀死了进程也能在系统有广播的时候自动程序。。好神奇。

    先到这。

    3.DEC2,2013补充

    今天测试发现如果已经在Manifest文件中注册了BroadcastReceiver,再在onReceiver()方法中使用

    if (intent.getAction().equals( SMS_RECEIVED ))
    判断是否有短信似乎是多此一举的。

    后来发现,如果这个广播注册了多个action,这个语句是可以用来区分的。这样就不用写好多个BroadcastReceiver了。

    http://zhidao.baidu.com/question/1894114941584455300.html

    4.July 25th,2014补充(代码中注册Receiver)

    过去了这么久,发现之前对BroadcastReceiver的理解也仅限于静态注册的一点点知识,现在又学了一点,记录下来,不过还有很多东西没懂,比如有序广播无序广播什么的。

    又看了一遍Mars的视频,他说在UI更新等情况下最好是动态注册,因为只有在展示给用户的时候注册才有意义。

    其实动态注册还有个好处,就是优先级比静态注册优先级高,也就是会先拦截到广播。比如你做一个短信应用,却发现短信先被360拦截了,如何抢在360前面呢?

    来个示例,工程里有三个文件:

    如果是2.3之前的版本,是不需要MainActivity的(这个想必都知道,4.0以后只有Receiver的应用,是没有权利接收广播的,程序必须运行一次才行)。这个Activity里啥也没有。

    然后是BroadcastReceiver,结构是这样的:

    package com.seclab.zygote;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    
    public class MyBrocast extends BroadcastReceiver {
    
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		// TODO Auto-generated method stub
    		Log.v("MyBrocast.onReceive", "received!");
    		if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
    			Log.d("REceiver","this is a receiver");
    			Intent service = new Intent(context, MyService.class);
    			context.startService(service);
    		}
    	}
    }
    

    看见它的onReceive()方法里先是Log了一下,然后用一个判断intent的语句判断是否开机启动,是的话就启动Service。

    然后是Service,代码中注册Receiver,也就是每次开机就注册:

    package com.seclab.zygote;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.nio.charset.Charset;
    
    import android.app.Service;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.os.IBinder;
    import android.util.Log;
    import android.widget.Toast;
    
    public class MyService extends Service{
    	
    	private MyBrocast myService = null ;  
    	@Override
    	public IBinder onBind(Intent arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		// TODO Auto-generated method stub
    		IntentFilter localIntentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
            localIntentFilter.setPriority(2147483647);//设置最高优先级
            myService = new MyBrocast();
            MyBrocast localMessageReceiver = myService;
            Log.v("MyBrocast.onReceive", "onCreate");
            registerReceiver(localMessageReceiver, localIntentFilter);
            
            //验证这个onStartCommand是否在开机启动之后被调用。如果没有,为什么不直接把注册放到启动开机启动里(放弃Service)
            FileOutputStream fos = null ; 
            try {
    			fos = new FileOutputStream("/sdcard/hey.txt");
    			OutputStream os = fos;
    			OutputStreamWriter osw = new OutputStreamWriter(os ,Charset.forName("GBK"));
    			osw.write("hey");
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return super.onStartCommand(intent, flags, startId);
    	}
    }
    

      

    在Service里面我加了一个验证Service是否成功启动的代码,就是在sd卡上创建一个txt文件。

    另外,在Manifest.xml中,也同时用了静态注册,并且设置了最高优先级。

    这样的话,我发一条短信,Logcat里可以同时收到两条「received!的log信息。一条是静态注册的Receiver接收到的的,一条是动态注册的Receiver接收到的。

    另外,看到一篇BLOG上说的收到重视的启动顺序是:

    1.首先,会解析手机中的/system/framework这个目录,原生系统中,这下面就一个apk - framework-res.apk
    当然各个厂商也会加入自己的内容,比如我的这个目录下就有com.htc.resources.apk
    2.然后受到重视的文件夹按顺序分别为:
    /system/app
    /vendor/app
    /data/app
    /drm/app-private

    下面我将把这个应用push到/system/framework里,试一下能不能抢得过360。

  • 相关阅读:
    父div不会被子div撑高
    ie6兼容问题
    浏览器兼容性技巧
    css hack基本语法
    网站设置为灰色
    .net cookie跨域请求指定请求域名
    实体对象属性和值转为键值对Dictionary
    C#通过对象属性名修改值
    jQuery.noConflict()解决imgBox.js依赖jquery版本问题
    华为OJ之最长公共子序列
  • 原文地址:https://www.cnblogs.com/larrylawrence/p/3421176.html
Copyright © 2011-2022 走看看