# คำถามที่พบบ่อยเกี่ยวกับ Pushwoosh Android SDK

* [Android push token และ HWID มีลักษณะอย่างไร?](#what-does-android-push-token-and-hwid-look-like)
* [ฉันจะรับ push token ของอุปกรณ์ Android ของฉันได้อย่างไร?](#how-can-i-obtain-my-android-device-push-token)
* [สิทธิ์ใดที่จำเป็นและสิทธิ์ใดที่เป็นทางเลือก?](#what-permissions-are-necessary-and-what-are-optional)
* [ฉันจะตั้งค่า UserID ได้อย่างไร?](#how-do-i-set-a-userid)
* [จำนวนผู้สมัครสมาชิก Android ทั้งหมดมีความแม่นยำเพียงใด?](#how-accurate-is-the-total-number-of-android-subscribers)
* [ฉันสามารถใช้แท็ก HTML ใน push ที่ส่งไปยัง Android ได้หรือไม่?](#can-i-use-html-tags-in-pushes-sent-to-android)
* [วิธีตั้งค่าไอคอนการแจ้งเตือนใน Android Lollipop (และเวอร์ชันที่ใหม่กว่า)?](#how-to-set-a-notification-icon-in-android-lollipop-and-later-versions)
* [การใช้ Pushwoosh SDK กับบริการ FCM อื่นๆ](#using-pushwoosh-sdk-with-other-fcm-services)
* [การใช้ Pushwoosh กับไลบรารี LeakCanary หรือ AppMetrica](#using-pushwoosh-with-leakcanary-or-appmetrica-libraries)
* [การลบการแจ้งเตือนที่ได้รับจากอุปกรณ์](#deleting-particular-received-notifications-from-a-device)

### Android push token และ HWID มีลักษณะอย่างไร?

Android device push tokens มีความยาวแตกต่างกัน (น้อยกว่า 255 ตัวอักษร) และขึ้นต้นด้วย **APA91b** ตัวอย่างเช่น:

`APA91bFoi3lMMre9G3XzR1LrF4ZT82_15MsMdEICogXSLB8-MrdkRuRQFwNI5u8Dh0cI90ABD3BOKnxkEla8cGdisbDHl5cVIkZah5QUhSAxzx4Roa7b4xy9tvx9iNSYw-eXBYYd8k1XKf8Q_Qq1X9-x-U-Y79vdPq`

Tokens มักจะมีคำนำหน้าที่คั่นด้วยโคลอนก่อน **APA91b** ตัวอย่างเช่น: `eQnyCE6ULAQ:APA91bGrh4ya3b_owo9tshZNVAGhZdGMGb3sA5HbM...`

Pushwoosh ใช้ UUID เป็น HWIDs ซึ่งเป็นสตริงที่สร้างขึ้นแบบสุ่มประกอบด้วยตัวอักษรและตัวเลข 32 ตัว: `123e4567-e89b-12d3-a456-426655440000`

### ฉันจะรับ push token ของอุปกรณ์ Android ของฉันได้อย่างไร?

คุณสามารถรับ push token ของอุปกรณ์ Android ของคุณได้ใน console log ใช้เครื่องมือ logcat ใน [Android Studio](https://developer.android.com/studio)

เปิด **monitor.bat** ใน `%USERPROFILE%\AppData\Local\Android\sdk\tools\monitor.bat` เชื่อมต่ออุปกรณ์ของคุณกับ PC และอนุญาต USB debugging ในการตั้งค่า Android รันแอปพลิเคชันของคุณบนอุปกรณ์ ค้นหา `/registerDevice` และค้นหา push token สำหรับอุปกรณ์ของคุณเพื่อใช้ใน Test Devices ในภายหลัง

<img src="/android-push-notifications-android-faq-1.webp" alt="Screenshot showing logcat output with push token registration information displayed in Android Studio"/>

### สิทธิ์ใดที่จำเป็นและสิทธิ์ใดที่เป็นทางเลือก?

เมื่อติดตั้งบนอุปกรณ์ Android แอปพลิเคชันจะขอสิทธิ์ต่อไปนี้ที่เกี่ยวข้องกับ Pushwoosh SDK:

```java
<!-- FCM เชื่อมต่อกับ Firebase Services -->
 <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 ได้อย่างไร?

คุณสามารถตั้งค่า [User identifier (UserID)](/th/developer/first-steps/collecting-user-ids/) ซึ่งอาจเป็น Facebook ID, username, email หรือ User ID ที่ไม่ซ้ำกันอื่นๆ ซึ่งจะช่วยให้คุณสามารถจับคู่ข้อมูลและเหตุการณ์ต่างๆ ในอุปกรณ์หลายเครื่องที่เชื่อมโยงกับผู้ใช้คนเดียวกันได้ หากต้องการตั้งค่า UserID ให้เรียกใช้เมธอด **setUserId**

**ตัวอย่าง**

```
Pushwoosh.getInstance().setUserId("testUser");
```

### จำนวนผู้สมัครสมาชิก Android ทั้งหมดมีความแม่นยำเพียงใด?

Pushwoosh จะล้างอุปกรณ์ Android ที่ยกเลิกการสมัครออกจากฐานข้อมูลเมื่อได้รับการตอบกลับ "NotRegistered" จาก FCM ซึ่งอาจถูกส่งกลับมาหลังจากการพยายามครั้งที่สองในการเข้าถึงอุปกรณ์นั้นๆ ซึ่งหมายความว่าคุณต้องส่ง push 2 ครั้งไปยังอุปกรณ์ที่ยกเลิกการสมัครเพื่อให้ถูกลบออกจากฐานข้อมูล

ต่อไปนี้เป็นสถานการณ์ที่พบบ่อยที่สุดที่อธิบายไว้ใน [เอกสารของ FCM](https://firebase.google.com/docs/cloud-messaging/):

1. ผู้สมัครของคุณถอนการติดตั้งแอป
2. Pushwoosh ส่งข้อความไปยังเซิร์ฟเวอร์ FCM
3. เซิร์ฟเวอร์ FCM ส่งข้อความไปยังอุปกรณ์ของผู้ใช้ของคุณ
4. ไคลเอนต์ FCM บนอุปกรณ์ได้รับข้อความและตรวจพบว่าแอปพลิเคชันของคุณถูกถอนการติดตั้งแล้ว รายละเอียดการตรวจจับขึ้นอยู่กับแพลตฟอร์มที่แอปกำลังทำงานอยู่
5. ไคลเอนต์ FCM บนอุปกรณ์แจ้งให้เซิร์ฟเวอร์ FCM ทราบว่าแอปถูกถอนการติดตั้งแล้ว
6. เซิร์ฟเวอร์ FCM ทำเครื่องหมาย ID การลงทะเบียนเพื่อลบ
7. Pushwoosh ส่งข้อความอื่นไปยัง FCM
8. FCM ส่งคืนข้อความ NotRegistered
9. Pushwoosh ลบ push token ออกจากฐานผู้ใช้ของคุณ

อาจใช้เวลาสักครู่เพื่อให้ ID การลงทะเบียนถูกลบออกจาก FCM อย่างสมบูรณ์ ดังนั้นจึงเป็นไปได้ที่ข้อความที่ส่งในขั้นตอนที่ 7 ข้างต้นจะได้รับการตอบกลับเป็น ID ข้อความที่ถูกต้อง แม้ว่าข้อความนั้นจะไม่ถูกส่งไปยังแอปของไคลเอนต์ก็ตาม

### ฉันสามารถใช้แท็ก HTML ใน push ที่ส่งไปยัง Android ได้หรือไม่?

ได้ ใน Android คุณสามารถใช้แท็ก HTML ต่อไปนี้เพื่อแก้ไขลักษณะที่ปรากฏของ push:

```txt
<span style="color: green;"><b><i><span style="text-decoration: underline;">Hello world!
Hello hi hey</span></i></b></span>
```

วางแท็ก HTML เหล่านี้ในช่องป้อนข้อมูล **Message** และใช้ในคำขอ API ด้วย อุปกรณ์ Android บางเครื่องอาจไม่สามารถประมวลผลแท็ก HTML เหล่านี้ได้อย่างถูกต้อง แต่อุปกรณ์ส่วนใหญ่แสดงการจัดรูปแบบได้อย่างถูกต้อง

### วิธีตั้งค่าไอคอนการแจ้งเตือนใน Android Lollipop (และเวอร์ชันที่ใหม่กว่า)?

ใน Android Lollipop ไอคอนถูกเปลี่ยนเป็นสีขาวเท่านั้น ดังนั้นหากคุณเลือก **targetSdkVersion >= 21** ในไฟล์ **AndroidManifest.xml** ของคุณ Android จะใช้เฉพาะ alpha-channel ของไอคอนเท่านั้น\
ดูข้อมูลเพิ่มเติมเกี่ยวกับพฤติกรรมนี้ได้ใน [เอกสารของ Android](https://developer.android.com/docs)

ระบบจะละเว้นช่องที่ไม่ใช่ alpha ทั้งหมดในไอคอนการกระทำและในไอคอนการแจ้งเตือนหลัก สมมติว่าไอคอนเหล่านี้จะเป็นแบบ alpha-only เท่านั้น ระบบจะวาดไอคอนการแจ้งเตือนเป็นสีขาวและไอคอนการกระทำเป็นสีเทาเข้ม _สิ่งนี้อยู่นอกเหนือการควบคุมของ Pushwoosh SDK_

**1.** สร้างไอคอนการแจ้งเตือนตาม [แนวทางของ Android](https://material.io/design/platform-guidance/android-notifications.html#style) ตาม [เอกสาร](https://developer.android.com/about/versions/lollipop/android-5.0-changes) ระบบจะละเว้นสีทั้งหมด

**2.** ตั้งชื่อไอคอนเป็น `pw_notification.png` และวางไว้ในโฟลเดอร์ **res/drawable** Pushwoosh SDK จะใช้ไอคอนนี้เป็นค่าเริ่มต้นสำหรับการแจ้งเตือน

**3.** อีกทางเลือกหนึ่งคือคุณสามารถใช้ Remote API และตั้งค่าพารามิเตอร์ `"android_icon"` เป็นรูปภาพไอคอน (โดยไม่มีนามสกุลไฟล์)

### การใช้ Pushwoosh SDK กับบริการ FCM อื่นๆ

คุณสามารถใช้ Pushwoosh ควบคู่ไปกับ SDK อื่นๆ ที่ใช้ FCM สำหรับการส่งข้อความ push ในการทำเช่นนั้น ให้สร้างบริการเราเตอร์เพื่อกระจายเหตุการณ์ระหว่างบริการต่างๆ ก่อนอื่นให้เพิ่ม dependency **pushwoosh-firebase** ควบคู่ไปกับโมดูลหลักของ Pushwoosh:

```groovy title="build.gradle"
implementation 'com.pushwoosh:pushwoosh-firebase:6.0.3'
```

สร้างคลาสเราเตอร์:

<Tabs>
<TabItem label="FirebaseMessagingRouterService.kt">
```kotlin
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)) {
           //นี่คือ push ของ Pushwoosh, SDK จะจัดการโดยอัตโนมัติ
            PushwooshFcmHelper.onMessageReceived(this, remoteMessage)
        } else {
            //นี่ไม่ใช่ push ของ Pushwoosh, คุณควรจัดการด้วยตัวเอง
            dispatchNonPushwooshMessage(remoteMessage);
        }
    }

    private fun dispatchNonPushwooshMessage(remoteMessage: RemoteMessage) {
       // นำตรรกะการจัดการ push ของคุณมาใส่ที่นี่
   }
}
```
</TabItem>

<TabItem label="FirebaseMessagingRouterService.java">
```java
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)) {
            //นี่คือ push ของ Pushwoosh, SDK จะจัดการโดยอัตโนมัติ
            PushwooshFcmHelper.onMessageReceived(this, remoteMessage);
        } else {
            //นี่ไม่ใช่ push ของ Pushwoosh, คุณควรจัดการด้วยตัวเอง
            dispatchNonPushwooshMessage(remoteMessage);
        }
    }

    private void dispatchNonPushwooshMessage(RemoteMessage remoteMessage) {
        // นำตรรกะการจัดการ push ของคุณมาใส่ที่นี่
    }
}
```
</TabItem>
</Tabs>

ลงทะเบียนเราเตอร์ใน AndroidManifest.xml ของคุณ:

```txt title="AndroidManifest.xml"
<service
    android:name=".FirebaseMessagingRouterService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>
```

### การใช้ Pushwoosh กับไลบรารี LeakCanary หรือ AppMetrica

เมื่อคุณรวมเครื่องมือวิเคราะห์เช่น LeakCanary, AppMetrica หรืออื่นๆ ไลบรารีเหล่านี้จะเริ่มกระบวนการใหม่ สร้างอินสแตนซ์ใหม่ของแอป เนื่องจากคุณไม่สามารถรอรับการแจ้งเตือน push ในกระบวนการอื่นได้ สิ่งนี้จะส่งผลให้เกิด `java.lang.NullPointerException`

หากคุณเรียกใช้ `registerForPushNotifications` ภายใน `Application.onCreate()` คุณควรตรวจสอบว่าคุณอยู่ในกระบวนการหลักของแอปพลิเคชันหรือไม่ ใช้โค้ดต่อไปนี้เพื่อทำการตรวจสอบนี้:

```java
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;
        }
    }
}
```

### การลบการแจ้งเตือนที่ได้รับจากอุปกรณ์เฉพาะที่

หากคุณต้องการลบ push ที่ไม่เกี่ยวข้องออกเมื่อดำเนินการบางอย่างภายในแอปพลิเคชันของคุณ คุณสามารถใช้วิธีการต่อไปนี้:

```java title="MainActivity.java"
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;

				//ยกเลิก push ที่มีแฟล็กที่ระบุเท่านั้น
				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());
		}
	}
}
```

## แบ่งปันความคิดเห็นของคุณกับเรา

ความคิดเห็นของคุณช่วยให้เราสร้างประสบการณ์ที่ดีขึ้น หากคุณประสบปัญหาใดๆ ในระหว่างกระบวนการรวม SDK โปรดแบ่งปันความคิดของคุณกับเรา [ผ่านฟอร์มนี้](https://docs.google.com/forms/d/e/1FAIpQLSd_0b8jwn-V_JmoPLIxIFYbHACCQhrzidOZV3ELywoQPXRSxw/viewform)