服务(Service)全解析(五)--前台Service

MainActivity如下:

package cc.testservice2;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
/**
 * Demo描述:
 * 前台Service使用示例
 *
 *
 * 主要实现:
 * 1 在Service的onCreate()中调用startForeground()
 * 2 在Service的onDestroy()中调用stopForeground()
 * 3 一个Notification常驻在状态栏,当后台数据变化时需要
 *   更新该通知中的显示内容.在该示例中只用了一个简单的
 *   系统自带Notification来演示,实际项目中多半会用到
 *   自定义的Notification涉及到RemoteView.
 *
 *
 * 前台服务的特点:
 * 1 可尽量避免系统内容不足的时候被系统回收
 * 2 它会有一个图标一直在状态栏显示,拉下状态栏后可见更多信息.
 *   比如有的天气App就采用了该前台服务来实现.
 *
 *
 * 测试环境:
 * 1 该示例测试环境为Android4.4
 * 2 在Android2.3及其以下版本可能报错:
 *   java.lang.IllegalArgumentException: contentIntent required
 *
 *
 * 注意权限:
 *  <uses-permission android:name="android.permission.VIBRATE"/>
 *
 *
 * 参考资料:
 * 1 http://blog.csdn.net/guolin_blog/article/details/11952435
 * 2 http://blog.csdn.net/lfdfhl/article/details/38226523
 * 3 http://blog.csdn.net/vipzjyno1/article/details/25248021
 * 4 http://blog.csdn.net/think_soft/article/details/7299438
 * 5 http://blog.csdn.net/lfdfhl/article/details/10044161
 *   Thank you very much
 */
public class MainActivity extends Activity {
    TextView mNumberTextView;
    TextView mResultTextView;
    Button mSearchButton;
    ServiceConnectionImpl mServiceConnectionImpl;
    QueryInterface  mBinder;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //用于接收服务返回的Binder对象
        mServiceConnectionImpl=new ServiceConnectionImpl();
        mNumberTextView=(TextView) findViewById(R.id.numberEditText);
        mResultTextView=(TextView) findViewById(R.id.resultTextView);
        mSearchButton=(Button) findViewById(R.id.searchButton);
        mSearchButton.setOnClickListener(new ButtonOnClickListener());
        Intent intent=new Intent(this,ServiceSubclass.class);
        //当Activity启动的时候就启动服务
        bindService(intent, mServiceConnectionImpl, this.BIND_AUTO_CREATE);
    }

    private class ButtonOnClickListener implements OnClickListener{
		public void onClick(View v) {
			String number=mNumberTextView.getText().toString();
			String result=mBinder.queryByNumber(Integer.valueOf(number));
			mResultTextView.setText(result);
		}
    }

    //绑定服务和解除服务
    private final class ServiceConnectionImpl implements ServiceConnection{
    	//绑定服务时,此方法调用
		public void onServiceConnected(ComponentName name, IBinder service) {
			 mBinder=(QueryInterface) service;
		}
		//解除服务时,此方法调用
		public void onServiceDisconnected(ComponentName name) {
			mBinder=null;
		}
    }

   //解除与服务的连接
	protected void onDestroy() {
		unbindService(mServiceConnectionImpl);
		super.onDestroy();
	}

}

ServiceSubclass如下:

package cc.testservice2;

import android.app.Notification;
import android.app.Notification.Builder;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class ServiceSubclass extends Service {
	private String[] names = new String[] { "小明", "小王", "小杨", "小李", "小强" };
	BinderSubclass mBinderSubclass = new BinderSubclass();
	private String result=null;
	private Context mContext;
	private Builder mBuilder;
	private PendingIntent mPendingIntent;
    private Notification mNotification;
    private NotificationManager mNotificationManager;
    private final int NOTIFICATION_ID=9527;
	@Override
	public void onCreate() {
		super.onCreate();
		mContext=this;
		System.out.println("在onCreate()中---> startForeground()");
		//准备Notification
		initNotification(mContext);
		//开启前台服务
		startForeground(NOTIFICATION_ID, mNotification);
	}

	@Override
	public IBinder onBind(Intent intent) {
		return mBinderSubclass;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		//终止前台服务
		stopForeground(true);
		System.out.println("在onDestroy()中---> stopForeground()");
	}

	// queryByNumber就是接口里的业务方法.
	//一般来讲将业务抽象为一个接口,然后去实现接口,比如此处。
	// 注意:BinderSubclass继承自Binder也实现了业务接口
	private final class BinderSubclass extends Binder implements QueryInterface {
		public String queryByNumber(int number) {
			return query(number);
		}
	}

	//服务内部的方法
	public String query(int i) {
		if (i > 0 && i < 6) {
			result=names[i - 1];
			//更新通知
			updateNotification(result);
			return result;
		}
		return "查询错误,请再次输入";
	}

	/**
	 * 发送通知
	 */
	private void initNotification(Context context){
		Intent intent=new Intent(mContext, MainActivity.class);
		mPendingIntent=PendingIntent.getActivity(mContext, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
		mNotificationManager=(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
		mBuilder=new Builder(mContext);
		//通知产生的时间
		mBuilder.setWhen(System.currentTimeMillis());
		//通知首次出现在通知栏时的提示文字
		mBuilder.setTicker("Ticker");
		mBuilder.setContentTitle("ContentTitle");
		mBuilder.setContentInfo("ContentInfo");
		mBuilder.setContentText("ContentText");
		mBuilder.setContentIntent(mPendingIntent);
		//通知的优先级
		mBuilder.setPriority(Notification.PRIORITY_DEFAULT);
		//设置通知的图标.必须要有这句否则通知不显示!!!
		mBuilder.setSmallIcon(R.drawable.ic_launcher);
		//为通知添加声音,闪灯和振动效果等效果
		mBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
		//设置通知是否为一个正在进行的通知.后台任务时常使用true
		mBuilder.setOngoing(false);

		mNotification=mBuilder.build();
		//通知被点击后自动消失
		mNotification.flags = Notification.FLAG_AUTO_CANCEL;
		mNotificationManager.notify(NOTIFICATION_ID, mNotification);
	}

	/**
	 * 更新通知
	 */
	private void updateNotification(String result){
		mBuilder.setContentTitle("Title");
		mBuilder.setContentInfo("Info");
		mBuilder.setContentText(result);
		mNotification=mBuilder.build();
		mNotification.flags = Notification.FLAG_AUTO_CANCEL;
		mNotificationManager.notify(NOTIFICATION_ID, mNotification);
	}

}

QueryInterface如下:

package cc.testservice2;
//业务接口
public interface QueryInterface {
   public String queryByNumber(int number);
}

main.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="请输入1到5的数字" />

    <EditText
        android:id="@+id/numberEditText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/searchButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查询" />

    <TextView
        android:id="@+id/resultTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>
时间: 2024-09-17 09:35:52

服务(Service)全解析(五)--前台Service的相关文章

SaaS软件服务优点全解析

本文讲的是SaaS软件服务优点全解析,[IT168 资讯]随着SOA.联合身份管理技术(Federated Identity Management)以及托管集成技术的发展,IT资源的物理位置会变得越来越不重要,Internet基础设施正使企业内外的界面模糊起来.对企业来说,如何使软件与硬件技术的发展更快速.方便地应用于企业,快速实现企业不断变化的业务流程,快速集成与展现不同来源的业务数据,成为了当前企业应用IT技术需要考虑的问题.以往那种从新购买软件硬件,从头建设的方式,从需求分析.选型.设计.

服务(Service)全解析(六)--避免被系统回收的Service

MainActivity如下: package cc.c; import java.util.List; import android.os.Bundle; import android.os.Process; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.app.Activity; import android.ap

服务(Service)全解析(二)--bindService

MainActivity如下: package cc.testservice2; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.v

服务(Service)全解析(一)--startService

MainActivity如下: package cn.testservice1; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.app.Activity; import android.content.Intent; /** * Demo描述: * 采用startSe

服务(Service)全解析(三)--IntentService

MainActivity如下: package cc.testservice3; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; /** * Demo描述: * IntentSer

使用Fiddler解析WCF RIA Service传输的数据

原文 http://www.cnblogs.com/wintersun/archive/2011/01/05/1926386.html     使用Fiddler 2 解析WCF RIA Service传输的数据,您需要安装一个PlugIn.下载解压后,放在Inspectors文件中.重新启动Fiddler,你就会看到WCF Binary的选项.       下面的场景是,点一个Button根据ID查询数据,UI如下图:            Server端Code,ItemContext是Do

免安装版本tomcat 指定的服务并未以已安装的服务存在,Unable to open the service

今天在自己的电脑上安装了Tomcat6.0.14,是在Tomcat主页上直接下载的免安装版.但是把文件解压的之后,双击Tomcat6w.exe时,去出现了"指定的服务并未以已安装的服务存在,Unable to open the service"Tomcat5"".在地址栏输入http://localhost:8080,也无法显示Tomcat的主页.         后来在网上查了原因,原来是没有安装此项服务.解决的办法是进入命令行提示符cmd中,进入Tomcat\b

WorldWind系列五:插件加载过程全解析

不得不承认World Wind的代码真的很庞大,没有太多帮助文档的前提下,一头钻进代码里肯定令你头疼的,甚至研究代码间关联仿佛是在走迷宫.我最近一直想弄明白如何在 MenuBar中加载那些插件的,WorldWind学习系列四中研究的只是特殊的三个功能加载的,那三个没有继承Plugin类,不算是插件功能加载.所以WorldWind学习系列四加载的三个是特殊情况,不是一般的插件加载.今天下午终于柳暗花明,如果你真正关注World Wind分析,那么就好好看看下面的插件加载过程全解析. 我们先看看Pl

Android异步加载全解析之IntentService

Android异步加载全解析之IntentService 搞什么IntentService 前面我们说了那么多,异步处理都使用钦定的AsyncTask,再不济也使用的Thread,那么这个IntentService是个什么鬼. 相对与前面我们提到的这两种异步加载的方式来说,IntentService有一个最大的特点,就是--IntentService不受大部分UI生命周期的影响,它为后台线程提供了一个更直接的操作方式.不过,IntentService的不足主要体现在以下几点: 不可以直接和UI做