关于 Pushwoosh Android SDK 的常见问题解答
- Android 推送令牌和 HWID 是什么样子的?
- 如何获取我的 Android 设备推送令牌?
- 哪些权限是必需的,哪些是可选的?
- 如何设置 UserID?
- Android 订阅者总数的准确性如何?
- 我可以在发送到 Android 的推送中使用 HTML 标签吗?
- 如何在 Android Lollipop(及更高版本)中设置通知图标?
- 将 Pushwoosh SDK 与其他 FCM 服务一起使用
- 将 Pushwoosh 与 LeakCanary 或 AppMetrica 库一起使用
- 从设备删除收到的通知
Android 推送令牌和 HWID 是什么样子的?
Anchor link toAndroid 设备推送令牌的长度不同(小于 255 个字符),并以 APA91b 开头,例如:
APA91bFoi3lMMre9G3XzR1LrF4ZT82_15MsMdEICogXSLB8-MrdkRuRQFwNI5u8Dh0cI90ABD3BOKnxkEla8cGdisbDHl5cVIkZah5QUhSAxzx4Roa7b4xy9tvx9iNSYw-eXBYYd8k1XKf8Q_Qq1X9-x-U-Y79vdPq
令牌在 APA91b 之前通常包含一个以冒号分隔的前缀,例如:eQnyCE6ULAQ:APA91bGrh4ya3b_owo9tshZNVAGhZdGMGb3sA5HbM...
Pushwoosh 使用 UUID 作为 HWID,即随机生成的 32 个字母数字字符的字符串:123e4567-e89b-12d3-a456-426655440000
如何获取我的 Android 设备推送令牌?
Anchor link to您可以在控制台日志中获取您的 Android 设备推送令牌。请使用 Android Studio 中的 logcat 工具。
在 %USERPROFILE%\AppData\Local\Android\sdk\tools\monitor.bat 中打开 monitor.bat,将您的设备连接到 PC,并在 Android 设置中允许 USB 调试。在设备上运行您的应用程序。找到 /registerDevice,找到您设备的推送令牌,以便稍后在“测试设备”中使用。

哪些权限是必需的,哪些是可选的?
Anchor link to当安装在 Android 设备上时,应用程序将请求与 Pushwoosh SDK 相关的以下权限:
<!-- FCM 连接到 Firebase 服务。 --> <uses-permission android:name="android.permission.INTERNET"/>
<!-- 在收到消息时防止处理器进入休眠状态。 --> <uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- 此权限用于确定设备是否可以访问网络。 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 此应用有权注册和接收数据消息。 --> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />我们的 SDK 不会请求访问图片、设备联系人等权限。
如何设置 UserID?
Anchor link to您可以设置一个用户标识符 (UserID),它可以是 Facebook ID、用户名、电子邮件或任何其他唯一的用户 ID。这使您能够匹配与同一用户关联的多个设备上的数据和事件。要设置 UserID,请调用 setUserId 方法。
示例
Pushwoosh.getInstance().setUserId("testUser");Android 订阅者总数的准确性如何?
Anchor link toPushwoosh 在收到来自 FCM 的“NotRegistered”响应后,会从数据库中清除已取消订阅的 Android 设备,该响应可能在第二次尝试联系特定设备后返回。这意味着您必须向一个已取消订阅的设备发送 2 次推送,才能将其从数据库中移除。
以下是 FCM 文档中描述的最常见场景:
- 您的订阅者卸载了应用。
- Pushwoosh 向 FCM 服务器发送一条消息。
- FCM 服务器将消息发送到您用户的设备。
- 设备上的 FCM 客户端收到消息并检测到您的应用程序已被卸载;检测细节取决于应用运行的平台。
- 设备上的 FCM 客户端通知 FCM 服务器应用已被卸载。
- FCM 服务器将注册 ID 标记为待删除。
- Pushwoosh 向 FCM 发送另一条消息。
- FCM 返回一条 NotRegistered 消息。
- Pushwoosh 从您的用户群中移除该推送令牌。
注册 ID 可能需要一段时间才能从 FCM 中完全移除。因此,即使消息不会传递到客户端应用,在上述步骤 7 中发送的消息也可能获得一个有效的消息 ID 作为响应。
我可以在发送到 Android 的推送中使用 HTML 标签吗?
Anchor link to是的,在 Android 中,您可以使用以下 HTML 标签来修改推送的外观:
<span style="color: green;"><b><i><span style="text-decoration: underline;">Hello world!Hello hi hey</span></i></b></span>将这些 HTML 标签放在消息输入字段中,并在 API 请求中使用它们。某些 Android 设备可能无法正确处理这些 HTML 标签,但大多数设备都能正确显示格式。
如何在 Android Lollipop(及更高版本)中设置通知图标?
Anchor link to在 Android Lollipop 中,图标被更改为仅为白色。因此,如果您在 AndroidManifest.xml 文件中选择 targetSdkVersion >= 21,Android 将只使用图标的 alpha 通道。
有关此行为的更多信息,请参阅 Android 文档。
系统会忽略操作图标和主通知图标中的所有非 alpha 通道。假设这些图标将仅为 alpha 通道。系统以白色绘制通知图标,以深灰色绘制操作图标。这超出了 Pushwoosh SDK 的控制范围。
1. 根据 Android 指南创建通知图标。根据文档,系统将忽略所有颜色。
2. 将图标命名为 pw_notification.png 并将其放入 res/drawable 文件夹中。Pushwoosh SDK 将使用此图标作为通知的默认图标。
3. 或者,您可以使用远程 API 并将 "android_icon" 参数值设置为图标图像(不带文件扩展名)。
将 Pushwoosh SDK 与其他 FCM 服务一起使用
Anchor link to您可以将 Pushwoosh 与其他使用 FCM 进行推送消息传递的 SDK 一起使用。为此,请创建一个路由器服务以在这些服务之间分发事件。首先,在主 Pushwoosh 模块旁边添加 pushwoosh-firebase 依赖项:
implementation 'com.pushwoosh:pushwoosh-firebase:6.0.3'创建路由类:
import com.pushwoosh.firebase.PushwooshFcmHelper;
class FirebaseMessagingRouterService : FirebaseMessagingService() {
override fun onNewToken(token: String?) { super.onNewToken(token) PushwooshFcmHelper.onTokenRefresh(token) sendTokenToAnotherService(token) }
override fun onMessageReceived(remoteMessage: RemoteMessage) { if (PushwooshFcmHelper.isPushwooshMessage(remoteMessage)) { // 这是 Pushwoosh 推送,SDK 将自动处理 PushwooshFcmHelper.onMessageReceived(this, remoteMessage) } else { // 这不是 Pushwoosh 推送,您应自行处理 dispatchNonPushwooshMessage(remoteMessage); } }
private fun dispatchNonPushwooshMessage(remoteMessage: RemoteMessage) { // 在此处实现您的推送处理逻辑 }}import com.pushwoosh.firebase.PushwooshFcmHelper;
public class FirebaseMessagingRouterService extends FirebaseMessagingService {
@Override public void onNewToken(String token) { super.onNewToken(token); PushwooshFcmHelper.onTokenRefresh(token); sendTokenToAnotherService(token); }
@Override public void onMessageReceived(RemoteMessage remoteMessage) { if (PushwooshFcmHelper.isPushwooshMessage(remoteMessage)) { // 这是 Pushwoosh 推送,SDK 将自动处理 PushwooshFcmHelper.onMessageReceived(this, remoteMessage); } else { // 这不是 Pushwoosh 推送,您应自行处理 dispatchNonPushwooshMessage(remoteMessage); } }
private void dispatchNonPushwooshMessage(RemoteMessage remoteMessage) { // 在此处实现您的推送处理逻辑 }}在您的 AndroidManifest.xml 中注册路由器:
<service android:name=".FirebaseMessagingRouterService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter></service>将 Pushwoosh 与 LeakCanary 或 AppMetrica 库一起使用
Anchor link to当您集成 LeakCanary、AppMetrica 或其他分析工具时,这些库会启动一个新进程,创建应用的新实例。由于您无法在另一个进程中监听推送通知,这会导致抛出 java.lang.NullPointerException。
如果您在 Application.onCreate() 中调用 registerForPushNotifications,您应该检查您是否在应用程序的主进程中。使用以下代码执行此检查:
List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE)).getRunningAppProcesses();if (runningAppProcesses != null && runningAppProcesses.size() != 0) { for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) { boolean isCurrentProcess = runningAppProcessInfo.pid == android.os.Process.myPid(); boolean isMainProcessName = getPackageName().equals(runningAppProcessInfo.processName); if (isCurrentProcess && isMainProcessName) {
Pushwoosh.getInstance().registerForPushNotifications(...); break; } }}在设备本地删除特定的已接收通知
Anchor link to如果您想在应用程序内执行特定操作时移除不相关的推送,可以使用以下方法:
public class MainActivity extends AppCompatActivity {
List<NotificationCreatedEvent> savedPushes = new ArrayList<>();
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Pushwoosh.getInstance().registerForPushNotifications();
PushwooshNotificationSettings.setMultiNotificationMode(true);
findViewById(R.id.clear_button).setOnClickListener( v -> { cancelPushes(); });
EventBus.subscribe(NotificationCreatedEvent.class, event -> { try { if (event.getMessage().getCustomData() == null) return;
// 仅取消带有特定标志的推送 if (new JSONObject(event.getMessage().getCustomData()).getBoolean("cancel")) { savedPushes.add(event); } } catch (JSONException e) { } }); } private void cancelPushes() { NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
if (manager == null) { return; }
for (NotificationCreatedEvent event : savedPushes) { manager.cancel(event.getMessageTag(), event.getMessageId()); } }}与我们分享您的反馈
Anchor link to您的反馈有助于我们创造更好的体验。如果您在 SDK 集成过程中遇到任何困难,请通过此表单与我们分享您的想法。