在项目初期,就安卓推送功能怎么做,曾经参考过例如XMPP之类的推送方法。但苦于那些是些英文档案,又没太多时间研究,所以打算采用第三方推送(个推,极光推送等),后来在美图技术老大推荐下用采用个推。
PS:网传个推的采用者有如(新浪微博、百度、网龙、去哪儿等)。

该android的PHP推送采用的思维逻辑跟 ios+php 推送同理,为APP推送架设的android_push.php部分

在linux的 crontab 定时计划里 加入

1
* * * * * /usr/local/php/bin/php /www/push/getui/android_push.php app1_android 100

第一个参数 app1_ios
标识app1应用,memcacheq队列里面等待推送的android队列名也是app1_android 在app推送架设里就是android_go所代表的那些中的一个队列
第二个参数 100
运行一次往个推服务器发送要推送的消息数。

android_push.php (该文件在个推的php demo上进行适当修改)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#!/usr/local/php/bin/php
<?php
date_default_timezone_set('Asia/Shanghai');
set_time_limit(0);
/**
 * 推送器安卓个推模块
 * @param string $argv[1] memcacheq 键值
 */
require_once(dirname(__FILE__). '/' . 'IGt.Push.php');
 
$mem_key = $argv[1];
$key_count = $argv[2];
 
if(empty($mem_key))
{
    exit('first parameter is a must');
}
if(empty($key_count))
{
    exit('second parameter is a must');
}
if($key_count>2000||$key_count<1){
    exit('error second parameter');
}
 
//该配置信息为注册个推时所给的app唯一标识信息
$app_config_arr=array(
    'app1_push_android' => array(
        'APPKEY' => 'xxxxxooooooddddddd',
        'APPID' => 'xxxxxooooooddddddd',
        'MASTERSECRET' => 'xxxxxooooooddddddd',
    ),
);
 
$app_config=$app_config_arr[$mem_key];
if(empty($app_config))
{
    exit('error app push name');
}
 
//开始推送
run($app_config, $mem_key, $key_count);
 
//用while死循环,来提高推送频率,间隔5秒。(可根据实际情况而定)
//createPidFile和deletePidFile 用来确保同一时刻只存在一个进程在执行推送php
function run($app_config,$mem_key,$key_count)
{
    if (createPidFile(__DIR__.'/../logs/cron_'.$mem_key.'_android.pid'))
    {
        exit();
    }
    while (TRUE)
    {
        try
        {
            pushMessageToSingle($app_config,$mem_key,$key_count);
            sleep(5);
        }
        catch (Exception $e)
        {
            log_error($mem_key,date("[Y-m-d H:i:s] ", time()) . $e->getMessage() . "\n");
            sleep(5);
        }
    }
    deletePidFile(__DIR__.'/../logs/cron_'.$mem_key.'_android.pid');
}
 
function pushMessageToSingle($app_config,$mem_key,$key_count){
     
    $igt = new IGeTui(HOST,$app_config['APPKEY'],$app_config['MASTERSECRET']);
    $time=time();
    //通用文字模板
    $template_base new IGtNotificationTemplate();
    $template_base->set_appId($app_config['APPID']);//应用appid
    $template_base->set_appkey($app_config['APPKEY']);//应用appkey
    $template_base->set_title("测试应用");//通知栏标题
    $template_base->set_transmissionType(1);//透传消息类型,打开应用
    $template_base->set_logo("logo.png");//通知栏logo
    $template_base->set_isRing(false);//是否响铃
    $template_base->set_isVibrate(false);//是否震动
    $template_base->set_isClearable(true);//通知栏是否可清除
     
     
    //通用带连接模板
    $template_url new IGtLinkTemplate();
    $template_url->set_appId($app_config['APPID']);//应用appid
    $template_url->set_appkey($app_config['APPKEY']);//应用appkey
    $template_url->set_title("测试应用");//通知栏标题
    $template_url->set_logo("logo.png");//通知栏logo
    $template_url->set_isRing(false);//是否响铃
    $template_url->set_isVibrate(false);//是否震动
    $template_url->set_isClearable(true);//通知栏是否可清除
     
    //个推信息体
    $message = new IGtSingleMessage();
    $message->set_isOffline(true);//是否离线
    $message->set_offlineExpireTime(3600*24);//离线时间
     
    //接收方
    $target = new IGtTarget();
    $target->set_appId($app_config['APPID']);
//开始连接推送memcacheq队列
    $m = new memcache();
    $m->connect('127.0.0.1',22201);
    for($i=0;$i<$key_count;$i++)
    {
        $push_body=$m->get($mem_key);
//从推送队列取出的推送体push_body,详见底部PS:1
        if(empty($push_body))
        {
            break;
        }
        else if(is_string($push_body))
        {
            $push_body=unserialize($push_body); //居然要反序列--
        }
        if($push_body['push_type']==1)  //文字推送 
        {
            $template_base->set_text($push_body['content']);//通知栏内容
            $message->set_data($template_base);//设置推送消息类型
        }
        else    //带连接推送
        {
            $template_url->set_text($push_body['content']);//通知栏内容
            $template_url->set_url($push_body['msg_link']);//打开连接地址
            $message->set_data($template_url);//设置推送消息类型
        }
        $target->set_clientId($push_body['device_code']);
        $rep = $igt->pushMessageToSingle($message,$target);
        if($rep["result"]!='ok')
        {
            log_pushed($push_body,$mem_key,$rep["result"]);
        }
        $push_body['push_time']=$time;
//每个完成推送的消息将附上时间,然后存储进推送完毕队列
        $m->set($mem_key.'_end',$push_body);
    }
}
//传输错误日志
function log_pushed($push_body,$mem_key,$result)
{
    $file = __DIR__.'/../logs/'.$mem_key.'_error_' . date("Y-m-d") . '.log';
    $str='[ '. date('Y-m-d H:i:s',time()) .' ] [ device_id - '.$push_body['id'].' ] [ '.$push_body['content'].' ] [ result :'.$result." ] \n";
    error_log($str, 3, $file);
}
//定时错误日志
function log_error($mem_key,$msg)
{
    $file = __DIR__.'/../logs/'.$mem_key.'_error_' . date("Y-m-d") . '.log';
    error_log($msg, 3, $file);
}
//将当前php文件执行进程写进pid文件
function createPidFile($pid_filename)
{
    if (file_exists($pid_filename))
    {
        $old_pid = trim(file_get_contents($pid_filename));
        if (file_exists('/proc/' . $old_pid . '/cmdline'))
        {
            return TRUE;
        }
    }
    $pid = posix_getpid();
    $pid = strval($pid);
    file_put_contents($pid_filename, $pid);
    return FALSE;
}
//删除pid文件
function deletePidFile($pid_filename)
{
    @unlink($pid_filename);
}
?>

PS:
1、从推送队列取出的推送体push_body
可能直接是个数组,也可能个字符串。这取决于你存入memecacheq时所处的位置。
(1)若是本台服务器代码组装push_body存入本身的memcacheq,那么取出时将直接是个数组。
(2)若是跨服务器的传输memcacheq,那么取出是将是个数组字符串化,需要unserialize。

2、个推demo
(下载地址:http://www.igetui.com/download/android/SDK_OPEN.zip
客户端包含:
• 文档(手把手教你在Android上嵌入SDK)
• 需导入的资源(包含GexinSdk.jar包,您的应用需导入该jar库用于和SDK通信)
• 演示工程源码
• 真机测试包
服务端包含:
• 文档(服务端API文档,详细指导如何调用接口)
• 需导入的资源
• php演示工程

android推送-PHP(第三方推送:个推)的更多相关文章

  1. Android、iOS和Windows Phone中的推送技术

    推送并不是什么新技术,这种技术在互联网时代就已经很流行了.只是随着进入移动互联网时代,推送技术显得更加重要.因为在智能手机中,推送从某种程度上,可以取代使用多年的短信,而且与短信相比,还可以向用户展示 ...

  2. 做推送,怎么能不了解推送的 4 种消息形式呢?( Android 篇)

    极光推送是为 App 提供第三方推送服务的平台之一,它提供四种消息形式:通知,自定义消息,富媒体和本地通知. 笔者将基于官方说明与个人理解来谈一下这四种消息.本篇为 Android 篇,iOS 篇入口 ...

  3. Android融合推送MixPush SDK集成多家推送平台,共享系统级推送,杀死APP也能收到推送

    消息推送是App运营的重要一环,为了优化消息推送成功率,降低电量和流量消耗,系统级的推送服务显得尤为重要.小米和魅族由此推出了自家的推送平台,在MIUI和Flyme上共享系统级推送服务,让APP在被杀 ...

  4. android系统和ios系统是如何实现推送的,ios为什么没有后台推送

    ios系统为什么没有后台推送? iOS 为了真正地为用户体验负责,不允许应用在后台活动.有了这个限制,但是对于终端设备,应用又是有必要“通知”到达用户的,随时与用户主动沟通起来的(典型的如聊天应用). ...

  5. ZABBIX新功能系列1-使用Webhook将告警主动推送至第三方系统

    Zabbix5以来的新版本与以前的版本除UI界面变化较大外,在很多功能上也有许多亮点,我这里计划安排1个系列来和大家交流一些新功能的使用,这是第一篇:使用Webhook将告警主动推送至第三方系统. 首 ...

  6. HTML5服务器端推送事件 解决PHP微信墙推送问题

    问题描述 以前的文章中<PHP微信墙制作,开源>已经用PHP搭建了一个微信墙获取信息的服务器,然后我就在想推送技术应该怎么解决,上一篇已经用了.NET 的signalr做了一个微信墙,PH ...

  7. AndroidStudio离线打包MUI集成JPush极光推送并在java后端管理推送

    1.AndroidStudio离线打包MUI 如何离线打包请参看上篇随笔<AndroidStudio离线打包MUI> 2.集成极光推送 官方文档:https://docs.jiguang. ...

  8. iOS原生推送(APNS)进阶iOS10推送图片、视频、音乐

    代码地址如下:http://www.demodashi.com/demo/13208.html 前言 我们首先要在AppDelegate里面进行iOS的适配,可以参考这篇文章 iOS原生推送(APNS ...

  9. 【开源毕设】一款精美的家校互动APP分享——爱吖校推 [你关注的,我们才推](持续开源更新3)附高效动态压缩Bitmap

    一.写在前面 爱吖校推如同它的名字一样,是一款校园类信息推送交流平台,这么多的家校互动类软件,你选择了我,这是我的幸运.从第一次在博客园上写博客到现在,我一次一次地提高博文的质量和代码的可读性,都是为 ...

随机推荐

  1. IOS设计模式学习(19)策略

    1 前言 面向对象软件设计中,我们可以把相关算法分离为不同的类,成为策略.与这种做法有关的一种设计模式成为策略模式. 2 详述 2.1 简述 策略模式中得一个关键角色是策略类,它为所有支持的或相关的算 ...

  2. javascript--瀑布流

    简单瀑布流代码实现 html代码例如以下 <!DOCTYPE html> <html> <head> <meta http-equiv="Conte ...

  3. 学习 Netty 3.x

    study link: http://netty.io/3.6/guide/#architecture 应用场景: Chat server that requires persistent conne ...

  4. android View各属性详解

    一.有8个直接子类:AnalogClock, ImageView, KeyboardView, ProgressBar, SurfaceView, TextView, ViewGroup, ViewS ...

  5. (转)Android 判断用户2G/3G/4G移动数据网络

    在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需(要根据用户当前网络情况来做一些调整的,也可以在 App 的设置模块里,让用户自己选择,在 2G ...

  6. linux nc命令

    即NetCat简写,在网络工具中有“瑞士军刀”美誉,其有Windows和Linux的版本.因为它短小精悍(1.84版本也不过25k,旧版本或缩减版甚至更小).功能实用,被设计为一个简单.可靠的网络工具 ...

  7. css快捷方式

    本来是年前准备整理发布的,都搞定50%了,一篇万恶的<盗墓笔记:九幽将军>让我猪油蒙了心.....诶,不说了,搞一半就算了,最后还忘了保存,此刻只听得那一万只草某马呼啸而过... 言归正传 ...

  8. HTML、CSS、JS、PHP 的学习顺序~(零基础初学者)

    如果你有耐心坚持一年以上的话, 我会推荐HTML->CSS->JS->PHP的顺序来学习. 1. HTML学习:首先学习HTML,HTML作为标记语言是非常容易学的,把w3schoo ...

  9. 《大话移动 APP 测试》

    <大话移动 APP 测试> wiki: Software testing 第5章 常用工具介绍和实践 Android.iOS Monkey Android SDK 提供的一个工具:发送伪随 ...

  10. C#--virtual,abstract,override,new,sealed

    virtual:使用此关键字,可以使其在派生类中被重写. abstract:抽象方法,由子类重写,或继续为抽象方法存在,并由其子子类实现. override: 重写父类方法,属性,或事件的抽象实现或虚 ...