android用闹钟定时做http请求推送的解决方案

设计思路

如果在开发当中需要做push接入,而产品又要求不允许用第三方sdk(百度push,友盟push),而且又没有网络编程的经验,这个时候怎么办?这里就给大家分享下用http请求解决这个问题。

大体的设计思路是,写一个service(为了保证长时间运行不被kill,就将其定义到另外的进程当中去),在这个service里面启动闹钟,每隔一段时间(这个时间可以自己定义)去请求服务器,如果有新的push消息,就通知给用户。

具体实现

貌似很简单定义一个闹钟不断轮循请求服务器一句话,却在实际开发中要考虑很多问题,下面简单给大家列出来。

1)闹钟时间校准
2)每天push只能在固定的或者某个定义的时间内推送
3)push类型的扩展,新添加一种类型的push

什么都不说,类图直接贴上

大概分为三级结构

第一级:MoboPushAlarmManager,主要工作是管理闹钟,初始化闹钟,对闹钟时间进行校准,取消闹钟。
第二级:MobogeniePushServiceNew,主要工作是对闹钟设置的pendingintent的动作(startservice)进行处理。
第三级:MoboPushNotifyHelper,主要工作是实例化notification对象,发送出通知,并且取消通知。MoboMessageSelector,主要工作是从n多个push中根据时间选择出可用的push。MoboPushRequest,主要是请求服务器,从服务器列表中获取push队列。
其余的PushActionCreator,MoboPushMessage等等都属于第三级或者第一第二级的工具类了。

开始来贴代码了(具体的源码还没抽出来,过段时间再贴上)
MoboPushAlarmManager来初始化闹钟,当闹钟响了就会发送一个intent给MobogeniePushServiceNew

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, requestCode, 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;
 }

}

基本上把一条线给贯穿了,其中
1)闹钟时间校准
解决方法可以自由的写在初始化闹钟里面,如果发现时间有错误,可以再初始化一下闹钟,这样就可以覆盖以前的闹钟
2)每天push只能在固定的或者某个定义的时间内推送
我们在MoboMessageSelector选择器里面专门对时间进行了筛选
3)push类型的扩展,新添加一种类型的push
我们要添加新的类型的push的时候,只需要实现IPushIntentAction 这个接口,然后在将对象添加到ArrayList mPushActions这个集合里面,供选择就OK了

最近比较忙,之后一定把整理好的demo分享给大家。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android编程使用Service实现Notification定时发送功能示例
  • Android闹钟机制实现定时任务功能
  • android service实现循环定时提醒功能
(0)

相关推荐

  • Android闹钟机制实现定时任务功能

    Android的闹钟实现机制, 需要调用AlarmManager.set()将闹铃时间记录到系统中,当闹铃时间到后,系统会给应用程序发送广播,我们只需要去注册广播接收器就可以了. 本文分三部分讲解如何实现闹钟: 目录: 1. 设置闹铃时间; 2. 接收闹铃事件广播; 3. 重开机后重新计算并设置闹铃时间; 1. 设置闹铃时间(毫秒) private void setAlarmTime(Context context, long triggerAtMillis) { AlarmManager am

  • android service实现循环定时提醒功能

    人每天都要喝8杯水才能保持健康,于是苦逼的程序员总是一遍代码就忘了时间,于是我突发奇想能不能开发一个apk能够实现固定的间隔时间定时提醒我要喝水了呢? apk基本功能: 1)能够设置间隔时间 2)在apk应用被停止的情况下仍然能定时提醒 3)能够播放指定闹铃 4)能够及时终止提醒 效果图: 设置间隔 时间到后会跳出全局AlertDialog提示并且开始播放闹铃 即使APP被终止了,仍然能够提示 结束提示 废话不多说,直接上代码: 布局layout: <?xml version="1.0&q

  • Android编程使用Service实现Notification定时发送功能示例

    本文实例讲述了Android编程使用Service实现Notification定时发送功能.分享给大家供大家参考,具体如下: /** * 通过启动或停止服务来管理通知功能 * * @description: * @author ldm * @date 2016-4-29 上午9:15:15 */ public class NotifyControlActivity extends Activity { private Button notifyStart;// 启动通知服务 private Bu

  • android用闹钟定时做http请求推送的解决方案

    设计思路 如果在开发当中需要做push接入,而产品又要求不允许用第三方sdk(百度push,友盟push),而且又没有网络编程的经验,这个时候怎么办?这里就给大家分享下用http请求解决这个问题. 大体的设计思路是,写一个service(为了保证长时间运行不被kill,就将其定义到另外的进程当中去),在这个service里面启动闹钟,每隔一段时间(这个时间可以自己定义)去请求服务器,如果有新的push消息,就通知给用户. 具体实现 貌似很简单定义一个闹钟不断轮循请求服务器一句话,却在实际开发中要

  • Android实现几种推送方式解决方案

    本文介绍在Android中实现推送方式的基础知识及相关解决方案.推送功能在手机开发中应用的场景是越来起来了,不说别的,就我们手机上的新闻客户端就时不j时的推送过来新的消息,很方便的阅读最新的新闻信息.这种推送功能是好的一面,但是也会经常看到很多推送过来的垃圾信息,这就让我们感到厌烦了,关于这个我们就不能多说什么了,毕竟很多商家要做广告.本文就是来探讨下Android中实现推送功能的一些解决方案,也希望能够起到抛砖引玉的作用.^_^ 1.推送方式基础知识: 在移动互联网时代以前的手机,如果有事情发

  • 浅谈我是如何用redis做实时订阅推送的

    前阵子开发了公司领劵中心的项目,这个项目是以redis作为关键技术落地的. 先说一下领劵中心的项目吧,这个项目就类似京东app的领劵中心,当然图是截取京东的,公司的就不截了... 其中有一个功能叫做领劵的订阅推送.什么是领劵的订阅推送?就是用户订阅了该劵的推送,在可领取前的一分钟就要把提醒信息推送到用户的app中.本来这个订阅功能应该是消息中心那边做的,但他们说这个短时间内做不了.所以让我这个负责优惠劵的做了-.-!.具体方案就是到具体的推送时间点了,coupon系统调用消息中心的推送接口,把信

  • Android中使用socket通信实现消息推送的方法详解

    原理 最近用socket写了一个消息推送的demo,在这里和大家分享一下. 主要实现了:一台手机向另外一台手机发送消息,这两台手机可以随时自由发送文本消息进行通信,类似我们常用的QQ. 效果图: 原理:手机通过socket发送消息到服务器,服务器每接收到一条消息之后,都会把这条消息放进一个messageList里面,服务器会不停地检测messageList是否含有消息,如果有的话就会根据messageList里面item的数据,推送到相应的另一端手机上面. 下面简单画了一个图来说明这个原理: 演

  • Android手机端小米推送Demo解析和实现方法

    最近这几个月都是在准备找工作和找工作中,付出了很多,总算是有点收获,所以都没有怎么整理笔记.到了最近才有空把自己的笔记整理一下发上来,分享一下我的学习经验. 推送 由于最近项目要用到Android的消息推送,关于Android推送的解决方案有很多种,有C2DM,轮询, SMS,MQTT协议,XMPP协议和第三方平台,经过我们对项目需求的考虑之后我们选择了第三方平台推送的小米推送,下面就是小米推送的实现方法. 实现准备 想要用小米推送首先要去小米开发者平台注册申请开发者账号,经过1到3天的审核之后

  • iOS10推送教程详解

    上个月接到一个需求,做ios10的推送,意图冲击AppStore头条.瞬间抓狂,工具都还没有,于是赶紧安装xcodeBeta版,ios10Beta版,然后就开始无尽的查资料,毕竟新功能,毕竟没做过........不过还好,在发布会之前赶出来了,由于本人比较懒,拖到现在才写出来,接下来就是见证奇迹的时刻! 原理 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple Push Notification Service(

  • iOS实现远程推送原理及过程

    推送通知,是现在的应用必不可少的功能.那么在 iOS 中,我们是如何实现远程推送的呢?iOS 的远程推送原理又是什么呢?在做 iOS 远程推送时,我们会遇到各种各样的问题.那么首先让我们准备一些做推送需要的东西.我们需要一个付费的苹果开发者账号(免费的不可以做远程推送),有了开发者账号,我们可以去苹果开发者网站,配置自己所需要的推送的相关证书.然后下载证书,供我们后面使用,详细的证书配置过程,我们下面再说. 首先我们要说说iOS推送通知的基本原理: 苹果的推送服务通知是由自己专门的推送服务器AP

  • .NET对接极光消息推送的实现方法

    目录 什么是APP消息推送? 极光推送介绍 快速对接Jpush极光推送 .NET FX 4.5项目接入 相关链接地址 什么是APP消息推送? 很多手机APP会不定时的给用户推送消息,例如一些新闻APP会给用户推送用户可能感兴趣的新闻,或者APP有更新了,会给用户推送是否选择更新的消息等等,这就是所谓的“消息推送”. 更多APP消息推送的介绍可查阅该篇文章:十分钟带你了解APP消息推送(Push) 如下是我们日常生活中常见的一些APP消息推送示例: 强营销类: 直接把营销力度,营销模式以一种叫卖式

  • 使用 Javascript 实现浏览器推送提醒功能的示例

    本篇文章内容简单,速读只需两三分钟,通过这两三分钟的时间你就可以给自己的网站实现推送提醒的功能 Notification 类 简单明了,这个类就是负责推送消息的,只要用户当前没有关闭页面,及时是在使用其他程序,浏览器也能够将消息推送给用户 请求权限 我们在手机上都收到过消息推送,在接收推送之前我们会先将消息推送权限开放给应用.在浏览器中也一样,在使用浏览器推送之前,需要先获取权限 Notification.requestPermission().then(permission => { cons

  • SignalR Self Host+MVC等多端消息推送服务(二)

    一.概述 上次的文章中我们简单的实现了SignalR自托管的服务端,今天我们来实现控制台程序调用SignalR服务端来实现推送信息,由于之前我们是打算做审批消息推送,所以我们的demo方向是做指定人发送信息,至于做聊天消息和全局广播,这里就不在进行演示了. 二.创建控制台客户端 1.在SignalRProject解决方案下新建一个名为Clinet的控制台 2.在程序包管理控制台中输入以下命令 Install-Package Microsoft.AspNet.SignalR.Client 3.修改

随机推荐