sion android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:name=".MyApplication"
android:theme="@style/AppTheme"> <!-- Required. For publish channel feature -->
<!-- JPUSH_CHANNEL 是为了方便开发者统计APK分发渠道。-->
<!-- 例如: -->
<!-- 发到 Google Play 的APK可以设置为 google-play; -->
<!-- 发到其他市场的 APK 可以设置为 xxx-market。 -->
<!-- 目前这个渠道统计功能的报表还未开放。-->
<meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
<!-- Required. AppKey copied from Portal -->
<meta-data android:name="JPUSH_APPKEY" android:value="52f7fd72d96df72e2a811d7c"/> <!-- Required -->
<receiver
android:name="cn.jpush.android.service.PushReceiver"
android:enabled="true" >
<intent-filter android:priority="1000">
<action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />
<category android:name="com.example.dell.imooc_jpushdemo"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<!-- Optional -->
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
<!-- Required SDK核心功能-->
<activity
android:name="cn.jpush.android.ui.PushActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false" >
<intent-filter>
<action android:name="cn.jpush.android.ui.PushActivity" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.example.dell.imooc_jpushdemo" />
</intent-filter>
</activity>
<!-- Required SDK核心功能-->
<service
android:name="cn.jpush.android.service.DownloadService"
android:enabled="true"
android:exported="false" >
</service>
<!-- Required SDK核心功能-->
<receiver android:name="cn.jpush.android.service.AlarmReceiver" /> <!-- Required SDK 核心功能-->
<!-- option since 2.0.5 可配置PushService,DaemonService,PushReceiver,AlarmReceiver的android:process参数 将JPush相关组件设置为一个独立进程 -->
<!-- 如:android:process=":remote" -->
<service
android:name="cn.jpush.android.service.PushService"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="cn.jpush.android.intent.REGISTER" />
<action android:name="cn.jpush.android.intent.REPORT" />
<action android:name="cn.jpush.android.intent.PushService" />
<action android:name="cn.jpush.android.intent.PUSH_TIME" />
</intent-filter>
</service> <activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

至此androidSDK的配置就完成了,现在我们可以去极光的去推送一下消息,如果应用可以收到推送,这说明配置正确。

wampServer服务端配置

服务端这里采用wampServer的方式,当然是处于简单方便的考虑,还可以使用其他的脚本语言来实现,而极光推送的官网也提供了相应的服务端SDK供大家使用

这里的继承方式采用官方提供的sdk(也就是本文介绍的第三种方法),当然,也可以使用PHP向推送方直接发送HTTP请求。

配置推送SDK

极光官方建议使用composer进行SDK安装,而且给了非常简单的介绍 

接下来介绍一下composer的安装。

通过composer配置

关于什么是composer,我个人把它理解为android里面的gradle,在android里面,我们可以在gradle中添加一句 “compile XXX”就能轻松引入第三方库,而composer的功能也是如此,composer是 PHP 用来管理依赖(dependency)关系的工具。你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer 会帮你安装这些依赖的库文件。

这里简单介绍一下composer的下载,不放心的小伙伴可以去Composer中文网相关查看教程。

(1)从官网下载composer

传送门:Windows下载

一路next,安装完毕后在cmd里面输入composer

即说明下载成功。

(2)关于composer.phar

在查阅资料的时候,我看到了composer.phar文件,后来研究了一下,得出了一些结论。

composer.phar 可以理解为composer的一个命令集合,不需要无需下载配置composer环境,只需要在PHP环境下,即可被使用,基本的使用方法是

php composer.phar XXXX

XXX表示composer的命令

而我们在这第一步下载的composer.exe,它实际做的一件事情是下载composer各种命令,并把composer添加到环境变量中(这也是为什么我们安装完毕后,在dos界面输入composer能够有反应的原因),其用法是:

composer XXX

发现没,这里的composer无需使用php,就能够执行composer的命令

综上述所述,如果你不想安装composer.exe,下载一个composer.phar文件,然后在PHP环境下运行就可以了,二者没有太大的差别。

不过有一点需要注意的是,命令的运行目录,一定要是当前的项目目录(存放有composer.json)。

(3)编写composer.json文件

此文件的作用主要用来声明包之间的相互关系和其他的一些元素标签。 
接下来,我们来到项目目录(我的是wamp/www/push) 
在此目录下新建一个叫 composer.json的文件

在此文件里面输入后保存,退出;

{
"require": {
"jpush/jpush": "v3.5.*"
}
}

(4)下载第三方库

接下来,我们需要在cmd当中不断的cd目录,一直进入到我们当前的push目录,这里教大家一个简单的方法。如果你装了git,那么直接右键push目录,点击git brash here 就能很方便地打开dos界面。

键入下载的命令:

composer install

或者

php composer.phar install

二者的区别请见第二点

在解释上面问题之前,需要讲讲composer.lock这个文件

在安装完所有需要的包之后,composer会生成一张标准的包版本的文件在composer.lock文件中。这将锁定所有包的版本。

使用composer.lock(当然是和composer.json一起)来控制你的项目的版本

这一点非常的重要,我们使用install命令来处理的时候,它首先会判断composer.lock文件是否存在,如果存在,将会下载相对应的版本(不会在于composer.json里面的配置),这意味着任何下载项目的人都将会得到一样的版本。

如果不存在composer.lock,composer将会通过composer.json来读取需要的包和相对的版本,然后创建composer.lock文件

这样子就可以在你的包有新的版本之后,你不会自动更新了,升级到新的版本,使用update命令即可,这样子就能获取最新版本的包并且也更新了你的composer.lock文件。

所以,第一次的话,使用install命令,之后的使用updata命令就好了。

全部下载完成后,我们的当前的项目目录应该是这个样子的。

编写推送接口

终于到了编写接口的部分了

为了方便的加载包文件,Composer自动生成了一个文件 vendor/autoload.PHP,我们可以方便只有的使用它在任何你需要使用的地方。

新建一个test.php文件 在里面实现我们的推送逻辑。

<?php
//composer下载下来的第三方SDK都放在vendor文件夹中
//注意路径
require 'vendor/jpush/jpush/autoload.php'; //接受post来的参数
$params=$_POST; //创建应用的AppKey和master_secret,可以在极光应用后台查看
$app_key="52f7fd72d96df72e2a811d7c";
$master_secret="847d609885ec219f313b0c12"; /*
* 官方代码
* */
$client = new \JPush\Client($app_key, $master_secret); $pusher = $client->push();
//设置平台
$pusher->setPlatform('all'); $pusher->addAllAudience(); //唯一标识符,暂不使用
//$pusher->addAlias($params['alias']);
// 简单地给所有平台推送相同的 alert 消息 $pusher->setNotificationAlert('Hello, JPush');
try {
$result=$pusher->send();
var_dump($result);
} catch (\JPush\Exceptions\JPushException $e) {
// try something else here
print $e;
}

官方文档里有更详细的介绍,相信大家结合上面的注释应该是可以看懂的。

这个API的作用是向所有的客户发送一条消息。

现在把wampServer运行起来,在浏览器输入这个接口。

http://localhost/push/test.php

如果调用成功,则说明接口正确~~

定向推送

到这里,从客户端到服务端的基本推送逻辑已经完成了,接下来我们做的一件事情就是实现定向的推送,即通过这个alias,将消息发送给指定的用户

android客户端改动

首先填写一个布局文件MainActivity.xml

效果如下: 

比较简陋,一个editText用于设定alias,一个editText用于输入目标alias,还有一个Spinner用于选择推送的类型。

xml代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.dell.imooc_jpushdemo.MainActivity"> <LinearLayout
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/et_set_alias"
android:gravity="center"
android:hint="设定alias"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <Button
android:id="@+id/bt_set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置"
/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="当前alias:未设置"
android:id="@+id/tv_alias"
android:textSize="18sp"
android:layout_marginTop="22dp" /> <EditText
android:id="@+id/et_alias"
android:gravity="center"
android:layout_marginTop="20dp"
android:hint="输入目标alias"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/> <Spinner
android:id="@+id/push_type"
android:layout_width="match_parent"
android:layout_height="30dp"
/> <Button
android:id="@+id/bt_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送"
android:layout_marginTop="23dp" /> <TextView
android:id="@+id/tv_result"
android:text="推送结果"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
/>
</LinearLayout>
</RelativeLayout>

接下来,我们编写MainActivity当中的逻辑

public class MainActivity extends AppCompatActivity {
//接口地址,根据本机的IP地址改动
private final String url="http://192.168.0.128/push/test.php";
//返回的结果
private TextView tvResult;
private Button btSend; //发送推送请求
private Spinner mSpinner; //选择推送方式
//推送种类
private String pushType;
//spinner的适配器
private ArrayAdapter<String> adapter;
//设置alias的按钮
private Button btSetAlias;
//显示用户设置的alias
private TextView tvAlias;
private String alias; //更新UI
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
StringBuffer sb = (StringBuffer) msg.obj;
tvResult.setText(sb.toString());
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSpinner= (Spinner) findViewById(R.id.push_type);
tvResult= (TextView) findViewById(R.id.tv_result);
btSend= (Button) findViewById(R.id.bt_send);
btSetAlias= (Button) findViewById(R.id.bt_set);
tvAlias= (TextView) findViewById(R.id.tv_alias);
//spinner内的文字
String[] strings=getResources().getStringArray(R.array.push_type);
List<String> list=new ArrayList<>();
for(String s:strings){
list.add(s);
} adapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_spinner_item,list);
//第三步:为适配器设置下拉列表下拉时的菜单样式。
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//第四步:将适配器添加到下拉列表上
mSpinner.setAdapter(adapter); mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
pushType=adapter.getItem(i);
/* 将mySpinner 显示*/
adapterView.setVisibility(View.VISIBLE);
} @Override
public void onNothingSelected(AdapterView<?> adapterView) {
adapterView.setVisibility(View.VISIBLE);
}
}); //设置alias
btSetAlias.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
alias=((EditText)findViewById(R.id.et_set_alias)).getText().toString();
//调用SDK接口
JPushInterface.setAlias(getBaseContext(),alias, new TagAliasCallback() {
@Override
public void gotResult(int i, String s, Set<String> set) {
tvAlias.setText("当前alias:"+alias);
Toast.makeText(MainActivity.this, "设置成功", Toast.LENGTH_SHORT).show();
}
});
}
}); btSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendRequest();
}
});
} private void sendRequest() {
new Thread(new Runnable() {
@Override
public void run() { String alias=((EditText)findViewById(R.id.et_alias)).getText().toString();
try {
// 传递的数据
String data ="&alias="+URLEncoder.encode(alias,"UTF-8")
+"&push_type="+URLEncoder.encode(pushType,"UTF-8");
URL httpUrl = new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) httpUrl.openConnection();
urlConnection.setRequestMethod("POST"); // 设置请求的超时时间
urlConnection.setReadTimeout(5000);
urlConnection.setConnectTimeout(5000); //调用conn.setDoOutput()方法以显式开启请求体
urlConnection.setDoOutput(true); // 发送POST请求必须设置允许输出
urlConnection.setDoInput(true); // 发送POST请求必须设置允许输入 //setDoInput的默认值就是true
OutputStream ost = urlConnection.getOutputStream(); PrintWriter pw = new PrintWriter(ost);
pw.print(data);
pw.flush();
pw.close(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer sb = new StringBuffer();
String s;
while ((s = bufferedReader.readLine()) != null) {
sb.append(s);
Log.d("111", "run: "+sb.toString());
}
Message msg = new Message();
msg.obj = sb;
handler.sendMessage(msg);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}

R.array.push_type里面的内容:(在res/value/arrays.xml中配置,如果没有这个xml文件,手动创建)

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="push_type">
<item>push Type</item>
<item>new_task</item>
<item>send_task</item>
<item>get_task</item>
<item>finish_task</item>
</string-array>
</resources>

注释都比较清楚,网络操作使用的是调用android原生的API,当然也可以使用一些网络框架来完成。

最后,我们对服务端的代码进行改动

服务端改动

服务端test.php

<?php
//composer下载下来的第三方SDK都放在vendor文件夹中
//注意路径
require 'vendor/jpush/jpush/autoload.php'; //接受post来的参数
$params=$_POST; //创建应用的AppKey和master_secret,可以在极光应用后台查看
$app_key="52f7fd72d96df72e2a811d7c";
$master_secret="847d609885ec219f313b0c12"; $title='';
$alert='';
//接受客户端参数
@$alias=$_POST['alias'];
@$push_type=$_POST['push_type']; if(empty($alias)){
echo 'alias null';
return;
}
switch ($push_type){
case "new_task":
$title="新订单提醒";
$alert="您有新的订单";
break;
case "send_task":
$title='订单指派提醒';
$alert='您的订单已被指派';
break;
case "get_task":
$title='订单受理提醒';
$alert='您有订单已被受理';
break;
case "finish_task":
$title='订单完成提醒';
$alert='您的订单已完成';
break;
} /*
* 官方代码
* */
$client = new \JPush\Client($app_key, $master_secret); $pusher = $client->push();
//设置平台
$pusher->setPlatform('all'); //唯一标识符
$pusher->addAlias($alias); echo $alert." ".$title; $pusher->setNotificationAlert($title, $alert);
try {
$result=$pusher->send();
var_dump($result);
} catch (\JPush\Exceptions\JPushException $e) {
// try something else here
print $e;
}

服务端这里新增了对post参数的接收,当然……这里的参数验证逻辑写的还不够严谨,在实际项目中肯定还要有更多的验证及错误信息反馈。

PHP端代码相对比较简单……当然,写的还不够优雅,不过已经可以实现基本的功能了~

至此,代码部分就全部完成了,现在让我们来测试一下效果!

效果测试

首先我开启了2台虚拟机,并且提前设置好了他们的alias

夜神模拟器: 

android模拟器: 

夜神模拟机的alias设为001,推送的type设为new_task 
as 的模拟机alias 设为002,推送的type设为send_task

接下来,我们点击推送

 
可以看到,两台机器都成功收到了相应的推送!

结语(终于完成了……)

国庆期间花了不少时间折腾这个……现在才整理出来……(不过好在整理出来了)

这个demo从客户端到后台,相对比较全面地介绍了推送的相关内容,当然,这些内容在官网上都能找到相应的资料,而且这篇文章的代码还不够优雅(尤其是PHP部分),实现的功能还比较基础,所以要完成更加复杂功能的小伙伴,还需要去官网深入学习文档,以满足实际的需求。

好了~最后感谢坚持看到了这里的小伙伴(≧▽≦)/

【android极光推送】—从客户端到后台,一文通吃的更多相关文章

  1. Android 极光推送造成IM服务绑定失败bug

    由于极光推送对8.0的支持问题,升级到了最新版本的极光推送.但是最新版本的极光推送,默认将推送服务设置到了新的进程里面,由此引发 Android 极光推送多进程造成的application运行两次 和 ...

  2. android极光推送

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android开发记录18-集成推送服务的一点说明 关于推送服务,国内有很多选择,笔者也对它们进行了一个详细的对比,一般我们产品选择推送服务主要考 ...

  3. Android 极光推送JPush---自定义提示音

    极光推送提供三种方法实现Notification通知 三方开发平台发送普通消息,客户端设置PushNotificationBuilder,实现基础的Notification通知 三方开放平台发送普通消 ...

  4. Android 极光推送集成

    集成Jpush 1.用Android Studio创建一个Demo 2.创建激光推送开发者账号,要创建极光推送开发者帐号,请访问极光推送官方网站https://www.jiguang.cn/push ...

  5. android极光推送初步了解

    推送可以及时,主动的与用户发起交互 (1)继承jar包,照示例AndroidManifest.xml添加. (2)自定义MyApp继承自Application,在onCreate方法中调用JPushI ...

  6. android 极光推送 声音与振动 的关闭和开启

    前言:最近刚好在写一些推送方面的东西,又是新手,不断在网上找资料,很少,不过还是找到了一些,反正百度我是再也不想百度了,谷歌一下子就能找到想要的. 废话不多说. 1.主要方法就是如下一个函数 priv ...

  7. 使用极光推送(www.jpush.cn)向安卓手机推送消息【服务端向客户端主送推送】C#语言

    在VisualStudio2010中新建网站JPushAndroid.添加引用json帮助类库Newtonsoft.Json.dll. 在web.config增加appkey和mastersecret ...

  8. Android消息推送——JPush极光推送

    刚看了一篇关于Android消息推送评测总结的博客http://www.cnblogs.com/logan/p/4514635.html: 自己也对原学过的JPush极光进行一下小结,方便后续工作使用 ...

  9. .net平台借助第三方推送服务在推送Android消息(极光推送)

    最近做的.net项目(Windows Service)需要向Android手机发送推送消息,真是有点困难,没有搞过就不停的搜文档,最后看到了一个开源项目PushSharp,可以在.net平台推送IOS ...

随机推荐

  1. URAL 1671 Anansi's Cobweb (并查集)

    题意:给一个无向图.每次查询破坏一条边,每次输出查询后连通图的个数. 思路:并查集.逆向思维,删边变成加边. #include<cstdio> #include<cstring> ...

  2. Chapter 5: Container

    Chapter 5: Container A container is a module that processes the requests for a servlet and populates ...

  3. Ubuntu 升级VisualBox后无法启动 Kernel driver not installed (rc=-1908)

    VisualBox之所以在Linux上比传统的VMware快得多,关键一点就是它和Linux内核的结合比较紧密,这也是开源的优点. 不过Linux内核更新很频繁,每次更新内核后启动VirtualBox ...

  4. Python的文件类型

    Python的文件类型主要分为3种:源代码(source file).字节码(byte-code file).优化的字节码(optimized file).这些代码都可以直接运行,不需要编译或者连接. ...

  5. # 20145210 《Java程序设计》第05周学习总结

    教材学习内容总结 第八章 异常处理 8.1语法与继承架构 •使用 try.catch •Java中所有信息都会被打包为对象,如果愿意,可以尝试(try)捕捉(catch)代表错误的对象后做一些处理 • ...

  6. URAL 2040 (回文自动机)

    Problem Palindromes and Super Abilities 2 (URAL2040) 题目大意 给一个字符串,从左到右依次添加,询问每添加一个字符,新增加的回文串数量. 解题分析 ...

  7. 【转】自动化任务运行器 Grunt 迅速上手

    原文转自:http://blog.jobbole.com/51586/ 这篇文章将带领你用Grunt来提速和优化网站开发的流程.首先我们会简短介绍Grunt的功能,然后我们直接上手,介绍如何用Grun ...

  8. Rest文件下载

    public void DownloadFile(string fileId) { //Stream fileStream = null; try { int fileID = Convert.ToI ...

  9. EXT遮罩效果

    <link href="/resources/ext/resources/css/ext-all.css" rel="stylesheet" type=& ...

  10. JS操作DOM常用API总结

    <JS高程>中的DOM部分写的有些繁琐,还没勇气整理,直到看到了这篇博文 Javascript操作DOM常用API总结,顿时有了一种居高临下,一览全局的感觉.不过有时间还是得自己把书里面的 ...