【Android】16.3 带Intent过滤器的Services

分类:C#、Android、VS2015;

创建日期:2016-03-01

一、简介

这一节演示带Intent过滤器的Services的基本用法。

1、配置Intent Filter

不论是本地解决方案还是远程解决方案,都可以通过intent过滤器显式指定要调用的是哪个已启动的服务。换言之,Intent过滤器主要解决的问题是:在Activity中调用StartService方法启动自定义的Service类以后,通过Intent过滤器指定调用的是已启动的服务中的哪些服务(过滤掉其他的服务)。当然,其他应用程序也可以用这种方式来实现。

在C#代码中,可以用[IntentFilte(…)]特性声明来自动注册Intent过滤器,其作用就像可以用[Service]特性声明自动注册服务一样,也是让系统自动修改AndroidManifest.xml配置文件,而不需要我们去手工在AndroidManifest.xml文件中注册配置信息。

例如,下面的代码将Intent过滤器与 mj.demos.DemoService 关联在一起:

namespace ServiceDemo1
{
    [Service]
    [IntentFilter(new String[]{"mj.demos.ServiceDemo1"})]
    public class MyService : Service
    {
        ……
    }
}

通过C#代码声明Service特性和IntentFilter特性以后,系统就会自动在AndroidManifest.xml文件中添加下面的配置:

<service android:name="servicedemo1.MyService">
    <intent-filter>
        <action android:name="mj.demos.MyService" />
    </intent-filter>
</service>

其中,“servicedemo1.MyService”中的servicedemo1是将命名空间ServiceDemo1全部变为小写字母后的结果,MyService是自定义的服务名。

这样一来,就可以在任何类中调用StartService方法,并在参数中传递Intent过滤器。例如,下面的代码演示了如何在某个Activity中传递Intent过滤器:

StartService (new Intent ("mj.demos.MyService"));

下面的代码演示了如何停止过滤服务:

StopService (new Intent ("mj.demos.MyService"));

2、通知用户

利用前面章节介绍的通知用户的办法,可将后台运行的Service的状态或结果告诉用户,比如传输一个大文件时,告诉用户后台传输已完成等。

二、示例2--StartedServiceDemo2

该例子与上一节介绍的StartedServiceDemo1的运行结果相同。不同的是在这个例子中添加了Intent过滤器。

运行截图

image   image

主要设计步骤

(1)添加ch1602_Main.axml

<?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/ch1602StartService"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="启动服务" />
    <Button
        android:id="@+id/ch1602StopService"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="停止服务" />
</LinearLayout>

(2)添加ch1602ServiceDemo.cs

using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Widget;
using System.Threading;

namespace MyDemos.SrcDemos
{
    [Service]
    [IntentFilter(new string[] { action })]
    public class ch1602ServiceDemo : Service
    {
        public const string action = "MyDemos.ch1602Service";
        Thread thread;

        [return: GeneratedEnum]
        public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
        {
            var myHandler = new Handler(MainLooper);
            myHandler.Post(() =>
            {
                Toast.MakeText(this, "服务已启动", ToastLength.Short).Show();
            });
            thread = new Thread(() =>
            {
                for (int i = 1; i <= 10; i++)
                {
                    var msg = string.Format("这是来自服务的第{0}个消息", i);
                    Thread.Sleep(TimeSpan.FromSeconds(4));
                    myHandler.Post(() =>
                    {
                        Toast.MakeText(this, msg, ToastLength.Short).Show();
                    });
                }
                StopSelf();
            });
            thread.Start();
            return StartCommandResult.Sticky;
        }

        public override void OnDestroy()
        {
            base.OnDestroy();
            thread.Abort();
            new Handler(MainLooper).Post(() =>
            {
                Toast.MakeText(this, "服务已停止", ToastLength.Short).Show();
            });
        }

        //基类要求实现的接口
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }
    }
}

(3)添加ch1602MainActivity.cs

using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;

namespace MyDemos.SrcDemos
{
    [Activity(Label = "ch1602MainActivity")]
    public class ch1602MainActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.ch1602_Main);

            var start = FindViewById<Button>(Resource.Id.ch1602StartService);
            start.Click += delegate
            {
                StartService(new Intent(ch1602ServiceDemo.action));
            };

            var stop = FindViewById<Button>(Resource.Id.ch1602StopService);
            stop.Click += delegate
            {
                StopService(new Intent(ch1602ServiceDemo.action));
            };
        }
    }
}
原文地址:https://www.cnblogs.com/rainmj/p/5229569.html