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>