分类:C#、Android、VS2015;

创建日期:2016-02-29

一、简介

Android系统和你自己编写的应用程序都可以通过Indent发送和接收广播信息。广播的内容既可以是自定义的信息,也可以是Android的系统信息。例如,网络连接变化、电池电量变化、系统设置变化、接收到新的短信、微信、……等。

1、发送广播消息

一般都是通过后台服务中向前台发送广播消息。当然,也可以在某个Activity中向其他的Activity发送广播,不过,这种情况很少见。

要通过服务发送广播,可先定义一个继承自Service的子类,例如:

[Service]

public class MyService : Service

{

……

}

在该服务子类中,重写StartCommandResult()方法,然后在该方法中创建一个Intent实例,同时还可以调用这个Intent实例的PutExtra()方法包含要发送的附加消息(可选),最后调用SendBroadcast()方法,即可将该消息广播出去。例如:

intent = new Intent(action);

intent.PutExtra("message", "这是来自广播的消息");

SendBroadcast(intent);

注意:

(a)用Intent发送广播时,必须在参数中使用“全局唯一的标识符”指定该Intent要执行的动作,总之,你只要确保这个Action名称在整个项目中是唯一的就行了。

在实际应用中,动作字符串一般用“解决方案名+项目名+动作名”来表示,例如:

public static readonly string action = "MyBroadcastDemo.action1";

也可以用“自定义的命名空间+动作名”来表示。例如:

public static readonly string action = "www.cnblogs.com.rainmj.MyBroadcastDemo";

但是,这些都是一些约定的大家觉得比较好的做法,并不是必须这样做。换言之,唯一的要求就是不要在同一个项目中有相同的Action名称就行,这就是“全局唯一的标识符”的含义。

(b)由于发送广播一般都是通过后台服务来实现的,为了不让后台服务影响前台的界面操作,可以通过Task或者Thread来发送(见示例)。当然,如果服务用时很短,比如仅发送一个简单的字符串,那就没有必要用Task或者Thread来实现了。

发送广播的完整代码见示例中的ch1501Service.cs文件。

2、接收广播消息

对于广播接收端来说,凡是注册了BroadcastReceiver的应用程序类,都可以从继承自BroadcastReceiver的类中接收到广播消息,这个实现接收广播的BroadcastReceiver子类就叫广播接收器。

广播接收器(Broadcast Receivers)接收的广播内容一般来自Android内置的标准服务,另外,还可以来自你自己定义的服务。

例如:

public class MyBroadcastReceiver : BroadcastReceiver

{

……

}

广播接收器一旦启动,就会自动监听你注册的广播,并在OnReceive()方法中接收广播消息。因此,要正常接收广播,必须在该子类中重写OnReceive()方法,例如:

public override void OnReceive(Context context, Intent intent)

{

……

}

默认情况下,Android要求OnReceive方法必须在5秒内执行完毕,否则Android会认为该组件失去响应,并提示用户强行关闭该组件。

接收广播的完整代码见示例中的ch1501BroadcastReceiver.cs文件。

3、注册接收的广播地址

一般在Activity中注册要用哪个广播接收器来接收广播。

有两种注册接收广播地址的方式,一种是通过C#代码实现(常用),另一种是在配置文件AndroidManifest.xml中实现(不常用)。

通过C#代码实现的办法示例如下:

var receiver = new MyBroadcastReceiver();

RegisterReceiver(receiver, new IntentFilter(MyService.action));

StartService(new Intent(this, typeof(MyService)));

这段代码注册一个BroadcastReceiver,并通过IntentFilter(Intent过滤器)指定要执行的动作,然后就可以调用StartService()方法启动广播服务。

调用RegisterReceiver()后,系统就会自动在配置文件(AndroidManifest.xml)中配置Intent过滤器,不需要我们自己在这个文件中去手动配置。

二、示例1运行截图

本示例演示如何定时发送多种类型的广播。通过这个例子,相信你应该能真正理解“要发送的动作(Action)”的含义,同时也应该能明白如何在一个接收器中通过Intent过滤器注册多个动作。

该例子提前使用了下一章将要介绍的Android Service的功能。

三、主要设计步骤

1、添加ch1501_Main.axml文件

在Resource/layout文件夹下添加该文件。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/ch1501_btnStart"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="启动服务(发送广播)" />
<Button
android:id="@+id/ch1501_btnStop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="停止服务(停止广播)" />
<TextView
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView1"
android:layout_marginLeft="10dp"
android:layout_marginTop="50dp" />
</LinearLayout>

2、添加ch1501Service文件

在SrcDemos文件夹下添加该文件,模板选择【Class】。

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using System;
using System.Threading.Tasks; namespace MyDemos.SrcDemos
{
[Service]
public class ch1501Service : Service
{
public const string action1 = "www.cnblogs.com.rainmj.ch1501Service";
public const string action2 = "MyDemos.ch1501Service.Info1";
public const string action3 = "MyDemos.ch1501Service.Info2";
public const string action4 = "MyDemos.ch1501Service.Info3";
public static bool IsCancel; [return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
//一般应根据不同的情况通过action发送不同的广播信息,
//如果仅发送一条广播,像下面这样直接发送即可,不需要用Task.Run实现
//intent = new Intent(action1);
//SendBroadcast(intent); //如果是长时间运行的后台服务,为了不影响界面操作,最好用
//线程来实现,比如发送后台处理的进度等。
//下面以每隔1秒随机选取一个action为例,来演示长时间运行
//的服务以及定时向前台发送不同类型广播的办法
Task.Run(async () =>
{
Random r = new Random();
string[] actions = { action1, action2, action3, action4 };
string action = actions[0];
while (true)
{
if (IsCancel == true)
{
break;
}
intent = new Intent(action);
SendBroadcast(intent);
action = actions[r.Next(actions.Length)];
await Task.Delay(1000);
}
});
return StartCommandResult.Sticky;
} public override IBinder OnBind(Intent intent)
{
return null;
}
}
}

3、添加ch1501BroadcastReceiver.cs文件

在SrcDemos文件夹下添加该文件,模板选择【Class】。

using Android.Content;
using Android.Widget; namespace MyDemos.SrcDemos
{
public class ch1501BroadcastReceiver : BroadcastReceiver
{
private TextView txt;
public ch1501BroadcastReceiver(ch1501MainActivity activity)
{
txt = activity.FindViewById<TextView>(Resource.Id.textView1);
} public override void OnReceive(Context context, Intent intent)
{
//此处应该对接收到的intent.Action分别进行处理
//为简单起见,例子仅将这个字符串在界面上显示出来了
txt.Text += "\n收到:" + intent.Action;
}
}
}

4、添加ch1501MainActivity.cs文件

在SrcDemos文件夹下添加该文件,模板选择【Activity】。

using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget; namespace MyDemos.SrcDemos
{
[Activity(Label = "【例15-1】广播基本用法")]
public class ch1501MainActivity : Activity
{
private ch1501BroadcastReceiver receiver;
private Intent intent;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.ch1501_Main);
var txt = FindViewById<TextView>(Resource.Id.textView1); IntentFilter intentFilter = new IntentFilter();
intentFilter.AddAction(ch1501Service.action1);
intentFilter.AddAction(ch1501Service.action2);
intentFilter.AddAction(ch1501Service.action3);
intentFilter.AddAction(ch1501Service.action4);
receiver = new ch1501BroadcastReceiver(this);
RegisterReceiver(receiver, intentFilter); intent = new Intent(this, typeof(ch1501Service));
var btnStart = FindViewById<Button>(Resource.Id.ch1501_btnStart);
btnStart.Click += delegate
{
txt.Text = "";
ch1501Service.IsCancel = false;
StartService(intent);
};
var btnStop = FindViewById<Button>(Resource.Id.ch1501_btnStop);
btnStop.Click += delegate
{
ch1501Service.IsCancel = true;
StopService(intent);
};
} protected override void OnDestroy()
{
UnregisterReceiver(receiver);
ch1501Service.IsCancel = true;
StopService(intent);
base.OnDestroy();
}
}
}

【Android】15.2 广播的更多相关文章

  1. 【Android】15.0 第15章 广播和通知—本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-02-28 一.简介 广播(Broadcast):其功能类似于收音机的广播,你只要调到那个台(只要在接收的类中注册了要接收的广播),就能 ...

  2. Android之旅---广播(BroadCast)

    什么是广播 在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制.我们拿广播电台来做个比方.我们平常使用收音机收音是这样的:许许多多不同的广播电台通过特定的频率来发送他们 ...

  3. Android开发之广播

    广播是Android开发中的一个重要的功能,在Android里面有各式各样的广播,比如:电池的状态变化.信号的强弱状态.电话的接听和短信的接收等等,现在给大家简单介绍一下系统发送.监听这些广播的机制. ...

  4. android之自定义广播

    布局文件 点击按钮发送广播 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmln ...

  5. Android 常见的广播 action常量

    Intent.ACTION_AIRPLANE_MODE_CHANGED; //关闭或打开飞行模式时的广播 Intent.ACTION_BATTERY_CHANGED; //充电状态,或者电池的电量发生 ...

  6. Android中的广播

    Android中的广播 广播接受器,可以比喻成收音机.而广播则可以看成电台. Android系统内部相当于已经有一个电台 定义了好多的广播事件,比如外拨电话 短信到来 sd卡状态 电池电量变化... ...

  7. Android中本地广播的实现

    其实Android的本地广播并没有什么好讲的,他就是用了一个localbroadcastmanager类来sendbroadcast,以及注册和注销广播,没有什么特点,其中实例该类的时候用了getin ...

  8. Android 中的广播(Broadcast)

    Android 广播(broadcast) 饮水思源 本文章内容学习和总结自 郭霖大神:<Android第一行代码> Overview 就像我们的学校里的喇叭一样,是用来通知的.而Andr ...

  9. Android 中的广播机制

    Android 中的广播机制 Android 中的广播,按照广播响应范围,可以分为应用内广播和全局广播.按照广播的接收方式,可以分为标准广播和有序广播. 广播的分类 响应范围 应用内广播:此类广播只能 ...

  10. Android为什么需要广播Broadcast

       在Android系统中,为什么需要广播机制呢?广播机制,本质上它就是一种组件间的通信方式,如果是两个组件位于不同的进程当中,那么可以用Binder机制来实现,如果两个组件是在同一个进程中,那么它 ...

随机推荐

  1. .NET:在C#中模拟Javascript的setTimeout方法

    背景 每种语言都有自己的定时器(Timer),很多人熟悉Javascript中的setInterval和setTimeout,在Javascript中为了实现平滑的动画一般采用setTimeout模拟 ...

  2. easyui radio 取值和赋值

    1.html文件 <td><input id="client" type="text" name="client" sty ...

  3. jquery hide和show方法

    html 元素的显示和隐藏hide() 如果被选的元素已被显示,则隐藏该元素. show() 如果被选的元素已被隐藏,则显示该元素. <html> <head> <scr ...

  4. 如何在jenkins上通过mvn方式运行sonar

    1.首先在jenkins所在机器的的maven配置文件(settings.xml)里做如下配置: <profile> <id>sonar</id> <acti ...

  5. SQL OUTER JOIN

    When we want to select out all the record from two table, no matter it's present at second table or ...

  6. phpstorm failed to create jvm:error code -6 解决办法 解决方法

    phpStorm 软件打开运行提示 failed to create JVM的解决办法. 修改文件 D:\Program Files (x86)\JetBrains\PhpStorm 7.1.3\bi ...

  7. 【Python】Python Mako模板使用

    参考资料: Mako Templates for Python官网:http://www.makotemplates.org/ Python模板库Mako的用法:http://my.oschina.n ...

  8. linux查看当前shell的方法

    这篇文章主要对比一下 source 命令执行shell文件和 ./ping.sh 这种方式执行shell文件的区别. 1. source   ping.sh 这个是在当前的shell 中执行 ping ...

  9. RUP(Rational Unified Process),统一软件开发过程

    RUP(Rational Unified Process),统一软件开发过程 https://baike.baidu.com/item/RUP/8924595?fr=aladdin RUP最重要的它有 ...

  10. (剑指Offer)面试题39:二叉树的深度

    题目: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 结点的定义如下: struct TreeNode{ int val; ...