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>