android用闹钟定时做http请求推送的解决方案
设计思路 如果在开发当中需要做push接入,而产品又要求不允许用第三方sdk(百度push,友盟push),而且又没有网络编程的经验,这个时候怎么办?这里就给大家分享下用http请求解决这个问题。 大体的设计思路是,写一个service(为了保证长时间运行不被kill,就将其定义到另外的进程当中去),在这个service里面启动闹钟,每隔一段时间(这个时间可以自己定义)去请求服务器,如果有新的push消息,就通知给用户。 具体实现 貌似很简单定义一个闹钟不断轮循请求服务器一句话,却在实际开发中要考虑很多问题,下面简单给大家列出来。 1)闹钟时间校准 什么都不说,类图直接贴上 大概分为三级结构 第一级:MoboPushAlarmManager,主要工作是管理闹钟,初始化闹钟,对闹钟时间进行校准,取消闹钟。 开始来贴代码了(具体的源码还没抽出来,过段时间再贴上) public void initPullAlarm(Context context,boolean boot) { Bundle bundle = new Bundle(); bundle.putInt(START_SERVICE_TYPE,TYPE_REQUEST); PendingIntent pendingIntent = getPendingIntent(context,bundle,REQ_PULL); //循环时间 long repeat_time = HOUR_MILLIS * 2; Log.i(TAG,"repeat_time is " + repeat_time); // 计算下一次执行时间 long triggerAtMillis = boot ? 10000 : 0; Log.i(TAG,"initPullAlarm,and next pull time is after: " + triggerAtMillis); // 这个行为会覆盖之前的Alarm,主要根据PendingIntent来辨别不同的闹钟 getAlarmManager(context).setRepeating(AlarmManager.RTC,System.currentTimeMillis() + triggerAtMillis,repeat_time,pendingIntent); } MobogeniePushServiceNew接收到闹钟之后,就会解析intent,并且进行相应的操作(请求网络,发送通知) @Override public void onStart(Intent intent,int startId) { super.onStart(intent,startId); LogUtil.p("pushservice onStart"); if (intent == null) { LogUtil.d("mobopush","intent == null)"); return; } // 解析打开service的意图 parsePushServiceIntent(intent); } private void parsePushServiceIntent(Intent intent) { Log.i(TAG,"parsePushServiceIntent"); if (intent == null) { return; } Bundle bundle = intent.getExtras(); if (bundle == null) { // 不明渠道调起service,默认处理为准备获取新消息,重设闹钟 PushAlarmManager.getInstance().initPullAlarm(this,false); return; } int type = bundle.getInt(PushAlarmManager.START_SERVICE_TYPE); if (type == PushAlarmManager.TYPE_STARTSERVICE) { //判断闹钟是否过期,如果过期则重设 } else if (type == PushAlarmManager.TYPE_REQUEST) { // 预设的网络请求 mREQ_RESULT = REQ_RESULT.ING; MoboPushRequest.getInstance().pullPushMessages(this,this,MoboPushRequest.REQUEST_NORMAL); } } //请求网络回调的数据处理 @Override public void onMessageLoaded(int actionCode,int requestCode,MessageResponse response) { //将网络请求回来的结果利用MessageSelector选择器,选择出有用的消息 getMessageSelector().assignMessageFromNet(MobogeniePushServiceNew.this,new MessageGetListener() { @Override public void showMessages(List<MoboPushMessage> msgs) { if (msgs.size() > 0) { for (MoboPushMessage msg : msgs) { notifyMessageAndDelete(msg,false); } } } @Override public void prepareMessages(List<MoboPushMessage> msgs) { if (msgs == null || msgs.size() == 0) { return; } MoboPushMessageDBUtils.insertBatch(MobogeniePushServiceNew.this,msgs); initShowMessageAlarm(msgs); } },response.messages); } MoboPushRequest去拉取新的消息 public void pullPushMessages(Context context,final IMessageGetListener l,final int requestCode) { boolean pushFlag = true; if (!pushFlag) { return; } final Context appcontext = context.getApplicationContext(); //这里进行http请求,得到json数据 String json = ""; if (!TextUtils.isEmpty(json)) { JSONObject jsonObj = null; String str = null; try { jsonObj = new JSONObject(json); if (jsonObj.optInt("code") == 100) { int interval = jsonObj.optInt("interval"); MessageResponse response = new MessageResponse(); response.interval = interval * 1000; JSONArray jsonArray = jsonObj.optJSONArray("list"); if (jsonArray == null || jsonArray.length() == 0) { } int aLength = jsonArray.length(); response.initMessageArray(aLength); response.resCode = 100; for (int i = 0; i < aLength; i++) { JSONObject jsonInArray = jsonArray.getJSONObject(i); str = jsonInArray.toString(); MoboPushMessage pushMessage = new MoboPushMessage(); pushMessage.parseJson(str); response.messages[i] = pushMessage; if (pushMessage != null ) { } } } else { } } catch (JSONException e) { } } Object object=null; int actionCode=0; if (l == null) { return; } if (actionCode==0 && object != null && object instanceof MessageResponse) { MessageResponse response = (MessageResponse) object; l.onMessageLoaded(actionCode,requestCode,response); } else { l.onMessageLoaded(actionCode,null); } } 剩下的就是处理具体的push消息了 private void notifyMessageAndDelete(MoboPushMessage message,boolean delete) { if (message == null) { return; } //传入message对象发送通知 getMoboPushNotifyHelper().showNotification(message); } 我们只有message对象怎样利用这个message对象去发送不同类型的push呢,为了很好的扩展,直接上代码 public void showNotification(MoboPushMessage message) { final Intent targetIntent = obtainNotificationClick(message,false); setNotification(message,targetIntent); } public void setNotification(final MoboPushMessage message,final Intent intent) { //根据MoboPushMessage和Intent来show通知 } 重点就在这句话了,怎样根据message检测出需要的push呢 final Intent targetIntent = obtainNotificationClick(message,false); 我们可以看见getTargetIntent(mContext,message)这个方法主要作用 public Intent obtainNotificationClick(MoboPushMessage message,boolean flag) { if (message == null) { return null; } PushActionCreator actionCreator = new PushActionCreator(); return actionCreator.getTargetIntent(mContext,message); } 核心在这里 public Intent getTargetIntent(Context c,MoboPushMessage pushMessage){ if(pushMessage==null) { return null; } int type = pushMessage.type; Intent resultIntent = null; for(IPushIntentAction action:mPushActions){ if(action.isTypeForAction(type)){ try{ resultIntent = action.createTargetIntent(c,pushMessage); }catch(Exception e){ } break; } } return resultIntent; } 将不同类型的push对象添加到这个集合里面去 ArrayList<IPushIntentAction> mPushActions; 也就是所有的push数据都要实现这个公共的接口 public interface IPushIntentAction { public Intent createTargetIntent(Context context,MoboPushMessage message); public int getActionKey(); public boolean isTypeForAction(int type); public String getNextPage(); } 其中createTargetIntent这个根据不同的类型new出各自的intent,isTypeForAction比对类型 举个例子大家就知道了。 public class PushActionDefault implements IPushIntentAction { @Override public Intent createTargetIntent(Context c,MoboPushMessage message) { Intent intent = new Intent(); intent.setAction("android.intent.action.MAIN"); intent.addCategory("android.intent.category.LAUNCHER"); return intent; } @Override public int getActionKey() { return MoboPushMessage.TYPE_OPEN_APP; } @Override public String getNextPage() { return null; } @Override public boolean isTypeForAction(int type) { return false; } } 基本上把一条线给贯穿了,其中 最近比较忙,之后一定把整理好的demo分享给大家。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。 您可能感兴趣的文章:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |