標籤:
一.前言
嗯,其實需求很簡單,但是因為伺服器不會主動聯絡用戶端,所以用戶端必須不間斷的向伺服器請求以便得到一些資料,突然不知道怎麼描述這個問題了,總之,我是通過AlarmManager來實現用戶端不斷地向伺服器發送請求,好吧,往下。
二.實現
用戶端不斷的發請求,然後通過獲得的響應做一些處理就可以了,流程就簡簡單單的像下面這個圖。
第一步:利用AlarmManager開啟輪詢服務
public class MyAlarmManager{ //開啟輪詢服務 public static void startPollingService(Context context, int seconds, Class<?> cls,String carUserId) { //擷取AlarmManager系統服務 AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Log.e("startPollingService:","開啟輪詢服務"); Intent intent = new Intent(context, cls); intent.putExtra("carUserId",carUserId);//添加需要傳遞的一些參數 PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);//我是用的是service //使用AlarmManger的setRepeating方法設定定期執行的時間間隔(seconds秒)和需要執行的Service manager.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), seconds * 1000, pendingIntent); } //停止輪詢服務 public static void stopPollingService(Context context, Class<?> cls,String action) { AlarmManager manager = (AlarmManager) context .getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, cls); intent.setAction(action); PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); //取消正在執行的服務 manager.cancel(pendingIntent); }}
第二步:Service/BroadcastReceiver/Activity完成相應的請求
我使用的是Service
/** *輪詢服務 *使用notification彈出訊息 */public class QueryUnusualService extends Service { private Notification notification; private NotificationManager manager; private Handler handler; @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return null; } @Override public void onCreate() { super.onCreate(); handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case R.id.query_unusual_car_result: List<Map<String,Object>> unusualCarList = (List<Map<String,Object>>)msg.getData().getSerializable("unusualCarList"); if(unusualCarList==null||unusualCarList.size()<1) return; showNotification(unusualCarList); break; default: break; } } }; } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); //請求資料 CarController.queryUnusualCar(intent.getStringExtra("carUserId"), handler); } //彈出Notification private void showNotification(List<Map<String,Object>> unusualCarList) { final Bitmap largeIcon = ((BitmapDrawable) getResources().getDrawable(R.drawable.stefan)).getBitmap(); manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); PendingIntent pendingIntent3 = PendingIntent.getActivity(this, 0, new Intent().setAction("intvehapp.intvehapp.Activity.BaiDuMapActivity"), 0); notification = new Notification.Builder(this) .setSmallIcon(R.drawable.head_image) .setLargeIcon(largeIcon) .setTicker("新訊息!!") .setContentTitle("新訊息!!!!") .setContentText("新訊息~") .setContentIntent(pendingIntent3).setNumber(1).getNotification(); // 需要注意build()是在API // level16及之後增加的,API11可以使用getNotificatin()來替代 notification.flags |= Notification.FLAG_AUTO_CANCEL; // FL manager.notify(1, notification); } @Override public void onDestroy() { super.onDestroy(); System.out.println("Service:onDestroy"); }}
大功告成
三.問題
大家在開發的過程中可能會發現一些問題,比如
1.不間斷輪詢失敗
這裡一定要注意 manager.setRepeating()的參數,特別是第一個參數和第二個參數相對應,即關於鬧鈴的類型問題:
//一共有五種鬧鈴類型: public static final int ELAPSED_REALTIME //當系統進入睡眠狀態時,這種類型的鬧鈴不會喚醒系統。直到系統下次被喚醒才傳遞它,該鬧鈴所用的時間是相對時間,是從系統啟動後開始計時的,包括睡眠時間,可以通過調用SystemClock.elapsedRealtime()獲得。系統值是3 (0x00000003)。 public static final int ELAPSED_REALTIME_WAKEUP //能喚醒系統,用法同ELAPSED_REALTIME,系統值是2 (0x00000002) ublic static final int RTC //當系統進入睡眠狀態時,這種類型的鬧鈴不會喚醒系統。直到系統下次被喚醒才傳遞它,該鬧鈴所用的時間是絕對時間,所用時間是UTC時間,可以通過調用 System.currentTimeMillis()獲得。系統值是1 (0x00000001) 。 public static final int RTC_WAKEUP //能喚醒系統,用法同RTC類型,系統值為 0 (0x00000000) 。 Public static final int POWER_OFF_WAKEUP //能喚醒系統,它是一種關機鬧鈴,就是說裝置在關機狀態下也可以喚醒系統,所以我們把它稱之為關機鬧鈴。使用方法同RTC類型,系統值為4(0x00000004)。
2.Notification不提示訊息的問題
1).請設定icon
2).如果API是16請將getNotification()換成build()
Android開發:利用AlarmManager不間斷向伺服器發送請求以及notification通知