需求:
(搭车请求信息)-应用在后台运行,凡设置为允许接收搭车请求者,并且距离在5KM之内的用户,均会收到提示“**用户在距离你**米距离处靠近**地址,想到**目的地去,正在等待搭车,希望得到你的帮助!”,提示以最前面窗口式显示,发出提示声音“请求搭车信息”,显示倒计时10秒后,窗口自动关闭。
设计:首先,这个服务得一直在后台运行,监听Server发送过来的请求信息,然后发送给Activity显示。
其次,显示一个对话框,当然对话框不能阻碍用户当前的Activity,这里把dialog设置成TYPE_SYSTEM_ALERT。
最后,显示倒计时10秒。
初步实现的Code(不带跟服务的交互):
需要加使用权限: <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
/** * ShareCarBGService is a service run in background and * deliver msgs from server to user. * Attention: build thread for self. * @author xinyan * @date 2011-10-23 */ public class ShareCarBGService extends Service { public static final String TAG = "ReserveActivity"; public static final int MSG_DIALOG_TIME_COUNT = 0; public static final int MSG_SHOW_REQUEST_DIALOG = 1; private static AlertDialog mDialog; private final String mDialogTitle = "收到搭车请求"; String strRequest = "**用户在距离你**米距离处靠近**地址,想到**目的地去,正在等待搭车,希望得到你的帮助!"; private Looper mServiceLooper; private ServiceHandler mServiceHandler; private Runnable mDialogRunnable; private int mTimeCount = 10; // Handler that receives messages from the thread private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_DIALOG_TIME_COUNT: mServiceHandler.postDelayed(mDialogRunnable, 1000); break; case MSG_SHOW_REQUEST_DIALOG: showNewRequestDialog(strRequest); break; default: break; } } } @Override public void onCreate() { super.onCreate(); // Start up the thread running the service. Note that we create a // separate thread because the service normally runs in the process's // main thread, which we don't want to block. We also make it // background priority so CPU-intensive work will not disrupt our UI. HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); // Get theHandlerThread's Looper and use it for our Handler mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); Log.v(TAG, "service started."); } @Override public int onStartCommand(Intent intent, int flags, int startId) { // For each start request, send a message to start a job and deliver the // start ID so we know which request we're stopping when we finish the // job Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.what = MSG_SHOW_REQUEST_DIALOG; mServiceHandler.sendMessageDelayed(msg, 5000); mDialogRunnable = new Runnable() { @Override public void run() { if (mTimeCount > 0) { mDialog.setTitle(mDialogTitle + "(" + mTimeCount + ")"); mTimeCount--; mServiceHandler.postDelayed(mDialogRunnable, 1000); } else { // 10s later, dismiss the request msg dialog. mDialog.dismiss(); } } }; Log.v(TAG, "onStartCommand"); // If we get killed, after returning from here, restart return START_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); Log.v(TAG, "service destroyed."); } /** * show a msg dialog when a new pickride request received. * @param request the content of request */ public void showNewRequestDialog(String request) { // i don't know whether a static dialog can use as this. if (null == mDialog) { mDialog = new AlertDialog.Builder(this).create(); mDialog.setTitle(mDialogTitle); mDialog.setMessage(request); // This the point, this dialog won't block the user's current // activity // via this attr mDialog.getWindow().setType( WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); mDialog.setButton(DialogInterface.BUTTON_POSITIVE, "查看", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // Bundle bundle = new Bundle(); Intent intent = new Intent(); intent.setClass(ShareCarBGService.this, ReserveRequestListTabWidgetActivity.class); startActivity(intent); } }); } else { mDialog.setMessage(request); } mDialog.show(); mServiceHandler.sendEmptyMessage(MSG_DIALOG_TIME_COUNT); } }