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>