临沂网站建设多少钱,罗湖商城网站建设找哪家公司好,网站诚信建设,微信怎么注册小程序商店【声明】 欢迎转载#xff0c;但请保留文章原始出处→_→ 生命壹号#xff1a;http://www.cnblogs.com/smyhvae/ 文章来源#xff1a;http://www.cnblogs.com/smyhvae/p/3960623.html 【正文】 一、广播的功能和特征 广播的生命周期很短#xff0c;经过调用对象--… 【声明】 欢迎转载但请保留文章原始出处→_→ 生命壹号http://www.cnblogs.com/smyhvae/ 文章来源http://www.cnblogs.com/smyhvae/p/3960623.html 【正文】 一、广播的功能和特征 广播的生命周期很短经过调用对象--实现onReceive--结束整个过程就结束了。从实现的复杂度和代码量来看广播无疑是最迷你的Android 组件实现往往只需几行代码。广播对象被构造出来后通常只执行BroadcastReceiver.onReceive方法便结束了其生命周期。所以有的时候我们可以把它当做函数看也未必不可。和所有组件一样广播对象也是在应用进程的主线程中被构造所以广播对象的执行必须是要同步且快速的。也不推荐在里面开子线程因为往往线程还未结束广播对象就已经执行完毕被系统销毁。如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由 Service 来完成。每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 . 当 onReceive() 方法在 10 秒内没有执行完毕 Android 会认为该程序无响应。 二、接收系统广播 广播接收器可以自由地对自己感兴趣的广播进行注册这样当有相应的广播发出时广播接收器就能收到该广播并在内部处理相应的逻辑。注册广播的方式有两种在代码中注册和在清单文件中注册前者称为动态注册后者称为静态注册。 1、动态注册监听网络变化 新建工程文件首先在MainActivity中定义一个内部类netWorkChangeReceiver并重写父类的onReceive()方法这样每当网络状态发生变化时onReceive()方法就会得到执行这里使用Toast提示一段文本信息代码如下 class netWorkChangeReceiver extends BroadcastReceiver {Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, network changes, Toast.LENGTH_SHORT).show();} } 紧接着在onCreate方法中进行动态注册然后在onDestroy方法中进行取消注册 1 private IntentFilter intentFilter;2 private netWorkChangeReceiver netWorkChangeReceiver;3 4 Override5 protected void onCreate(Bundle savedInstanceState) {6 super.onCreate(savedInstanceState);7 setContentView(R.layout.activity_main);8 9 //动态注册创建一个IntentFilter的实例添加网络变化的广播(功能是对组件进行过滤只获取需要的消息)
10 intentFilter new IntentFilter();
11 intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
12 //创建NetWorkChangeReceiver的实例并调用registerReceiver()方法进行注册
13 netWorkChangeReceiver new netWorkChangeReceiver();
14 registerReceiver(netWorkChangeReceiver, intentFilter);
15
16 }
17
18 //取消注册一定要记得不然系统会报错
19 Override
20 protected void onDestroy() {
21 super.onDestroy();
22 unregisterReceiver(netWorkChangeReceiver);
23 } 上方代码解释如下 11行给意图过滤器intentFilter添加一个值为android.net.conn.CONNECTIVITY_CHANGE的action。因为每当网络状态发生变化时系统就会发出一条值为android.net.conn.CONNECTIVITY_CHANG的广播。 注最后要记得动态注册的广播接收器一定要取消注册才行。 运行程序就可以了。 不过只是提醒网络发生变化还不够人性化为了能够准确的告诉用户当前是有网络还是没有网络我们还需要对上述代码进一步优化修改netWorkChangeReceiver中的代码如下 1 class netWorkChangeReceiver extends BroadcastReceiver {2 3 Override4 public void onReceive(Context context, Intent intent) {5 //通过getSystemService()方法得到connectionManager这个系统服务类专门用于管理网络连接6 ConnectivityManager connectionManager (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);7 NetworkInfo networkInfo connectionManager.getActiveNetworkInfo();8 if(networkInfo ! null networkInfo.isAvailable()){9 Toast.makeText(context, network is available,Toast.LENGTH_SHORT).show();
10 }else{
11 Toast.makeText(context, network is unavailable,Toast.LENGTH_SHORT).show();
12 }
13
14 }
15 } 上方代码解释 06行在onReceive()方法中首先通过通过getSystemService()方法得到connectionManager这个系统服务类专门用于管理网络连接。 07行然后调用它的getActiveNetworkInfo()方法可以得到NetworkInfo的实例接着调用NetworkInfo的isAvailable()方法就可以判断当前是否有网络了最后通过Toast提示用户。 另外查询系统的网络状态是需要申明权限的打开清单文件添加如下权限 uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE/ 注访问http://developer.android.com/reference/android/Manifest.permission.html可以查看Android系统所有的可声明的权限。 现在运行程序就可以了。 上方程序完整版代码如下 1 package com.example.m05_broadcastreceiver01;2 import android.app.Activity;3 import android.content.BroadcastReceiver;4 import android.content.Context;5 import android.content.Intent;6 import android.content.IntentFilter;7 import android.net.ConnectivityManager;8 import android.net.NetworkInfo;9 import android.os.Bundle;
10 import android.widget.Toast;
11 public class MainActivity extends Activity {
12 private IntentFilter intentFilter;
13 private netWorkChangeReceiver netWorkChangeReceiver;
14 Override
15 protected void onCreate(Bundle savedInstanceState) {
16 super.onCreate(savedInstanceState);
17 setContentView(R.layout.activity_main);
18 // 动态注册创建一个IntentFilter的实例添加网络变化的广播
19 intentFilter new IntentFilter();
20 intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
21 // 创建NetWorkChangeReceiver的实例并调用registerReceiver()方法进行注册
22 netWorkChangeReceiver new netWorkChangeReceiver();
23 registerReceiver(netWorkChangeReceiver, intentFilter);
24 }
25 // 取消注册一定要记得不然系统会报错
26 Override
27 protected void onDestroy() {
28 super.onDestroy();
29 unregisterReceiver(netWorkChangeReceiver);
30 }
31 class netWorkChangeReceiver extends BroadcastReceiver {
32 Override
33 public void onReceive(Context context, Intent intent) {
34 //通过getSystemService()方法得到connectionManager这个系统服务类专门用于管理网络连接
35 ConnectivityManager connectionManager (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
36 NetworkInfo networkInfo connectionManager.getActiveNetworkInfo();
37 if(networkInfo ! null networkInfo.isAvailable()){
38 Toast.makeText(context, network is available,Toast.LENGTH_SHORT).show();
39 }else{
40 Toast.makeText(context, network is unavailable,Toast.LENGTH_SHORT).show();
41 }
42
43 }
44 }
45 } View Code 2、静态注册实现开机启动 动态注册的方式比较灵活但缺点是必须在程序启动之后才能接收到广播因为注册的逻辑是写在onCreate()方法中的。为了让程序在未启动的情况下就能接收到广播这里就需要使用到静态注册。 这里我们准备让程序接收一条开机广播当收到这条广播时就可以在onReceive()方法中执行相应的逻辑从而实现开机启动的功能。 新建一个类BootCompleteReceiver让他继承BroadcastReceiver在onReceive()方法中简单地Toast一下代码如下 public class BootCompleteReceiver extends BroadcastReceiver {Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, Boot Complete, Toast.LENGTH_SHORT).show();}
} 可以看到这里不再使用内部类的方式来定义广播接收器因为稍后我们需要在清单文件AndroidManifest.xml中将这个广播接收器的类名注册进去。 然后修改清单文件AndroidManifest.xml代码如下 1 uses-sdk2 android:minSdkVersion83 android:targetSdkVersion16 /4 uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE/5 uses-permission android:nameandroid.permission.RECEIVE_BOOT_COMPLETED/6 7 application8 android:allowBackuptrue9 android:icondrawable/ic_launcher
10 android:labelstring/app_name
11 android:themestyle/AppTheme
12 activity
13 android:namecom.example.m05_broadcastreceiver01.MainActivity
14 android:labelstring/app_name
15 intent-filter
16 action android:nameandroid.intent.action.MAIN /
17
18 category android:nameandroid.intent.category.LAUNCHER /
19 /intent-filter
20 /activity
21
22 receiver android:name.BootCompleteReceiver
23 intent-filter
24 action android:nameandroid.intent.action.BOOT_COMPLETED/
25 /intent-filter
26 /receiver
27 /application 代码解释如下 终于application标签内多了个子标签receiver所有的静态注册的广播接收器都是在这里进行注册的。 22行name中为广播接收器的名字 24行想要接收的广播。Android系统启动完成后会发出这条名为android.intent.action.BOOT_COMPLETED的广播。 05行监听系统开机广播需要声明权限。 运行程序后将手机关机重启就能收到这条广播了。 三、发送自定义广播 1、发送标准广播 新建工程文件。在发广播之前我们先定义一个广播接收器来接收此广播才行。因此新建一个类MyBroadcastReceiver让他继承BroadcastReceiver代码如下 public class MyBroadcastReceiver extends BroadcastReceiver {Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, received in MyBroadcastReceiver, Toast.LENGTH_SHORT).show();}
} 这里当MyBroadcastReceiver 收到自定义的广播时就会执行onReceive()方法中的逻辑弹出一个Toast。 紧接着要在清单文件AndroidManifest.xml中对这个广播接收器进行注册 1 application2 android:allowBackuptrue3 android:icondrawable/ic_launcher4 android:labelstring/app_name5 android:themestyle/AppTheme 6 activity7 android:namecom.example.m05_broadcastreceiver02.MainActivity8 android:labelstring/app_name 9 intent-filter
10 action android:nameandroid.intent.action.MAIN /
11
12 category android:nameandroid.intent.category.LAUNCHER /
13 /intent-filter
14 /activity
15
16 receiver android:name.MyBroadcastReceiver
17 intent-filter
18 action android:namecom.example.m05_broadcastreceiver02.MY_BROADCAST/
19 /intent-filter
20 /receiver
21 /application 代码解释 18行让MyBroadcastReceiver接收一条值为om.example.m05_broadcastreceiver02.MY_BROADCAST的广播因此待会儿在发送广播的时候我们就需要发出这样的一条广播。 紧接着修改activity.xml中的代码添加一个按钮Button。 然后修改MainActivity.java中的代码添加Button的监听事件点击按钮时发送广播 Button button1(Button)findViewById(R.id.button1);button1.setOnClickListener(new OnClickListener() { Overridepublic void onClick(View v) {Intent intent new Intent(com.example.m05_broadcastreceiver02.MY_BROADCAST);sendBroadcast(intent);}}); 总结可以看到点击按钮时发送com.example.m05_broadcastreceiver02.MY_BROADCAST这条广播这样所有能够监听com.example.m05_broadcastreceiver02.MY_BROADCAST这条广播的广播接收器就都会同时收到消息此时发出去的就是一条标准广播即无序广播。所以接下来就需要讲到有序广播。 2、发送有序广播 广播是一种可以跨进程的通信方式其他应用程序是可以收到的。现在我们来发一条有序广播。 有序广播不仅有先后顺序而且前面的广播还可以将后面的广播截断。 在3.1的代码基础之上将按钮的监听事件修改如下 1 Button button1(Button)findViewById(R.id.button1);
2 button1.setOnClickListener(new OnClickListener() {
3 Override
4 public void onClick(View v) {
5 Intent intent new Intent(com.example.m05_broadcastreceiver02.MY_BROADCAST);
6 sendOrderedBroadcast(intent, null);
7 }
8 }); 即将06行代码修改一下将sendBroadcast()方法改为sendOrderedBroadcast()方法sendOrderedBroadcast()方法接收两个参数第二个参数是一个与权限相关的字符串这里传入null即可。 紧接着修改清单文件AndroidManifest.xml中对广播接收器的注册设置优先级 1 receiver android:name.MyBroadcastReceiver
2 intent-filter android:priority100
3 action android:namecom.example.m05_broadcastreceiver02.MY_BROADCAST/
4 /intent-filter
5 /receiver 即添加第02行代码。可以看到通过android:priority属性给广播接收器设置了优先级。这个属性的范围在-1000到1000数值越大优先级越高。 接下来如果想要拦截这个广播防止让后面的广播接收器也接收到了这个广播。可以修改MyBroadcastReceiver中的代码 1 public class MyBroadcastReceiver extends BroadcastReceiver {
2
3 Override
4 public void onReceive(Context context, Intent intent) {
5 Toast.makeText(context, received in MyBroadcastReceiver, Toast.LENGTH_SHORT).show();
6 abortBroadcast();//拦截广播防止后面的接收到
7 }
8 } 即添加第06行代码。如果在onReceive()方法中调用了abortBroadcast()方法就表示是将这条广播拦截后面的广播接收器将无法再接收到。 特别关注 广播接收器的生命周期关键在于BroadcastReceiver中的onReceive()方法从onReceive()里的第一行代码开始onReceive()里的最后一行代码结束。一个广播到来的时候用什么方式提醒用户是最友好的呢第一种方式是吐司第二种方式是通知。注不要使用对话框以免中断了用户正在进行的操作。 四、使用本地广播 之前我们发送和接收的广播全部都是属于全局广播即发出去的广播可以被其他任何应用程序接收到并且我们也可以接收来自于其他任何应用程序的广播。这样一来必然会造成安全问题。于是便有了本地广播即只能在本应用程序中发送和接收广播。这就要使用到了LocalBroadcastManager这个类来对广播进行管理。 我们修改2.1中动态注册广播接收器的代码即修改MainActivity.java中的代码如下 package com.example.broadcasttest;import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;public class MainActivity extends Activity {private IntentFilter intentFilter;private LocalReceiver localReceiver;private LocalBroadcastManager localBroadcastManager;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//通过LocalBroadcastManager的getInstance()方法得到它的一个实例localBroadcastManager LocalBroadcastManager.getInstance(this);Button button (Button) findViewById(R.id.button);button.setOnClickListener(new OnClickListener() {Overridepublic void onClick(View v) {Intent intent new Intent(com.example.broadcasttest.LOCAL_BROADCAST);localBroadcastManager.sendBroadcast(intent);//调用sendBroadcast()方法发送广播}});//动态注册本地的广播接收器intentFilter new IntentFilter();intentFilter.addAction(com.example.broadcasttest.LOCAL_BROADCAST);localReceiver new LocalReceiver();localBroadcastManager.registerReceiver(localReceiver, intentFilter);}Overrideprotected void onDestroy() {super.onDestroy(); localBroadcastManager.unregisterReceiver(localReceiver);}class LocalReceiver extends BroadcastReceiver {Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, received local broadcast,Toast.LENGTH_SHORT).show();}}
} 注本地广播是无法通过静态注册的方式来接收的。其实也完全可以理解因为静态注册主要就是为了让程序在未启动的情况下也能收到广播。而发送本地广播时我们的程序肯定是已经启动了没有必要使用到静态注册的功能。 五、各种各样的广播 在android中有很多系统自带的intent.action通过监听这些事件我们可以完成很多功能。 开机String BOOT_COMPLETED_ACTION 广播在系统启动后。这个动作被广播一次只有一次。监听 “android.intent.action.BOOT_COMPLETED”电话拨入String ANSWER_ACTION 动作处理拨入的电话。监听 “android.intent.action.ANSWER”电量变化String BATTERY_CHANGED_ACTION 广播充电状态或者电池的电量发生变化。监听 “android.intent.action.BATTERY_CHANGED”日期改变String DATE_CHANGED_ACTION 广播日期被改变。 监听“android.intent.action.DATE_CHANGED”取消更新下载String FOTA_CANCEL_ACTION 广播取消所有被挂起的 (pending) 更新下载。 监听“android.server.checkin.FOTA_CANCEL”更新开始安装String FOTA_READY_ACTION 广播更新已经被下载 可以开始安装。监听 “android.server.checkin.FOTA_READY”主屏幕String HOME_CATEGORY 类别主屏幕 (activity)。设备启动后显示的第一个 activity。 监听android.intent.category.HOME”新应用String PACKAGE_ADDED_ACTION 广播设备上新安装了一个应用程序包。监听 “android.intent.action.PACKAGE_ADDED”删除应用String PACKAGE_REMOVED_ACTION 广播设备上删除了一个应用程序包。监听 “android.intent.action.PACKAGE_REMOVED”屏幕关闭String SCREEN_OFF_ACTION 广播屏幕被关闭。监听 “android.intent.action.SCREEN_OFF”屏幕开启String SCREEN_ON_ACTION 广播屏幕已经被打开。 监听“android.intent.action.SCREEN_ON”时区改变String TIMEZONE_CHANGED_ACTION 广播时区已经改变。监听 “android.intent.action.TIMEZONE_CHANGED”时间改变String TIME_CHANGED_ACTION 广播时间已经改变重新设置。 “android.intent.action.TIME_SET”时间流逝String TIME_TICK_ACTION 广播当前时间已经变化正常的时间流逝。 “android.intent.action.TIME_TICK”进入大容量存储模式String UMS_CONNECTED_ACTION 广播设备进入 USB 大容量存储模式。 “android.intent.action.UMS_CONNECTED”退出大容量存储模式String UMS_DISCONNECTED_ACTION 广播设备从 USB 大容量存储模式退出。 “android.intent.action.UMS_DISCONNECTED”壁纸改变String WALLPAPER_CHANGED_ACTION 广播系统的墙纸已经改变。 “android.intent.action.WALLPAPER_CHANGED”web搜索String WEB_SEARCH_ACTION 动作执行 web 搜索。 “android.intent.action.WEB_SEARCH”网络变化String CONNECTIVITY_CHANGE_ACTION 动作网络变化。“android.intent.action.CONNECTIVITY_CHANGE_ACTION” 六、实例使用动态注册监听手机的电量变化。 完整版代码如下 1activity_main.xml代码如下 1 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android2 xmlns:toolshttp://schemas.android.com/tools3 android:layout_widthmatch_parent4 android:layout_heightmatch_parent5 android:paddingBottomdimen/activity_vertical_margin6 android:paddingLeftdimen/activity_horizontal_margin7 android:paddingRightdimen/activity_horizontal_margin8 android:paddingTopdimen/activity_vertical_margin9 tools:context.MainActivity
10
11 TextView
12 android:idid/textView1
13 android:layout_widthmatch_parent
14 android:layout_heightwrap_content
15 android:textSize30dp
16 android:gravitycenter/
17
18 /LinearLayout 2MainActivity.java的代码如下 1 package com.example.m05_broadcastreceiver02;2 3 import android.app.Activity;4 import android.content.BroadcastReceiver;5 import android.content.Context;6 import android.content.Intent;7 import android.content.IntentFilter;8 import android.os.Bundle;9 import android.widget.TextView;
10
11 public class MainActivity extends Activity {
12
13
14 private BatteryBroadcastReceiver batteryBroadcastReceiver;
15 private TextView textView;
16 Override
17 protected void onCreate(Bundle savedInstanceState) {
18 super.onCreate(savedInstanceState);
19 setContentView(R.layout.activity_main);
20 textView(TextView)findViewById(R.id.textView1);
21
22 //动态注册监听电量的广播接收器
23 IntentFilter intentFilter new IntentFilter();
24 intentFilter.addAction(android.intent.action.BATTERY_CHANGED);
25 batteryBroadcastReceiver new BatteryBroadcastReceiver();
26 registerReceiver(batteryBroadcastReceiver, intentFilter);
27 }
28
29 //取消注册监听电量的广播接收器
30 Override
31 protected void onDestroy() {
32 super.onDestroy();
33 unregisterReceiver(batteryBroadcastReceiver);
34 }
35
36 //新建一个广播接收器监听电量的变化
37 public class BatteryBroadcastReceiver extends BroadcastReceiver {
38 Override
39 public void onReceive(Context context, Intent intent) {
40 if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
41 //获取当前电量
42 int level intent.getIntExtra(level, 0);
43 //电量的总刻度
44 int scale intent.getIntExtra(scale, 100);
45 textView.setText(电池电量为((level*100) / scale)%);
46
47 //当电量低时可以进行一些操作例如弹出通知等
48 /* if(level15){
49 do something
50 }*/
51 }
52 }
53
54 }
55
56 } 紧接着在清单文件中进行权限声明 uses-permission android:nameandroid.permission.BATTERY_STATS/ MainActivity.java的代码解释如下 40至45行固定代码用于获取当前电量 48至50行当电量低时可以进行一些操作例如弹出通知等 运行后界面如下 转载于:https://www.cnblogs.com/qianguyihao/p/3960623.html