Commit f0b5504f authored by frank's avatar frank 🏀

Initial commit

parents
# Created by https://www.gitignore.io/api/macos,apachecordova
.idea
### ApacheCordova ###
# Apache Cordova generated files and directories
bin/*
!/plugins
!/plugins/android.json
!/plugins/fetch.json
plugins/*
platforms/*
### macOS ###
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Ionic example
ionic/example/.sourcemaps/*
ionic/example/node_modules/*
ionic/example/plugins/*
ionic/example/config.xml
ionic/example/ionic.config.json
ionic/example/package-lock.json
ionic/example/package.json
ionic/example/tsconfig.json
ionic/example/tslint.json
ionic/example/resources/README\.md
ionic/example/www/*
ionic/example/src/assets/*
ionic/example/src/theme
ionic/example/platforms
ionic/example/src/manifest\.json
ionic/example/resources/android/splash/
ionic/example/resources/
ionic/example/src/service-worker\.js
ionic/example/src/index\.html
ionic/example/src/app/app\.scss
ionic/example/src/app/main\.ts
# End of https://www.gitignore.io/api/macos,apachecordova
language: node_js
sudo: false
node_js:
- "4.2"
# JPush PhoneGap / Cordova Plugin
[![Build Status](https://travis-ci.org/jpush/jpush-phonegap-plugin.svg?branch=master)](https://travis-ci.org/jpush/jpush-phonegap-plugin)
[![release](https://img.shields.io/badge/release-3.4.1-blue.svg)](https://github.com/jpush/jpush-phonegap-plugin/releases)
[![platforms](https://img.shields.io/badge/platforms-iOS%7CAndroid-lightgrey.svg)](https://github.com/jpush/jpush-phonegap-plugin)
[![weibo](https://img.shields.io/badge/weibo-JPush-blue.svg)](http://weibo.com/jpush?refer_flag=1001030101_&is_all=1)
极光官方支持的 cordova 推送插件。
- 如需要 IM 功能的插件,可关注 [jmessage-phonegap-plugin](https://github.com/jpush/jmessage-phonegap-plugin)
- 如需要短信验证码功能插件,可关注 [cordova-plugin-jsms](https://github.com/jpush/cordova-plugin-jsms)
- 如需要统计分析功能插件,可关注 [cordova-plugin-janalytics](https://github.com/jpush/cordova-plugin-janalytics)
>注意:插件从 v3.4.0 开始支持 cordova-android 7.0.0,因 cordova-android 7.0.0 修改了 Android 项目结构,因此不兼容之前的版本,升级前请务必注意。
>
>如果需要在cordova-android 7.0.0之前版本集成最新插件,参照[这篇文章](https://www.jianshu.com/p/23b117ca27a6)
>
>如果需要安装之前版本的插件,请先安装 v1.2.0 以下版本(建议安装 v1.1.12)的 [cordova-plugin-jcore](https://github.com/jpush/cordova-plugin-jcore),再安装旧版本插件(比如 v3.3.2),否则运行会报错。
>
>[Cordova Android版本与原生版本对应表](http://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html#requirements-and-support)
## Install
> 注意:
> - 应用的包名一定要和 APP_KEY 对应应用的包名一致,否则极光推送服务无法注册成功。
> - 在使用 8 或以上版本的 Xcode 调试 iOS 项目时,需要先在项目配置界面的 Capabilities 中打开 Push Notifications 开关。
- 通过 Cordova Plugins 安装,要求 Cordova CLI 5.0+:
```shell
cordova plugin add jpush-phonegap-plugin --variable APP_KEY=your_jpush_appkey
```
- 或直接通过 url 安装:
```shell
cordova plugin add https://github.com/jpush/jpush-phonegap-plugin.git --variable APP_KEY=your_jpush_appkey
```
- 或下载到本地安装:
```shell
cordova plugin add Your_Plugin_Path --variable APP_KEY=your_jpush_appkey
```
### 参数
- APP_KEY: 必须设置,JPush 上注册的包名对应的 Appkey
```shell
--variable APP_KEY=your_jpush_appkey
```
- CHANNEL: 可以不设置,v3.6.0+ 版本开始支持(Android Only),方便开发者统计 APK 分发渠道,默认为 developer-default.
```shell
--variable CHANNEL=your_channel
```
- 同时动态配置 APP_KEY 和 CHANNEL 示例
```shell
cordova plugin add jpush-phonegap-plugin --variable APP_KEY=your_jpush_appkey --variable CHANNEL=your_channel
```
### Ionic
如果使用了 Ionic,可以再安装 @jiguang-ionic/jpush 包,适配 ionic-native:
```shell
npm install --save @jiguang-ionic/jpush@1.0.2
# npm install --save @jiguang-ionic/jpush@2.0.0 for ionic4+
```
然后在 *app.module.ts* 中增加:
```js
// @jiguang-ionic/jpush@1.0.0+
import { JPush } from '@jiguang-ionic/jpush';
// @jiguang-ionic/jpush@2.0.0+
import { JPush } from '@jiguang-ionic/jpush/ngx';
...
providers: [
...
JPush,
...
]
```
具体可参考 ./ionic/example 中的文件。
## Usage
### API
- [Common](/doc/Common_detail_api.md)
- [iOS](/doc/iOS_API.md)
- [Android](/doc/Android_detail_api.md)
### Demo
插件项目中包含一个简单的 Demo。若想参考,可以在 */example* 文件夹内找到并拷贝以下文件:
example/index.html -> www/index.html
example/css/* -> www/css
example/js/* -> www/js
### 关于 PhoneGap build 云服务
该项目基于 Cordova 实现,目前无法使用 PhoneGap build 云服务进行打包,建议使用本地环境进行打包。
## FAQ
> 如果遇到了疑问,请优先参考 Demo 和 API 文档。若还无法解决,可到 [Issues](https://github.com/jpush/jpush-phonegap-plugin/issues) 提问。
### Android
#### 在 Eclipse 中 import 工程之后出现:*Type CallbackContext cannot be resolved to a type*
右键单击工程名 -> Build Path -> Config Build Path -> Projects -> 选中工程名称 -> CordovaLib -> 点击 add。
#### 无法获取到 Registration Id
检查 AppKey 和应用包名是否对应、是否调用了 `init` 方法。
#### 如何自定义通知声音?
Android 因为各 Rom 的高度定制化,不像 iOS 一样能有一个统一的管理,如果在 Android 中想自定义通知铃声,推荐通过 JPush 推送自定义
消息,之后在 `jpush.receiveMessage` 事件监听中通过 [Cordova Local-Notification Plugin](https://github.com/katzer/cordova-plugin-local-notifications) 触发通知,再配合 [Cordova Background Plugin](https://github.com/katzer/cordova-plugin-background-mode) 插件保证应用的后台运行。
#### 如何让通知内容像 iOS 一样自动换行展示?
[#267](https://github.com/jpush/jpush-phonegap-plugin/issues/267)
#### 关闭 App 后收不到通知
Android 的推送通过长连接的方式实现,只有在保持连接的情况下才能收到通知。而有的第三方 ROM 会限制一般应用服务的自启动,也就是在退出应用后,应用的所有服务均被杀死,且无法自启动,所以就会收不到通知。
目前 JPush 是做了应用互相拉起机制的,也就是当用户打开其他集成了 JPush 的应用时,你的应用也能同时收到推送消息。
如果你的应用希望随时都能收到推送,官方推荐是通过文案的方式引导用户在设置中允许你的应用能够自启动,常见机型的设置方法可以参考[这里](https://docs.jiguang.cn/jpush/client/Android/android_faq/#_2)。
或者自己实现应用保活,网上有很多相关文章(不推荐)。
> 为什么 QQ、微信之类的应用退出后还能够收到通知?因为这些大厂应用,手机厂商默认都会加入自启动白名单中,也不会在应用退出后杀死它们的相关服务。
> 如果你多加留意,就会发现非大厂的应用如果你一段时间不用都是收不到推送的。
### iOS
#### XCode 10 收不到推送怎么办?
打开 xcode -> file -> WorkSpace Settings… -> Build System 改成 Legacy Build System 然后卸载 App 重新运行。
#### 打包时遇到 i386 打包失败怎么办?
```shell
cordova platform update ios
```
#### PushConfig.plist 文件中的字段都是什么意思?
- Appkey:应用标识。
- Channel:渠道标识。
- IsProduction:是否生产环境。
- IsIDFA:是否使用 IDFA 启动 SDK。
#### 刚集成完插件收不到推送怎么办?
请首先按照正确方式再次配置证书、描述文件,具体可参考 [iOS 证书设置指南](https://docs.jiguang.cn/jpush/client/iOS/ios_cer_guide/)
#### iOS 集成插件白屏、或无法启动插件、或打包报错无法找到需要引入的文件怎么办?
按照以下步骤逐个尝试:
- 升级至最新版本 Xcode
- 删除插件、再重装插件(先使用 `cordova platform add ios`,后使用 `cordova plugin add`
## Support
- QQ 群:413602425 / 524248013
- [JPush 官网文档](https://docs.jiguang.cn/jpush/guideline/intro/)
- [极光社区](http://community.jiguang.cn/)
## Contribute
Please contribute! [Look at the issues](https://github.com/jpush/jpush-phonegap-plugin/issues).
## License
MIT © [JiGuang](/license)
# Android API 简介
- [清除通知](#清除通知)
- [设置允许推送时间](#设置允许推送时间)
- [设置通知静默时间](#设置通知静默时间)
- [通知栏样式定制](#通知栏样式定制)
- [设置保留最近通知条数](#设置保留最近通知条数)
- [本地通知](#本地通知)
- [获取推送连接状态](#获取推送连接状态)
- [地理围栏](#地理围栏)
## 获取集成日志(同时适用于 iOS)
### API - setDebugMode
用于开启调试模式,可以查看集成 JPush 过程中的 Log,如果集成失败,可方便定位问题所在。
#### 接口定义
```js
window.JPush.setDebugMode(mode)
```
#### 参数说明
- mode:
- true 显示集成日志。
- false 不显示集成日志。
### API - reportNotificationOpened
用于上报用户的通知栏被打开,或者用于上报用户自定义消息被展示等客户端需要统计的事件。
#### 接口定义
```js
window.JPush.reportNotificationOpened(msgID)
```
#### 参数说明
- msgID: 收到的通知或者自定义消息的 id。
## 清除通知
### API - clearAllNotification
推送通知到客户端时,由 JPush SDK 展现通知到通知栏上。
此 API 提供清除通知的功能,包括:清除所有 JPush 展现的通知(不包括非 JPush SDK 展现的)。
#### 接口定义
```js
window.JPush.clearAllNotification()
```
### API - clearNotificationById
根据通知 Id 清除通知(包括本地通知)。
#### 接口定义
```js
window.JPush.clearNotificationById(notificationId)
```
#### 参数说明
- notificationId:int,通知的 id。
#### 代码示例
```js
window.JPush.clearNotificationById(1)
```
## 设置允许推送时间
### API - setPushTime
默认情况下用户在任何时间都允许推送。即任何时候有推送下来,客户端都会收到,并展示。
开发者可以调用此 API 来设置允许推送的时间。
如果不在该时间段内收到消息,当前的行为是:推送到的通知会被扔掉。
#### 接口定义
```js
window.JPush.setPushTime(days, startHour, endHour)
```
#### 参数说明
- days: 数组,0 表示星期天,1 表示星期一,以此类推(7天制,数组中值的范围为 0 到 6 )。
数组的值为 null, 表示任何时间都可以收到消息和通知,数组的 size 为 0,则表示任何时间都收不到消息和通知。
- startHour: 整形,允许推送的开始时间 (24 小时制:startHour 的范围为 0 到 23)。
- endHour: 整形,允许推送的结束时间 (24 小时制:endHour 的范围为 0 到 23)。
## 设置通知静默时间
### API - setSilenceTime
默认情况下用户在收到推送通知时,客户端可能会有震动,响铃等提示。
但用户在睡觉、开会等时间点希望为 "免打扰" 模式,也是静音时段的概念。
开发者可以调用此 API 来设置静音时段。如果在该时间段内收到消息,则:不会有铃声和震动。
#### 接口定义
```js
window.JPush.setSilenceTime(startHour, startMinute, endHour, endMinute)
```
#### 参数说明
- startHour: 整形,静音时段的开始时间 - 小时 (24小时制,范围:0~23 )。
- startMinute: 整形,静音时段的开始时间 - 分钟(范围:0~59 )。
- endHour: 整形,静音时段的结束时间 - 小时 (24小时制,范围:0~23 )。
- endMinute: 整形,静音时段的结束时间 - 分钟(范围:0~59 )。
## 通知栏样式定制
目前 REST API 与极光控制台均已支持「大文本通知栏样」、「文本条目通知栏样式」和「大图片通知栏样式」。可直接推送对应样式
的通知。
此外也能够通过设置 Notification 的 flag 来控制通知提醒方式,具体用法可参考 [后台 REST API](https://docs.jiguang.cn/jpush/server/push/rest_api_v3_push/#notification)
### API - setBasicPushNotificationBuilder, setCustomPushNotificationBuilder
当用户需要定制默认的通知栏样式时,则可调用此方法。
需要用户去自定义 ../JPushPlugin.java 中的同名方法代码,然后再在 js 端 调用该方法。
具体用法可参考[官方文档](http://docs.jiguang.cn/jpush/client/Android/android_api/#api_6)
JPush SDK 提供了 2 个用于定制通知栏样式的构建类:
- setBasicPushNotificationBuilder:
Basic 用于定制 Android Notification 里的 defaults / flags / icon 等基础样式(行为)。
- setCustomPushNotificationBuilder:
继承 Basic 进一步让开发者定制 Notification Layout。
如果不调用此方法定制,则极光 Push SDK 默认的通知栏样式是 Android 标准的通知栏。
#### 接口定义
```js
window.JPush.setBasicPushNotificationBuilder()
window.JPush.setCustomPushNotificationBuilder()
```
## 设置保留最近通知条数
### API - setLatestNotificationNum
通过极光推送,推送了很多通知到客户端时,如果用户不去处理,就会有很多保留在那里。
默认为保留最近 5 条通知,开发者可通过调用此 API 来定义为不同的数量。
#### 接口定义
```js
window.JPush.setLatestNotificationNum(num)
```
#### 参数说明
- num: 保存的条数。
## 本地通知
### API - addLocalNotification, removeLocalNotification, clearLocalNotifications
本地通知 API 不依赖于网络,无网条件下依旧可以触发。
本地通知与网络推送的通知是相互独立的,不受保留最近通知条数上限的限制。
本地通知的定时时间是自发送时算起的,不受中间关机等操作的影响。
三个接口的功能分别为:添加一个本地通知,清除一个本地通知,清除所有的本地通知。
#### 接口定义
```js
window.JPush.addLocalNotification(builderId, content, title, notificationID, broadcastTime, extras)
window.JPush.removeLocalNotification(notificationID)
window.JPush.clearLocalNotifications() // 同时适用于 iOS
```
#### 参数说明
- builderId: 设置本地通知样式。
- content: 设置本地通知的 content。
- title: 设置本地通知的 title。
- notificationID: 设置本地通知的 ID(不要为 0)。
- broadcastTime: 设置本地通知触发时间,为距离当前时间的数值,单位是毫秒。
- extras: 设置额外的数据信息 extras 为 json 字符串。
## 获取推送连接状态
### API - getConnectionState
开发者可以使用此功能获取当前 Push 服务的连接状态
#### 接口定义
```js
window.JPush.getConnectionState(callback)
```
#### 参数说明
- callback: 回调函数,用来通知 JPush 的推送服务是否开启。
#### 代码示例
```js
window.JPush.getConnectionState(function (result) {
if (result == 0) {
// 链接状态
} else {
// 断开状态
}
})
```
## 地理围栏
### API - setGeofenceInterval
设置地理围栏监控周期,最小3分钟,最大1天。默认为15分钟,当距离地理围栏边界小于1000米周期自动调整为3分钟。设置成功后一直使用设置周期,不会进行调整。
#### 接口定义
```js
window.JPush.setGeofenceInterval(interval)
```
#### 参数说明
- interval: 监控周期,单位是毫秒。
### API - setMaxGeofenceNumber
设置最多允许保存的地理围栏数量,超过最大限制后,如果继续创建先删除最早创建的地理围栏。默认数量为10个,允许设置最小1个,最大100个。
#### 接口定义
```js
window.JPush.setMaxGeofenceNumber(maxNumber)
```
#### 参数说明
- maxNumber: 最多允许保存的地理围栏个数
### API - setBadgeNumber
设置App角标,目前仅华为系手机支持。
#### 接口定义
```js
window.JPush.setBadgeNumber(badgeNumb)
```
#### 参数说明
- badgeNumb: 角标显示数字,小于或等0,角标显示数字清楚
### API - setAuth
设置用户是否同意隐私协议
#### 接口定义
```js
window.JPush.setAuth(isAuth)
```
#### 参数说明
- isAuth: 是否同意隐私协议,true 已同意;false未同意
#### 调用逻辑
- 宿主 APP 在首次安装,冷启动
- 用户隐私协议告知
- 用户确认授权
- 告知极光授权结果
同意隐私协议:
```js
window.JPush.setAuth(true)
```
不同意隐私协议:
```js
window.JPush.setAuth(false)
```
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
* {
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
}
body {
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
background-color:#E4E4E4;
background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image:-webkit-gradient(
linear,
left top,
left bottom,
color-stop(0, #A7A7A7),
color-stop(0.51, #E4E4E4)
);
background-attachment:fixed;
font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
font-size:12px;
height:100%;
margin:0px;
padding:0px;
text-transform:uppercase;
width:100%;
}
/* Portrait layout (default) */
.app {
background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
position:absolute; /* position in the center of the screen */
left:50%;
top:50%;
height:50px; /* text area height */
width:225px; /* text area width */
text-align:center;
padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
/* offset horizontal: half of text area width */
}
/* Landscape layout (with min-width) */
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
.app {
background-position:left center;
padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
/* offset horizontal: half of image width and text area width */
}
}
h1 {
font-size:24px;
font-weight:normal;
margin:0px;
overflow:visible;
padding:0px;
text-align:center;
}
.event {
border-radius:4px;
-webkit-border-radius:4px;
color:#FFFFFF;
font-size:12px;
margin:0px 30px;
padding:2px 0px;
}
.event.listening {
background-color:#333333;
display:block;
}
.event.received {
background-color:#4B946A;
display:none;
}
@keyframes fade {
from { opacity: 1.0; }
50% { opacity: 0.4; }
to { opacity: 1.0; }
}
@-webkit-keyframes fade {
from { opacity: 1.0; }
50% { opacity: 0.4; }
to { opacity: 1.0; }
}
.blink {
animation:fade 3000ms infinite;
-webkit-animation:fade 3000ms infinite;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
/* Datewheel overlay */
.dw {
min-width:170px;
padding: 0 10px;
position: absolute;
top: 5%;
left: 0;
z-index: 1001;
color: #000;
font-family: arial, verdana, sans-serif;
font-size: 12px;
text-shadow: none;
}
.dwi {
position: static;
margin: 5px;
display: inline-block;
}
.dwwr {
zoom: 1;
}
/* Datewheel overlay background */
.dwo {
width: 100%;
background: #000;
position: absolute;
top: 0;
left: 0;
z-index: 1000;
opacity: .7;
filter:Alpha(Opacity=70);
}
/* Datewheel wheel container wrapper */
.dwc {
float: left;
margin: 0 2px 5px 2px;
padding-top: 30px;
}
.dwcc {
clear: both;
}
/* Datewheel label */
.dwl {
/*margin: 0 2px;*/
text-align: center;
line-height: 30px;
height: 30px;
white-space: nowrap;
position: absolute;
top: -30px;
width: 100%;
}
/* Datewheel value */
.dwv {
padding: 10px 0;
border-bottom: 1px solid #000;
}
/* Datewheel wheel container */
.dwrc {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.dwwc {
margin: 0;
padding: 0 2px;
position: relative;
background: #000;
zoom:1;
}
/* Datewheel wheels */
.dwwl {
margin: 4px 2px;
position: relative;
background: #888;
background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #000),color-stop(0.35, #333),color-stop(0.50, #888),color-stop(0.65, #333),color-stop(1, #000));
background: -moz-linear-gradient(#000 0%,#333 35%, #888 50%,#333 65%,#000 100%);
background: -ms-linear-gradient(#000 0%,#333 35%, #888 50%,#333 65%,#000 100%);
background: -o-linear-gradient(#000 0%,#333 35%, #888 50%,#333 65%,#000 100%);
}
.dww {
margin: 0 2px;
overflow: hidden;
position: relative;
/*top: -30px;*/
}
.dwsc .dww {
color: #fff;
background: #444;
background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #000),color-stop(0.45, #444),color-stop(0.55, #444),color-stop(1, #000));
background: -moz-linear-gradient(#000 0%,#444 45%, #444 55%, #000 100%);
background: -ms-linear-gradient(#000 0%,#444 45%, #444 55%, #000 100%);
background: -o-linear-gradient(#000 0%,#444 45%, #444 55%, #000 100%);
}
.dww ul {
list-style: none;
margin: 0;
padding: 0;
/*display: block;
width: 100%;*/
position: relative;
z-index: 2;
}
.dww li {
list-style: none;
margin: 0;
padding: 0 5px;
display: block;
text-align: center;
line-height: 40px;
font-size: 26px;
white-space: nowrap;
text-shadow: 0 1px 1px #000;
opacity: .3;
filter: Alpha(Opacity=30);
}
/* Valid entry */
.dww li.dw-v {
opacity: 1;
filter: Alpha(Opacity=100);
}
/* Hidden entry */
.dww li.dw-h {
visibility: hidden;
}
/* Wheel +/- buttons */
.dwwb {
position: absolute;
z-index: 4;
left: 0;
cursor: pointer;
width: 100%;
height: 40px;
text-align: center;
}
.dwwbp {
top: 0;
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
border-radius: 3px 3px 0 0;
font-size: 40px;
}
.dwwbm {
bottom: 0;
-webkit-border-radius: 0 0 3px 3px;
-moz-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
font-size: 32px;
font-weight: bold;
}
.dwpm .dwwc {
background: transparent;
}
.dwpm .dww {
margin: -1px;
}
.dwpm .dww li {
text-shadow: none;
}
.dwpm .dwwol {
display: none;
}
/* Datewheel wheel overlay */
.dwwo {
position: absolute;
z-index: 3;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #000),color-stop(0.52, rgba(44,44,44,0)),color-stop(0.48, rgba(44,44,44,0)),color-stop(1, #000));
background: -moz-linear-gradient(#000 0%,rgba(44,44,44,0) 52%, rgba(44,44,44,0) 48%, #000 100%);
background: -ms-linear-gradient(#000 0%,rgba(44,44,44,0) 52%, rgba(44,44,44,0) 48%, #000 100%);
background: -o-linear-gradient(#000 0%,rgba(44,44,44,0) 52%, rgba(44,44,44,0) 48%, #000 100%);
}
/* Background line */
.dwwol {
position: absolute;
z-index: 1;
top: 50%;
left: 0;
width: 100%;
height: 0;
margin-top: -1px;
border-top: 1px solid #333;
border-bottom: 1px solid #555;
}
/* Datewheel button */
.dwbg .dwb {
display: block;
height: 40px;
line-height: 40px;
padding: 0 15px;
margin: 0 2px;
font-size: 14px;
font-weight: bold;
text-decoration: none;
text-shadow:0 -1px 1px #000;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius:5px;
box-shadow:0 1px 3px rgba(0,0,0,0.5);
-moz-box-shadow:0 1px 3px rgba(0,0,0,0.5);
-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.5);
color: #fff;
background:#000;
background:-webkit-gradient(linear,left bottom,left top,color-stop(0.5, #000),color-stop(0.5, #6e6e6e));
background:-moz-linear-gradient(#6e6e6e 50%,#000 50%);
background:-ms-linear-gradient(#6e6e6e 50%,#000 50%);
background:-o-linear-gradient(#6e6e6e 50%,#000 50%);
}
/* Datewheel button container */
.dwbc {
/*margin-top: 5px;*/
padding: 5px 0;
text-align: center;
clear: both;
}
/* Datewheel button wrapper */
.dwbw {
display: inline-block;
width: 50%;
}
/* Hidden label */
.dwhl {
padding-top: 10px;
}
.dwhl .dwl {
display: none;
}
/* Backgrounds */
.dwbg {
background: #fff;
border-radius: 3px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
}
.dwbg .dwpm .dww {
color: #000;
background: #fff;
border: 1px solid #AAA;
}
.dwbg .dwwb {
background: #ccc;
color: #888;
text-shadow: 0 -1px 1px #333;
box-shadow: 0 0 5px #333;
-webkit-box-shadow: 0 0 5px #333;
-moz-box-shadow: 0 0 5px #333;
}
.dwbg .dwwbp {
background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #bdbdbd),color-stop(1, #f7f7f7));
background: -moz-linear-gradient(#f7f7f7,#bdbdbd);
background: -ms-linear-gradient(#f7f7f7,#bdbdbd);
background: -o-linear-gradient(#f7f7f7,#bdbdbd);
}
.dwbg .dwwbm {
background: -webkit-gradient(linear,left bottom,left top,color-stop(0, #f7f7f7),color-stop(1, #bdbdbd));
background: -moz-linear-gradient(#bdbdbd,#f7f7f7);
background: -ms-linear-gradient(#bdbdbd,#f7f7f7);
background: -o-linear-gradient(#bdbdbd,#f7f7f7);
}
.dwbg .dwb-a {
background:#3c7500;
background:-webkit-gradient(linear,left bottom,left top,color-stop(0.5, #3c7500),color-stop(0.5, #94c840));
background:-moz-linear-gradient(#94c840 50%,#3c7500 50%);
background:-ms-linear-gradient(#94c840 50%,#3c7500 50%);
background:-o-linear-gradient(#94c840 50%,#3c7500 50%);
}
.dwbg .dwwl .dwb-a {
background:#3c7500;
background:-webkit-gradient(linear,left bottom,left top,color-stop(0, #3c7500),color-stop(1, #94c840));
background:-moz-linear-gradient(#94c840,#3c7500);
background:-ms-linear-gradient(#94c840,#3c7500);
background:-o-linear-gradient(#94c840,#3c7500);
}
/* jQuery Mobile Theme */
.jqm .dwo {
background: none;
}
.jqm .dw {
padding: 6px;
z-index: 1003;
}
.jqm .dwv {
position: static;
width: auto;
padding: .7em 15px .7em 15px;
border: 0;
}
.jqm .dwwr {
border: 0;
}
.jqm .dwpm .dwwo {
background: none;
}
.jqm .dwc {
margin: 0;
padding: 30px 5px 5px 5px;
}
.jqm .dwhl {
padding: 5px;
}
.jqm .dwwb {
margin: 0;
border: 0;
}
.jqm .dwwb span {
padding: 0;
}
.jqm .dwwbp .ui-btn-inner {
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
border-radius: 3px 3px 0 0;
}
.jqm .dwwbm .ui-btn-inner {
-webkit-border-radius: 0 0 3px 3px;
-moz-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
}
.jqm .dwwbp span {
font-weight: normal;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
</dict>
</plist>
/*
* Author: Derek Chia <snipking@gmail.com>
* common functions for cordova plugin after hook
*/
const fs = require('fs');
const path = require('path');
module.exports.addAPNSinEntitlements = (entitlementPath, isProduction) => {
if( fs.existsSync(entitlementPath) ) {
fs.readFile(entitlementPath, "utf8", function(err, data) {
if (err) {
throw err;
}
console.log("Reading entitlements file asynchronously");
let toInsert = '<key>aps-environment</key>\n' +
'\t\t<string>development</string>';
if(isProduction) {
toInsert = '<key>aps-environment</key>\n' +
'\t\t<string>production</string>';
}
let re1 = new RegExp('<key>aps-environment<\/key>(.|[\r\n])*<string>.*<\/string>');
let matched = data.match(re1);
let result;
if (matched === null) {
if(data.match(/<\/dict>/g)) {
result = data.replace(/<\/dict>/, '\t' + toInsert + '\n\t</dict>');
} else if(data.match(/<dict\/>/g)) {
result = data.replace(/<dict\/>/, '\t<dict>\n\t\t' + toInsert + '\n\t</dict>');
}
} else {
result = data.replace(re1, toInsert);
}
// write result to entitlements file
fs.writeFile(entitlementPath, result, {"encoding": 'utf8'}, function(err) {
if (err) {
throw err;
}
console.log(entitlementPath + " written successfully");
});
});
} else {
console.log("Entitlement File '" + entitlementPath + "' not found. Make sure your ios platform upper than 4.3.0");
}
}
module.exports.removeAPNSinEntitlements = (entitlementPath) => {
if( fs.existsSync(entitlementPath) ) {
fs.readFile(entitlementPath, "utf8", function(err, data) {
if (err) {
throw err;
}
console.log("Reading entitlements file asynchronously");
let re1 = new RegExp('<key>aps-environment<\/key>(.|[\r\n])*<string>.*<\/string>');
let matched = data.match(re1);
let result;
if (matched != null) {
result = data.replace(re1, "");
}
// write result to entitlements file
fs.writeFile(entitlementPath, result, {"encoding": 'utf8'}, function(err) {
if (err) {
throw err;
}
console.log(entitlementPath + " written successfully");
});
});
} else {
console.log("Entitlement File '" + entitlementPath + "' not found. Make sure your ios platform upper than 4.3.0");
}
}
module.exports.getXcodeProjName = (searchPath) => {
if(searchPath == null || searchPath == undefined) {
searchPath = './';
}
let resultFolderName = null;
let folderNames = fs.readdirSync(searchPath).filter(file => fs.lstatSync(path.join(searchPath, file)).isDirectory());
let folderNamesReg = new RegExp('.*\.xcodeproj', 'g') // get filder name like `*.xcodeproj`
for(let folderName of folderNames) {
if(folderName.match(folderNamesReg)) {
resultFolderName = folderName;
break;
}
}
return resultFolderName.substr(0, resultFolderName.length - 10);
}
/*
* Author: Derek Chia <snipking@gmail.com>
* Cordova plugin after hook to disable `Push Notification` capability for XCode 8
*/
const fs = require('fs');
const path = require('path');
let commonFuncs = require('./common');
/**
* remove APNS env from cordova project Entitlements-Debug.plist and Entitlements-Release.plist
* This two file will work when xcode archive app
*/
let disablePushNotificationForCI = (basePath, xcodeprojName) => {
commonFuncs.removeAPNSinEntitlements(basePath + xcodeprojName + '/Entitlements-Debug.plist');
commonFuncs.removeAPNSinEntitlements(basePath + xcodeprojName + '/Entitlements-Release.plist');
}
/**
* remove APNS env to entitlement file; disable Push Notification capability in .pbxproj file
* This two file will work when xcode archive app
*/
let disablePushNotificationForXCode = (entitlementsPath, pbxprojPath) => {
/**
* remove APNS env to entitlement file
*/
if( fs.existsSync(entitlementsPath) ) {
commonFuncs.removeAPNSinEntitlements(entitlementsPath);
}
/**
* disable Push Notification capability in .pbxproj file
* equally disable "Push Notification" switch in xcode
*/
fs.readFile(pbxprojPath, "utf8", function(err, data) {
if (err) {
throw err;
}
console.log("Reading pbxproj file asynchronously");
// turn off Push Notification Capability
let re4rep = new RegExp('isa = PBXProject;(.|[\r\n])*TargetAttributes(.|[\r\n])*SystemCapabilities(.|[\r\n])*com\.apple\.Push = {(.|[\r\n])*enabled = [01]');
let parts = re4rep.exec(data);
if(parts !== null && parts !== undefined && parts.length > 0) {
result = data.replace(re4rep, parts[0].substr(0, parts[0].length - 1) + '0');
// write result to project.pbxproj
fs.writeFile(pbxprojPath, result, {"encoding": 'utf8'}, function(err) {
if (err) {
throw err;
}
console.log(pbxprojPath + " written successfully");
});
}
});
}
let basePath = './platforms/ios/';
let buildType = 'dev';
let xcodeprojName = commonFuncs.getXcodeProjName(basePath);
let pbxprojPath = basePath + xcodeprojName + '.xcodeproj/project.pbxproj';
let entitlementsPath = basePath + xcodeprojName + '/' + xcodeprojName + '.entitlements';
disablePushNotificationForCI(basePath, xcodeprojName);
disablePushNotificationForXCode(entitlementsPath, pbxprojPath);
/*
* Author: Derek Chia <snipking@gmail.com>
* Cordova plugin after hook to enable `Push Notification` capability for XCode 8
*/
const fs = require('fs');
const path = require('path');
let commonFuncs = require('./common');
/**
* add APNS env to cordova project Entitlements-Debug.plist and Entitlements-Release.plist
* This two file will work when xcode archive app
*/
let enablePushNotificationForCI = (basePath, xcodeprojName) => {
commonFuncs.addAPNSinEntitlements(basePath + xcodeprojName + '/Entitlements-Debug.plist', false);
commonFuncs.addAPNSinEntitlements(basePath + xcodeprojName + '/Entitlements-Release.plist', true);
}
/**
* add APNS env to entitlement file; enable Push Notification capability in .pbxproj file
* This two file will work when xcode archive app
*/
let enablePushNotificationForXCode = (entitlementsPath, pbxprojPath, cordovaBuildConfig) => {
console.log('will enable push notification capability for XCode');
let needAddEntitlementToPbxproj = false;
/**
* add APNS env to entitlement file
* without this file will cause a worning in xcode
*/
if( fs.existsSync(entitlementsPath) ) {
commonFuncs.addAPNSinEntitlements(entitlementsPath, false);
} else {
// copy default entitlements file
fs.readFile(__dirname + '/apns.entitlements', 'utf8', function(err, data) {
if (err) {
throw err;
}
fs.writeFileSync(entitlementsPath, data);
console.log(entitlementsPath + " written successfully");
});
needAddEntitlementToPbxproj = true;
}
/**
* enable Push Notification capability in .pbxproj file
* equally enable "Push Notification" switch in xcode
*/
fs.readFile(pbxprojPath, "utf8", function(err, data) {
if (err) {
throw err;
}
console.log("Reading pbxproj file asynchronously");
// add Push Notification Capability
let re1 = new RegExp('isa = PBXProject;(.|[\r\n])*TargetAttributes', 'g');
let re1rep = new RegExp('isa = PBXProject;(.|[\r\n])*attributes = {', 'g');
let re2 = new RegExp('(?:isa = PBXProject;(.|[\r\n])*TargetAttributes(.|[\r\n])*)SystemCapabilities', 'g');
let re2rep = new RegExp('isa = PBXProject;(.|[\r\n])*TargetAttributes = {', 'g');
let re3 = new RegExp('(?:isa = PBXProject;(.|[\r\n])*TargetAttributes(.|[\r\n])*SystemCapabilities(.|[\r\n])*)com\.apple\.Push', 'g');
let re3rep = new RegExp('isa = PBXProject;(.|[\r\n])*TargetAttributes(.|[\r\n])*SystemCapabilities = {', 'g');
let re4rep = new RegExp('isa = PBXProject;(.|[\r\n])*TargetAttributes(.|[\r\n])*SystemCapabilities(.|[\r\n])*com\.apple\.Push = {(.|[\r\n])*enabled = [01]');
let matched = data.match(re1);
let result;
if (matched === null) {
console.log('re1 not match, no TargetAttributes');
result = data.replace(re1rep, 'isa = PBXProject;\n' +
'\t\t\tattributes = {\n' +
'\t\t\t\tTargetAttributes = {\n' +
'\t\t\t\t\t1D6058900D05DD3D006BFB54 = {\n' +
'\t\t\t\t\t\tDevelopmentTeam = ' + cordovaBuildConfig.ios.release.developmentTeam + ';\n' +
'\t\t\t\t\t\tSystemCapabilities = {\n' +
'\t\t\t\t\t\t\tcom.apple.Push = {\n' +
'\t\t\t\t\t\t\t\tenabled = 1;\n' +
'\t\t\t\t\t\t\t};\n' +
'\t\t\t\t\t\t};\n' +
'\t\t\t\t\t};\n' +
'\t\t\t\t};');
} else {
matched = data.match(re2);
if(matched === null) {
console.log('re2 not match, nothing under TargetAttributes');
let parts = re2rep.exec(data);
result = data.replace(re2rep, parts[0] + '\n' + '\t\t\t\t\t1D6058900D05DD3D006BFB54 = {\n' +
'\t\t\t\t\t\tDevelopmentTeam = ' + cordovaBuildConfig.ios.release.developmentTeam + ';\n' +
'\t\t\t\t\t\tSystemCapabilities = {\n' +
'\t\t\t\t\t\t\tcom.apple.Push = {\n' +
'\t\t\t\t\t\t\t\tenabled = 1;\n' +
'\t\t\t\t\t\t\t};\n' +
'\t\t\t\t\t\t};\n' +
'\t\t\t\t\t};');
} else {
matched = data.match(re3);
if(matched === null) {
console.log('re3 not match, no com.apple.Push defined');
let parts = re3rep.exec(data);
result = data.replace(re3rep, parts[0] + '\n' + '\t\t\t\t\t\t\tcom.apple.Push = {\n' +
'\t\t\t\t\t\t\t\tenabled = 1;\n' +
'\t\t\t\t\t\t\t};');
} else {
console.log('just enable com.apple.Push');
let parts = re4rep.exec(data);
result = data.replace(re4rep, parts[0].substr(0, parts[0].length - 1) + '1');
}
}
}
// add entitlements
if (needAddEntitlementToPbxproj) {
let pathArray = entitlementsPath.split("/");
let entitlementsFileName = pathArray[pathArray.length - 1];
let projectFolderName = pathArray[pathArray.length - 2];
result = result.replace(new RegExp('\\/\\* Begin PBXFileReference section \\*\\/'), '/* Begin PBXFileReference section */\n' +
'\t\tD7BB385F1E4DB54800345BF4 /* ' + entitlementsFileName + ' */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = "' + entitlementsFileName + '"; path = "' + projectFolderName + '/' + entitlementsFileName + '"; sourceTree = "<group>"; };');
result = result.replace(new RegExp('\\/\\* CustomTemplate \\*\\/.*\n.*isa = PBXGroup;.*\n.*children = \\('), '/* CustomTemplate */ = {\n' +
'\t\t\tisa = PBXGroup;\n' +
'\t\t\tchildren = (\n' +
'\t\t\t\tD7BB385F1E4DB54800345BF4 /* ' + entitlementsFileName + ' */,');
let re5rep = new RegExp('\\/\\* Debug \\*\\/.*\n.*isa = XCBuildConfiguration;.*\n.*\n.*buildSettings = {');
let parts = result.match(re5rep);
result = result.replace(re5rep, parts + '\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = "' + projectFolderName + '/' + entitlementsFileName + '";');
let re6rep = new RegExp('\\/\\* Release \\*\\/.*\n.*isa = XCBuildConfiguration;.*\n.*\n.*buildSettings = {');
parts = result.match(re6rep);
result = result.replace(re6rep, parts + '\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = "' + projectFolderName + '/' + entitlementsFileName + '";');
}
// write result to project.pbxproj
fs.writeFile(pbxprojPath, result, {"encoding": 'utf8'}, function(err) {
if (err) {
throw err;
}
console.log(pbxprojPath + " written successfully");
});
});
}
module.exports = (context) => {
let basePath = './platforms/ios/';
let buildType = 'dev';
let xcodeprojName = commonFuncs.getXcodeProjName(basePath);
let pbxprojPath = basePath + xcodeprojName + '.xcodeproj/project.pbxproj';
let entitlementsPath = basePath + xcodeprojName + '/' + xcodeprojName + '.entitlements';
let cordovaBuildConfigPath = './build.json'
let cordovaBuildConfig = null;
let willEnablePushNotificationForXCode = true;
try { // try to read ios developmentTeam from build.json
cordovaBuildConfig = JSON.parse(fs.readFileSync(cordovaBuildConfigPath, "utf8"));
if(cordovaBuildConfig.ios.release.developmentTeam === null && cordovaBuildConfig.ios.release.developmentTeam === undefined) {
throw 'no valid developmentTeam found in build.json';
}
} catch(e) {
console.log("Do not detected 'build.json' or ios.release.developmentTeam not avaliable in 'build.json' \n" +
"Will not enable XCode Push Notification Capability. \n" +
"Will only enable Push Notification for CI by add config to '" + basePath + xcodeprojName + "/Entitlements-Debug.plist' and '" + basePath + xcodeprojName + "/Entitlements-Release.plist' \n" +
"Please add 'build.json' to cordova project root folder to make after hook fully functional. \n" +
"Reference [1]https://cordova.apache.org/docs/en/latest/reference/cordova-cli/#cordova-build-command \n" +
"Reference [2]https://cordova.apache.org/docs/en/latest/guide/platforms/ios/#signing-an-app");
willEnablePushNotificationForXCode = false;
}
enablePushNotificationForCI(basePath, xcodeprojName);
if(willEnablePushNotificationForXCode) {
enablePushNotificationForXCode(entitlementsPath, pbxprojPath, cordovaBuildConfig);
}
}
import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { JPush } from '@jiguang-ionic/jpush';
import { HomePage } from '../pages/home/home';
@Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen, jpush: JPush) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
jpush.init();
jpush.setDebugMode(true);
});
}
}
<ion-nav [root]="rootPage"></ion-nav>
import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';
import { Device } from '@ionic-native/device';
import { JPush } from '@jiguang-ionic/jpush';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
@NgModule({
declarations: [
MyApp,
HomePage
],
imports: [
BrowserModule,
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage
],
providers: [
StatusBar,
SplashScreen,
Device,
JPush,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
})
export class AppModule {}
<ion-header>
<ion-navbar>
<ion-title>
JPush Ionic Example
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-item>
<div>Registration Id: {{registrationId}}</div>
<button ion-button full (click)="getRegistrationID()">Get Registration Id</button>
</ion-item>
<ion-item>
<button ion-button full (click)="setTags()">Set tags - Tag1, Tag2</button>
<button ion-button full (click)="addTags()">Add tags - Tag3, Tag4</button>
<button ion-button full (click)="checkTagBindState()">Check tag bind state - Tag1</button>
<button ion-button full (click)="deleteTags()">Delete tags - Tag4</button>
<button ion-button full (click)="getAllTags()">Get all tags</button>
<button ion-button full (click)="cleanTags()">Clean tags</button>
</ion-item>
<ion-item>
<button ion-button full (click)="setAlias()">Set Alias - TestAlias</button>
<button ion-button full (click)="getAlias()">Get Alias</button>
<button ion-button full (click)="deleteAlias()">Delete Alias</button>
</ion-item>
<ion-item>
<button ion-button full (click)="addLocalNotification()">Trigger local notification after 5 seconds</button>
</ion-item>
</ion-list>
</ion-content>
import { Component } from "@angular/core";
import { NavController } from "ionic-angular";
import { JPush } from "@jiguang-ionic/jpush";
import { Device } from "@ionic-native/device";
@Component({
selector: "page-home",
templateUrl: "home.html"
})
export class HomePage {
public registrationId: string;
devicePlatform: string;
sequence: number = 0;
tagResultHandler = function(result) {
var sequence: number = result.sequence;
var tags: Array<string> = result.tags == null ? [] : result.tags;
alert(
"Success!" + "\nSequence: " + sequence + "\nTags: " + tags.toString()
);
};
aliasResultHandler = function(result) {
var sequence: number = result.sequence;
var alias: string = result.alias;
alert("Success!" + "\nSequence: " + sequence + "\nAlias: " + alias);
};
errorHandler = function(err) {
var sequence: number = err.sequence;
var code = err.code;
alert("Error!" + "\nSequence: " + sequence + "\nCode: " + code);
};
constructor(
public navCtrl: NavController,
public jpush: JPush,
device: Device
) {
this.devicePlatform = device.platform;
document.addEventListener(
"jpush.receiveNotification",
(event: any) => {
var content;
if (this.devicePlatform == "Android") {
content = event.alert;
} else {
content = event.aps.alert;
}
alert("Receive notification: " + JSON.stringify(event));
},
false
);
document.addEventListener(
"jpush.openNotification",
(event: any) => {
var content;
if (this.devicePlatform == "Android") {
content = event.alert;
} else {
// iOS
if (event.aps == undefined) {
// 本地通知
content = event.content;
} else {
// APNS
content = event.aps.alert;
}
}
alert("open notification: " + JSON.stringify(event));
},
false
);
document.addEventListener(
"jpush.receiveLocalNotification",
(event: any) => {
// iOS(*,9) Only , iOS(10,*) 将在 jpush.openNotification 和 jpush.receiveNotification 中触发。
var content;
if (this.devicePlatform == "Android") {
} else {
content = event.content;
}
alert("receive local notification: " + JSON.stringify(event));
},
false
);
}
getRegistrationID() {
this.jpush.getRegistrationID().then(rId => {
this.registrationId = rId;
});
}
setTags() {
this.jpush
.setTags({ sequence: this.sequence++, tags: ["Tag1", "Tag2"] })
.then(this.tagResultHandler)
.catch(this.errorHandler);
}
addTags() {
this.jpush
.addTags({ sequence: this.sequence++, tags: ["Tag3", "Tag4"] })
.then(this.tagResultHandler)
.catch(this.errorHandler);
}
checkTagBindState() {
this.jpush
.checkTagBindState({ sequence: this.sequence++, tag: "Tag1" })
.then(result => {
var sequence = result.sequence;
var tag = result.tag;
var isBind = result.isBind;
alert(
"Sequence: " + sequence + "\nTag: " + tag + "\nIsBind: " + isBind
);
})
.catch(this.errorHandler);
}
deleteTags() {
this.jpush
.deleteTags({ sequence: this.sequence++, tags: ["Tag4"] })
.then(this.tagResultHandler)
.catch(this.errorHandler);
}
getAllTags() {
this.jpush
.getAllTags({ sequence: this.sequence++ })
.then(this.tagResultHandler)
.catch(this.errorHandler);
}
cleanTags() {
this.jpush
.cleanTags({ sequence: this.sequence++ })
.then(this.tagResultHandler)
.catch(this.errorHandler);
}
setAlias() {
this.jpush
.setAlias({ sequence: this.sequence++, alias: "TestAlias" })
.then(this.aliasResultHandler)
.catch(this.errorHandler);
}
getAlias() {
this.jpush
.getAlias({ sequence: this.sequence++ })
.then(this.aliasResultHandler)
.catch(this.errorHandler);
}
deleteAlias() {
this.jpush
.deleteAlias({ sequence: this.sequence++ })
.then(this.aliasResultHandler)
.catch(this.errorHandler);
}
addLocalNotification() {
if (this.devicePlatform == "Android") {
this.jpush.addLocalNotification(0, "Hello JPush", "JPush", 1, 5000);
} else {
this.jpush.addLocalNotificationForIOS(5, "Hello JPush", 1, "localNoti1");
}
}
}
import { Plugin, Cordova, IonicNativePlugin } from '@ionic-native/core';
import { Injectable } from '@angular/core';
export interface TagOptions {
sequence: number;
tags?: Array<string>;
}
export interface AliasOptions {
sequence: number;
alias?: string;
}
@Plugin({
pluginName: 'JPush',
plugin: 'jpush-phonegap-plugin',
pluginRef: 'plugins.jPushPlugin',
repo: 'https://github.com/jpush/jpush-phonegap-plugin',
install: 'ionic cordova plugin add jpush-phonegap-plugin --variable APP_KEY=your_app_key',
installVariables: ['APP_KEY'],
platforms: ['Android', 'iOS']
})
@Injectable()
export class JPush extends IonicNativePlugin {
@Cordova({
sync: true,
platforms: ['iOS', 'Android']
})
init(): void { }
@Cordova({
sync: true,
platforms: ['iOS', 'Android']
})
setDebugMode(enable: boolean): void { }
@Cordova()
getRegistrationID(): Promise<any> { return; }
@Cordova()
stopPush(): Promise<any> { return; }
@Cordova()
resumePush(): Promise<any> { return; }
@Cordova()
isPushStopped(): Promise<any> { return; }
@Cordova()
setTags(params: TagOptions): Promise<any> { return; }
@Cordova()
addTags(params: TagOptions): Promise<any> { return; }
@Cordova()
deleteTags(params: TagOptions): Promise<any> { return; }
@Cordova()
cleanTags(params: TagOptions): Promise<any> { return; }
@Cordova()
getAllTags(params: TagOptions): Promise<any> { return; }
/**
* @param params { sequence: number, tag: string }
*/
@Cordova()
checkTagBindState(params: object): Promise<any> { return; }
@Cordova()
setAlias(params: AliasOptions): Promise<any> { return; }
@Cordova()
deleteAlias(params: AliasOptions): Promise<any> { return; }
@Cordova()
getAlias(params: AliasOptions): Promise<any> { return; }
/**
* Determinate whether the application notification has been opened.
*
* iOS: 0: closed; >1: opened.
* UIRemoteNotificationTypeNone = 0,
* UIRemoteNotificationTypeBadge = 1 << 0,
* UIRemoteNotificationTypeSound = 1 << 1,
* UIRemoteNotificationTypeAlert = 1 << 2,
* UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3
*
* Android: 0: closed; 1: opened.
*/
@Cordova()
getUserNotificationSettings(): Promise<any> { return; }
@Cordova()
clearLocalNotifications(): Promise<any> { return; }
// iOS API - start
@Cordova({
sync: true,
platforms: ['iOS']
})
setBadge(badge: number): void { }
@Cordova({
sync: true,
platforms: ['iOS']
})
resetBadge(): void { }
@Cordova({
sync: true,
platforms: ['iOS']
})
setApplicationIconBadgeNumber(badge: number): void { }
@Cordova()
getApplicationIconBadgeNumber(): Promise<any> { return; }
@Cordova({
sync: true,
platforms: ['iOS']
})
addLocalNotificationForIOS(delayTime: number, content: string, badge: number, identifierKey: string, extras?: object): void { }
@Cordova({
sync: true,
platforms: ['iOS']
})
deleteLocalNotificationWithIdentifierKeyInIOS(identifierKey: string): void { }
@Cordova({
sync: true,
platforms: ['iOS']
})
addDismissActions(actions: Array<object>, categoryId: string): void { }
@Cordova({
sync: true,
platforms: ['iOS']
})
addNotificationActions(actions: Array<object>, categoryId: string): void { }
@Cordova({
sync: true,
platforms: ['iOS']
})
setLocation(latitude: number, longitude: number): void { }
@Cordova({
sync: true,
platforms: ['iOS']
})
startLogPageView(pageName: string): void { return; }
@Cordova({
sync: true,
platforms: ['iOS']
})
stopLogPageView(pageName: string): void { return; }
@Cordova({
sync: true,
platforms: ['iOS']
})
beginLogPageView(pageName: string, duration: number): void { return; }
// iOS API - end
// Android API - start
@Cordova()
getConnectionState(): Promise<any> { return; }
@Cordova()
setBasicPushNotificationBuilder(): Promise<any> { return; }
@Cordova()
setCustomPushNotificationBuilder(): Promise<any> { return; }
@Cordova()
clearAllNotification(): Promise<any> { return; }
@Cordova()
clearNotificationById(id: number): Promise<any> { return; }
@Cordova()
setLatestNotificationNum(num: number): Promise<any> { return; }
@Cordova()
addLocalNotification(builderId: number, content: string, title: string, notificationId: number, broadcastTime: number, extras?: string): Promise<any> { return; }
@Cordova()
removeLocalNotification(notificationId: number): Promise<any> { return; }
@Cordova()
reportNotificationOpened(msgId: number): Promise<any> { return; }
@Cordova()
requestPermission(): Promise<any> { return; }
@Cordova()
setSilenceTime(startHour: number, startMinute: number, endHour: number, endMinute: number): Promise<any> { return; }
@Cordova()
setPushTime(weekdays: Array<string>, startHour: number, endHour: number): Promise<any> { return; }
// Android API - end
}
import { IonicNativePlugin } from '@ionic-native/core';
export interface TagOptions {
sequence: number;
tags?: Array<string>;
}
export interface AliasOptions {
sequence: number;
alias?: string;
}
/**
* @name jpush
* @description
* This plugin does something
*
* @usage
* ```typescript
* import { jpush } from '@ionic-native/jpush';
*
*
* constructor(private jpush: jpush) { }
*
* ...
*
*
* this.jpush.functionName('Hello', 123)
* .then((res: any) => console.log(res))
* .catch((error: any) => console.error(error));
*
* ```
*/
export declare class JPushOriginal extends IonicNativePlugin {
/**
* This function does something
* @param arg1 {string} Some param to configure something
* @param arg2 {number} Another param to configure something
* @return {Promise<any>} Returns a promise that resolves when something happens
*/
functionName(arg1: string, arg2: number): Promise<any>;
init(): void;
setDebugMode(enable: boolean): void;
getRegistrationID(): Promise<any>;
stopPush(): Promise<any>;
resumePush(): Promise<any>;
isPushStopped(): Promise<any>;
setTags(params: TagOptions): Promise<any>;
addTags(params: TagOptions): Promise<any>;
deleteTags(params: TagOptions): Promise<any>;
cleanTags(params: TagOptions): Promise<any>;
getAllTags(params: TagOptions): Promise<any>;
/**
* @param params { sequence: number, tag: string }
*/
checkTagBindState(params: object): Promise<any>;
setAlias(params: AliasOptions): Promise<any>;
deleteAlias(params: AliasOptions): Promise<any>;
getAlias(params: AliasOptions): Promise<any>;
/**
* Determinate whether the application notification has been opened.
*
* iOS: 0: closed; >1: opened.
* UIRemoteNotificationTypeNone = 0,
* UIRemoteNotificationTypeBadge = 1 << 0,
* UIRemoteNotificationTypeSound = 1 << 1,
* UIRemoteNotificationTypeAlert = 1 << 2,
* UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3
*
* Android: 0: closed; 1: opened.
*/
getUserNotificationSettings(): Promise<any>;
clearLocalNotifications(): Promise<any>;
setBadge(badge: number): void;
resetBadge(): void;
setApplicationIconBadgeNumber(badge: number): void;
getApplicationIconBadgeNumber(): Promise<any>;
addLocalNotificationForIOS(delayTime: number, content: string, badge: number, identifierKey: string, extras?: object): void;
deleteLocalNotificationWithIdentifierKeyInIOS(identifierKey: string): void;
addDismissActions(actions: Array<object>, categoryId: string): void;
addNotificationActions(actions: Array<object>, categoryId: string): void;
setLocation(latitude: number, longitude: number): void;
startLogPageView(pageName: string): void;
stopLogPageView(pageName: string): void;
beginLogPageView(pageName: string, duration: number): void;
getConnectionState(): Promise<any>;
setBasicPushNotificationBuilder(): Promise<any>;
setCustomPushNotificationBuilder(): Promise<any>;
clearAllNotification(): Promise<any>;
clearNotificationById(id: number): Promise<any>;
setLatestNotificationNum(num: number): Promise<any>;
addLocalNotification(builderId: number, content: string, title: string, notificationId: number, broadcastTime: number, extras?: string): Promise<any>;
removeLocalNotification(notificationId: number): Promise<any>;
reportNotificationOpened(msgId: number): Promise<any>;
requestPermission(): Promise<any>;
setSilenceTime(startHour: number, startMinute: number, endHour: number, endMinute: number): Promise<any>;
setPushTime(weekdays: Array<string>, startHour: number, endHour: number): Promise<any>;
}
export declare const JPush: JPushOriginal;
\ No newline at end of file
This diff is collapsed.
import { IonicNativePlugin } from '@ionic-native/core';
export interface TagOptions {
sequence: number;
tags?: Array<string>;
}
export interface AliasOptions {
sequence: number;
alias?: string;
}
/**
* @name jpush
* @description
* This plugin does something
*
* @usage
* ```typescript
* import { jpush } from '@ionic-native/jpush';
*
*
* constructor(private jpush: jpush) { }
*
* ...
*
*
* this.jpush.functionName('Hello', 123)
* .then((res: any) => console.log(res))
* .catch((error: any) => console.error(error));
*
* ```
*/
export declare class JPush extends IonicNativePlugin {
/**
* This function does something
* @param arg1 {string} Some param to configure something
* @param arg2 {number} Another param to configure something
* @return {Promise<any>} Returns a promise that resolves when something happens
*/
functionName(arg1: string, arg2: number): Promise<any>;
init(): void;
setDebugMode(enable: boolean): void;
getRegistrationID(): Promise<any>;
stopPush(): Promise<any>;
resumePush(): Promise<any>;
isPushStopped(): Promise<any>;
setTags(params: TagOptions): Promise<any>;
addTags(params: TagOptions): Promise<any>;
deleteTags(params: TagOptions): Promise<any>;
cleanTags(params: TagOptions): Promise<any>;
getAllTags(params: TagOptions): Promise<any>;
/**
* @param params { sequence: number, tag: string }
*/
checkTagBindState(params: object): Promise<any>;
setAlias(params: AliasOptions): Promise<any>;
deleteAlias(params: AliasOptions): Promise<any>;
getAlias(params: AliasOptions): Promise<any>;
/**
* Determinate whether the application notification has been opened.
*
* iOS: 0: closed; >1: opened.
* UIRemoteNotificationTypeNone = 0,
* UIRemoteNotificationTypeBadge = 1 << 0,
* UIRemoteNotificationTypeSound = 1 << 1,
* UIRemoteNotificationTypeAlert = 1 << 2,
* UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3
*
* Android: 0: closed; 1: opened.
*/
getUserNotificationSettings(): Promise<any>;
clearLocalNotifications(): Promise<any>;
setBadge(badge: number): void;
resetBadge(): void;
setApplicationIconBadgeNumber(badge: number): void;
getApplicationIconBadgeNumber(): Promise<any>;
addLocalNotificationForIOS(delayTime: number, content: string, badge: number, identifierKey: string, extras?: object): void;
deleteLocalNotificationWithIdentifierKeyInIOS(identifierKey: string): void;
addDismissActions(actions: Array<object>, categoryId: string): void;
addNotificationActions(actions: Array<object>, categoryId: string): void;
setLocation(latitude: number, longitude: number): void;
startLogPageView(pageName: string): void;
stopLogPageView(pageName: string): void;
beginLogPageView(pageName: string, duration: number): void;
getConnectionState(): Promise<any>;
setBasicPushNotificationBuilder(): Promise<any>;
setCustomPushNotificationBuilder(): Promise<any>;
clearAllNotification(): Promise<any>;
clearNotificationById(id: number): Promise<any>;
setLatestNotificationNum(num: number): Promise<any>;
addLocalNotification(builderId: number, content: string, title: string, notificationId: number, broadcastTime: number, extras?: string): Promise<any>;
removeLocalNotification(notificationId: number): Promise<any>;
reportNotificationOpened(msgId: number): Promise<any>;
requestPermission(): Promise<any>;
setSilenceTime(startHour: number, startMinute: number, endHour: number, endMinute: number): Promise<any>;
setPushTime(weekdays: Array<string>, startHour: number, endHour: number): Promise<any>;
}
This diff is collapsed.
[{"__symbolic":"module","version":4,"metadata":{"TagOptions":{"__symbolic":"interface"},"AliasOptions":{"__symbolic":"interface"},"JPush":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"@ionic-native/core","name":"IonicNativePlugin","line":67,"character":27},"decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":64,"character":1},"arguments":[{"providedIn":"root"}]}],"members":{"functionName":[{"__symbolic":"method"}],"init":[{"__symbolic":"method"}],"setDebugMode":[{"__symbolic":"method"}],"getRegistrationID":[{"__symbolic":"method"}],"stopPush":[{"__symbolic":"method"}],"resumePush":[{"__symbolic":"method"}],"isPushStopped":[{"__symbolic":"method"}],"setTags":[{"__symbolic":"method"}],"addTags":[{"__symbolic":"method"}],"deleteTags":[{"__symbolic":"method"}],"cleanTags":[{"__symbolic":"method"}],"getAllTags":[{"__symbolic":"method"}],"checkTagBindState":[{"__symbolic":"method"}],"setAlias":[{"__symbolic":"method"}],"deleteAlias":[{"__symbolic":"method"}],"getAlias":[{"__symbolic":"method"}],"getUserNotificationSettings":[{"__symbolic":"method"}],"clearLocalNotifications":[{"__symbolic":"method"}],"setBadge":[{"__symbolic":"method"}],"resetBadge":[{"__symbolic":"method"}],"setApplicationIconBadgeNumber":[{"__symbolic":"method"}],"getApplicationIconBadgeNumber":[{"__symbolic":"method"}],"addLocalNotificationForIOS":[{"__symbolic":"method"}],"deleteLocalNotificationWithIdentifierKeyInIOS":[{"__symbolic":"method"}],"addDismissActions":[{"__symbolic":"method"}],"addNotificationActions":[{"__symbolic":"method"}],"setLocation":[{"__symbolic":"method"}],"startLogPageView":[{"__symbolic":"method"}],"stopLogPageView":[{"__symbolic":"method"}],"beginLogPageView":[{"__symbolic":"method"}],"getConnectionState":[{"__symbolic":"method"}],"setBasicPushNotificationBuilder":[{"__symbolic":"method"}],"setCustomPushNotificationBuilder":[{"__symbolic":"method"}],"clearAllNotification":[{"__symbolic":"method"}],"clearNotificationById":[{"__symbolic":"method"}],"setLatestNotificationNum":[{"__symbolic":"method"}],"addLocalNotification":[{"__symbolic":"method"}],"removeLocalNotification":[{"__symbolic":"method"}],"reportNotificationOpened":[{"__symbolic":"method"}],"requestPermission":[{"__symbolic":"method"}],"setSilenceTime":[{"__symbolic":"method"}],"setPushTime":[{"__symbolic":"method"}]}}}}]
{
"name": "@jiguang-ionic/jpush",
"version": "2.0.0",
"description": "JPush support for ionic-native",
"module": "index.js",
"typings": "index.d.ts",
"author": "hevin",
"license": "MIT",
"peerDependencies": {
"@ionic-native/core": "^5.1.0",
"@angular/core": "*",
"rxjs": "^6.3.0"
},
"repository": {
"type": "git",
"url": "https://github.com/jpush/jpush-phonegap-plugin"
}
}
**WARNING: 如果不按照这个表格,我们将无法帮助你,并将忽略你的问题。**
## 你的运行环境
* 插件版本:
* 平台(Android / iOS):
* Cordova version (```cordova -v```):
* Cordova platform version (```cordova platform ls```):
* Ionic Version (if using Ionic)
## 期望效果
告诉我们你希望达到什么效果。
## 实际效果
告诉我们实际是什么效果。
## 重现步骤
1. ...
2. ...
3. ...
4. ...
## 背景
你尝试做过些什么?
## Debug logs
包括 Android 或 iOS 的日志:
* iOS: XCode logs
* Android: $ adb logcat / Android Studio logcat
\ No newline at end of file
The MIT License (MIT)
Copyright (c) JiGuang <support@jpush.cn> (jiguang.cn)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
{
"name": "jpush-phonegap-plugin",
"version": "5.2.0",
"description": "JPush for cordova plugin",
"cordova": {
"id": "jpush-phonegap-plugin",
"platforms": [
"ios",
"android"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/jpush/jpush-phonegap-plugin.git"
},
"keywords": [
"JPush",
"push",
"Push",
"ecosystem:cordova",
"cordova-ios",
"cordova-android"
],
"devDependencies": {
"cordova-plugin-device": "*",
"cordova-plugin-jcore": ">=4.2.2"
},
"author": "JiGuang",
"license": "MIT",
"bugs": {
"url": "https://github.com/jpush/jpush-phonegap-plugin/issues"
},
"homepage": "https://github.com/jpush/jpush-phonegap-plugin#readme"
}
This diff is collapsed.
package cn.jiguang.cordova.push;
import android.util.Log;
public class JLogger {
public static final String TAG = "[Cordova-JPush]";
private static boolean isLoggerEnable = false;
public static void setLoggerEnable(boolean loggerEnable) {
Log.d(TAG, "setLoggerEnable:" + loggerEnable);
isLoggerEnable = loggerEnable;
}
public static void i(String tag,String msg) {
if (isLoggerEnable) {
Log.i(TAG+tag, msg);
}
}
public static void d(String tag,String msg) {
if (isLoggerEnable) {
Log.d(TAG+tag, msg);
}
}
public static void v(String tag,String msg) {
if (isLoggerEnable) {
Log.v(TAG+tag, msg);
}
}
public static void w(String tag,String msg) {
if (isLoggerEnable) {
Log.w(TAG+tag, msg);
}
}
public static void e(String tag,String error) {
if (isLoggerEnable) {
Log.e(TAG+tag, error);
}
}
}
package cn.jiguang.cordova.push;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Set;
import cn.jpush.android.api.CustomMessage;
import cn.jpush.android.api.JPushMessage;
import cn.jpush.android.api.NotificationMessage;
import cn.jpush.android.helper.Logger;
import cn.jpush.android.service.JPushMessageService;
public class JPushEventReceiver extends JPushMessageService {
private static final String TAG = JPushEventReceiver.class.getSimpleName();
@Override
public void onTagOperatorResult(Context context, JPushMessage jPushMessage) {
super.onTagOperatorResult(context, jPushMessage);
JLogger.d(TAG,"onTagOperatorResult:"+jPushMessage);
tryCallback(jPushMessage, new SuccessCallback() {
@Override
public void onSuccessCallback(JSONObject resultJson) throws JSONException {
Set<String> tags = jPushMessage.getTags();
JSONArray tagsJsonArr = new JSONArray();
for (String tag : tags) {
tagsJsonArr.put(tag);
}
if (tagsJsonArr.length() != 0) {
resultJson.put("tags", tagsJsonArr);
}
}
});
}
@Override
public void onCheckTagOperatorResult(Context context, JPushMessage jPushMessage) {
super.onCheckTagOperatorResult(context, jPushMessage);
JLogger.d(TAG,"onCheckTagOperatorResult:"+jPushMessage);
tryCallback(jPushMessage, new SuccessCallback() {
@Override
public void onSuccessCallback(JSONObject resultJson) throws JSONException {
resultJson.put("tag", jPushMessage.getCheckTag());
resultJson.put("isBind", jPushMessage.getTagCheckStateResult());
}
});
}
@Override
public void onAliasOperatorResult(Context context, JPushMessage jPushMessage) {
super.onAliasOperatorResult(context, jPushMessage);
JLogger.d(TAG,"onAliasOperatorResult:"+jPushMessage);
tryCallback(jPushMessage, new SuccessCallback() {
@Override
public void onSuccessCallback(JSONObject resultJson) throws JSONException {
if (!TextUtils.isEmpty(jPushMessage.getAlias())) {
resultJson.put("alias", jPushMessage.getAlias());
}
}
});
}
@Override
public void onRegister(Context context, String regId) {
JLogger.d(TAG,"onRegister:"+regId);
JPushPlugin.transmitReceiveRegistrationId(regId);
}
@Override
public void onMessage(Context context, CustomMessage customMessage) {
super.onMessage(context,customMessage);
//Log.e(TAG,"onMessage:"+customMessage);
// String msg = customMessage.message;//intent.getStringExtra(JPushInterface.EXTRA_MESSAGE);
// Map<String, Object> extras = getNotificationExtras(intent);
// JPushPlugin.transmitMessageReceive(msg, extras);
}
@Override
public void onNotifyMessageArrived(Context context, NotificationMessage notificationMessage) {
super.onNotifyMessageArrived(context, notificationMessage);
JLogger.d(TAG,"onNotifyMessageArrived:"+notificationMessage);
}
@Override
public void onNotifyMessageOpened(Context context, NotificationMessage notificationMessage) {
super.onNotifyMessageOpened(context, notificationMessage);
JLogger.d(TAG,"onNotifyMessageOpened:"+notificationMessage);
}
@Override
public void onMobileNumberOperatorResult(Context context, JPushMessage jPushMessage) {
super.onMobileNumberOperatorResult(context, jPushMessage);
JLogger.d(TAG,"onMobileNumberOperatorResult:"+jPushMessage);
tryCallback(jPushMessage, new SuccessCallback() {
@Override
public void onSuccessCallback(JSONObject resultJson) throws JSONException {
if (!TextUtils.isEmpty(jPushMessage.getMobileNumber())) {
resultJson.put("mobileNumber", jPushMessage.getMobileNumber());
}
}
});
}
@Override
public void onMultiActionClicked(Context context, Intent intent) {
super.onMultiActionClicked(context, intent);
JLogger.d(TAG,"onMultiActionClicked:"+intent);
}
@Override
public void onInAppMessageShow(Context context,final NotificationMessage message) {
JLogger.d(TAG, "[onInAppMessageShow], " + message.toString());
try {
JSONObject jsonObject=new JSONObject();
jsonObject.put("title", message.inAppMsgTitle);
jsonObject.put("alert", message.inAppMsgContentBody);
jsonObject.put("messageId", message.msgId);
jsonObject.put("inAppShowTarget", message.inAppExtras);
jsonObject.put("inAppClickAction", message.inAppClickAction);
jsonObject.put("inAppExtras", message.inAppExtras);
cn.jiguang.cordova.push.JPushPlugin.transmitInAppMessageShow(jsonObject);
}catch (Throwable throwable){
}
}
@Override
public void onInAppMessageClick(Context context,final NotificationMessage message) {
JLogger.d(TAG, "[onInAppMessageClick], " + message.toString());
try {
JSONObject jsonObject=new JSONObject();
jsonObject.put("title", message.inAppMsgTitle);
jsonObject.put("alert", message.inAppMsgContentBody);
jsonObject.put("messageId", message.msgId);
jsonObject.put("inAppShowTarget", message.inAppExtras);
jsonObject.put("inAppClickAction", message.inAppClickAction);
jsonObject.put("inAppExtras", message.inAppExtras);
cn.jiguang.cordova.push.JPushPlugin.transmitInAppMessageClick(jsonObject);
}catch (Throwable throwable){
}
}
interface SuccessCallback{
void onSuccessCallback(JSONObject resultJson) throws JSONException;
}
public void tryCallback(JPushMessage jPushMessage,SuccessCallback successCallback){
JSONObject resultJson = new JSONObject();
int sequence = jPushMessage.getSequence();
try {
resultJson.put("sequence", sequence);
} catch (JSONException e) {
e.printStackTrace();
}
CallbackContext callback = JPushPlugin.eventCallbackMap.get(sequence);
if (callback == null) {
Logger.i(TAG, "Unexpected error, callback is null!");
return;
}
if (jPushMessage.getErrorCode() == 0) {
try {
successCallback.onSuccessCallback(resultJson);
} catch (JSONException e) {
e.printStackTrace();
}
callback.success(resultJson);
} else {
try {
resultJson.put("code", jPushMessage.getErrorCode());
} catch (JSONException e) {
e.printStackTrace();
}
callback.error(resultJson);
}
JPushPlugin.eventCallbackMap.remove(sequence);
}
}
This diff is collapsed.
package cn.jiguang.cordova.push;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.jpush.android.api.JPushInterface;
public class JPushReceiver extends BroadcastReceiver {
private static final List<String> IGNORED_EXTRAS_KEYS = Arrays.asList("cn.jpush.android.TITLE",
"cn.jpush.android.MESSAGE", "cn.jpush.android.APPKEY", "cn.jpush.android.NOTIFICATION_CONTENT_TITLE","key_show_entity","platform");
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(JPushInterface.ACTION_REGISTRATION_ID)) {
String rId = intent.getStringExtra(JPushInterface.EXTRA_REGISTRATION_ID);
JPushPlugin.transmitReceiveRegistrationId(rId);
} else if (action.equals(JPushInterface.ACTION_MESSAGE_RECEIVED)) {
handlingMessageReceive(intent);
} else if (action.equals(JPushInterface.ACTION_NOTIFICATION_RECEIVED)) {
handlingNotificationReceive(context, intent);
} else if (action.equals(JPushInterface.ACTION_NOTIFICATION_OPENED)) {
handlingNotificationOpen(context, intent);
}
}
private void handlingMessageReceive(Intent intent) {
String msg = intent.getStringExtra(JPushInterface.EXTRA_MESSAGE);
Map<String, Object> extras = getNotificationExtras(intent);
JPushPlugin.transmitMessageReceive(msg, extras);
}
private void handlingNotificationOpen(Context context, Intent intent) {
String title = intent.getStringExtra(JPushInterface.EXTRA_NOTIFICATION_TITLE);
JPushPlugin.openNotificationTitle = title;
String alert = intent.getStringExtra(JPushInterface.EXTRA_ALERT);
JPushPlugin.openNotificationAlert = alert;
Map<String, Object> extras = getNotificationExtras(intent);
JPushPlugin.openNotificationExtras = extras;
JPushPlugin.transmitNotificationOpen(title, alert, extras);
Intent launch = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
if (launch != null) {
launch.addCategory(Intent.CATEGORY_LAUNCHER);
launch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(launch);
}
}
private void handlingNotificationReceive(Context context, Intent intent) {
String title = intent.getStringExtra(JPushInterface.EXTRA_NOTIFICATION_TITLE);
JPushPlugin.notificationTitle = title;
String alert = intent.getStringExtra(JPushInterface.EXTRA_ALERT);
JPushPlugin.notificationAlert = alert;
Map<String, Object> extras = getNotificationExtras(intent);
JPushPlugin.notificationExtras = extras;
JPushPlugin.transmitNotificationReceive(title, alert, extras);
}
private Map<String, Object> getNotificationExtras(Intent intent) {
Map<String, Object> extrasMap = new HashMap<String, Object>();
for (String key : intent.getExtras().keySet()) {
if (!IGNORED_EXTRAS_KEYS.contains(key)) {
if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {
extrasMap.put(key, intent.getIntExtra(key, 0));
} else {
extrasMap.put(key, intent.getStringExtra(key));
}
}
}
return extrasMap;
}
}
package cn.jiguang.cordova.push;
import cn.jpush.android.service.JCommonService;
public class PushService extends JCommonService {
}
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<corners android:radius="6dp" />
<solid android:color="#0A9789" />
<stroke android:color="#0A9789" android:width="1dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ff2c6bff" />
<corners android:radius="25dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffffff" />
<stroke android:width="0.1dp"/>
<corners android:radius="20dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<stroke android:width="1dp"
android:color="#E2E3E5"
/>
<corners android:radius="25dp" />
</shape>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportWidth="30"
android:viewportHeight="30">
<path
android:pathData="M15,15m-15,0a15,15 0,1 1,30 0a15,15 0,1 1,-30 0"
android:strokeWidth="1"
android:fillColor="#253044"
android:fillAlpha="0.68"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M19.7356,10.2465C20.0722,10.5832 20.0722,11.129 19.7356,11.4656L16.21,14.99L19.7328,18.5129C20.0696,18.8498 20.0696,19.3959 19.7328,19.7328C19.3959,20.0696 18.8498,20.0696 18.5129,19.7328L14.99,16.21L11.4656,19.7356C11.129,20.0722 10.5832,20.0722 10.2465,19.7356C9.9099,19.3989 9.9099,18.8531 10.2465,18.5165L13.771,14.991L10.2493,11.4692C9.9125,11.1323 9.9125,10.5862 10.2493,10.2493C10.5862,9.9125 11.1323,9.9125 11.4692,10.2493L14.991,13.771L18.5165,10.2465C18.8531,9.9099 19.3989,9.9099 19.7356,10.2465Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffffff" />
<corners android:radius="15dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffffff" />
<corners android:topLeftRadius="0dp" android:topRightRadius="0dp" android:bottomLeftRadius="15dp" android:bottomRightRadius="15dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 获得焦点但未按下时的背景图片 -->
<item
android:state_focused="true"
android:state_enabled="true"
android:state_pressed="false"
android:drawable="@drawable/jpush_ic_richpush_actionbar_back" />
<!-- 按下时的背景图片 -->
<item
android:state_enabled="true"
android:state_pressed="true"
android:drawable="@android:color/darker_gray" />
<!-- 按下时的背景图片 -->
<item
android:state_enabled="true"
android:state_checked="true"
android:drawable="@android:color/darker_gray" />
<!-- 默认时的背景图片 -->
<item android:drawable="@drawable/jpush_ic_richpush_actionbar_back" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 背景 gradient是渐变,corners定义的是圆角 -->
<item android:id="@android:id/background">
<shape>
<solid android:color="#ffffff" />
</shape>
</item>
<!-- 进度条 -->
<item android:id="@android:id/progress">
<clip>
<shape>
<solid android:color="#4393ea" />
</shape>
</clip>
</item>
</layer-list>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<RelativeLayout
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<cn.jpush.android.ui.ShadowViewCard
android:id="@+id/bg_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<RelativeLayout
android:id="@+id/banner_content"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<cn.jpush.android.ui.RoundedImageView
android:id="@+id/image_small"
android:layout_centerVertical="true"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginEnd="8dp"
android:scaleType="fitXY"
/>
<TextView
android:id="@+id/text_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/image_small"
android:layout_marginBottom="6dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#ff253044"
android:textSize="20sp" />
<TextView
android:id="@+id/text_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/text_title"
android:layout_toRightOf="@+id/image_small"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#85253044"
android:textSize="18sp" />
</RelativeLayout>
</cn.jpush.android.ui.ShadowViewCard>
<cn.jpush.android.ui.RoundedImageView
android:id="@+id/image_only"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:visibility="gone" />
</RelativeLayout>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
/>
<FrameLayout
android:id="@+id/countdown_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="20dp"
android:layout_marginRight="16dp">
<TextView
android:layout_gravity="right"
android:id="@+id/btn_countdown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/jpush_btn_grey_bg"
android:paddingLeft="12dp"
android:paddingTop="5dp"
android:ellipsize="end"
android:maxLines="1"
android:paddingRight="12dp"
android:paddingBottom="5dp"
android:text=""
android:textColor="#ff2c6bff"
android:textSize="20sp" />
<ImageView
android:id="@+id/image_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/jpush_close" />
</FrameLayout>
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/banner_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0">
<RelativeLayout
android:id="@+id/banner_content_root"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:clickable="true"
android:focusable="true"
android:gravity="center"
android:padding="15dp"
android:orientation="vertical"
android:visibility="visible">
<ImageView
android:id="@+id/banner_image_only"
android:adjustViewBounds="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:scaleType="fitXY"/>
<ImageView
android:id="@+id/banner_image"
android:adjustViewBounds="true"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_centerVertical="true"
android:padding="5dp"
android:layout_marginLeft="3dp"
android:visibility="visible" />
<LinearLayout
android:id="@+id/banner_text_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="74dp"
android:layout_toRightOf="@id/banner_image"
android:layout_marginLeft="3dp"
android:gravity="center_vertical"
android:orientation="vertical"
android:layout_centerInParent="true">
<TextView
android:id="@+id/banner_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/banner_image"
android:ellipsize="end"
android:singleLine="true"
android:layout_marginRight="4dp"
android:text=""
android:textSize="14sp"
android:visibility="visible" />
<TextView
android:id="@+id/banner_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/banner_title"
android:layout_toRightOf="@+id/banner_image"
android:ellipsize="end"
android:singleLine="true"
android:layout_marginRight="4dp"
android:text=""
android:textSize="14sp" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</FrameLayout>
\ No newline at end of file
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/popLayoutId"
style="@style/MyDialogStyle"
android:orientation="vertical"
android:layout_width="280dp"
android:layout_height="380dp" >
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/wvPopwin"/>
</LinearLayout>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="jg_channel_name_p_min">不重要</string>
<string name="jg_channel_name_p_low">不重要</string>
<string name="jg_channel_name_p_default">普通</string>
<string name="jg_channel_name_p_high">重要</string>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="jg_channel_name_p_min">LOW</string>
<string name="jg_channel_name_p_low">LOW</string>
<string name="jg_channel_name_p_default">NORMAL</string>
<string name="jg_channel_name_p_high">HIGH</string>
</resources>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment