Godot Push 通知 SDK (版本 1.2.0)
SDK 正常运行条件
以下是 push 通知的工作条件。
- 应用程序不同类型版本(debug、release 等)的签名和包名(package name)可能互不相同。 在这种情况下,您必须在 RuStore 控制台 的“推送通知 > 项目”部分为每种版本类型创建一个项目。。
- 正在使用最新版本的 SDK。
- 已在 RuStore 控制台 的“推送通知 > 项目”部分上传应用程序数据。
应用程序已通过审核(无需发布应用程序)。
。- 用户设备上已安装最新版本的 RuStore。
- RuStore 应用程序支持推送通知功能。
- RuStore 应用程序已获准在后台运行。
- 用户已在 RuStore 中登录。
- 设备上安装的应用程序签名指纹与 RuStore 控制台 的 “推送通知 > 项目”部分中添加的应用程序签名指纹一致。
- Godot 4 版本 4.1.4。
实现示例
请参阅 示例应用程序,以了解如何正确集成推送通知 SDK。
连接到项目
-
在您的 IDE 中打开
godot_plugin_libraries文件夹中的 Android 项目。 -
将
godot-lib.xxx.yyy.template_release.aar包放入godot_plugin_libraries/libs文件夹中,其中xxx.yyy是您所使用的 Godot Engine 版本的版本号。 -
使用
gradle assemble命令执行项目构建。
构建成功后,godot_example/android/plugins 文件夹中将创建以下文件:
RuStoreGodotPush.gdap;RuStoreGodotPush.aar;RuStoreGodotCore.gdap;RuStoreGodotCore.aar。
请特别注意,插件库必须针对您的 Godot Engine 版本进行构建。
- 将
godot_example/android/plugins文件夹的内容复制到your_project/android/plugins文件夹中。 - 将
godot_example/android/build_example文件夹的内容复制并替换到godot_example/android/build文件夹中。 - 在 Android 构建预设的插件列表中,勾选 Ru Store Godot Push 和 Ru Store Godot Core。
编辑应用清单文件
在清单文件 your_project/android/build/AndroidManifest.xml 中,声明一个继承自 RuStoreMessagingService 的服务。
<service
android:name="ru.rustore.godot.pushclient.RuStoreGodotMessagingService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="ru.rustore.sdk.pushclient.MESSAGING_EVENT" />
</intent-filter>
</service>
如果需要更改标准通知的图标或颜色,请添加以下代码。
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_icon"
android:resource="@drawable/ic_baseline_android_24" />
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_color"
android:resource="@color/your_favorite_color" />
如果需要重定义通知渠道,请添加以下代码。
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_channel_id"
android:value="@string/pushes_notification_channel_id" />
在添加 push 通知渠道时,您必须自行创建该渠道。
在 Android 13+ 中请求显示通知的权限
Android 13 版本引入了一个用于显示 push 通知的新权限。 这将影响所有在 Android 13 或更高版本上运行并使用 RuStore Push SDK 的应用程序。
默认情况下,1.4.0 及更高版本的 RuStore Push SDK 在清单文件中包含了 POST_NOTIFICATIONS 权限。
但是,应用程序还需要在运行时通过 android.permission.POST_NOTIFICATIONS 常量请求此权限。
只有在用户授予权限后,应用程序才能显示 push 通知。
请求显示 push 通知的权限。
// Declare the launcher at the top of your Activity/Fragment:
private final ActivityResultLauncher<String> requestPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) {
// RuStore Push SDK (and your app) can post notifications.
} else {
// TODO: Inform user that your app will not show notifications.
}
});
private void askNotificationPermission() {
// This is only necessary for API level>= 33 (TIRAMISU)
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
PackageManager.PERMISSION_GRANTED) {
// RuStore Push SDK (and your app) can post notifications.
} else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
// TODO: display an educational UI explaining to the user the features that will be enabled
// by them granting the POST_NOTIFICATION permission. This UI should provide the user
// "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
// If the user selects "No thanks," allow the user to continue without notifications.
} else {
// Directly ask for the permission
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
}
}
}
初始化
初始化需要 来自 RuStore 控制台 的项目 ID。 要获取该 ID,请在应用程序页面中转到 推送通知 > 项目 部分,并复制 项目 ID 字段中的值。
请注意,Push SDK 不支持在多个进程中同时运行。
如果您的应用程序使用多个进程,则必须仅在主进程中初始化 SDK。
如果在辅助进程中进行初始化,可能会导致 push 通知工作异常。
插件初始化
在调用库方法之前,需要先创建一个 RuStoreGodotPushClient 推送通知客户端对象。 请执行 init 方法来初始化客户端。
const PROJECT_ID = "123456"
const LOG_MODE = ERuStoreLogMode.Item.CUSTOM
const CLIENT_ID_TYPE = ERuStoreClientIdType.Item.GAID
const CLIENT_ID_VALUE = "your_client_id"
var _push_client: RuStoreGodotPushClient = null
func _ready:
_push_client = RuStoreGodotPushClient.get_instance()
_push_client.init(PROJECT_ID, LOG_MODE)
PROJECT_ID— 项目标识符。LOG_MODE— 日志记录模式:NONE— 不记录日志;LOGCAT— 将消息输出到logcat;CUSTOM— 将消息输出到on_log_*事件中。
事件日志记录
如果您想记录推送通知库的事件,请在初始化插件时将 LOG_MODE 设置为 ERuStoreLogMode.Item.CUSTOM,并执行一次事件订阅:
on_log_verbose;on_log_debug;on_log_info;on_log_warn;on_log_error。
cfunc _ready:
# Инициализация _push_client
_push_client.on_log_verbose.connect(_on_log_verbose)
_push_client.on_log_debug.connect(_on_log_debug)
_push_client.on_log_info.connect(_on_log_info)
_push_client.on_log_warn.connect(_on_log_warn)
_push_client.on_log_error.connect(_on_log_error)
func _on_log_verbose(message: String):
pass
func _on_log_debug(message: String):
pass
func _on_log_info(message: String):
pass
func _on_log_warn(message: String):
pass
func _on_log_error(message: String):
pass
message —— 日志消息。
用户分群管理
分群是指您根据特定参数选择的一组用户。 例如,带来最高收入的用户,或使用旧版本 Android 的用户。 有关分群的详细信息,请参阅 MyTracker 文档。
要开始使用分群,请在初始化 SDK 时指定 ClientIdType 和 ClientIdValue 参数。
const CLIENT_ID_TYPE = ERuStoreClientIdType.Item.GAID
const CLIENT_ID_VALUE = "your_client_id"
var _push_client: RuStoreGodotPushClient = null
func _ready:
_push_client = RuStoreGodotPushClient.get_instance()
_push_client.init(PROJECT_ID, LOG_MODE, CLIENT_ID_TYPE, CLIENT_ID_VALUE)
CLIENT_ID_TYPE— 标识符类型:GAID— Google 广告标识符;OAID— 华为广告标识符。
CLIENT_ID_VALUE— 标识符的值。
检查接收推送通知的能力
Push 通知的工作条件请参阅“SDK 正确工作条件”章节。
若要检查分发应用程序是否已安装在用户设备上,请使用check_push_availability 方法。
在使用该方法之前,请先执行一次事件订阅:
on_check_push_availability_success;on_check_push_availability_failure。
func _ready():
# Инициализация _push_client
_push_client.on_check_push_availability_success.connect(_on_check_push_availability_success)
_push_client.on_check_push_availability_failure.connect(_on_check_push_availability_failure)
func _on_check_push_availability_success(result: RuStoreFeatureAvailabilityResult):
pass
func _on_check_push_availability_failure(error: RuStoreError):
pass
_push_client.check_push_availability()
- 回调函数 (callback)
on_check_push_availability_success返回一个包含服务可用性信息的RuStoreFeatureAvailabilityResult对象。
class_name RuStoreFeatureAvailabilityResult extends Object
var isAvailable: bool = false
var cause: RuStoreError = null
func _init(json: String = ""):
if json != "":
var obj = JSON.parse_string(json)
isAvailable = obj["isAvailable"]
if obj.has("cause"):
var jcause = JSON.stringify(obj["cause"])
cause = RuStoreError.new(jcause)
isAvailable— 接收 push 通知的条件是否满足:true— 条件已满足;false— 条件未满足。
cause— 错误信息。RuStoreError类的结构和所有可能的错误在错误处理章节中有所描述
- 回调函数 (callback)
on_check_push_availability_failure返回一个包含所有其他错误的RuStoreError对象,例如—«无互联网连接»。RuStoreError类的结构在错误处理章节中有所描述。
Push 令牌操作方法
获取用户的 Push 令牌
如果用户没有 push 令牌,该方法将创建并返回一个新的 push 令牌。
get_token 方法来获取当前用 户的 push 令牌。
在使用该方法之前,请先执行一次事件订阅:
on_get_token_success;on_get_token_failure。
func _ready():
# Инициализация _push_client
_push_client.on_get_token_success.connect(_on_get_token_success)
_push_client.on_get_token_failure.connect(_on_get_token_failure)
func _on_get_token_success(data: String):
pass
func _on_get_token_failure(error: RuStoreError):
pass
_push_client.get_token()
-
回调函数 (callback)
on_get_token_success将返回一个包含当前推送令牌 (push-token) 信息的字符串。 -
回调函数 (callback)
on_get_token_failure将返回一个包含错误信息的RuStoreError对象。RuStoreError类的结构在错误处理章节中有所描述。
删除用户的 Push 令牌
在初始化库之后,您可以使用delete_token 方法来删除当前用户的 push 令牌。
在使用该方法之前,请先执行一次事件订阅:
on_delete_token_success;on_delete_token_failure。
func _ready():
# Инициализация _push_client
_push_client.on_delete_token_success.connect(_on_delete_token_success)
_push_client.on_delete_token_failure.connect(_on_delete_token_failure)
func _on_delete_token_success():
pass
func _on_delete_token_failure(error: RuStoreError):
pass
_push_client.delete_token()
回调函数 (callback) on_delete_token_failure 将返回一个包含错误信息的 RuStoreError 对象。 RuStoreError 类的结构在错误处理章节中有所描述。
Push 主题操作方法
订阅主题 Push 通知
初始化库后,您可以使用subscribe_to_topic 方法订阅主题。
在使用该方法之前,请先执行一次事件订阅:
on_subscribe_to_topic_success;on_subscribe_to_topic_failure。
func _ready():
# Инициализация _push_client
_push_client.on_subscribe_to_topic_success(_on_subscribe_to_topic_success)
_push_client.on_subscribe_to_topic_failure(_on_subscribe_to_topic_failure)
func _on_subscribe_to_topic_success():
pass
func _on_subscribe_to_topic_failure(error: RuStoreError):
pass
const TOPIC_NAME = "hello"
_push_client.subscribe_to_topic(TOPIC_NAME)
TOPIC_NAME — 主题名称。
回调函数 (callback) on_subscribe_to_topic_success 表示操作已成功完成。
回调函数 (callback) on_subscribe_to_topic_failure 会返回一个包含错误信息的 RuStoreError 对象。 RuStoreError 类的结构在错误处理章节中有所描述。
取消订阅主题 Push 通知
初始化库后,您可以使用unsubscribe_from_topic 方法取消订阅主题。
在使用该方法之前,请先执行一次事件订阅:
on_unsubscribe_from_topic_success;on_unsubscribe_from_topic_failure.
func _ready():
# Инициализация _push_client
_push_client.on_unsubscribe_from_topic_success(_on_unsubscribe_from_topic_success)
_push_client.on_unsubscribe_from_topic_failure(_on_unsubscribe_from_topic_failure)
func _on_unsubscribe_from_topic_success():
pass
func _on_unsubscribe_from_topic_failure(error: RuStoreError):
pass
};
const TOPIC_NAME = "hello"
_push_client.unsubscribe_from_topic(TOPIC_NAME)
TOPIC_NAME — 主题名称。
回调函数 (callback) on_unsubscribe_to_topic_success 表示操作已成功完成。
回调函数 (callback) on_unsubscribe_to_topic_failure 返回一个包含错误信息的 RuStoreError 对象。 RuStoreError 类的结构在错误处理章节中有所描述。
从 RuStore SDK 获取数据
若要从 RuStore SDK 接收推送通知数据,请在创建客户端并初始化后,执行一次事件订阅:
on_new_token;on_message_received;on_deleted_messages;on_error。
func _ready:
# Инициализация _push_client
_push_client.on_new_token.connect(_on_new_token)
_push_client.on_message_received.connect(_on_message_received)
_push_client.on_deleted_messages.connect(_on_deleted_messages)
_push_client.on_error.connect(_on_error)
func _on_new_token(data: String):
pass
func _on_message_received(data: Dictionary):
pass
func _on_deleted_messages():
pass
func _on_error(errors: Array):
pass
| 方法名称 | 描述 |
|---|---|
| 在收到新的推送令牌(push token)时调用此方法。 调用此方法后,您的应用程序负责将新的推送令牌发送到自己的服务器。 该方法返回新令牌的值。 |
| 在收到新的推送通知时调用此方法。 如果 可以通过 |
| 如果一条或多条推送通知未送达设备,则调用此方法。 例如,如果通知在送达前已过期。 在调用此方法时,建议与自己的服务器进行同步,以免丢失数据。 |
| 如果在初始化时发生错误,则调用此方法。 它返回一个包含错误对象的数组。 可能的错误:
|
通知结构
func _on_message_received(data: Dictionary):
print("messageId: " + data["messageId"])
print("priority: " + data["priority"])
print("ttl: " + data["ttl"])
print("collapseKey: " + data["collapseKey"])
print("data: " + data["data"])
print("rawData: " + data["rawData"])
messageId— 消息的唯一 ID。 它是每条消息的标识符。-
priority— 返回优先级值(目前不考虑)。 目前定义了以下选项:0—UNKNOWN;1—HIGH;2—NORMAL。
ttl—Int类型的 push 通知生存时间,单位为秒。from— 用于识别通知来源的字段:- 对于发送到主题(topic)的通知,该字段显示主题名称;
- 在其他情况下,显示服务令牌的一部分。
collapseKey— 通知组的标识符(目前不考虑)。data— 一个字典,其中可以传递通知的附加数据。rawData— 以字节数组形式表示的data字典。notification— 通知对象。
func _on_message_received(data: Dictionary):
print("title: " + data["notification_title"])
print("body: " + data["notification_body"])
print("channelId: " + data["notification_channelId"])
print("color: " + data["notification_color"])
print("icon: " + data["notification_icon"])
print("clickAction: " + data["notification_clickAction"])
print("imageUrl: " + data["notification_imageUrl"])
title— 通知标题。body— 通知正文。channelId— 用于指定发送通知的渠道。 适用于 Android 8.0 及更高版本。imageUrl— 用于插入通知的图像直接链接。 图像大小不得超过 1 MB。color— 以字符串形式表示的 HEX 格式通知颜色。 例如,#0077FF。icon— 来自res/drawable的通知图标,以与资源名称一致的字符串格式表示。
例如,res/drawable中有一个small_icon.xml图标,可以通过R.drawable.small_icon在代码中访问。
为了让图标在通知中显示,服务器必须在icon参数中指定small_icon的值。clickAction— 点击通知时用于打开 Activity 的intent action。
创建用于发送通知的渠道
发送通知的渠道遵循以下优先级。
-
如果推送通知中包含
channelId字段,RuStore SDK 将把通知发送到指定的渠道。 您的应用程序必须提前创建此渠道。 -
如果推送通知中没有
channelId字段,但您的应用程序在AndroidManifest.xml中指定了渠道参数,则将使用该指定渠道。 您的应用程序必须提前创建此渠道。 -
如果 push 通知中没有
channelId字段,且AndroidManifest.xml中未指定默认通道,RuStore SDK 将创建该通道并将通知发送至其中。 此后,所有未明确指定通道的通知都将发送到该通道。
点击通知时打开 Activity
默认情况下,点击通知时,RuStore SDK 将打开 action 为 android.intent.action.MAIN 的 activity。
如果存在 clickAction 字段,RuStore SDK 将打开符合指定 action 的 Intent filter 的 activity。
请在应用程序清单文件中,在 activity 相应的 <intent-filter> 元素中添加一行 <category android:name="android.intent.category.DEFAULT" />。
这是为了确保在点击通知时能默认打开 activity。
如果没有这一行,RuStore SDK 将无法打开 activity。
为了让 SDK 能够在不重启游戏的情况下打开 game activity,在点击推送通知进入应用程序时,需要清除 intent。
具体操作如下:
-
进入
your_project/android/build/src/com /godot/game文件夹。 -
创建一个继承自
FullScreenGodotApp的GodotPushApp类。
package com.godot.game;
import org.godotengine.godot.FullScreenGodotApp;
import android.os.Bundle;
public class GodotPushApp extends FullScreenGodotApp {
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.GodotAppMainTheme);
super.onCreate(savedInstanceState);
}
}
- 修改
GodotApp类。
package com.godot.game;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class GodotApp extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.GodotAppMainTheme);
super.onCreate(savedInstanceState);
/**
* Processing intenss here
*/
Intent newIntent = new Intent(this, GodotPushApp.class);
startActivity(newIntent);
finish();
}
}
- 在
your_project/android/build/AndroidManifest.xml清单文件中添加关于GodotPushAppactivity 的信息。
<activity
android:name="com.godot.game.GodotPushApp"
android:label="@string/godot_project_name_string"
android:theme="@style/GodotAppSplashTheme"
android:launchMode="singleInstance"
android:excludeFromRecents="false"
android:exported="true"
android:screenOrientation="sensor"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:resizeableActivity="false"
tools:ignore="UnusedAttribute" >
</activity>
- 将 activity
android:name=".GodotApp"中的android:launchMode="singleInstance"修改为android:launchMode="singleTask"。
错误处理
class_name RuStoreError extends Object
var description: String
func _init(json: String = ""):
if json == "":
description = ""
else:
var obj = JSON.parse_string(json)
description = obj["detailMessage"]
description— 错误描述。
以下是错误类:
RuStoreNotInstalledException— 用户设备上未安装 RuStore。RuStoreOutdatedException— 用户设备上安装的 RuStore 版本不支持此 SDK。RuStoreUserUnauthorizedException— 用户未在 RuStore 中登录。RuStoreFeatureUnavailableException— RuStore 没有后台运行权限。RuStoreException— RuStore 基础错误,其他错误均继承自此类。