project init
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/.idea/
|
||||
197
CHANGELOG.md
Normal file
@ -0,0 +1,197 @@
|
||||
## 2.5.8
|
||||
修复onCommandResult 方法崩溃
|
||||
## 2.5.7
|
||||
修复onCommandResult 方法中没有 extra 参数问题,都放到map中
|
||||
## 2.5.6
|
||||
修复清单文件少包名问题
|
||||
## 2.5.5
|
||||
修复后台不能获取回调的问题
|
||||
## 2.5.4
|
||||
修复在map中且套map不能获取数据问题
|
||||
## 2.5.3
|
||||
1、升级 iOS SDK JPush 5.3.0, 升级 android JPush 5.4.0
|
||||
2、开放 setLinkMergeEnable、setGeofenceEnable、setSmartPushEnable、setCollectControl 接口设置
|
||||
3、删除 setLbsEnable 接口设置
|
||||
## 2.5.2
|
||||
开放支持动态设置appkey
|
||||
## 2.5.1
|
||||
JPush 523
|
||||
## 2.5.0
|
||||
更新JCore 440 JPush 520
|
||||
## 2.4.9
|
||||
修复testCountryCode报错问题
|
||||
## 2.4.8
|
||||
修复不能清理本地通知问题
|
||||
## 2.4.7
|
||||
开放requestRequiredPermission API
|
||||
## 2.4.6
|
||||
开放setChannelAndSound API
|
||||
## 2.4.5
|
||||
+ 修复:onConnected 崩溃问题
|
||||
+ 升级:升级 Android+IOS JPush 5.0.4
|
||||
升级 Android+IOS JCore 4.2.4
|
||||
+ 新增:setLbsEnable API
|
||||
## 2.4.4
|
||||
+ 修复:优化代码结构
|
||||
## 2.4.3
|
||||
+ 升级:升级 Android+IOS JPush 5.0.0
|
||||
升级 Android+IOS JCore 4.2.0
|
||||
+ 新增:enableAutoWakeup API
|
||||
## 2.4.2
|
||||
开放 onConnected 回调
|
||||
## 2.4.1
|
||||
+ 升级:升级 Android JPush 4.9.0
|
||||
升级 Android JCore 4.1.0
|
||||
## 2.4.0
|
||||
+ 升级:升级 Android JPush 4.8.4
|
||||
## 2.3.9
|
||||
+ 升级:升级 Android JPush 4.8.3
|
||||
升级 Android JCore 3.3.6
|
||||
## 2.3.8
|
||||
+ 新增:testCountryCode API
|
||||
## 2.3.7
|
||||
+ 升级:升级 Android JPush 4.8.1
|
||||
升级 Android JCore 3.3.2
|
||||
升级 IOS JPush 4.8.1
|
||||
升级 IOS JCore 3.2.5
|
||||
## 2.3.6
|
||||
+ 新增:修复崩溃问题
|
||||
## 2.3.5
|
||||
+ 新增:iOS新增getAlias接口实现
|
||||
## 2.3.4
|
||||
+ 升级:升级 Android JPush 4.7.2
|
||||
升级 Android JCore 3.3.0
|
||||
## 2.3.3
|
||||
+ 升级:升级 Android JPush 4.7.0
|
||||
## 2.3.2
|
||||
+ 新增:修复setAuth()方法问题
|
||||
## 2.3.1
|
||||
+ 新增:iOS对外暴露setAuth()方法
|
||||
## 2.3.0
|
||||
+ 新增:对外暴露setAuth()方法
|
||||
修复:点开通知会默认跳转到主页问题
|
||||
## 2.2.9
|
||||
+ 升级:升级 Android JPush 4.6.6
|
||||
## 2.2.8
|
||||
+ 升级:使用g版本
|
||||
## 2.2.7
|
||||
+ 升级:升级 Android JCore 3.2.4
|
||||
## 2.2.6
|
||||
+ 修复:自定义消息解析崩溃问题
|
||||
## 2.2.5
|
||||
+ 升级:jpsuh 4.6.4 jcore 3.2.2
|
||||
## 2.2.4
|
||||
+ 修复:iOS点击通知冷启动app,不回调onOpenNotification问题
|
||||
## 2.2.3
|
||||
+ 升级:jpsuh 4.6.0
|
||||
## 2.2.2
|
||||
+ 新增:getAlias接口
|
||||
## 2.2.1
|
||||
+ 升级:iOS:jpush3.7.0->jpus4.4.0
|
||||
## 2.2.0
|
||||
+ 修复channel为null时,异常崩溃问题
|
||||
## 2.1.9
|
||||
+ 升级:新增onNotifyMessageUnShow方法
|
||||
## 2.1.8
|
||||
+ 升级: jpush 4.4.5
|
||||
## 2.1.7
|
||||
+ 升级: jcore 3.1.0
|
||||
## 2.1.6
|
||||
+ 升级:升级 android push 4.4.0 jcore 3.0.0
|
||||
## 2.1.5
|
||||
+ 升级:升级 android push 4.2.8 jcore 2.9.0,ios push 3.7.0,jcore 2.7.1。
|
||||
## 2.1.4
|
||||
+ 新增:Android push 新增 setWakeEnable 接口
|
||||
## 2.1.2
|
||||
+ 升级:升级 android push 4.0.8 jcore 2.8.2,ios push 3.6.1,jcore 2.6.2。
|
||||
## 2.0.9
|
||||
+ 适配:处理 demo 运行时报错。
|
||||
## 2.0.7
|
||||
+ 适配:适配 null safety
|
||||
## 2.0.5
|
||||
+ 升级:android jcore 升级 2.7.8
|
||||
## 2.0.3
|
||||
+ 升级:android push 升级4.0.6,ios push 升级 3.5.2
|
||||
## 2.0.1
|
||||
+ 适配Flutter 2.0,Flutter 2.0 以下版本请使用 0.6.3版本
|
||||
## 0.6.3
|
||||
+ 修复:Android端获取RegistrationID偶现奔溃问题
|
||||
## 0.6.2
|
||||
+ 同步更最新版本SDK
|
||||
## 0.6.1
|
||||
+ 修复:Android 端 context为空时的crash问题
|
||||
## 0.6.0
|
||||
+ 修复:修复已知bug
|
||||
## 0.5.9
|
||||
+ 适配最新版本 JPush SDK Android 3.8.0 , IOS 3.3.6
|
||||
## 0.5.6
|
||||
+ 修复:iOS点击本地通知的通知栏消息缺少extras 字段
|
||||
## 0.5.5
|
||||
+ 适配iOS点击本地通知的通知栏消息响应事件
|
||||
+ 更新最新Android SDK
|
||||
## 0.5.3
|
||||
+ 修复一个可能引起崩溃的日志打印代码
|
||||
## 0.5.2
|
||||
+ 内部安全策略优化
|
||||
+ 同步 JPush SDK 版本
|
||||
## 0.5.1
|
||||
+ 修改 minSdkVersion 最小支持 17
|
||||
## 0.5.0
|
||||
+ 适配最新版本 JPush SDK
|
||||
+ 适配新版 SDK 的新功能接口
|
||||
## 0.3.0
|
||||
+ 新增:清除通知栏单条通知方法
|
||||
+ 修复:点击通知栏无法获取消息问题
|
||||
+ 同步最新版 SDK
|
||||
## 0.2.0
|
||||
+ 适配最新版本 JPush SDK
|
||||
+ Android 支持设置角标 badge
|
||||
## 0.1.0
|
||||
+ 修复:调用 sendLocalNotification 接口 crash 问题;
|
||||
+ 修复:iOS 启动 APP 角标自动消失问题;
|
||||
+ 修复执行 flutter build apk 打包错误问题;
|
||||
+ 更新配置
|
||||
|
||||
## 0.0.13
|
||||
|
||||
featurn:
|
||||
适配flutter 1.7.8
|
||||
升级 jpush sdk 版本为3.3.4
|
||||
|
||||
## 0.0.12
|
||||
|
||||
featurn: 修改LocalNotification的属性名为"extra"
|
||||
|
||||
## 0.0.11
|
||||
|
||||
iOS: 修复 getLaunchAppNotification 返回 null 的情况。
|
||||
featurn: APNS 推送字段将 extras 字段移动到 notification.extras 中和 android 保持一致。
|
||||
|
||||
## 0.0.9
|
||||
|
||||
android: 修复 JPushReceiver 类型转换的错误。
|
||||
|
||||
## 0.0.8
|
||||
|
||||
更新 setup 方法,android 端现在支持 channel 字段,用于动态设置 channel,和 iOS 保持一致。
|
||||
注意通过 setup 设置 的 channel 会覆盖 manifestPlaceholders 中的 JPUSH_CHANNEL 字段。
|
||||
|
||||
## 0.0.7
|
||||
|
||||
修改 setup 方法,添加 boolean debug 参数,如果 debug 为 true 这打印日志,如果为 false 则不打印日志。
|
||||
|
||||
## 0.0.6
|
||||
|
||||
增加 swift 工程支持。
|
||||
|
||||
|
||||
## 0.0.3
|
||||
添加 localnotification api。
|
||||
|
||||
## 0.0.2
|
||||
|
||||
修复 android 类名文件名不匹配问题。
|
||||
|
||||
## 0.0.1
|
||||
|
||||
第一个版本。
|
||||
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 极光开发者
|
||||
|
||||
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.
|
||||
120
README.md
@ -1,93 +1,61 @@
|
||||
# jpush_flutter_sdk
|
||||
[]()
|
||||
# JPush Flutter Plugin
|
||||
|
||||
### 安装
|
||||
|
||||
|
||||
## Getting started
|
||||
|
||||
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
|
||||
|
||||
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
|
||||
|
||||
## Add your files
|
||||
|
||||
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
|
||||
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
|
||||
在工程 pubspec.yaml 中加入 dependencies
|
||||
|
||||
```
|
||||
cd existing_repo
|
||||
git remote add origin http://code-internal.star-lock.cn/liuyanfeng/jpush_flutter_sdk.git
|
||||
git branch -M main
|
||||
git push -uf origin main
|
||||
|
||||
//github 集成
|
||||
dependencies:
|
||||
jpush_flutter:
|
||||
git:
|
||||
url: git://github.com/jpush/jpush-flutter-plugin.git
|
||||
ref: dev-2.x
|
||||
|
||||
// pub 集成
|
||||
dependencies:
|
||||
jpush_flutter: 2.5.8
|
||||
```
|
||||
|
||||
## Integrate with your tools
|
||||
### 配置
|
||||
|
||||
- [ ] [Set up project integrations](http://code-internal.star-lock.cn/liuyanfeng/jpush_flutter_sdk/-/settings/integrations)
|
||||
##### Android:
|
||||
|
||||
## Collaborate with your team
|
||||
在 `/android/app/build.gradle` 中添加下列代码:
|
||||
|
||||
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
|
||||
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
|
||||
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
|
||||
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
|
||||
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
|
||||
```groovy
|
||||
android: {
|
||||
....
|
||||
defaultConfig {
|
||||
applicationId "替换成自己应用 ID"
|
||||
...
|
||||
ndk {
|
||||
//选择要添加的对应 cpu 类型的 .so 库。
|
||||
abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64', 'mips', 'mips64', 'arm64-v8a',
|
||||
}
|
||||
|
||||
## Test and Deploy
|
||||
manifestPlaceholders = [
|
||||
JPUSH_PKGNAME : applicationId,
|
||||
JPUSH_APPKEY : "appkey", // NOTE: JPush 上注册的包名对应的 Appkey.
|
||||
JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
|
||||
]
|
||||
}
|
||||
```
|
||||
##### iOS:
|
||||
|
||||
Use the built-in continuous integration in GitLab.
|
||||
- 在 xcode8 之后需要点开推送选项: TARGETS -> Capabilities -> Push Notification 设为 on 状态
|
||||
|
||||
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
|
||||
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
|
||||
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
|
||||
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
|
||||
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
|
||||
### 使用
|
||||
|
||||
***
|
||||
```dart
|
||||
import 'package:jpush_flutter/jpush_flutter.dart';
|
||||
```
|
||||
|
||||
# Editing this README
|
||||
### APIs
|
||||
|
||||
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
|
||||
**注意** : 需要先调用 JPush.setup 来初始化插件,才能保证其他功能正常工作。
|
||||
|
||||
## Suggestions for a good README
|
||||
[参考](./documents/APIs.md)
|
||||
|
||||
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
|
||||
|
||||
## Name
|
||||
Choose a self-explaining name for your project.
|
||||
|
||||
## Description
|
||||
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
|
||||
|
||||
## Badges
|
||||
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
|
||||
|
||||
## Visuals
|
||||
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
|
||||
|
||||
## Installation
|
||||
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
|
||||
|
||||
## Usage
|
||||
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
|
||||
|
||||
## Support
|
||||
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
|
||||
|
||||
## Roadmap
|
||||
If you have ideas for releases in the future, it is a good idea to list them in the README.
|
||||
|
||||
## Contributing
|
||||
State if you are open to contributions and what your requirements are for accepting them.
|
||||
|
||||
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
|
||||
|
||||
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
|
||||
|
||||
## Authors and acknowledgment
|
||||
Show your appreciation to those who have contributed to the project.
|
||||
|
||||
## License
|
||||
For open source projects, say how it is licensed.
|
||||
|
||||
## Project status
|
||||
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
|
||||
|
||||
BIN
android/.DS_Store
vendored
Normal file
39
android/build.gradle
Normal file
@ -0,0 +1,39 @@
|
||||
group 'com.jiguang.jpush'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 17
|
||||
}
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'cn.jiguang.sdk:jpush:5.4.0'
|
||||
}
|
||||
1
android/gradle.properties
Normal file
@ -0,0 +1 @@
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
#Fri Jul 26 11:14:36 CST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
|
||||
160
android/gradlew
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
android/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
1
android/settings.gradle
Normal file
@ -0,0 +1 @@
|
||||
rootProject.name = 'jpush'
|
||||
41
android/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jiguang.jpush"
|
||||
>
|
||||
<application>
|
||||
<!-- <receiver-->
|
||||
<!-- android:name="com.jiguang.jpush.JPushPlugin$JPushReceiver"-->
|
||||
<!-- android:enabled="true"-->
|
||||
<!-- android:exported="false">-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="cn.jpush.android.intent.REGISTRATION" />-->
|
||||
<!-- <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" />-->
|
||||
<!-- <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" />-->
|
||||
<!-- <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" />-->
|
||||
<!-- <action android:name="cn.jpush.android.intent.NOTIFICATION_CLICK_ACTION" />-->
|
||||
<!-- <action android:name="cn.jpush.android.intent.CONNECTION" />-->
|
||||
<!-- <category android:name="${applicationId}" />-->
|
||||
<!-- </intent-filter>-->
|
||||
<!-- </receiver>-->
|
||||
|
||||
<receiver android:name="com.jiguang.jpush.JPushEventReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="cn.jpush.android.intent.RECEIVER_MESSAGE" />
|
||||
<category android:name="${applicationId}" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- Since JCore2.0.0 Required SDK核心功能-->
|
||||
<!-- 可配置android:process参数将Service放在其他进程中;android:enabled属性不能是false -->
|
||||
<!-- 这个是自定义Service,要继承极光JCommonService,可以在更多手机平台上使得推送通道保持的更稳定 -->
|
||||
<service android:name=".JPushCustomService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:stopWithTask="true"
|
||||
android:process=":pushcore">
|
||||
<intent-filter>
|
||||
<action android:name="cn.jiguang.user.service.action" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/>
|
||||
</manifest>
|
||||
@ -0,0 +1,6 @@
|
||||
package com.jiguang.jpush;
|
||||
|
||||
import cn.jpush.android.service.JCommonService;
|
||||
|
||||
public class JPushCustomService extends JCommonService {
|
||||
}
|
||||
238
android/src/main/java/com/jiguang/jpush/JPushEventReceiver.java
Normal file
@ -0,0 +1,238 @@
|
||||
package com.jiguang.jpush;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import cn.jpush.android.api.CmdMessage;
|
||||
import cn.jpush.android.api.CustomMessage;
|
||||
import cn.jpush.android.api.JPushInterface;
|
||||
import cn.jpush.android.api.JPushMessage;
|
||||
import cn.jpush.android.api.NotificationMessage;
|
||||
import cn.jpush.android.service.JPushMessageReceiver;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
|
||||
public class JPushEventReceiver extends JPushMessageReceiver {
|
||||
@Override
|
||||
public void onNotifyMessageArrived(Context context, NotificationMessage notificationMessage) {
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().transmitNotificationReceive(notificationMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotifyMessageOpened(Context context, NotificationMessage notificationMessage) {
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().transmitNotificationOpen(notificationMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(Context context, CustomMessage customMessage) {
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().transmitMessageReceive(customMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegister(Context context, String s) {
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().transmitReceiveRegistrationId(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandResult(Context context,final CmdMessage cmdMessage) {
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().onCommandResult(cmdMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onNotifyMessageUnShow(Context context,final NotificationMessage notificationMessage) {
|
||||
super.onNotifyMessageUnShow(context,notificationMessage);
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().onNotifyMessageUnShow(notificationMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onConnected(Context context,final boolean isConnected) {
|
||||
//连接状态
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().onConnected(isConnected);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInAppMessageShow(Context context,final NotificationMessage message) {
|
||||
Log.i("JPushPlugin", "[onInAppMessageShow], " + message.toString());
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().onInAppMessageShow(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInAppMessageClick(Context context,final NotificationMessage message) {
|
||||
Log.i("JPushPlugin", "[onInAppMessageClick], " + message.toString());
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JPushHelper.getInstance().onInAppMessageClick(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void onTagOperatorResult(Context context, final JPushMessage jPushMessage) {
|
||||
super.onTagOperatorResult(context, jPushMessage);
|
||||
|
||||
final JSONObject resultJson = new JSONObject();
|
||||
|
||||
final int sequence = jPushMessage.getSequence();
|
||||
try {
|
||||
resultJson.put("sequence", sequence);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
final Result callback = JPushHelper.getInstance().getCallback(sequence);//instance.eventCallbackMap.get(sequence);
|
||||
|
||||
if (callback == null) {
|
||||
Log.i("JPushPlugin", "Unexpected error, callback is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (jPushMessage.getErrorCode() == 0) { // success
|
||||
Set<String> tags = jPushMessage.getTags();
|
||||
List<String> tagList = new ArrayList<>(tags);
|
||||
Map<String, Object> res = new HashMap<>();
|
||||
res.put("tags", tagList);
|
||||
callback.success(res);
|
||||
} else {
|
||||
try {
|
||||
resultJson.put("code", jPushMessage.getErrorCode());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
callback.error(Integer.toString(jPushMessage.getErrorCode()), "", "");
|
||||
}
|
||||
|
||||
JPushHelper.getInstance().removeCallback(sequence);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCheckTagOperatorResult(Context context, final JPushMessage jPushMessage) {
|
||||
super.onCheckTagOperatorResult(context, jPushMessage);
|
||||
|
||||
|
||||
|
||||
final int sequence = jPushMessage.getSequence();
|
||||
|
||||
|
||||
final Result callback = JPushHelper.getInstance().getCallback(sequence);;
|
||||
|
||||
if (callback == null) {
|
||||
Log.i("JPushPlugin", "Unexpected error, callback is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (jPushMessage.getErrorCode() == 0) {
|
||||
Set<String> tags = jPushMessage.getTags();
|
||||
List<String> tagList = new ArrayList<>(tags);
|
||||
Map<String, Object> res = new HashMap<>();
|
||||
res.put("tags", tagList);
|
||||
callback.success(res);
|
||||
} else {
|
||||
|
||||
callback.error(Integer.toString(jPushMessage.getErrorCode()), "", "");
|
||||
}
|
||||
|
||||
JPushHelper.getInstance().removeCallback(sequence);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAliasOperatorResult(Context context, final JPushMessage jPushMessage) {
|
||||
super.onAliasOperatorResult(context, jPushMessage);
|
||||
|
||||
final int sequence = jPushMessage.getSequence();
|
||||
|
||||
|
||||
final Result callback = JPushHelper.getInstance().getCallback(sequence);;
|
||||
|
||||
if (callback == null) {
|
||||
Log.i("JPushPlugin", "Unexpected error, callback is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
JPushHelper.getInstance().getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (jPushMessage.getErrorCode() == 0) { // success
|
||||
Map<String, Object> res = new HashMap<>();
|
||||
res.put("alias", (jPushMessage.getAlias() == null)? "" : jPushMessage.getAlias());
|
||||
callback.success(res);
|
||||
|
||||
} else {
|
||||
callback.error(Integer.toString(jPushMessage.getErrorCode()), "", "");
|
||||
}
|
||||
|
||||
JPushHelper.getInstance().removeCallback(sequence);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationSettingsCheck(Context context, boolean isOn, int source) {
|
||||
super.onNotificationSettingsCheck(context, isOn, source);
|
||||
|
||||
|
||||
HashMap<String, Object> map = new HashMap();
|
||||
map.put("isEnabled",isOn);
|
||||
JPushHelper.getInstance().runMainThread(map,null,"onReceiveNotificationAuthorization");
|
||||
}
|
||||
}
|
||||
363
android/src/main/java/com/jiguang/jpush/JPushHelper.java
Normal file
@ -0,0 +1,363 @@
|
||||
package com.jiguang.jpush;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import cn.jpush.android.api.CmdMessage;
|
||||
import cn.jpush.android.api.CustomMessage;
|
||||
import cn.jpush.android.api.JPushInterface;
|
||||
import cn.jpush.android.api.NotificationMessage;
|
||||
import cn.jpush.android.local.JPushConstants;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
|
||||
public class JPushHelper {
|
||||
private static String TAG = "| JPUSH | Flutter | Android | ";
|
||||
private List<Map<String, Object>> openNotificationCache = new ArrayList<>();
|
||||
|
||||
private boolean dartIsReady = false;
|
||||
private boolean jpushDidinit = false;
|
||||
private Handler mHandler;
|
||||
|
||||
private List<Result> getRidCache = new ArrayList<>();
|
||||
private MethodChannel channel;
|
||||
private Map<Integer, Result> callbackMap = new HashMap<>();
|
||||
private WeakReference<Context> mContext;
|
||||
|
||||
private JPushHelper() {
|
||||
}
|
||||
|
||||
private static final class SingleHolder {
|
||||
private static final JPushHelper single = new JPushHelper();
|
||||
}
|
||||
|
||||
public static JPushHelper getInstance() {
|
||||
return SingleHolder.single;
|
||||
}
|
||||
|
||||
|
||||
public MethodChannel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public Result getCallback(int sequence) {
|
||||
return callbackMap.get(sequence);
|
||||
}
|
||||
|
||||
public void addCallback(int sequence, Result result) {
|
||||
callbackMap.put(sequence, result);
|
||||
}
|
||||
|
||||
public void removeCallback(int sequence) {
|
||||
callbackMap.remove(sequence);
|
||||
}
|
||||
|
||||
public void addRid(Result result) {
|
||||
getRidCache.add(result);
|
||||
}
|
||||
|
||||
|
||||
public Handler getHandler() {
|
||||
if (mHandler == null) {
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
return mHandler;
|
||||
}
|
||||
|
||||
public void setMethodChannel(MethodChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public void setContext(Context context) {
|
||||
if (mContext != null) {
|
||||
mContext.clear();
|
||||
mContext = null;
|
||||
}
|
||||
mContext = new WeakReference<>(context.getApplicationContext());
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
public void setDartIsReady(boolean isReady) {
|
||||
dartIsReady = isReady;
|
||||
}
|
||||
|
||||
public void setJpushDidinit(boolean jpushDidinit) {
|
||||
this.jpushDidinit = jpushDidinit;
|
||||
}
|
||||
|
||||
public void dispatchNotification() {
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the channel is null");
|
||||
return;
|
||||
}
|
||||
List<Object> tempList = new ArrayList<Object>();
|
||||
if (dartIsReady) {
|
||||
// try to shedule notifcation cache
|
||||
List<Map<String, Object>> openNotificationCacheList = openNotificationCache;
|
||||
for (Map<String, Object> notification : openNotificationCacheList) {
|
||||
channel.invokeMethod("onOpenNotification", notification);
|
||||
tempList.add(notification);
|
||||
}
|
||||
openNotificationCacheList.removeAll(tempList);
|
||||
tempList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void dispatchRid() {
|
||||
if (mContext == null || mContext.get() == null) {
|
||||
return;
|
||||
}
|
||||
List<Object> tempList = new ArrayList<Object>();
|
||||
String rid = JPushInterface.getRegistrationID(mContext.get());
|
||||
boolean ridAvailable = rid != null && !rid.isEmpty();
|
||||
if (ridAvailable && dartIsReady) {
|
||||
// try to schedule get rid cache
|
||||
tempList.clear();
|
||||
List<Result> resultList = getRidCache;
|
||||
for (Result res : resultList) {
|
||||
Log.d(TAG, "scheduleCache rid = " + rid);
|
||||
res.success(rid);
|
||||
tempList.add(res);
|
||||
}
|
||||
resultList.removeAll(tempList);
|
||||
tempList.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void transmitMessageReceive(CustomMessage customMessage) {
|
||||
Log.d(TAG, "transmitMessageReceive " + "customMessage=" + customMessage);
|
||||
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the instance is null");
|
||||
return;
|
||||
}
|
||||
Map<String, Object> msg = new HashMap<>();
|
||||
msg.put("message", customMessage.message);
|
||||
msg.put("alert", customMessage.title);
|
||||
msg.put("extras", getExtras(customMessage));
|
||||
Log.d(TAG, "transmitMessageReceive msg=" + msg);
|
||||
channel.invokeMethod("onReceiveMessage", msg);
|
||||
}
|
||||
|
||||
public void transmitNotificationOpen(NotificationMessage notificationMessage) {
|
||||
Log.d(TAG, "transmitNotificationOpen notificationMessage=" + notificationMessage);
|
||||
Map<String, Object> notification = new HashMap<>();
|
||||
notification.put("title", notificationMessage.notificationTitle);
|
||||
notification.put("alert", notificationMessage.notificationContent);
|
||||
notification.put("extras", getExtras(notificationMessage));
|
||||
openNotificationCache.add(notification);
|
||||
Log.d(TAG, "transmitNotificationOpen notification=" + notification);
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the channel is null");
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "instance.dartIsReady =" + dartIsReady);
|
||||
if (dartIsReady) {
|
||||
channel.invokeMethod("onOpenNotification", notification);
|
||||
openNotificationCache.remove(notification);
|
||||
}
|
||||
}
|
||||
|
||||
public void transmitNotificationReceive(NotificationMessage notificationMessage) {
|
||||
Log.d(TAG, "transmitNotificationReceive notificationMessage=" + notificationMessage);
|
||||
// Log.d(TAG, "transmitNotificationReceive " + "title=" + title + "alert=" + alert + "extras=" + extras);
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the channel is null");
|
||||
return;
|
||||
}
|
||||
Map<String, Object> notification = new HashMap<>();
|
||||
notification.put("title", notificationMessage.notificationTitle);
|
||||
notification.put("alert", notificationMessage.notificationContent);
|
||||
notification.put("extras", getExtras(notificationMessage));
|
||||
Log.d(TAG, "transmitNotificationReceive notification=" + notification);
|
||||
channel.invokeMethod("onReceiveNotification", notification);
|
||||
}
|
||||
|
||||
public void onCommandResult(CmdMessage cmdMessage) {
|
||||
Log.e(TAG, "[onCommandResult] message:" + cmdMessage);
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the channel is null");
|
||||
return;
|
||||
}
|
||||
Map<String, Object> notification = new HashMap<>();
|
||||
notification.put("cmd", cmdMessage.cmd);
|
||||
notification.put("errorCode", cmdMessage.errorCode);
|
||||
notification.put("msg", cmdMessage.msg);
|
||||
notification.put("extras", bundleToMap(cmdMessage.extra));
|
||||
channel.invokeMethod("onCommandResult", notification);
|
||||
}
|
||||
|
||||
public void onNotifyMessageUnShow(NotificationMessage notificationMessage) {
|
||||
Log.e(TAG, "[onNotifyMessageUnShow] message:" + notificationMessage);
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the channel is null");
|
||||
return;
|
||||
}
|
||||
Map<String, Object> notification = new HashMap<>();
|
||||
notification.put("title", notificationMessage.notificationTitle);
|
||||
notification.put("alert", notificationMessage.notificationContent);
|
||||
notification.put("extras", getExtras(notificationMessage));
|
||||
channel.invokeMethod("onNotifyMessageUnShow", notification);
|
||||
}
|
||||
|
||||
public void onConnected(boolean isConnected) {
|
||||
Log.e(TAG, "[onConnected] :" + isConnected);
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the channel is null");
|
||||
return;
|
||||
}
|
||||
Map<String, Object> results = new HashMap<>();
|
||||
results.put("result", isConnected);
|
||||
channel.invokeMethod("onConnected", results);
|
||||
}
|
||||
|
||||
public void onInAppMessageShow(NotificationMessage notificationMessage) {
|
||||
Log.e(TAG, "[onInAppMessageShow] :" + notificationMessage);
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the channel is null");
|
||||
return;
|
||||
}
|
||||
Map<String, Object> notification = new HashMap<>();
|
||||
notification.put("title", notificationMessage.inAppMsgTitle);
|
||||
notification.put("alert", notificationMessage.inAppMsgContentBody);
|
||||
notification.put("messageId", notificationMessage.msgId);
|
||||
notification.put("inAppShowTarget", notificationMessage.inAppShowTarget);
|
||||
notification.put("inAppClickAction", notificationMessage.inAppClickAction);
|
||||
notification.put("inAppExtras", stringToMap(notificationMessage.inAppExtras));
|
||||
channel.invokeMethod("onInAppMessageShow", notification);
|
||||
}
|
||||
|
||||
public void onInAppMessageClick(NotificationMessage notificationMessage) {
|
||||
Log.e(TAG, "[onInAppMessageClick] :" + notificationMessage);
|
||||
if (channel == null) {
|
||||
Log.d(TAG, "the channel is null");
|
||||
return;
|
||||
}
|
||||
Map<String, Object> notification = new HashMap<>();
|
||||
notification.put("title", notificationMessage.inAppMsgTitle);
|
||||
notification.put("alert", notificationMessage.inAppMsgContentBody);
|
||||
notification.put("messageId", notificationMessage.msgId);
|
||||
notification.put("inAppShowTarget", notificationMessage.inAppShowTarget);
|
||||
notification.put("inAppClickAction", notificationMessage.inAppClickAction);
|
||||
notification.put("inAppExtras", stringToMap(notificationMessage.inAppExtras));
|
||||
channel.invokeMethod("onInAppMessageClick", notification);
|
||||
}
|
||||
|
||||
private Map<String, Object> getExtras(CustomMessage customMessage) {
|
||||
Map<String, Object> extra = new HashMap<>();
|
||||
extra.put(JPushInterface.EXTRA_EXTRA, stringToMap(customMessage.extra));
|
||||
extra.put(JPushInterface.EXTRA_MSG_ID, customMessage.messageId);
|
||||
extra.put(JPushInterface.EXTRA_CONTENT_TYPE, customMessage.contentType);
|
||||
if (JPushConstants.SDK_VERSION_CODE >= 387) {
|
||||
extra.put(JPushInterface.EXTRA_TYPE_PLATFORM, customMessage.platform);
|
||||
}
|
||||
return extra;
|
||||
}
|
||||
|
||||
private Map<String, Object> getExtras(NotificationMessage notificationMessage) {
|
||||
Map<String, Object> extras = new HashMap<>();
|
||||
try {
|
||||
extras.put(JPushInterface.EXTRA_MSG_ID, notificationMessage.msgId);
|
||||
extras.put(JPushInterface.EXTRA_NOTIFICATION_ID, notificationMessage.notificationId);
|
||||
extras.put(JPushInterface.EXTRA_ALERT_TYPE, notificationMessage.notificationAlertType + "");
|
||||
extras.put(JPushInterface.EXTRA_EXTRA, stringToMap(notificationMessage.notificationExtras));
|
||||
if (notificationMessage.notificationStyle == 1 && !TextUtils.isEmpty(notificationMessage.notificationBigText)) {
|
||||
extras.put(JPushInterface.EXTRA_BIG_TEXT, notificationMessage.notificationBigText);
|
||||
} else if (notificationMessage.notificationStyle == 2 && !TextUtils.isEmpty(notificationMessage.notificationInbox)) {
|
||||
extras.put(JPushInterface.EXTRA_INBOX, notificationMessage.notificationInbox);
|
||||
} else if ((notificationMessage.notificationStyle == 3) && !TextUtils.isEmpty(notificationMessage.notificationBigPicPath)) {
|
||||
extras.put(JPushInterface.EXTRA_BIG_PIC_PATH, notificationMessage.notificationBigPicPath);
|
||||
}
|
||||
if (!(notificationMessage.notificationPriority == 0)) {
|
||||
extras.put(JPushInterface.EXTRA_NOTI_PRIORITY, notificationMessage.notificationPriority + "");
|
||||
}
|
||||
if (!TextUtils.isEmpty(notificationMessage.notificationCategory)) {
|
||||
extras.put(JPushInterface.EXTRA_NOTI_CATEGORY, notificationMessage.notificationCategory);
|
||||
}
|
||||
if (!TextUtils.isEmpty(notificationMessage.notificationSmallIcon)) {
|
||||
extras.put(JPushInterface.EXTRA_NOTIFICATION_SMALL_ICON, notificationMessage.notificationSmallIcon);
|
||||
}
|
||||
if (!TextUtils.isEmpty(notificationMessage.notificationLargeIcon)) {
|
||||
extras.put(JPushInterface.EXTRA_NOTIFICATION_LARGET_ICON, notificationMessage.notificationLargeIcon);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, "[onNotifyMessageUnShow] e:" + e.getMessage());
|
||||
}
|
||||
return extras;
|
||||
}
|
||||
public static Map<String, Object> bundleToMap(Bundle bundle) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
if (bundle != null) {
|
||||
for (String key : bundle.keySet()) {
|
||||
if("intent_component".equals(key)||"intent_action".equals(key)){
|
||||
continue;
|
||||
}
|
||||
Object value = bundle.get(key);
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
public Map<String, Object> stringToMap(String extra) {
|
||||
Map<String, Object> useExtra = new HashMap<String, Object>();
|
||||
try {
|
||||
if (TextUtils.isEmpty(extra)) {
|
||||
return useExtra;
|
||||
}
|
||||
JSONObject object = new JSONObject(extra);
|
||||
Iterator<String> keys = object.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
Object value = object.get(key);
|
||||
useExtra.put(key, value);
|
||||
}
|
||||
} catch (Throwable throwable) {
|
||||
}
|
||||
return useExtra;
|
||||
}
|
||||
|
||||
|
||||
public void transmitReceiveRegistrationId(String rId) {
|
||||
Log.d(TAG, "transmitReceiveRegistrationId: " + rId);
|
||||
jpushDidinit = true;
|
||||
dispatchNotification();
|
||||
dispatchRid();
|
||||
}
|
||||
|
||||
// 主线程再返回数据
|
||||
public void runMainThread(final Map<String, Object> map, final Result result, final String method) {
|
||||
Log.d(TAG, "runMainThread:" + "map = " + map + ",method =" + method);
|
||||
getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (result == null && method != null) {
|
||||
if (null != channel) {
|
||||
channel.invokeMethod(method, map);
|
||||
} else {
|
||||
Log.d(TAG, "channel is null do nothing");
|
||||
}
|
||||
} else {
|
||||
result.success(map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
618
android/src/main/java/com/jiguang/jpush/JPushPlugin.java
Normal file
@ -0,0 +1,618 @@
|
||||
package com.jiguang.jpush;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import cn.jpush.android.data.JPushConfig;
|
||||
import cn.jiguang.api.JCoreInterface;
|
||||
import cn.jiguang.api.utils.JCollectionAuth;
|
||||
import cn.jpush.android.api.JPushInterface;
|
||||
import cn.jpush.android.api.NotificationMessage;
|
||||
import cn.jpush.android.data.JPushCollectControl;
|
||||
import cn.jpush.android.data.JPushLocalNotification;
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
|
||||
/**
|
||||
* JPushPlugin
|
||||
*/
|
||||
public class JPushPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
|
||||
private static String TAG = "| JPUSH | Flutter | Android | ";
|
||||
private Context context;
|
||||
private Activity mActivity;
|
||||
private int sequence;
|
||||
public JPushPlugin() {
|
||||
this.sequence = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToEngine(FlutterPluginBinding flutterPluginBinding) {
|
||||
MethodChannel channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "jpush");
|
||||
channel.setMethodCallHandler(this);
|
||||
context = flutterPluginBinding.getApplicationContext();
|
||||
JPushHelper.getInstance().setMethodChannel(channel);
|
||||
JPushHelper.getInstance().setContext(context);
|
||||
}
|
||||
@Override
|
||||
public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
|
||||
if(activityPluginBinding!=null){
|
||||
mActivity = activityPluginBinding.getActivity();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromActivityForConfigChanges() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromActivity() {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onDetachedFromEngine(FlutterPluginBinding binding) {
|
||||
MethodChannel channel =JPushHelper.getInstance().getChannel();
|
||||
if(channel!=null){
|
||||
channel.setMethodCallHandler(null);
|
||||
}
|
||||
JPushHelper.getInstance().setDartIsReady(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(MethodCall call, Result result) {
|
||||
Log.i(TAG, call.method);
|
||||
if (call.method.equals("getPlatformVersion")) {
|
||||
result.success("Android " + android.os.Build.VERSION.RELEASE);
|
||||
} else if (call.method.equals("setup")) {
|
||||
setup(call, result);
|
||||
} else if (call.method.equals("setTags")) {
|
||||
setTags(call, result);
|
||||
} else if (call.method.equals("cleanTags")) {
|
||||
cleanTags(call, result);
|
||||
} else if (call.method.equals("addTags")) {
|
||||
addTags(call, result);
|
||||
} else if (call.method.equals("deleteTags")) {
|
||||
deleteTags(call, result);
|
||||
} else if (call.method.equals("getAllTags")) {
|
||||
getAllTags(call, result);
|
||||
} else if (call.method.equals("setAlias")) {
|
||||
setAlias(call, result);
|
||||
} else if (call.method.equals("getAlias")) {
|
||||
getAlias(call, result);
|
||||
} else if (call.method.equals("deleteAlias")) {
|
||||
deleteAlias(call, result);
|
||||
;
|
||||
} else if (call.method.equals("stopPush")) {
|
||||
stopPush(call, result);
|
||||
} else if (call.method.equals("resumePush")) {
|
||||
resumePush(call, result);
|
||||
} else if (call.method.equals("clearAllNotifications")) {
|
||||
clearAllNotifications(call, result);
|
||||
}else if (call.method.equals("clearLocalNotifications")) {
|
||||
clearLocalNotifications(call, result);
|
||||
} else if (call.method.equals("clearNotification")) {
|
||||
clearNotification(call, result);
|
||||
} else if (call.method.equals("getLaunchAppNotification")) {
|
||||
getLaunchAppNotification(call, result);
|
||||
} else if (call.method.equals("getRegistrationID")) {
|
||||
getRegistrationID(call, result);
|
||||
} else if (call.method.equals("sendLocalNotification")) {
|
||||
sendLocalNotification(call, result);
|
||||
} else if (call.method.equals("setBadge")) {
|
||||
setBadge(call, result);
|
||||
} else if (call.method.equals("isNotificationEnabled")) {
|
||||
isNotificationEnabled(call, result);
|
||||
} else if (call.method.equals("openSettingsForNotification")) {
|
||||
openSettingsForNotification(call, result);
|
||||
} else if (call.method.equals("setWakeEnable")) {
|
||||
setWakeEnable(call, result);
|
||||
} else if (call.method.equals("setAuth")) {
|
||||
setAuth(call, result);
|
||||
} else if (call.method.equals("testCountryCode")) {
|
||||
testCountryCode(call, result);
|
||||
}else if (call.method.equals("enableAutoWakeup")) {
|
||||
enableAutoWakeup(call, result);
|
||||
} else if (call.method.equals("setLinkMergeEnable")) {
|
||||
setLinkMergeEnable(call, result);
|
||||
} else if (call.method.equals("setGeofenceEnable")) {
|
||||
setGeofenceEnable(call, result);
|
||||
} else if (call.method.equals("setSmartPushEnable")) {
|
||||
setSmartPushEnable(call, result);
|
||||
}else if (call.method.equals("setCollectControl")) {
|
||||
setCollectControl(call, result);
|
||||
}else if (call.method.equals("setChannelAndSound")) {
|
||||
setChannelAndSound(call, result);
|
||||
}else if (call.method.equals("requestRequiredPermission")) {
|
||||
requestRequiredPermission(call, result);
|
||||
} else {
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
public void requestRequiredPermission(MethodCall call, Result result){
|
||||
JPushInterface.requestRequiredPermission(mActivity);
|
||||
}
|
||||
public void setChannelAndSound(MethodCall call, Result result) {
|
||||
HashMap<String, Object> readableMap = call.arguments();
|
||||
if (readableMap == null) {
|
||||
return;
|
||||
}
|
||||
String channel = (String)readableMap.get("channel");
|
||||
String channelId = (String)readableMap.get("channel_id");
|
||||
String sound = (String)readableMap.get("sound");
|
||||
try {
|
||||
NotificationManager manager= (NotificationManager) context.getSystemService("notification");
|
||||
if(Build.VERSION.SDK_INT<26){
|
||||
return;
|
||||
}
|
||||
if(TextUtils.isEmpty(channel)||TextUtils.isEmpty(channelId)){
|
||||
return;
|
||||
}
|
||||
NotificationChannel channel1=new NotificationChannel(channelId,channel, NotificationManager.IMPORTANCE_HIGH);
|
||||
if(!TextUtils.isEmpty(sound)){
|
||||
channel1.setSound(Uri.parse("android.resource://"+context.getPackageName()+"/raw/"+sound),null);
|
||||
}
|
||||
manager.createNotificationChannel(channel1);
|
||||
JPushInterface.setChannel(context,channel);
|
||||
Log.d(TAG,"setChannelAndSound channelId="+channelId+" channel="+channel+" sound="+sound);
|
||||
|
||||
}catch (Throwable throwable){
|
||||
}
|
||||
}
|
||||
private void setLinkMergeEnable(MethodCall call, Result result) {
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
Boolean enable = (Boolean) map.get("enable");
|
||||
if (enable == null) {
|
||||
enable = true;
|
||||
}
|
||||
JPushInterface.setLinkMergeEnable(context,enable);
|
||||
}
|
||||
private void setGeofenceEnable(MethodCall call, Result result) {
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
Boolean enable = (Boolean) map.get("enable");
|
||||
if (enable == null) {
|
||||
enable = true;
|
||||
}
|
||||
JPushInterface.setGeofenceEnable(context,enable);
|
||||
}
|
||||
private void setSmartPushEnable(MethodCall call, Result result) {
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
Boolean enable = (Boolean) map.get("enable");
|
||||
if (enable == null) {
|
||||
enable = true;
|
||||
}
|
||||
JPushInterface.setSmartPushEnable(context,enable);
|
||||
}
|
||||
private void setCollectControl(MethodCall call, Result result) {
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
JPushCollectControl.Builder builder=new JPushCollectControl.Builder();
|
||||
boolean hadValue=false;
|
||||
if(map.containsKey("imsi")){
|
||||
Boolean imsi = (Boolean) map.get("imsi");
|
||||
builder.imsi(imsi);
|
||||
hadValue=true;
|
||||
}
|
||||
if(map.containsKey("mac")){
|
||||
Boolean mac = (Boolean) map.get("mac");
|
||||
builder.mac(mac);
|
||||
hadValue=true;
|
||||
}
|
||||
if(map.containsKey("wifi")){
|
||||
Boolean wifi = (Boolean) map.get("wifi");
|
||||
builder.wifi(wifi);
|
||||
hadValue=true;
|
||||
}
|
||||
if(map.containsKey("bssid")){
|
||||
Boolean bssid = (Boolean) map.get("bssid");
|
||||
builder.bssid(bssid);
|
||||
hadValue=true;
|
||||
}
|
||||
if(map.containsKey("ssid")){
|
||||
Boolean ssid = (Boolean) map.get("ssid");
|
||||
builder.ssid(ssid);
|
||||
hadValue=true;
|
||||
}
|
||||
if(map.containsKey("imei")){
|
||||
Boolean imei = (Boolean) map.get("imei");
|
||||
builder.imei(imei);
|
||||
hadValue=true;
|
||||
}
|
||||
if(map.containsKey("cell")){
|
||||
Boolean cell = (Boolean) map.get("cell");
|
||||
builder.cell(cell);
|
||||
hadValue=true;
|
||||
}
|
||||
if(hadValue){
|
||||
JPushInterface.setCollectControl(context,builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
private void setAuth(MethodCall call, Result result){
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
Boolean enable = (Boolean) map.get("enable");
|
||||
if (enable == null) {
|
||||
enable = false;
|
||||
}
|
||||
JCollectionAuth.setAuth(context,enable);
|
||||
}
|
||||
private void testCountryCode(MethodCall call, Result result){
|
||||
String code = call.arguments();
|
||||
Log.d(TAG,"testCountryCode code="+code);
|
||||
JCoreInterface.testCountryCode(context,code);
|
||||
}
|
||||
private void setWakeEnable(MethodCall call, Result result) {
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
Boolean enable = (Boolean) map.get("enable");
|
||||
if (enable == null) {
|
||||
enable = false;
|
||||
}
|
||||
JCoreInterface.setWakeEnable(context,enable);
|
||||
}
|
||||
private void enableAutoWakeup(MethodCall call, Result result) {
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
Boolean enable = (Boolean) map.get("enable");
|
||||
if (enable == null) {
|
||||
enable = false;
|
||||
}
|
||||
JCollectionAuth.enableAutoWakeup(context,enable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setup(MethodCall call, Result result) {
|
||||
Log.d(TAG, "setup :" + call.arguments);
|
||||
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
boolean debug = (boolean) map.get("debug");
|
||||
JPushInterface.setDebugMode(debug);
|
||||
String appKey = (String) map.get("appKey");
|
||||
if(!TextUtils.isEmpty(appKey)){
|
||||
JPushConfig config=new JPushConfig();
|
||||
config.setjAppKey(appKey);
|
||||
JPushInterface.init(context,config);
|
||||
}else {
|
||||
JPushInterface.init(context);
|
||||
} // 初始化 JPush
|
||||
JPushInterface.setNotificationCallBackEnable(context, true);
|
||||
String channel = (String) map.get("channel");
|
||||
JPushInterface.setChannel(context, channel);
|
||||
JPushHelper.getInstance().setDartIsReady(true);
|
||||
|
||||
// try to clean getRid cache
|
||||
scheduleCache();
|
||||
}
|
||||
|
||||
public void scheduleCache() {
|
||||
Log.d(TAG, "scheduleCache:");
|
||||
JPushHelper.getInstance().dispatchNotification();
|
||||
JPushHelper.getInstance().dispatchRid();
|
||||
}
|
||||
|
||||
public void setTags(MethodCall call, Result result) {
|
||||
Log.d(TAG, "setTags:");
|
||||
|
||||
List<String> tagList = call.arguments();
|
||||
Set<String> tags = new HashSet<>(tagList);
|
||||
sequence += 1;
|
||||
JPushHelper.getInstance().addCallback(sequence,result);
|
||||
JPushInterface.setTags(context, sequence, tags);
|
||||
}
|
||||
|
||||
public void cleanTags(MethodCall call, Result result) {
|
||||
Log.d(TAG, "cleanTags:");
|
||||
|
||||
sequence += 1;
|
||||
JPushHelper.getInstance().addCallback(sequence,result);
|
||||
JPushInterface.cleanTags(context, sequence);
|
||||
}
|
||||
|
||||
public void addTags(MethodCall call, Result result) {
|
||||
Log.d(TAG, "addTags: " + call.arguments);
|
||||
|
||||
List<String> tagList = call.arguments();
|
||||
Set<String> tags = new HashSet<>(tagList);
|
||||
sequence += 1;
|
||||
JPushHelper.getInstance().addCallback(sequence,result);
|
||||
JPushInterface.addTags(context, sequence, tags);
|
||||
}
|
||||
|
||||
public void deleteTags(MethodCall call, Result result) {
|
||||
Log.d(TAG, "deleteTags: " + call.arguments);
|
||||
|
||||
List<String> tagList = call.arguments();
|
||||
Set<String> tags = new HashSet<>(tagList);
|
||||
sequence += 1;
|
||||
JPushHelper.getInstance().addCallback(sequence,result);
|
||||
JPushInterface.deleteTags(context, sequence, tags);
|
||||
}
|
||||
|
||||
public void getAllTags(MethodCall call, Result result) {
|
||||
Log.d(TAG, "getAllTags: ");
|
||||
|
||||
sequence += 1;
|
||||
JPushHelper.getInstance().addCallback(sequence,result);
|
||||
JPushInterface.getAllTags(context, sequence);
|
||||
}
|
||||
public void getAlias(MethodCall call, Result result) {
|
||||
Log.d(TAG, "getAlias: ");
|
||||
|
||||
sequence += 1;
|
||||
JPushHelper.getInstance().addCallback(sequence,result);
|
||||
JPushInterface.getAlias(context, sequence);
|
||||
}
|
||||
|
||||
public void setAlias(MethodCall call, Result result) {
|
||||
Log.d(TAG, "setAlias: " + call.arguments);
|
||||
|
||||
String alias = call.arguments();
|
||||
sequence += 1;
|
||||
JPushHelper.getInstance().addCallback(sequence,result);
|
||||
JPushInterface.setAlias(context, sequence, alias);
|
||||
}
|
||||
|
||||
public void deleteAlias(MethodCall call, Result result) {
|
||||
Log.d(TAG, "deleteAlias:");
|
||||
|
||||
String alias = call.arguments();
|
||||
sequence += 1;
|
||||
JPushHelper.getInstance().addCallback(sequence,result);
|
||||
JPushInterface.deleteAlias(context, sequence);
|
||||
}
|
||||
|
||||
public void stopPush(MethodCall call, Result result) {
|
||||
Log.d(TAG, "stopPush:");
|
||||
|
||||
JPushInterface.stopPush(context);
|
||||
}
|
||||
|
||||
public void resumePush(MethodCall call, Result result) {
|
||||
Log.d(TAG, "resumePush:");
|
||||
|
||||
JPushInterface.resumePush(context);
|
||||
}
|
||||
|
||||
public void clearAllNotifications(MethodCall call, Result result) {
|
||||
Log.d(TAG, "clearAllNotifications: ");
|
||||
|
||||
JPushInterface.clearAllNotifications(context);
|
||||
}
|
||||
public void clearLocalNotifications(MethodCall call, Result result) {
|
||||
Log.d(TAG, "clearLocalNotifications: ");
|
||||
JPushInterface.clearLocalNotifications(context);
|
||||
}
|
||||
public void clearNotification(MethodCall call, Result result) {
|
||||
Log.d(TAG, "clearNotification: ");
|
||||
Object id = call.arguments;
|
||||
if (id != null) {
|
||||
JPushInterface.clearNotificationById(context, (int) id);
|
||||
}
|
||||
}
|
||||
|
||||
public void getLaunchAppNotification(MethodCall call, Result result) {
|
||||
Log.d(TAG, "");
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void getRegistrationID(MethodCall call, Result result) {
|
||||
Log.d(TAG, "getRegistrationID: ");
|
||||
|
||||
if (context == null) {
|
||||
Log.d(TAG, "register context is nil.");
|
||||
return;
|
||||
}
|
||||
|
||||
String rid = JPushInterface.getRegistrationID(context);
|
||||
if (rid == null || rid.isEmpty()) {
|
||||
JPushHelper.getInstance().addRid(result);
|
||||
} else {
|
||||
result.success(rid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendLocalNotification(MethodCall call, Result result) {
|
||||
Log.d(TAG, "sendLocalNotification: " + call.arguments);
|
||||
|
||||
try {
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
|
||||
JPushLocalNotification ln = new JPushLocalNotification();
|
||||
ln.setBuilderId((Integer) map.get("buildId"));
|
||||
ln.setNotificationId((Integer) map.get("id"));
|
||||
ln.setTitle((String) map.get("title"));
|
||||
ln.setContent((String) map.get("content"));
|
||||
HashMap<String, Object> extra = (HashMap<String, Object>) map.get("extra");
|
||||
|
||||
if (extra != null) {
|
||||
JSONObject json = new JSONObject(extra);
|
||||
ln.setExtras(json.toString());
|
||||
}
|
||||
|
||||
long date = (long) map.get("fireTime");
|
||||
ln.setBroadcastTime(date);
|
||||
|
||||
JPushInterface.addLocalNotification(context, ln);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setBadge(MethodCall call, Result result) {
|
||||
Log.d(TAG, "setBadge: " + call.arguments);
|
||||
|
||||
HashMap<String, Object> map = call.arguments();
|
||||
Object numObject = map.get("badge");
|
||||
if (numObject != null) {
|
||||
int num = (int) numObject;
|
||||
JPushInterface.setBadgeNumber(context, num);
|
||||
result.success(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// 检查当前应用的通知开关是否开启
|
||||
private void isNotificationEnabled(MethodCall call, Result result) {
|
||||
Log.d(TAG, "isNotificationEnabled: ");
|
||||
int isEnabled = JPushInterface.isNotificationEnabled(context);
|
||||
//1表示开启,0表示关闭,-1表示检测失败
|
||||
HashMap<String, Object> map = new HashMap();
|
||||
map.put("isEnabled", isEnabled == 1 ? true : false);
|
||||
|
||||
JPushHelper.getInstance().runMainThread(map, result, null);
|
||||
}
|
||||
|
||||
private void openSettingsForNotification(MethodCall call, Result result) {
|
||||
Log.d(TAG, "openSettingsForNotification: ");
|
||||
|
||||
JPushInterface.goToAppNotificationSettings(context);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收自定义消息,通知,通知点击事件等事件的广播
|
||||
* 文档链接:http://docs.jiguang.cn/client/android_api/
|
||||
*/
|
||||
// public static 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");
|
||||
//
|
||||
// public JPushReceiver() {
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @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);
|
||||
// Log.d("JPushPlugin", "on get registration");
|
||||
// JPushHelper.getInstance().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) {
|
||||
// Log.d(TAG, "handlingMessageReceive " + intent.getAction());
|
||||
//
|
||||
// String msg = intent.getStringExtra(JPushInterface.EXTRA_MESSAGE);
|
||||
// String title = intent.getStringExtra(JPushInterface.EXTRA_TITLE);
|
||||
// Map<String, Object> extras = getNotificationExtras(intent);
|
||||
// JPushHelper.getInstance().transmitMessageReceive(msg, title,extras);
|
||||
// }
|
||||
//
|
||||
// private void handlingNotificationOpen(Context context, Intent intent) {
|
||||
// Log.d(TAG, "handlingNotificationOpen " + intent.getAction());
|
||||
//
|
||||
// String title = intent.getStringExtra(JPushInterface.EXTRA_NOTIFICATION_TITLE);
|
||||
// String alert = intent.getStringExtra(JPushInterface.EXTRA_ALERT);
|
||||
// Map<String, Object> extras = getNotificationExtras(intent);
|
||||
// JPushHelper.getInstance().transmitNotificationOpen(title, alert, extras);
|
||||
// }
|
||||
//
|
||||
// private void handlingNotificationReceive(Context context, Intent intent) {
|
||||
// Log.d(TAG, "handlingNotificationReceive " + intent.getAction());
|
||||
//
|
||||
// String title = intent.getStringExtra(JPushInterface.EXTRA_NOTIFICATION_TITLE);
|
||||
// String alert = intent.getStringExtra(JPushInterface.EXTRA_ALERT);
|
||||
// Map<String, Object> extras = getNotificationExtras(intent);
|
||||
// JPushHelper.getInstance().transmitNotificationReceive(title, alert, extras);
|
||||
// }
|
||||
//
|
||||
// private Map<String, Object> getNotificationExtras(Intent intent) {
|
||||
// Map<String, Object> extrasMap = new HashMap<String, Object>();
|
||||
// Bundle extras = intent.getExtras();
|
||||
// for (String key : extras.keySet()) {
|
||||
// Object value = extras.get(key);
|
||||
// if (!IGNORED_EXTRAS_KEYS.contains(key)) {
|
||||
// if (key.equals(JPushInterface.EXTRA_NOTIFICATION_ID)) {
|
||||
// extrasMap.put(key, intent.getIntExtra(key, 0));
|
||||
// }else if(key.equals("cn.jpush.android.EXTRA")){
|
||||
// try {
|
||||
// JSONObject object=new JSONObject((String)value);
|
||||
// Map<String, Object> useExtra = new HashMap<String, Object>();
|
||||
// jsonToMap(object,useExtra);
|
||||
// extrasMap.put(key,useExtra);
|
||||
// }catch (Throwable throwable){
|
||||
// }
|
||||
// } else {
|
||||
// extrasMap.put(key, value);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return extrasMap;
|
||||
// }
|
||||
// public static void jsonToMap(JSONObject object,Map<String, Object> map) {
|
||||
// try {
|
||||
// Iterator<String> keys = object.keys();
|
||||
// while (keys.hasNext()) {
|
||||
// String key = keys.next();
|
||||
// Object value = object.get(key);
|
||||
// map.put(key, value);
|
||||
// }
|
||||
// }catch (Throwable throwable){
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
282
documents/APIs.md
Normal file
@ -0,0 +1,282 @@
|
||||
[Common API](#common-api)
|
||||
|
||||
- [addEventHandler](#addeventhandler)
|
||||
- [setup](#setup)
|
||||
- [getRegistrationID](#getregistrationid)
|
||||
- [stopPush](#stoppush)
|
||||
- [setChannelAndSound](#setChannelAndSound)
|
||||
- [resumePush](#resumepush)
|
||||
- [setAlias](#setalias)
|
||||
- [getAlias](#getAlias)
|
||||
- [deleteAlias](#deletealias)
|
||||
- [addTags](#addtags)
|
||||
- [deleteTags](#deletetags)
|
||||
- [setTags](#settags)
|
||||
- [cleanTags](#cleantags)
|
||||
- [getAllTags](getalltags)
|
||||
- [sendLocalNotification](#sendlocalnotification)
|
||||
- [clearAllNotifications](#clearallnotifications)
|
||||
|
||||
|
||||
[iOS Only]()
|
||||
|
||||
- [applyPushAuthority](#applypushauthority)
|
||||
- [setBadge](#setbadge)
|
||||
- [getLaunchAppNotification](#getlaunchappnotification)
|
||||
- [pageEnterTo](#pageEnterTo)
|
||||
- [pageLeave](#pageLeave)
|
||||
|
||||
**注意:addEventHandler 方法建议放到 setup 之前,其他方法需要在 setup 方法之后调用,**
|
||||
|
||||
#### addEventHandler
|
||||
|
||||
添加事件监听方法。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.addEventHandler(
|
||||
// 接收通知回调方法。
|
||||
onReceiveNotification: (Map<String, dynamic> message) async {
|
||||
print("flutter onReceiveNotification: $message");
|
||||
},
|
||||
// 点击通知回调方法。
|
||||
onOpenNotification: (Map<String, dynamic> message) async {
|
||||
print("flutter onOpenNotification: $message");
|
||||
},
|
||||
// 接收自定义消息回调方法。
|
||||
onReceiveMessage: (Map<String, dynamic> message) async {
|
||||
print("flutter onReceiveMessage: $message");
|
||||
},
|
||||
onConnected: (Map<String, dynamic> message) async {
|
||||
print("flutter onConnected: $message");
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
#### setup
|
||||
|
||||
添加初始化方法,调用 setup 方法会执行两个操作:
|
||||
|
||||
- 初始化 JPush SDK
|
||||
- 将缓存的事件下发到 dart 环境中。
|
||||
|
||||
**注意:** 插件版本 >= 0.0.8 android 端支持在 setup 方法中动态设置 channel,动态设置的 channel 优先级比 manifestPlaceholders 中的 JPUSH_CHANNEL 优先级要高。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.setup(
|
||||
appKey: "替换成你自己的 appKey",
|
||||
channel: "theChannel",
|
||||
production: false,
|
||||
debug: false, // 设置是否打印 debug 日志
|
||||
);
|
||||
```
|
||||
|
||||
* iOS使用推送功能,需要调用申请通知权限的方法,详情见 [applyPushAuthority](#applyPushAuthority)。
|
||||
|
||||
```
|
||||
jpush.applyPushAuthority(new NotificationSettingsIOS(
|
||||
sound: true,
|
||||
alert: true,
|
||||
badge: true));
|
||||
```
|
||||
|
||||
#### getRegistrationID
|
||||
|
||||
获取 registrationId,这个 JPush 运行通过 registrationId 来进行推送.
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.getRegistrationID().then((rid) { });
|
||||
```
|
||||
|
||||
#### stopPush
|
||||
|
||||
停止推送功能,调用该方法将不会接收到通知。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.stopPush();
|
||||
```
|
||||
|
||||
|
||||
#### setChannelAndSound
|
||||
动态配置 channel 、channel id 及sound,优先级比 AndroidManifest 里配置的高
|
||||
备注:channel、channel id为必须参数,否则接口调用失败。sound 可选
|
||||
|
||||
#### 参数说明
|
||||
- Object
|
||||
|
||||
|参数名称|参数类型|参数说明|
|
||||
|:-----:|:----:|:-----:|
|
||||
|channel|string|希望配置的 channel|
|
||||
|channel_id|string|希望配置的 channel id|
|
||||
|sound|string|希望配置的 sound(铃声名称,只有铃声名称即可,如AA.mp3,填写AA )|
|
||||
|
||||
#### 示例
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.setChannelAndSound();
|
||||
```
|
||||
|
||||
|
||||
#### resumePush
|
||||
|
||||
调用 stopPush 后,可以通过 resumePush 方法恢复推送。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.resumePush();
|
||||
```
|
||||
|
||||
#### setAlias
|
||||
|
||||
设置别名,极光后台可以通过别名来推送,一个 App 应用只有一个别名,一般用来存储用户 id。
|
||||
|
||||
```
|
||||
JPush jpush = new JPush();
|
||||
jpush.setAlias("your alias").then((map) { });
|
||||
```
|
||||
|
||||
#### deleteAlias
|
||||
|
||||
可以通过 deleteAlias 方法来删除已经设置的 alias。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.deleteAlias().then((map) {})
|
||||
```
|
||||
#### getAlias
|
||||
|
||||
获取当前 alias 列表。
|
||||
|
||||
```
|
||||
JPush jpush = new JPush();
|
||||
jpush.getAlias().then((map) { });
|
||||
```
|
||||
#### addTags
|
||||
|
||||
在原来的 Tags 列表上添加指定 tags。
|
||||
|
||||
```
|
||||
JPush jpush = new JPush();
|
||||
jpush.addTags(["tag1","tag2"]).then((map) {});
|
||||
```
|
||||
|
||||
#### deleteTags
|
||||
|
||||
在原来的 Tags 列表上删除指定 tags。
|
||||
|
||||
```
|
||||
JPush jpush = new JPush();
|
||||
jpush.deleteTags(["tag1","tag2"]).then((map) {});
|
||||
```
|
||||
|
||||
#### setTags
|
||||
|
||||
重置 tags。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.setTags(["tag1","tag2"]).then((map) {});
|
||||
```
|
||||
|
||||
#### cleanTags
|
||||
|
||||
清空所有 tags
|
||||
|
||||
```dart
|
||||
jpush.setTags().then((map) {});
|
||||
```
|
||||
|
||||
#### getAllTags
|
||||
|
||||
获取当前 tags 列表。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.getAllTags().then((map) {});
|
||||
```
|
||||
|
||||
#### sendLocalNotification
|
||||
|
||||
指定触发时间,添加本地推送通知。
|
||||
|
||||
```dart
|
||||
// 延时 3 秒后触发本地通知。
|
||||
JPush jpush = new JPush();
|
||||
var fireDate = DateTime.fromMillisecondsSinceEpoch(DateTime.now().millisecondsSinceEpoch + 3000);
|
||||
var localNotification = LocalNotification(
|
||||
id: 234,
|
||||
title: 'notification title',
|
||||
buildId: 1,
|
||||
content: 'notification content',
|
||||
fireTime: fireDate,
|
||||
subtitle: 'notification subtitle', // 该参数只有在 iOS 有效
|
||||
badge: 5, // 该参数只有在 iOS 有效
|
||||
extras: {"fa": "0"} // 设置 extras ,extras 需要是 Map<String, String>
|
||||
);
|
||||
jpush.sendLocalNotification(localNotification).then((res) {});
|
||||
```
|
||||
|
||||
#### clearAllNotifications
|
||||
|
||||
清楚通知栏上所有通知。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.clearAllNotifications();
|
||||
```
|
||||
|
||||
#### applyPushAuthority
|
||||
|
||||
申请推送权限,注意这个方法只会向用户弹出一次推送权限请求(如果用户不同意,之后只能用户到设置页面里面勾选相应权限),需要开发者选择合适的时机调用。
|
||||
|
||||
**注意: iOS10+ 可以通过该方法来设置推送是否前台展示,是否触发声音,是否设置应用角标 badge**
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.applyPushAuthority(new NotificationSettingsIOS(
|
||||
sound: true,
|
||||
alert: true,
|
||||
badge: true));
|
||||
```
|
||||
|
||||
**iOS Only**
|
||||
|
||||
#### setBadge
|
||||
|
||||
设置应用 badge 值,该方法还会同步 JPush 服务器的的 badge 值,JPush 服务器的 badge 值用于推送 badge 自动 +1 时会用到。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.setBadge(66).then((map) {});
|
||||
```
|
||||
|
||||
### getLaunchAppNotification
|
||||
|
||||
获取 iOS 点击推送启动应用的那条通知。
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.getLaunchAppNotification().then((map) {});
|
||||
```
|
||||
|
||||
### pageEnterTo
|
||||
|
||||
进入页面,应用内消息功能需要配置该接口,请与pageLeave函数配套使用
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.pageEnterTo("页面名");
|
||||
```
|
||||
|
||||
### pageLeave
|
||||
|
||||
离开页面,应用内消息功能需要配置该接口,请与pageEnterTo函数配套使用
|
||||
|
||||
```dart
|
||||
JPush jpush = new JPush();
|
||||
jpush.pageLeave("页面名");
|
||||
```
|
||||
|
||||
BIN
example/.DS_Store
vendored
Normal file
8
example/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# jpush_example
|
||||
|
||||
Demonstrates how to use the jpush plugin.
|
||||
|
||||
## Getting Started
|
||||
|
||||
For help getting started with Flutter, view our online
|
||||
[documentation](https://flutter.io/).
|
||||
BIN
example/android/.DS_Store
vendored
Normal file
96
example/android/app/build.gradle
Normal file
@ -0,0 +1,96 @@
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
def keystorePropertiesFile = rootProject.file("key.properties")
|
||||
def keystoreProperties = new Properties()
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
|
||||
// applicationId "com.jiguang.jpushexample"
|
||||
|
||||
applicationId "com.shikk.testJpush" //JPush 上注册的包名.
|
||||
|
||||
minSdkVersion 17
|
||||
targetSdkVersion 31
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
||||
|
||||
ndk {
|
||||
//选择要添加的对应 cpu 类型的 .so 库。
|
||||
abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64', 'mips', 'mips64', 'arm64-v8a'
|
||||
// 还可以添加
|
||||
}
|
||||
|
||||
manifestPlaceholders = [
|
||||
JPUSH_PKGNAME : applicationId,
|
||||
JPUSH_APPKEY : "31c7c1b2cf59c1d42895a782", //JPush 上注册的包名对应的 Appkey.
|
||||
JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
|
||||
]
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile file(keystoreProperties['storeFile'])
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
// buildToolsVersion '28.0.1'
|
||||
|
||||
packagingOptions {
|
||||
exclude 'lib/arm64-v8a/libgojni.so'
|
||||
exclude 'lib/x86/libgojni.so'
|
||||
exclude 'lib/x86_64/libgojni.so'
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
}
|
||||
54
example/android/app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,54 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jiguang.jpushexample">
|
||||
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
flutter needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
In most cases you can leave this as-is, but you if you want to provide
|
||||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
<application
|
||||
android:label="jpush_example"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTask"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- This keeps the window background of the activity showing
|
||||
until Flutter renders its first frame. It can be removed if
|
||||
there is no splash screen (such as the default splash screen
|
||||
defined in @style/LaunchTheme). -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<!-- Displays an Android View that continues showing the launch screen
|
||||
Drawable until Flutter paints its first frame, then this splash
|
||||
screen fades out. A splash screen is useful to avoid any visual
|
||||
gap between the end of Android's launch screen and the painting of
|
||||
Flutter's first frame. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||
android:resource="@drawable/launch_background"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
</manifest>
|
||||
@ -0,0 +1,6 @@
|
||||
package com.jiguang.jpushexample;
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity;
|
||||
|
||||
public class MainActivity extends FlutterActivity {
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
BIN
example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 544 B |
BIN
example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 442 B |
BIN
example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 721 B |
BIN
example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
18
example/android/app/src/main/res/values-night/styles.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
18
example/android/app/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
31
example/android/build.gradle
Normal file
@ -0,0 +1,31 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
22
example/android/gradle.properties
Normal file
@ -0,0 +1,22 @@
|
||||
## Project-wide Gradle settings.
|
||||
#
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
#
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx1024m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
#
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
#Wed Sep 19 16:44:40 CST 2018
|
||||
#systemProp.http.proxyHost=127.0.0.1
|
||||
#systemProp.https.proxyPort=1086
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
#systemProp.https.proxyHost=127.0.0.1
|
||||
#systemProp.http.proxyPort=1086
|
||||
android.enableR8=true
|
||||
android.useAndroidX=true
|
||||
BIN
example/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
example/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
#Wed Aug 21 15:20:04 CST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||
160
example/android/gradlew
vendored
Executable file
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
example/android/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
4
example/android/key.properties
Normal file
@ -0,0 +1,4 @@
|
||||
storePassword=<password from previous step>
|
||||
keyPassword=<password from previous step>
|
||||
keyAlias=key
|
||||
storeFile=<location of the key store file, e.g. /Users/<user name>/key.jks>
|
||||
15
example/android/settings.gradle
Normal file
@ -0,0 +1,15 @@
|
||||
include ':app'
|
||||
|
||||
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
|
||||
|
||||
def plugins = new Properties()
|
||||
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
|
||||
if (pluginsFile.exists()) {
|
||||
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
|
||||
}
|
||||
|
||||
plugins.each { name, path ->
|
||||
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
|
||||
include ":$name"
|
||||
project(":$name").projectDir = pluginDirectory
|
||||
}
|
||||
BIN
example/ios/.DS_Store
vendored
Normal file
26
example/ios/Flutter/AppFrameworkInfo.plist
Normal file
@ -0,0 +1,26 @@
|
||||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>8.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
2
example/ios/Flutter/Debug.xcconfig
Normal file
@ -0,0 +1,2 @@
|
||||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
18
example/ios/Flutter/Flutter.podspec
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# NOTE: This podspec is NOT to be published. It is only used as a local source!
|
||||
# This is a generated file; do not edit or check into version control.
|
||||
#
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'Flutter'
|
||||
s.version = '1.0.0'
|
||||
s.summary = 'High-performance, high-fidelity mobile apps.'
|
||||
s.homepage = 'https://flutter.io'
|
||||
s.license = { :type => 'MIT' }
|
||||
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
|
||||
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
|
||||
s.ios.deployment_target = '9.0'
|
||||
# Framework linking is handled by Flutter tooling, not CocoaPods.
|
||||
# Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs.
|
||||
s.vendored_frameworks = 'path/to/nothing'
|
||||
end
|
||||
2
example/ios/Flutter/Release.xcconfig
Normal file
@ -0,0 +1,2 @@
|
||||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
494
example/ios/Runner.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,494 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
342565195A7B02408C258C63 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E8558CD656C3CFECC78ECB83 /* libPods-Runner.a */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
|
||||
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
|
||||
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
243DB7546D048251A9867C1C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
625494FA213F7D30005E4423 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
C3EB3B32DF8D367805D86460 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
E8558CD656C3CFECC78ECB83 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
342565195A7B02408C258C63 /* libPods-Runner.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
014620662F76D9C7C4749081 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E8558CD656C3CFECC78ECB83 /* libPods-Runner.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */,
|
||||
);
|
||||
name = Flutter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146E51CF9000F007C117D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
AB735DD26662031199114838 /* Pods */,
|
||||
014620662F76D9C7C4749081 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146EF1CF9000F007C117D /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
625494FA213F7D30005E4423 /* Runner.entitlements */,
|
||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
97C147021CF9000F007C117D /* Info.plist */,
|
||||
97C146F11CF9000F007C117D /* Supporting Files */,
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||
);
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146F11CF9000F007C117D /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146F21CF9000F007C117D /* main.m */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
AB735DD26662031199114838 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
243DB7546D048251A9867C1C /* Pods-Runner.debug.xcconfig */,
|
||||
C3EB3B32DF8D367805D86460 /* Pods-Runner.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
7A418C368FF000006114CEC1 /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Runner;
|
||||
productName = Runner;
|
||||
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0910;
|
||||
ORGANIZATIONNAME = "The Chromium Authors";
|
||||
TargetAttributes = {
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
DevelopmentTeam = UT282795WK;
|
||||
ProvisioningStyle = Manual;
|
||||
SystemCapabilities = {
|
||||
com.apple.ApplePay = {
|
||||
enabled = 0;
|
||||
};
|
||||
com.apple.BackgroundModes = {
|
||||
enabled = 1;
|
||||
};
|
||||
com.apple.Push = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 97C146E51CF9000F007C117D;
|
||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
97C146ED1CF9000F007C117D /* Runner */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
|
||||
};
|
||||
7A418C368FF000006114CEC1 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
|
||||
97C146F31CF9000F007C117D /* main.m in Sources */,
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C146FB1CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C147001CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
97C147031CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147041CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
97C147061CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = UT282795WK;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = cn.jiguang.hxhg;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = cn.jiguang.hxhg;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147071CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = UT282795WK;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = cn.jiguang.hxhg;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = cn.jiguang.hxhg;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147031CF9000F007C117D /* Debug */,
|
||||
97C147041CF9000F007C117D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147061CF9000F007C117D /* Debug */,
|
||||
97C147071CF9000F007C117D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||
}
|
||||
7
example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0910"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
10
example/ios/Runner.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@ -0,0 +1,8 @@
|
||||
<?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>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
6
example/ios/Runner/AppDelegate.h
Normal file
@ -0,0 +1,6 @@
|
||||
#import <Flutter/Flutter.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : FlutterAppDelegate
|
||||
|
||||
@end
|
||||
14
example/ios/Runner/AppDelegate.m
Normal file
@ -0,0 +1,14 @@
|
||||
#include "AppDelegate.h"
|
||||
#include "GeneratedPluginRegistrant.h"
|
||||
#include <jpush_flutter/JPushPlugin.h>
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
[GeneratedPluginRegistrant registerWithRegistry:self];
|
||||
// Override point for customization after application launch.
|
||||
return [super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
@ -0,0 +1,122 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 564 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
23
example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "LaunchImage@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
BIN
example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
BIN
example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 68 B |
5
example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Launch Screen Assets
|
||||
|
||||
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
|
||||
|
||||
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
|
||||
37
example/ios/Runner/Base.lproj/LaunchScreen.storyboard
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="EHf-IW-A2E">
|
||||
<objects>
|
||||
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
|
||||
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="LaunchImage" width="168" height="185"/>
|
||||
</resources>
|
||||
</document>
|
||||
26
example/ios/Runner/Base.lproj/Main.storyboard
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Flutter View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
50
example/ios/Runner/Info.plist
Normal file
@ -0,0 +1,50 @@
|
||||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>jpush_example</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>fetch</string>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
8
example/ios/Runner/Runner.entitlements
Normal file
@ -0,0 +1,8 @@
|
||||
<?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>
|
||||
9
example/ios/Runner/main.m
Normal file
@ -0,0 +1,9 @@
|
||||
#import <Flutter/Flutter.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
||||
BIN
example/ios/Runner/sound.caf
Executable file
388
example/lib/main.dart
Normal file
@ -0,0 +1,388 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:jpush_flutter/jpush_flutter.dart';
|
||||
|
||||
void main() => runApp(new MyApp());
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
@override
|
||||
_MyAppState createState() => new _MyAppState();
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
String? debugLable = 'Unknown';
|
||||
final JPush jpush = new JPush();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
initPlatformState();
|
||||
}
|
||||
|
||||
// Platform messages are asynchronous, so we initialize in an async method.
|
||||
Future<void> initPlatformState() async {
|
||||
String? platformVersion;
|
||||
|
||||
try {
|
||||
jpush.addEventHandler(
|
||||
onReceiveNotification: (Map<String, dynamic> message) async {
|
||||
print("flutter onReceiveNotification: $message");
|
||||
setState(() {
|
||||
debugLable = "flutter onReceiveNotification: $message";
|
||||
});
|
||||
}, onOpenNotification: (Map<String, dynamic> message) async {
|
||||
print("flutter onOpenNotification: $message");
|
||||
setState(() {
|
||||
debugLable = "flutter onOpenNotification: $message";
|
||||
});
|
||||
}, onReceiveMessage: (Map<String, dynamic> message) async {
|
||||
print("flutter onReceiveMessage: $message");
|
||||
setState(() {
|
||||
debugLable = "flutter onReceiveMessage: $message";
|
||||
});
|
||||
}, onReceiveNotificationAuthorization:
|
||||
(Map<String, dynamic> message) async {
|
||||
print("flutter onReceiveNotificationAuthorization: $message");
|
||||
setState(() {
|
||||
debugLable = "flutter onReceiveNotificationAuthorization: $message";
|
||||
});
|
||||
}, onNotifyMessageUnShow: (Map<String, dynamic> message) async {
|
||||
print("flutter onNotifyMessageUnShow: $message");
|
||||
setState(() {
|
||||
debugLable = "flutter onNotifyMessageUnShow: $message";
|
||||
});
|
||||
}, onInAppMessageShow: (Map<String, dynamic> message) async {
|
||||
print("flutter onInAppMessageShow: $message");
|
||||
setState(() {
|
||||
debugLable = "flutter onInAppMessageShow: $message";
|
||||
});
|
||||
}, onInAppMessageClick: (Map<String, dynamic> message) async {
|
||||
print("flutter onInAppMessageClick: $message");
|
||||
setState(() {
|
||||
debugLable = "flutter onInAppMessageClick: $message";
|
||||
});
|
||||
}, onConnected: (Map<String, dynamic> message) async {
|
||||
print("flutter onConnected: $message");
|
||||
setState(() {
|
||||
debugLable = "flutter onConnected: $message";
|
||||
});
|
||||
});
|
||||
} on PlatformException {
|
||||
platformVersion = 'Failed to get platform version.';
|
||||
}
|
||||
|
||||
jpush.setAuth(enable: true);
|
||||
jpush.setup(
|
||||
appKey: "xxxxx", //你自己应用的 AppKey
|
||||
channel: "theChannel",
|
||||
production: false,
|
||||
debug: true,
|
||||
);
|
||||
jpush.applyPushAuthority(
|
||||
new NotificationSettingsIOS(sound: true, alert: true, badge: true));
|
||||
|
||||
// Platform messages may fail, so we use a try/catch PlatformException.
|
||||
jpush.getRegistrationID().then((rid) {
|
||||
print("flutter get registration id : $rid");
|
||||
setState(() {
|
||||
debugLable = "flutter getRegistrationID: $rid";
|
||||
});
|
||||
});
|
||||
|
||||
// iOS要是使用应用内消息,请在页面进入离开的时候配置pageEnterTo 和 pageLeave 函数,参数为页面名。
|
||||
jpush.pageEnterTo("HomePage"); // 在离开页面的时候请调用 jpush.pageLeave("HomePage");
|
||||
|
||||
// If the widget was removed from the tree while the asynchronous platform
|
||||
// message was in flight, we want to discard the reply rather than calling
|
||||
// setState to update our non-existent appearance.
|
||||
if (!mounted) return;
|
||||
|
||||
setState(() {
|
||||
debugLable = platformVersion;
|
||||
});
|
||||
}
|
||||
|
||||
// 编写视图
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
home: new Scaffold(
|
||||
appBar: new AppBar(
|
||||
title: const Text('Plugin example app'),
|
||||
),
|
||||
body: new Center(
|
||||
child: new Column(children: [
|
||||
Container(
|
||||
margin: EdgeInsets.fromLTRB(10, 10, 10, 10),
|
||||
color: Colors.brown,
|
||||
child: Text(debugLable ?? "Unknown"),
|
||||
width: 350,
|
||||
height: 100,
|
||||
),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "发本地推送",
|
||||
onPressed: () {
|
||||
// 三秒后出发本地推送
|
||||
var fireDate = DateTime.fromMillisecondsSinceEpoch(
|
||||
DateTime.now().millisecondsSinceEpoch + 3000);
|
||||
var localNotification = LocalNotification(
|
||||
id: 234,
|
||||
title: 'fadsfa',
|
||||
buildId: 1,
|
||||
content: 'fdas',
|
||||
fireTime: fireDate,
|
||||
subtitle: 'fasf',
|
||||
badge: 5,
|
||||
extra: {"fa": "0"});
|
||||
jpush
|
||||
.sendLocalNotification(localNotification)
|
||||
.then((res) {
|
||||
setState(() {
|
||||
debugLable = res;
|
||||
});
|
||||
});
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "getLaunchAppNotification",
|
||||
onPressed: () {
|
||||
jpush.getLaunchAppNotification().then((map) {
|
||||
print("flutter getLaunchAppNotification:$map");
|
||||
setState(() {
|
||||
debugLable = "getLaunchAppNotification success: $map";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "getLaunchAppNotification error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
]),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "setTags",
|
||||
onPressed: () {
|
||||
jpush.setTags(["lala", "haha"]).then((map) {
|
||||
var tags = map['tags'];
|
||||
setState(() {
|
||||
debugLable = "set tags success: $map $tags";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "set tags error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "addTags",
|
||||
onPressed: () {
|
||||
jpush.addTags(["lala", "haha"]).then((map) {
|
||||
var tags = map['tags'];
|
||||
setState(() {
|
||||
debugLable = "addTags success: $map $tags";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "addTags error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "deleteTags",
|
||||
onPressed: () {
|
||||
jpush.deleteTags(["lala", "haha"]).then((map) {
|
||||
var tags = map['tags'];
|
||||
setState(() {
|
||||
debugLable = "deleteTags success: $map $tags";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "deleteTags error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
]),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "getAllTags",
|
||||
onPressed: () {
|
||||
jpush.getAllTags().then((map) {
|
||||
setState(() {
|
||||
debugLable = "getAllTags success: $map";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "getAllTags error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "cleanTags",
|
||||
onPressed: () {
|
||||
jpush.cleanTags().then((map) {
|
||||
var tags = map['tags'];
|
||||
setState(() {
|
||||
debugLable = "cleanTags success: $map $tags";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "cleanTags error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
]),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "setAlias",
|
||||
onPressed: () {
|
||||
jpush.setAlias("thealias11").then((map) {
|
||||
setState(() {
|
||||
debugLable = "setAlias success: $map";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "setAlias error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "deleteAlias",
|
||||
onPressed: () {
|
||||
jpush.deleteAlias().then((map) {
|
||||
setState(() {
|
||||
debugLable = "deleteAlias success: $map";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "deleteAlias error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "getAlias",
|
||||
onPressed: () {
|
||||
jpush.getAlias().then((map) {
|
||||
setState(() {
|
||||
debugLable = "getAlias success: $map";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "getAlias error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
]),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "stopPush",
|
||||
onPressed: () {
|
||||
jpush.stopPush();
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "resumePush",
|
||||
onPressed: () {
|
||||
jpush.resumePush();
|
||||
}),
|
||||
],
|
||||
),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "clearAllNotifications",
|
||||
onPressed: () {
|
||||
jpush.clearAllNotifications();
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "setBadge",
|
||||
onPressed: () {
|
||||
jpush.setBadge(66).then((map) {
|
||||
setState(() {
|
||||
debugLable = "setBadge success: $map";
|
||||
});
|
||||
}).catchError((error) {
|
||||
setState(() {
|
||||
debugLable = "setBadge error: $error";
|
||||
});
|
||||
});
|
||||
}),
|
||||
],
|
||||
),
|
||||
new Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "通知授权是否打开",
|
||||
onPressed: () {
|
||||
jpush.isNotificationEnabled().then((bool value) {
|
||||
setState(() {
|
||||
debugLable = "通知授权是否打开: $value";
|
||||
});
|
||||
}).catchError((onError) {
|
||||
setState(() {
|
||||
debugLable = "通知授权是否打开: ${onError.toString()}";
|
||||
});
|
||||
});
|
||||
}),
|
||||
new Text(" "),
|
||||
new CustomButton(
|
||||
title: "打开系统设置",
|
||||
onPressed: () {
|
||||
jpush.openSettingsForNotification();
|
||||
}),
|
||||
],
|
||||
),
|
||||
])),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 封装控件
|
||||
class CustomButton extends StatelessWidget {
|
||||
final VoidCallback? onPressed;
|
||||
final String? title;
|
||||
|
||||
const CustomButton({@required this.onPressed, @required this.title});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new TextButton(
|
||||
onPressed: onPressed,
|
||||
child: new Text("$title"),
|
||||
style: new ButtonStyle(
|
||||
foregroundColor: MaterialStateProperty.all(Colors.white),
|
||||
overlayColor: MaterialStateProperty.all(Color(0xff888888)),
|
||||
backgroundColor: MaterialStateProperty.all(Color(0xff585858)),
|
||||
padding: MaterialStateProperty.all(EdgeInsets.fromLTRB(10, 5, 10, 5)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
72
example/pubspec.yaml
Normal file
@ -0,0 +1,72 @@
|
||||
name: jpush_example
|
||||
description: Demonstrates how to use the jpush plugin.
|
||||
|
||||
# The following defines the version and build number for your application.
|
||||
# A version number is three numbers separated by dots, like 1.2.43
|
||||
# followed by an optional build number separated by a +.
|
||||
# Both the version and the builder number may be overridden in flutter
|
||||
# build by specifying --build-name and --build-number, respectively.
|
||||
# Read more about versioning at semver.org.
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^0.1.2
|
||||
|
||||
dev_dependencies:
|
||||
test: ^1.3.0
|
||||
mockito: ^3.0.0
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
jpush_flutter:
|
||||
path: ../
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://www.dartlang.org/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter.
|
||||
flutter:
|
||||
|
||||
# The following line ensures that the Material Icons font is
|
||||
# included with your application, so that you can use the icons in
|
||||
# the material Icons class.
|
||||
uses-material-design: true
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.io/assets-and-images/#resolution-aware.
|
||||
|
||||
# For details regarding adding assets from package dependencies, see
|
||||
# https://flutter.io/assets-and-images/#from-packages
|
||||
|
||||
# To add custom fonts to your application, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts from package dependencies,
|
||||
# see https://flutter.io/custom-fonts/#from-packages
|
||||
54
example/test/widget_test.dart
Normal file
@ -0,0 +1,54 @@
|
||||
// This is a basic Flutter widget test.
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter
|
||||
// provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to
|
||||
// find child widgets in the widget tree, read text, and verify that the values of widget properties
|
||||
// are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'package:jpush_example/main.dart';
|
||||
import 'package:jpush_flutter/jpush_flutter.dart';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
/*
|
||||
testWidgets('Verify Platform version', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(new MyApp());
|
||||
|
||||
// Verify that platform version is retrieved.
|
||||
|
||||
// expect(
|
||||
// find.byWidgetPredicate(
|
||||
// (Widget widget) =>
|
||||
// widget is Text && widget.data.startsWith('Running on:'),
|
||||
// ),
|
||||
// findsOneWidget);
|
||||
});
|
||||
|
||||
MockMethodChannel mockChannel;
|
||||
|
||||
JPush.setup(
|
||||
appKey: "a1703c14b186a68a66ef86c1",
|
||||
channel: "theChannel",
|
||||
production: false
|
||||
);
|
||||
|
||||
test('requestNotificationPermissions on ios with custom permissions', () {
|
||||
JPush.applyPushAuthority(new NotificationSettingsIOS(
|
||||
sound: false,
|
||||
alert: false,
|
||||
badge: false));
|
||||
|
||||
// firebaseMessaging.requestNotificationPermissions(
|
||||
// const IosNotificationSettings(sound: false));
|
||||
verify(mockChannel.invokeMethod('requestNotificationPermissions',
|
||||
<String, bool>{'sound': false, 'badge': true, 'alert': true}));
|
||||
});
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
BIN
ios/.DS_Store
vendored
Normal file
5
ios/Classes/JPushPlugin.h
Normal file
@ -0,0 +1,5 @@
|
||||
#import <Flutter/Flutter.h>
|
||||
|
||||
@interface JPushPlugin : NSObject<FlutterPlugin>
|
||||
@property FlutterMethodChannel *channel;
|
||||
@end
|
||||
793
ios/Classes/JPushPlugin.m
Normal file
@ -0,0 +1,793 @@
|
||||
#import "JPushPlugin.h"
|
||||
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
|
||||
#import <UserNotifications/UserNotifications.h>
|
||||
#endif
|
||||
|
||||
#import "JPUSHService.h"
|
||||
#import "JGInforCollectionAuth.h"
|
||||
|
||||
#define JPLog(fmt, ...) NSLog((@"| JPUSH | Flutter | iOS | " fmt), ##__VA_ARGS__)
|
||||
|
||||
@interface NSError (FlutterError)
|
||||
@property(readonly, nonatomic) FlutterError *flutterError;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSError (FlutterError)
|
||||
- (FlutterError *)flutterError {
|
||||
return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %d", (int)self.code]
|
||||
message:self.domain
|
||||
details:self.localizedDescription];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||
@interface JPushPlugin ()<JPUSHRegisterDelegate,JPUSHInAppMessageDelegate>
|
||||
//在前台时是否展示通知
|
||||
@property(assign, nonatomic) BOOL unShow;
|
||||
@end
|
||||
#endif
|
||||
|
||||
static NSMutableArray<FlutterResult>* getRidResults;
|
||||
|
||||
@implementation JPushPlugin {
|
||||
NSDictionary *_launchNotification;
|
||||
NSDictionary *_completeLaunchNotification;
|
||||
BOOL _isJPushDidLogin;
|
||||
JPAuthorizationOptions notificationTypes;
|
||||
}
|
||||
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
getRidResults = @[].mutableCopy;
|
||||
FlutterMethodChannel* channel = [FlutterMethodChannel
|
||||
methodChannelWithName:@"jpush"
|
||||
binaryMessenger:[registrar messenger]];
|
||||
JPushPlugin* instance = [[JPushPlugin alloc] init];
|
||||
instance.channel = channel;
|
||||
|
||||
|
||||
[registrar addApplicationDelegate:instance];
|
||||
[registrar addMethodCallDelegate:instance channel:channel];
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
notificationTypes = 0;
|
||||
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
|
||||
|
||||
[defaultCenter removeObserver:self];
|
||||
|
||||
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(networkConnecting:)
|
||||
name:kJPFNetworkIsConnectingNotification
|
||||
object:nil];
|
||||
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(networkRegister:)
|
||||
name:kJPFNetworkDidRegisterNotification
|
||||
object:nil];
|
||||
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(networkDidSetup:)
|
||||
name:kJPFNetworkDidSetupNotification
|
||||
object:nil];
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(networkDidClose:)
|
||||
name:kJPFNetworkDidCloseNotification
|
||||
object:nil];
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(networkDidLogin:)
|
||||
name:kJPFNetworkDidLoginNotification
|
||||
object:nil];
|
||||
[defaultCenter addObserver:self
|
||||
selector:@selector(networkDidReceiveMessage:)
|
||||
name:kJPFNetworkDidReceiveMessageNotification
|
||||
object:nil];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)networkConnecting:(NSNotification *)notification {
|
||||
_isJPushDidLogin = false;
|
||||
}
|
||||
|
||||
- (void)networkRegister:(NSNotification *)notification {
|
||||
_isJPushDidLogin = false;
|
||||
}
|
||||
|
||||
- (void)networkDidSetup:(NSNotification *)notification {
|
||||
_isJPushDidLogin = false;
|
||||
}
|
||||
|
||||
- (void)networkDidClose:(NSNotification *)notification {
|
||||
_isJPushDidLogin = false;
|
||||
}
|
||||
|
||||
|
||||
- (void)networkDidLogin:(NSNotification *)notification {
|
||||
_isJPushDidLogin = YES;
|
||||
for (FlutterResult result in getRidResults) {
|
||||
result([JPUSHService registrationID]);
|
||||
}
|
||||
[getRidResults removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)networkDidReceiveMessage:(NSNotification *)notification {
|
||||
[_channel invokeMethod:@"onReceiveMessage" arguments: [notification userInfo]];
|
||||
}
|
||||
|
||||
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"handleMethodCall:%@",call.method);
|
||||
|
||||
if ([@"getPlatformVersion" isEqualToString:call.method]) {
|
||||
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
|
||||
} else if([@"setup" isEqualToString:call.method]) {
|
||||
[self setup:call result: result];
|
||||
} else if([@"setUnShowAtTheForeground" isEqualToString:call.method]) {
|
||||
[self setUnShowAtTheForeground:call result: result];
|
||||
} else if([@"applyPushAuthority" isEqualToString:call.method]) {
|
||||
[self applyPushAuthority:call result:result];
|
||||
} else if([@"setTags" isEqualToString:call.method]) {
|
||||
[self setTags:call result:result];
|
||||
} else if([@"cleanTags" isEqualToString:call.method]) {
|
||||
[self cleanTags:call result:result];
|
||||
} else if([@"addTags" isEqualToString:call.method]) {
|
||||
[self addTags:call result:result];
|
||||
} else if([@"deleteTags" isEqualToString:call.method]) {
|
||||
[self deleteTags:call result:result];
|
||||
} else if([@"getAllTags" isEqualToString:call.method]) {
|
||||
[self getAllTags:call result:result];
|
||||
} else if([@"setAlias" isEqualToString:call.method]) {
|
||||
[self setAlias:call result:result];
|
||||
} else if([@"deleteAlias" isEqualToString:call.method]) {
|
||||
[self deleteAlias:call result:result];
|
||||
} else if([@"getAlias" isEqualToString:call.method]) {
|
||||
[self getAlias:call result:result];
|
||||
} else if([@"setBadge" isEqualToString:call.method]) {
|
||||
[self setBadge:call result:result];
|
||||
} else if([@"stopPush" isEqualToString:call.method]) {
|
||||
[self stopPush:call result:result];
|
||||
} else if([@"resumePush" isEqualToString:call.method]) {
|
||||
[self resumePush:call result:result];
|
||||
//[self applyPushAuthority:call result:result];
|
||||
} else if([@"clearAllNotifications" isEqualToString:call.method]) {
|
||||
[self clearAllNotifications:call result:result];
|
||||
} else if ([@"clearNotification" isEqualToString:call.method]) {
|
||||
[self clearNotification:call result:result];
|
||||
} else if([@"getLaunchAppNotification" isEqualToString:call.method]) {
|
||||
[self getLaunchAppNotification:call result:result];
|
||||
} else if([@"getRegistrationID" isEqualToString:call.method]) {
|
||||
[self getRegistrationID:call result:result];
|
||||
} else if([@"sendLocalNotification"isEqualToString:call.method]) {
|
||||
[self sendLocalNotification:call result:result];
|
||||
} else if([@"isNotificationEnabled"isEqualToString:call.method]) {
|
||||
[self isNotificationEnabled:call result:result];
|
||||
} else if([@"openSettingsForNotification"isEqualToString:call.method]) {
|
||||
[self openSettingsForNotification];
|
||||
} else if ([@"setAuth" isEqualToString:call.method]) {
|
||||
[self setAuth:call result:result];
|
||||
} else if ([@"pageEnterTo" isEqualToString:call.method]) {
|
||||
[self pageEnterTo:call];
|
||||
} else if ([@"pageLeave" isEqualToString:call.method]) {
|
||||
[self pageLeave:call];
|
||||
} else if ([@"setCollectControl" isEqualToString:call.method]) {
|
||||
[self setCollectControl:call result:result];
|
||||
} else{
|
||||
result(FlutterMethodNotImplemented);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)setCollectControl:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"setCollectControl:%@",call.arguments);
|
||||
BOOL gps = [call.arguments[@"gps"] boolValue];
|
||||
JPushCollectControl *control = [[JPushCollectControl alloc] init];
|
||||
control.gps = gps;
|
||||
[JPUSHService setCollectControl:control];
|
||||
}
|
||||
|
||||
- (void)setup:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"setup:");
|
||||
NSDictionary *arguments = call.arguments;
|
||||
NSNumber *debug = arguments[@"debug"];
|
||||
if ([debug boolValue]) {
|
||||
[JPUSHService setDebugMode];
|
||||
} else {
|
||||
[JPUSHService setLogOFF];
|
||||
}
|
||||
|
||||
[JPUSHService setInAppMessageDelegate:self];
|
||||
|
||||
[JPUSHService setupWithOption:_completeLaunchNotification
|
||||
appKey:arguments[@"appKey"]
|
||||
channel:arguments[@"channel"]
|
||||
apsForProduction:[arguments[@"production"] boolValue]];
|
||||
}
|
||||
|
||||
//设置APP在前台时是否展示通知
|
||||
- (void)setUnShowAtTheForeground:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"setUnShowDidEnterBackground:");
|
||||
NSDictionary *arguments = call.arguments;
|
||||
NSNumber *unShow = arguments[@"UnShow"];
|
||||
if(unShow && [unShow isKindOfClass:[NSNumber class]]) self.unShow = [unShow boolValue];
|
||||
}
|
||||
|
||||
- (void)applyPushAuthority:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"applyPushAuthority:%@",call.arguments);
|
||||
notificationTypes = 0;
|
||||
NSDictionary *arguments = call.arguments;
|
||||
if ([arguments[@"sound"] boolValue]) {
|
||||
notificationTypes |= JPAuthorizationOptionSound;
|
||||
}
|
||||
if ([arguments[@"alert"] boolValue]) {
|
||||
notificationTypes |= JPAuthorizationOptionAlert;
|
||||
}
|
||||
if ([arguments[@"badge"] boolValue]) {
|
||||
notificationTypes |= JPAuthorizationOptionBadge;
|
||||
}
|
||||
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
|
||||
entity.types = notificationTypes;
|
||||
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
|
||||
}
|
||||
|
||||
- (void)setTags:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"setTags:%@",call.arguments);
|
||||
NSSet *tagSet;
|
||||
|
||||
if (call.arguments != NULL) {
|
||||
tagSet = [NSSet setWithArray: call.arguments];
|
||||
}
|
||||
|
||||
[JPUSHService setTags:tagSet completion:^(NSInteger iResCode, NSSet *iTags, NSInteger seq) {
|
||||
if (iResCode == 0) {
|
||||
result(@{@"tags": [iTags allObjects] ?: @[]});
|
||||
} else {
|
||||
NSError *error = [[NSError alloc] initWithDomain:@"JPush.Flutter" code:iResCode userInfo:nil];
|
||||
result([error flutterError]);
|
||||
}
|
||||
} seq: 0];
|
||||
}
|
||||
|
||||
- (void)cleanTags:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"cleanTags:");
|
||||
[JPUSHService cleanTags:^(NSInteger iResCode, NSSet *iTags, NSInteger seq) {
|
||||
if (iResCode == 0) {
|
||||
result(@{@"tags": iTags ? [iTags allObjects] : @[]});
|
||||
} else {
|
||||
NSError *error = [[NSError alloc] initWithDomain:@"JPush.Flutter" code:iResCode userInfo:nil];
|
||||
result([error flutterError]);
|
||||
}
|
||||
} seq: 0];
|
||||
}
|
||||
|
||||
- (void)addTags:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"addTags:%@",call.arguments);
|
||||
NSSet *tagSet;
|
||||
|
||||
if (call.arguments != NULL) {
|
||||
tagSet = [NSSet setWithArray:call.arguments];
|
||||
}
|
||||
|
||||
[JPUSHService addTags:tagSet completion:^(NSInteger iResCode, NSSet *iTags, NSInteger seq) {
|
||||
if (iResCode == 0) {
|
||||
result(@{@"tags": [iTags allObjects] ?: @[]});
|
||||
} else {
|
||||
NSError *error = [[NSError alloc] initWithDomain:@"JPush.Flutter" code:iResCode userInfo:nil];
|
||||
result([error flutterError]);
|
||||
}
|
||||
} seq: 0];
|
||||
}
|
||||
|
||||
- (void)deleteTags:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"deleteTags:%@",call.arguments);
|
||||
NSSet *tagSet;
|
||||
|
||||
if (call.arguments != NULL) {
|
||||
tagSet = [NSSet setWithArray:call.arguments];
|
||||
}
|
||||
|
||||
[JPUSHService deleteTags:tagSet completion:^(NSInteger iResCode, NSSet *iTags, NSInteger seq) {
|
||||
if (iResCode == 0) {
|
||||
result(@{@"tags": [iTags allObjects] ?: @[]});
|
||||
} else {
|
||||
NSError *error = [[NSError alloc] initWithDomain:@"JPush.Flutter" code:iResCode userInfo:nil];
|
||||
result([error flutterError]);
|
||||
}
|
||||
} seq: 0];
|
||||
}
|
||||
|
||||
- (void)getAllTags:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"getAllTags:");
|
||||
[JPUSHService getAllTags:^(NSInteger iResCode, NSSet *iTags, NSInteger seq) {
|
||||
if (iResCode == 0) {
|
||||
result(@{@"tags": iTags ? [iTags allObjects] : @[]});
|
||||
} else {
|
||||
NSError *error = [[NSError alloc] initWithDomain:@"JPush.Flutter" code:iResCode userInfo:nil];
|
||||
result([error flutterError]);
|
||||
}
|
||||
} seq: 0];
|
||||
}
|
||||
|
||||
- (void)setAlias:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"setAlias:%@",call.arguments);
|
||||
NSString *alias = call.arguments;
|
||||
[JPUSHService setAlias:alias completion:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
|
||||
if (iResCode == 0) {
|
||||
result(@{@"alias": iAlias ?: @""});
|
||||
} else {
|
||||
NSError *error = [[NSError alloc] initWithDomain:@"JPush.Flutter" code:iResCode userInfo:nil];
|
||||
result([error flutterError]);
|
||||
}
|
||||
} seq: 0];
|
||||
}
|
||||
|
||||
- (void)deleteAlias:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"deleteAlias:%@",call.arguments);
|
||||
[JPUSHService deleteAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
|
||||
if (iResCode == 0) {
|
||||
result(@{@"alias": iAlias ?: @""});
|
||||
} else {
|
||||
NSError *error = [[NSError alloc] initWithDomain:@"JPush.Flutter" code:iResCode userInfo:nil];
|
||||
result([error flutterError]);
|
||||
}
|
||||
} seq: 0];
|
||||
}
|
||||
|
||||
- (void)getAlias:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"getAlias:%@",call.arguments);
|
||||
[JPUSHService getAlias:^(NSInteger iResCode, NSString *iAlias, NSInteger seq) {
|
||||
if (iResCode == 0) {
|
||||
result(@{@"alias": iAlias ?: @""});
|
||||
}else {
|
||||
NSError *error = [[NSError alloc] initWithDomain:@"JPush.Flutter" code:iResCode userInfo:nil];
|
||||
result([error flutterError]);
|
||||
}
|
||||
} seq: 0];
|
||||
}
|
||||
|
||||
- (void)setBadge:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"setBadge:%@",call.arguments);
|
||||
NSInteger badge = [call.arguments[@"badge"] integerValue];
|
||||
if (badge < 0) {
|
||||
badge = 0;
|
||||
}
|
||||
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: badge];
|
||||
[JPUSHService setBadge: badge];
|
||||
}
|
||||
|
||||
- (void)stopPush:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"stopPush:");
|
||||
[[UIApplication sharedApplication] unregisterForRemoteNotifications];
|
||||
}
|
||||
|
||||
- (void)resumePush:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"resumePush:");
|
||||
[[UIApplication sharedApplication] registerForRemoteNotifications];
|
||||
}
|
||||
|
||||
- (void)clearAllNotifications:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"clearAllNotifications:");
|
||||
|
||||
if (@available(iOS 10.0, *)) {
|
||||
//iOS 10 以上支持
|
||||
JPushNotificationIdentifier *identifier = [[JPushNotificationIdentifier alloc] init];
|
||||
identifier.identifiers = nil;
|
||||
identifier.delivered = YES; //等于 YES 则移除所有在通知中心显示的,等于 NO 则为移除所有待推送的
|
||||
[JPUSHService removeNotification:identifier];
|
||||
} else {
|
||||
// iOS 10 以下移除所有推送;iOS 10 以上移除所有在通知中心显示推送和待推送请求
|
||||
[JPUSHService removeNotification:nil];
|
||||
}
|
||||
}
|
||||
- (void)clearNotification:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"clearNotification:");
|
||||
|
||||
NSNumber *notificationId = call.arguments;
|
||||
if (!notificationId) {
|
||||
return ;
|
||||
}
|
||||
JPushNotificationIdentifier *identifier = [[JPushNotificationIdentifier alloc] init];
|
||||
identifier.identifiers = @[notificationId.stringValue];
|
||||
|
||||
if (@available(iOS 10.0, *)) {
|
||||
//iOS 10 以上有效,等于 YES 则在通知中心显示的里面移除,等于 NO 则为在待推送的里面移除;iOS 10 以下无效
|
||||
identifier.delivered = YES;
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
[JPUSHService removeNotification:identifier];
|
||||
}
|
||||
|
||||
- (void)getLaunchAppNotification:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"getLaunchAppNotification");
|
||||
result(_launchNotification == nil ? @{}: _launchNotification);
|
||||
}
|
||||
|
||||
- (void)getRegistrationID:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"getRegistrationID:");
|
||||
#if TARGET_IPHONE_SIMULATOR//模拟器
|
||||
NSLog(@"simulator can not get registrationid");
|
||||
result(@"");
|
||||
#elif TARGET_OS_IPHONE//真机
|
||||
|
||||
|
||||
if ([JPUSHService registrationID] != nil && ![[JPUSHService registrationID] isEqualToString:@""]) {
|
||||
// 如果已经成功获取 registrationID,从本地获取直接缓存
|
||||
result([JPUSHService registrationID]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isJPushDidLogin) {// 第一次获取未登录情况
|
||||
result(@[[JPUSHService registrationID]]);
|
||||
} else {
|
||||
[getRidResults addObject:result];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)sendLocalNotification:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"sendLocalNotification:%@",call.arguments);
|
||||
JPushNotificationContent *content = [[JPushNotificationContent alloc] init];
|
||||
NSDictionary *params = call.arguments;
|
||||
if (params[@"title"]) {
|
||||
content.title = params[@"title"];
|
||||
}
|
||||
|
||||
if (params[@"subtitle"] && ![params[@"subtitle"] isEqualToString:@"<null>"]) {
|
||||
content.subtitle = params[@"subtitle"];
|
||||
}
|
||||
|
||||
if (params[@"content"]) {
|
||||
content.body = params[@"content"];
|
||||
}
|
||||
|
||||
if (params[@"badge"]) {
|
||||
content.badge = params[@"badge"];
|
||||
}
|
||||
|
||||
if (params[@"action"] && ![params[@"action"] isEqualToString:@"<null>"]) {
|
||||
content.action = params[@"action"];
|
||||
}
|
||||
|
||||
if ([params[@"extra"] isKindOfClass:[NSDictionary class]]) {
|
||||
content.userInfo = params[@"extra"];
|
||||
}
|
||||
|
||||
if (params[@"soundName"] && ![params[@"soundName"] isEqualToString:@"<null>"]) {
|
||||
content.sound = params[@"soundName"];
|
||||
}
|
||||
|
||||
if (@available(iOS 15.0, *)) {
|
||||
content.interruptionLevel = UNNotificationInterruptionLevelActive;
|
||||
content.relevanceScore = 1;
|
||||
}
|
||||
|
||||
JPushNotificationTrigger *trigger = [[JPushNotificationTrigger alloc] init];
|
||||
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
|
||||
if (params[@"fireTime"]) {
|
||||
NSNumber *date = params[@"fireTime"];
|
||||
NSTimeInterval currentInterval = [[NSDate date] timeIntervalSince1970];
|
||||
NSTimeInterval interval = [date doubleValue]/1000 - currentInterval;
|
||||
interval = interval>0?interval:0;
|
||||
trigger.timeInterval = interval;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (params[@"fireTime"]) {
|
||||
NSNumber *date = params[@"fireTime"];
|
||||
trigger.fireDate = [NSDate dateWithTimeIntervalSince1970: [date doubleValue]/1000];
|
||||
}
|
||||
}
|
||||
JPushNotificationRequest *request = [[JPushNotificationRequest alloc] init];
|
||||
request.content = content;
|
||||
request.trigger = trigger;
|
||||
|
||||
if (params[@"id"]) {
|
||||
NSNumber *identify = params[@"id"];
|
||||
request.requestIdentifier = [identify stringValue];
|
||||
}
|
||||
request.completionHandler = ^(id result) {
|
||||
NSLog(@"result");
|
||||
};
|
||||
|
||||
[JPUSHService addNotification:request];
|
||||
|
||||
result(@[@[]]);
|
||||
}
|
||||
|
||||
/// 检查当前应用的通知开关是否开启
|
||||
- (void)isNotificationEnabled:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"isNotificationEnabled:");
|
||||
[JPUSHService requestNotificationAuthorization:^(JPAuthorizationStatus status) {
|
||||
BOOL isEnabled = NO;
|
||||
if (status == JPAuthorizationStatusAuthorized) {
|
||||
isEnabled = YES;
|
||||
}
|
||||
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:isEnabled],@"isEnabled", nil];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
result(dict);
|
||||
});
|
||||
}];
|
||||
|
||||
|
||||
}
|
||||
- (void)openSettingsForNotification {
|
||||
JPLog(@"openSettingsForNotification:");
|
||||
[JPUSHService openSettingsForNotification:^(BOOL success) {
|
||||
JPLog(@"openSettingsForNotification: %@",@(success));
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setAuth:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||||
JPLog(@"setAuth:%@",call.arguments);
|
||||
BOOL enable = [call.arguments[@"enable"] boolValue];
|
||||
[JGInforCollectionAuth JCollectionAuth:^(JGInforCollectionAuthItems * _Nonnull authInfo) {
|
||||
authInfo.isAuth = enable;
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
- (void)pageEnterTo:(FlutterMethodCall*)call {
|
||||
JPLog(@"pageEnterTo:%@",call.arguments);
|
||||
NSString *pageName = call.arguments;
|
||||
[JPUSHService pageEnterTo:pageName];
|
||||
}
|
||||
|
||||
- (void)pageLeave:(FlutterMethodCall*)call {
|
||||
JPLog(@"pageLeave:%@",call.arguments);
|
||||
NSString *pageName = call.arguments;
|
||||
[JPUSHService pageLeave:pageName];
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
_isJPushDidLogin = NO;
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
_completeLaunchNotification = launchOptions;
|
||||
if (launchOptions != nil) {
|
||||
_launchNotification = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
_launchNotification = [self jpushFormatAPNSDic:_launchNotification.copy];
|
||||
}
|
||||
|
||||
if ([launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey]) {
|
||||
UILocalNotification *localNotification = [launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
|
||||
NSMutableDictionary *localNotificationEvent = @{}.mutableCopy;
|
||||
localNotificationEvent[@"content"] = localNotification.alertBody;
|
||||
localNotificationEvent[@"badge"] = @(localNotification.applicationIconBadgeNumber);
|
||||
localNotificationEvent[@"extras"] = localNotification.userInfo;
|
||||
localNotificationEvent[@"fireTime"] = [NSNumber numberWithLong:[localNotification.fireDate timeIntervalSince1970] * 1000];
|
||||
localNotificationEvent[@"soundName"] = [localNotification.soundName isEqualToString:UILocalNotificationDefaultSoundName] ? @"" : localNotification.soundName;
|
||||
|
||||
if (@available(iOS 8.2, *)) {
|
||||
localNotificationEvent[@"title"] = localNotification.alertTitle;
|
||||
}
|
||||
_launchNotification = localNotificationEvent;
|
||||
}
|
||||
//[self performSelector:@selector(addNotificationWithDateTrigger) withObject:nil afterDelay:2];
|
||||
return YES;
|
||||
}
|
||||
- (void)addNotificationWithDateTrigger {
|
||||
|
||||
JPushNotificationTrigger *trigger = [[JPushNotificationTrigger alloc] init];
|
||||
|
||||
if (@available(iOS 10.0, *)) {
|
||||
trigger.timeInterval = 10;
|
||||
} else {
|
||||
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
|
||||
trigger.fireDate = fireDate;
|
||||
}
|
||||
|
||||
JPushNotificationContent *content = [[JPushNotificationContent alloc] init];
|
||||
content.title = @"title";
|
||||
content.subtitle = @"subtitle";
|
||||
content.body = @"body";
|
||||
content.badge = @(1);
|
||||
content.action = @"action";
|
||||
content.categoryIdentifier = @"categoryIdentifier";
|
||||
content.threadIdentifier = @"threadIdentifier";
|
||||
|
||||
JPushNotificationRequest *request = [[JPushNotificationRequest alloc] init];
|
||||
request.content = content;
|
||||
request.trigger = trigger;
|
||||
request.completionHandler = ^(id result) {
|
||||
// iOS10以上成功则result为UNNotificationRequest对象,失败则result为nil
|
||||
// iOS10以下成功result为UILocalNotification对象,失败则result为nil
|
||||
if (result) {
|
||||
NSLog(@"添加日期通知成功 --- %@", result);
|
||||
}
|
||||
};
|
||||
request.requestIdentifier = @"123";
|
||||
[JPUSHService addNotification:request];
|
||||
}
|
||||
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||
// _resumingFromBackground = YES;
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
// application.applicationIconBadgeNumber = 1;
|
||||
// application.applicationIconBadgeNumber = 0;
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
|
||||
[JPUSHService registerDeviceToken:deviceToken];
|
||||
}
|
||||
|
||||
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
|
||||
NSDictionary *settingsDictionary = @{
|
||||
@"sound" : [NSNumber numberWithBool:notificationSettings.types & UIUserNotificationTypeSound],
|
||||
@"badge" : [NSNumber numberWithBool:notificationSettings.types & UIUserNotificationTypeBadge],
|
||||
@"alert" : [NSNumber numberWithBool:notificationSettings.types & UIUserNotificationTypeAlert],
|
||||
};
|
||||
[_channel invokeMethod:@"onIosSettingsRegistered" arguments:settingsDictionary];
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
|
||||
JPLog(@"application:didReceiveRemoteNotification:fetchCompletionHandler");
|
||||
[JPUSHService handleRemoteNotification:userInfo];
|
||||
if (@available(* ,iOS 10)) {
|
||||
[_channel invokeMethod:@"onReceiveNotification" arguments:userInfo];
|
||||
|
||||
/**
|
||||
* 下面这段代码是解决 app处于杀死状态,点击通知启动app,但是不回调onOpenNotification的问题。
|
||||
* 上诉情况不会走didReceiveNotificationResponse:回调。但是会走didReceiveRemoteNotification:fetchCompletionHandler:回调。iOS原生项目中正常情况下,点击通知冷启动app是会回调didReceiveNotificationResponse,不回调didReceiveRemoteNotification:fetchCompletionHandler:的。
|
||||
* 因为不走didReceiveNotificationResponse:回调 所以没有onOpenNotification回调。这跟生命周期有关,didReceiveNotificationResponse:的代理需要通知的远程代理设置要在didFinishLaunch结束之前。但是flutter初始化jpush是在didFinishLaunch之后。
|
||||
* 在这个方法里做一个判断吧,如果收到的消息和启动时的消息是同一个消息,则判断该消息为app杀死状态下通过点击通知唤醒的。
|
||||
*/
|
||||
|
||||
if (_launchNotification && userInfo && [_launchNotification isKindOfClass:[NSDictionary class]] && [userInfo isKindOfClass:[NSDictionary class]]) {
|
||||
// 拿到启动时的推送数据里的msgid
|
||||
NSNumber *launchMsgid = [_launchNotification valueForKey:@"_j_msgid"];
|
||||
// 拿到收到的消息的msgid
|
||||
NSNumber *msgid = [userInfo valueForKey:@"_j_msgid"];
|
||||
// 如果消息id一致
|
||||
if ([launchMsgid isKindOfClass:[NSNumber class]] && [msgid isKindOfClass:[NSNumber class]] && [[launchMsgid stringValue] isEqualToString:[msgid stringValue]]) {
|
||||
[_channel invokeMethod:@"onOpenNotification" arguments:_launchNotification];
|
||||
}
|
||||
}
|
||||
}
|
||||
completionHandler(UIBackgroundFetchResultNewData);
|
||||
return YES;
|
||||
}
|
||||
|
||||
// iOS 10 以下点击本地通知
|
||||
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
|
||||
JPLog(@"application:didReceiveLocalNotification:");
|
||||
|
||||
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
|
||||
NSString *title = @"";
|
||||
if (@available(iOS 8.2, *)) {
|
||||
title = notification.alertTitle;
|
||||
} else {
|
||||
// Fallback on earlier versions
|
||||
}
|
||||
|
||||
NSString *body = notification.alertBody;
|
||||
NSString *action = notification.alertAction;
|
||||
|
||||
[dic setValue:title?:@"" forKey:@"title"];
|
||||
[dic setValue:body?:@"" forKey:@"body"];
|
||||
[dic setValue:action?:@"" forKey:@"action"];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.channel invokeMethod:@"onOpenNotification" arguments:dic];
|
||||
});
|
||||
}
|
||||
|
||||
//前台收到本地通知
|
||||
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler API_AVAILABLE(ios(10.0)){
|
||||
JPLog(@"jpushNotificationCenter:willPresentNotification::");
|
||||
NSDictionary * userInfo = notification.request.content.userInfo;
|
||||
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
|
||||
[JPUSHService handleRemoteNotification:userInfo];
|
||||
if (@available(iOS 10 , *)) {
|
||||
[_channel invokeMethod:@"onReceiveNotification" arguments: [self jpushFormatAPNSDic:userInfo]];
|
||||
}
|
||||
}else{
|
||||
JPLog(@"iOS10 前台收到本地通知:userInfo:%@",userInfo);
|
||||
}
|
||||
if (!self.unShow) completionHandler(notificationTypes);
|
||||
}
|
||||
|
||||
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler API_AVAILABLE(ios(10.0)){
|
||||
JPLog(@"jpushNotificationCenter:didReceiveNotificationResponse::");
|
||||
NSDictionary * userInfo = response.notification.request.content.userInfo;
|
||||
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
|
||||
[JPUSHService handleRemoteNotification:userInfo];
|
||||
[_channel invokeMethod:@"onOpenNotification" arguments: [self jpushFormatAPNSDic:userInfo]];
|
||||
}else{
|
||||
// iOS 10 以上点击本地通知
|
||||
JPLog(@"iOS10 点击本地通知");
|
||||
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
|
||||
NSString *identifier = response.notification.request.identifier;
|
||||
NSString *body = response.notification.request.content.body;
|
||||
NSString *categoryIdentifier = response.notification.request.content.categoryIdentifier;
|
||||
NSString *title = response.notification.request.content.title;
|
||||
NSString *subtitle = response.notification.request.content.subtitle;
|
||||
NSString *threadIdentifier = response.notification.request.content.threadIdentifier;
|
||||
|
||||
[dic setValue:body?:@"" forKey:@"body"];
|
||||
[dic setValue:title?:@"" forKey:@"title"];
|
||||
[dic setValue:subtitle?:@"" forKey:@"subtitle"];
|
||||
[dic setValue:identifier?:@"" forKey:@"identifier"];
|
||||
[dic setValue:threadIdentifier?:@"" forKey:@"threadIdentifier"];
|
||||
[dic setValue:categoryIdentifier?:@"" forKey:@"categoryIdentifier"];
|
||||
if (userInfo && userInfo.count) {
|
||||
NSMutableDictionary *extras = [NSMutableDictionary dictionary];
|
||||
for (NSString *key in userInfo) {
|
||||
extras[key] = userInfo[key];
|
||||
}
|
||||
dic[@"extras"] = extras;
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.channel invokeMethod:@"onOpenNotification" arguments:dic];
|
||||
});
|
||||
}
|
||||
completionHandler();
|
||||
}
|
||||
|
||||
- (void)jpushNotificationAuthorization:(JPAuthorizationStatus)status withInfo:(NSDictionary *)info {
|
||||
JPLog(@"");
|
||||
BOOL isEnabled = NO;
|
||||
if (status == JPAuthorizationStatusAuthorized) {
|
||||
isEnabled = YES;
|
||||
}
|
||||
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:isEnabled],@"isEnabled", nil];
|
||||
__weak typeof(self) weakself = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
__strong typeof(self) strongself = weakself;
|
||||
[strongself.channel invokeMethod:@"onReceiveNotificationAuthorization" arguments: dict];
|
||||
});
|
||||
}
|
||||
- (NSMutableDictionary *)jpushFormatAPNSDic:(NSDictionary *)dic {
|
||||
NSMutableDictionary *extras = @{}.mutableCopy;
|
||||
for (NSString *key in dic) {
|
||||
if([key isEqualToString:@"_j_business"] ||
|
||||
[key isEqualToString:@"_j_msgid"] ||
|
||||
[key isEqualToString:@"_j_uid"] ||
|
||||
[key isEqualToString:@"actionIdentifier"] ||
|
||||
[key isEqualToString:@"aps"]) {
|
||||
continue;
|
||||
}
|
||||
extras[key] = dic[key];
|
||||
}
|
||||
NSMutableDictionary *formatDic = dic.mutableCopy;
|
||||
formatDic[@"extras"] = extras;
|
||||
return formatDic;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - 应用内消息回调
|
||||
- (void)jPushInAppMessageDidShow:(JPushInAppMessage *)inAppMessage {
|
||||
[_channel invokeMethod:@"onInAppMessageShow" arguments: [self convertInappMsg:inAppMessage]];
|
||||
}
|
||||
|
||||
- (void)jPushInAppMessageDidClick:(JPushInAppMessage *)inAppMessage {
|
||||
[_channel invokeMethod:@"onInAppMessageClick" arguments: [self convertInappMsg:inAppMessage]];
|
||||
}
|
||||
|
||||
- (NSDictionary *)convertInappMsg:(JPushInAppMessage *)inAppMessage {
|
||||
NSDictionary *result = @{
|
||||
@"mesageId": inAppMessage.mesageId ?: @"", // 消息id
|
||||
@"title": inAppMessage.title ?:@"", // 标题
|
||||
@"content": inAppMessage.content ?: @"", // 内容
|
||||
@"target": inAppMessage.target ?: @[], // 目标页面
|
||||
@"clickAction": inAppMessage.clickAction ?: @"", // 跳转地址
|
||||
@"extras": inAppMessage.extras ?: @{} // 附加字段
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
22
ios/jpush_flutter.podspec
Normal file
@ -0,0 +1,22 @@
|
||||
#
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'jpush_flutter'
|
||||
s.version = '0.0.2'
|
||||
s.summary = 'A new flutter plugin project.'
|
||||
s.description = <<-DESC
|
||||
A new flutter plugin project.
|
||||
DESC
|
||||
s.homepage = 'http://example.com'
|
||||
s.license = { :file => '../LICENSE' }
|
||||
s.author = { 'xudong.rao' => 'xudong.rao@outlook.com' }
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.public_header_files = 'Classes/**/*.h'
|
||||
s.dependency 'Flutter'
|
||||
s.dependency 'JCore','>= 4.6.2'
|
||||
s.dependency 'JPush','5.3.0'
|
||||
s.ios.deployment_target = '8.0'
|
||||
s.static_framework = true
|
||||
end
|
||||
525
lib/jpush_flutter.dart
Normal file
@ -0,0 +1,525 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:platform/platform.dart';
|
||||
|
||||
typedef Future<dynamic> EventHandler(Map<String, dynamic> event);
|
||||
|
||||
class JPush {
|
||||
static const String flutter_log = "| JPUSH | Flutter | ";
|
||||
|
||||
factory JPush() => _instance;
|
||||
|
||||
final MethodChannel _channel;
|
||||
final Platform _platform;
|
||||
|
||||
@visibleForTesting
|
||||
JPush.private(MethodChannel channel, Platform platform)
|
||||
: _channel = channel,
|
||||
_platform = platform;
|
||||
|
||||
static final JPush _instance =
|
||||
new JPush.private(const MethodChannel('jpush'), const LocalPlatform());
|
||||
|
||||
EventHandler? _onReceiveNotification;
|
||||
EventHandler? _onOpenNotification;
|
||||
EventHandler? _onReceiveMessage;
|
||||
EventHandler? _onReceiveNotificationAuthorization;
|
||||
EventHandler? _onNotifyMessageUnShow;
|
||||
EventHandler? _onConnected;
|
||||
EventHandler? _onInAppMessageClick;
|
||||
EventHandler? _onInAppMessageShow;
|
||||
void setup({
|
||||
String appKey = '',
|
||||
bool production = false,
|
||||
String channel = '',
|
||||
bool debug = false,
|
||||
}) {
|
||||
print(flutter_log + "setup:");
|
||||
|
||||
_channel.invokeMethod('setup', {
|
||||
'appKey': appKey,
|
||||
'channel': channel,
|
||||
'production': production,
|
||||
'debug': debug
|
||||
});
|
||||
}
|
||||
|
||||
void setChannelAndSound({
|
||||
String channel = '',
|
||||
String channelID = '',
|
||||
String sound = '',
|
||||
}) {
|
||||
if (_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
print(flutter_log + "setChannelAndSound:");
|
||||
|
||||
_channel.invokeMethod('setChannelAndSound',
|
||||
{'channel': channel, 'channel_id': channelID, 'sound': sound});
|
||||
}
|
||||
|
||||
//APP活跃在前台时是否展示通知
|
||||
void setUnShowAtTheForeground({bool unShow = false}) {
|
||||
print(flutter_log + "setUnShowAtTheForeground:");
|
||||
_channel.invokeMethod('setUnShowAtTheForeground', {'UnShow': unShow});
|
||||
}
|
||||
|
||||
void setWakeEnable({bool enable = false}) {
|
||||
_channel.invokeMethod('setWakeEnable', {'enable': enable});
|
||||
}
|
||||
|
||||
void enableAutoWakeup({bool enable = false}) {
|
||||
if (_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
_channel.invokeMethod('enableAutoWakeup', {'enable': enable});
|
||||
}
|
||||
|
||||
void setAuth({bool enable = true}) {
|
||||
print(flutter_log + "setAuth:");
|
||||
_channel.invokeMethod('setAuth', {'enable': enable});
|
||||
}
|
||||
|
||||
void setLinkMergeEnable({bool enable = true}) {
|
||||
if (_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
print(flutter_log + "setLinkMergeEnable:");
|
||||
_channel.invokeMethod('setLinkMergeEnable', {'enable': enable});
|
||||
}
|
||||
|
||||
void setGeofenceEnable({bool enable = true}) {
|
||||
if (_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
print(flutter_log + "setGeofenceEnable:");
|
||||
_channel.invokeMethod('setGeofenceEnable', {'enable': enable});
|
||||
}
|
||||
|
||||
void setSmartPushEnable({bool enable = true}) {
|
||||
if (_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
print(flutter_log + "setSmartPushEnable:");
|
||||
_channel.invokeMethod('setSmartPushEnable', {'enable': enable});
|
||||
}
|
||||
|
||||
void setCollectControl({
|
||||
bool imsi = true, // only android
|
||||
bool mac = true, // only android
|
||||
bool wifi = true, // only android
|
||||
bool bssid = true, // only android
|
||||
bool ssid = true, // only android
|
||||
bool imei = true, // only android
|
||||
bool cell = true, // only android
|
||||
bool gps = true, // only ios
|
||||
}) {
|
||||
print(flutter_log + "setCollectControl:");
|
||||
|
||||
_channel.invokeMethod('setCollectControl', {
|
||||
'imsi': imsi,
|
||||
'mac': mac,
|
||||
'wifi': wifi,
|
||||
'bssid': bssid,
|
||||
'ssid': ssid,
|
||||
'imei': imei,
|
||||
'cell': cell,
|
||||
'gps': gps
|
||||
});
|
||||
}
|
||||
|
||||
///
|
||||
/// 初始化 JPush 必须先初始化才能执行其他操作(比如接收事件传递)
|
||||
///
|
||||
void addEventHandler({
|
||||
EventHandler? onReceiveNotification,
|
||||
EventHandler? onOpenNotification,
|
||||
EventHandler? onReceiveMessage,
|
||||
EventHandler? onReceiveNotificationAuthorization,
|
||||
EventHandler? onNotifyMessageUnShow,
|
||||
EventHandler? onConnected,
|
||||
EventHandler? onInAppMessageClick,
|
||||
EventHandler? onInAppMessageShow,
|
||||
}) {
|
||||
print(flutter_log + "addEventHandler:");
|
||||
|
||||
_onReceiveNotification = onReceiveNotification;
|
||||
_onOpenNotification = onOpenNotification;
|
||||
_onReceiveMessage = onReceiveMessage;
|
||||
_onReceiveNotificationAuthorization = onReceiveNotificationAuthorization;
|
||||
_onNotifyMessageUnShow = onNotifyMessageUnShow;
|
||||
_onConnected = onConnected;
|
||||
_onInAppMessageClick = onInAppMessageClick;
|
||||
_onInAppMessageShow = onInAppMessageShow;
|
||||
_channel.setMethodCallHandler(_handleMethod);
|
||||
}
|
||||
|
||||
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||
print(flutter_log + "_handleMethod:");
|
||||
|
||||
switch (call.method) {
|
||||
case "onReceiveNotification":
|
||||
return _onReceiveNotification!(call.arguments.cast<String, dynamic>());
|
||||
case "onOpenNotification":
|
||||
return _onOpenNotification!(call.arguments.cast<String, dynamic>());
|
||||
case "onReceiveMessage":
|
||||
return _onReceiveMessage!(call.arguments.cast<String, dynamic>());
|
||||
case "onReceiveNotificationAuthorization":
|
||||
return _onReceiveNotificationAuthorization!(
|
||||
call.arguments.cast<String, dynamic>());
|
||||
case "onNotifyMessageUnShow":
|
||||
return _onNotifyMessageUnShow!(call.arguments.cast<String, dynamic>());
|
||||
case "onConnected":
|
||||
return _onConnected!(call.arguments.cast<String, dynamic>());
|
||||
case "onInAppMessageClick":
|
||||
return _onInAppMessageClick!(call.arguments.cast<String, dynamic>());
|
||||
case "onInAppMessageShow":
|
||||
return _onInAppMessageShow!(call.arguments.cast<String, dynamic>());
|
||||
default:
|
||||
throw new UnsupportedError("Unrecognized Event");
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// iOS Only
|
||||
/// 申请推送权限,注意这个方法只会向用户弹出一次推送权限请求(如果用户不同意,之后只能用户到设置页面里面勾选相应权限),需要开发者选择合适的时机调用。
|
||||
///
|
||||
void applyPushAuthority(
|
||||
[NotificationSettingsIOS iosSettings = const NotificationSettingsIOS()]) {
|
||||
print(flutter_log + "applyPushAuthority:");
|
||||
|
||||
if (!_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
|
||||
_channel.invokeMethod('applyPushAuthority', iosSettings.toMap());
|
||||
}
|
||||
|
||||
// iOS Only
|
||||
// 进入页面, pageName:页面名 请与pageLeave配套使用
|
||||
void pageEnterTo(String pageName) {
|
||||
print(flutter_log + "pageEnterTo:" + pageName);
|
||||
if (!_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
_channel.invokeMethod('pageEnterTo', pageName);
|
||||
}
|
||||
|
||||
// iOS Only
|
||||
// 离开页面,pageName:页面名, 请与pageEnterTo配套使用
|
||||
void pageLeave(String pageName) {
|
||||
print(flutter_log + "pageLeave:" + pageName);
|
||||
if (!_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
_channel.invokeMethod('pageLeave', pageName);
|
||||
}
|
||||
|
||||
///
|
||||
/// 设置 Tag (会覆盖之前设置的 tags)
|
||||
///
|
||||
/// @param {Array} params = [String]
|
||||
/// @param {Function} success = ({"tags":[String]}) => { }
|
||||
/// @param {Function} fail = ({"errorCode":int}) => { }
|
||||
///
|
||||
Future<Map<dynamic, dynamic>> setTags(List<String> tags) async {
|
||||
print(flutter_log + "setTags:");
|
||||
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('setTags', tags);
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// 清空所有 tags。
|
||||
///
|
||||
/// @param {Function} success = ({"tags":[String]}) => { }
|
||||
/// @param {Function} fail = ({"errorCode":int}) => { }
|
||||
///
|
||||
Future<Map<dynamic, dynamic>> cleanTags() async {
|
||||
print(flutter_log + "cleanTags:");
|
||||
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('cleanTags');
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// 在原有 tags 的基础上添加 tags
|
||||
///
|
||||
/// @param {Array} tags = [String]
|
||||
/// @param {Function} success = ({"tags":[String]}) => { }
|
||||
/// @param {Function} fail = ({"errorCode":int}) => { }
|
||||
///
|
||||
|
||||
Future<Map<dynamic, dynamic>> addTags(List<String> tags) async {
|
||||
print(flutter_log + "addTags:");
|
||||
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('addTags', tags);
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// 删除指定的 tags
|
||||
///
|
||||
/// @param {Array} tags = [String]
|
||||
/// @param {Function} success = ({"tags":[String]}) => { }
|
||||
/// @param {Function} fail = ({"errorCode":int}) => { }
|
||||
///
|
||||
Future<Map<dynamic, dynamic>> deleteTags(List<String> tags) async {
|
||||
print(flutter_log + "deleteTags:");
|
||||
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('deleteTags', tags);
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// 获取所有当前绑定的 tags
|
||||
///
|
||||
/// @param {Function} success = ({"tags":[String]}) => { }
|
||||
/// @param {Function} fail = ({"errorCode":int}) => { }
|
||||
///
|
||||
Future<Map<dynamic, dynamic>> getAllTags() async {
|
||||
print(flutter_log + "getAllTags:");
|
||||
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('getAllTags');
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// 获取所有当前绑定的 alias
|
||||
///
|
||||
/// @param {Function} success = ({"alias":String}) => { }
|
||||
/// @param {Function} fail = ({"errorCode":int}) => { }
|
||||
///
|
||||
Future<Map<dynamic, dynamic>> getAlias() async {
|
||||
print(flutter_log + "getAlias:");
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('getAlias');
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// 重置 alias.
|
||||
///
|
||||
/// @param {String} alias
|
||||
///
|
||||
/// @param {Function} success = ({"alias":String}) => { }
|
||||
/// @param {Function} fail = ({"errorCode":int}) => { }
|
||||
///
|
||||
Future<Map<dynamic, dynamic>> setAlias(String alias) async {
|
||||
print(flutter_log + "setAlias:");
|
||||
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('setAlias', alias);
|
||||
return result;
|
||||
}
|
||||
|
||||
void testCountryCode(String code) {
|
||||
print(flutter_log + "testCountryCode:" + code);
|
||||
_channel.invokeMethod('testCountryCode', code);
|
||||
}
|
||||
|
||||
///
|
||||
/// 删除原有 alias
|
||||
///
|
||||
/// @param {Function} success = ({"alias":String}) => { }
|
||||
/// @param {Function} fail = ({"errorCode":int}) => { }
|
||||
///
|
||||
Future<Map<dynamic, dynamic>> deleteAlias() async {
|
||||
print(flutter_log + "deleteAlias:");
|
||||
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('deleteAlias');
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// 设置应用 Badge(小红点)
|
||||
///
|
||||
/// @param {Int} badge
|
||||
///
|
||||
/// 注意:如果是 Android 手机,目前仅支持华为手机
|
||||
///
|
||||
Future setBadge(int badge) async {
|
||||
print(flutter_log + "setBadge:");
|
||||
|
||||
await _channel.invokeMethod('setBadge', {"badge": badge});
|
||||
}
|
||||
|
||||
///
|
||||
/// 停止接收推送,调用该方法后应用将不再受到推送,如果想要重新收到推送可以调用 resumePush。
|
||||
///
|
||||
Future stopPush() async {
|
||||
print(flutter_log + "stopPush:");
|
||||
|
||||
await _channel.invokeMethod('stopPush');
|
||||
}
|
||||
|
||||
///
|
||||
/// 恢复推送功能。
|
||||
///
|
||||
Future resumePush() async {
|
||||
print(flutter_log + "resumePush:");
|
||||
|
||||
await _channel.invokeMethod('resumePush');
|
||||
}
|
||||
|
||||
///
|
||||
/// 清空通知栏上的所有通知。
|
||||
///
|
||||
Future clearAllNotifications() async {
|
||||
print(flutter_log + "clearAllNotifications:");
|
||||
|
||||
await _channel.invokeMethod('clearAllNotifications');
|
||||
}
|
||||
|
||||
Future clearLocalNotifications() async {
|
||||
if (_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
print(flutter_log + "clearLocalNotifications:");
|
||||
await _channel.invokeMethod('clearLocalNotifications');
|
||||
}
|
||||
|
||||
///
|
||||
/// 清空通知栏上某个通知
|
||||
/// @param notificationId 通知 id,即:LocalNotification id
|
||||
///
|
||||
void clearNotification({int notificationId = 0}) {
|
||||
print(flutter_log + "clearNotification:");
|
||||
_channel.invokeListMethod("clearNotification", notificationId);
|
||||
}
|
||||
|
||||
///
|
||||
/// iOS Only
|
||||
/// 点击推送启动应用的时候原生会将该 notification 缓存起来,该方法用于获取缓存 notification
|
||||
/// 注意:notification 可能是 remoteNotification 和 localNotification,两种推送字段不一样。
|
||||
/// 如果不是通过点击推送启动应用,比如点击应用 icon 直接启动应用,notification 会返回 @{}。
|
||||
/// @param {Function} callback = (Object) => {}
|
||||
///
|
||||
Future<Map<dynamic, dynamic>> getLaunchAppNotification() async {
|
||||
print(flutter_log + "getLaunchAppNotification:");
|
||||
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('getLaunchAppNotification');
|
||||
return result;
|
||||
}
|
||||
|
||||
///
|
||||
/// 获取 RegistrationId, JPush 可以通过制定 RegistrationId 来进行推送。
|
||||
///
|
||||
/// @param {Function} callback = (String) => {}
|
||||
///
|
||||
Future<String> getRegistrationID() async {
|
||||
print(flutter_log + "getRegistrationID:");
|
||||
|
||||
final String rid = await _channel.invokeMethod('getRegistrationID');
|
||||
return rid;
|
||||
}
|
||||
|
||||
///
|
||||
/// 发送本地通知到调度器,指定时间出发该通知。
|
||||
/// @param {Notification} notification
|
||||
///
|
||||
Future<String> sendLocalNotification(LocalNotification notification) async {
|
||||
print(flutter_log + "sendLocalNotification:");
|
||||
|
||||
await _channel.invokeMethod('sendLocalNotification', notification.toMap());
|
||||
|
||||
return notification.toMap().toString();
|
||||
}
|
||||
|
||||
/// 调用此 API 检测通知授权状态是否打开
|
||||
Future<bool> isNotificationEnabled() async {
|
||||
final Map<dynamic, dynamic> result =
|
||||
await _channel.invokeMethod('isNotificationEnabled');
|
||||
bool isEnabled = result["isEnabled"];
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
/// 调用此 API 跳转至系统设置中应用设置界面
|
||||
void openSettingsForNotification() {
|
||||
_channel.invokeMethod('openSettingsForNotification');
|
||||
}
|
||||
|
||||
void requestRequiredPermission() {
|
||||
if (_platform.isIOS) {
|
||||
return;
|
||||
}
|
||||
_channel.invokeMethod('requestRequiredPermission');
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationSettingsIOS {
|
||||
final bool sound;
|
||||
final bool alert;
|
||||
final bool badge;
|
||||
|
||||
const NotificationSettingsIOS({
|
||||
this.sound = true,
|
||||
this.alert = true,
|
||||
this.badge = true,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, bool>{'sound': sound, 'alert': alert, 'badge': badge};
|
||||
}
|
||||
}
|
||||
|
||||
/// @property {number} [buildId] - 通知样式:1 为基础样式,2 为自定义样式(需先调用 `setStyleCustom` 设置自定义样式)
|
||||
/// @property {number} [id] - 通知 id, 可用于取消通知
|
||||
/// @property {string} [title] - 通知标题
|
||||
/// @property {string} [content] - 通知内容
|
||||
/// @property {object} [extra] - extra 字段
|
||||
/// @property {number} [fireTime] - 通知触发时间(毫秒)
|
||||
/// // iOS Only
|
||||
/// @property {number} [badge] - 本地推送触发后应用角标值
|
||||
/// // iOS Only
|
||||
/// @property {string} [soundName] - 指定推送的音频文件
|
||||
/// // iOS 10+ Only
|
||||
/// @property {string} [subtitle] - 子标题
|
||||
class LocalNotification {
|
||||
final int? buildId; //?
|
||||
final int? id;
|
||||
final String? title;
|
||||
final String? content;
|
||||
final Map<String, String>? extra; //?
|
||||
final DateTime? fireTime;
|
||||
final int? badge; //?
|
||||
final String? soundName; //?
|
||||
final String? subtitle; //?
|
||||
|
||||
const LocalNotification(
|
||||
{@required this.id,
|
||||
@required this.title,
|
||||
@required this.content,
|
||||
@required this.fireTime,
|
||||
this.buildId,
|
||||
this.extra,
|
||||
this.badge = 0,
|
||||
this.soundName,
|
||||
this.subtitle})
|
||||
: assert(id != null),
|
||||
assert(title != null),
|
||||
assert(content != null),
|
||||
assert(fireTime != null);
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return <String, dynamic>{
|
||||
'id': id,
|
||||
'title': title,
|
||||
'content': content,
|
||||
'fireTime': fireTime?.millisecondsSinceEpoch,
|
||||
'buildId': buildId,
|
||||
'extra': extra,
|
||||
'badge': badge,
|
||||
'soundName': soundName,
|
||||
'subtitle': subtitle
|
||||
}..removeWhere((key, value) => value == null);
|
||||
}
|
||||
}
|
||||
61
pubspec.yaml
Normal file
@ -0,0 +1,61 @@
|
||||
name: jpush_flutter
|
||||
description: JIGUANG officially supported JPush Flutter plugin (Android & iOS). 极光推送官方支持的 Flutter 插件(Android & iOS)(https://www.jiguang.cn).
|
||||
version: 2.5.8
|
||||
# author: xudong.rao <xudong.rao@outlook.com>
|
||||
homepage: https://www.jiguang.cn
|
||||
|
||||
environment:
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
||||
dependencies:
|
||||
platform: ^3.0.0
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
dev_dependencies:
|
||||
test: ^1.17.4
|
||||
mockito: ^5.0.7
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://www.dartlang.org/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter.
|
||||
flutter:
|
||||
plugin:
|
||||
platforms:
|
||||
android:
|
||||
package: com.jiguang.jpush
|
||||
pluginClass: JPushPlugin
|
||||
ios:
|
||||
pluginClass: JPushPlugin
|
||||
|
||||
# To add assets to your plugin package, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
#
|
||||
# For details regarding assets in packages, see
|
||||
# https://flutter.io/assets-and-images/#from-packages
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.io/assets-and-images/#resolution-aware.
|
||||
|
||||
# To add custom fonts to your plugin package, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts in packages, see
|
||||
# https://flutter.io/custom-fonts/#from-packages
|
||||