# FAQ sobre o SDK Android da Pushwoosh

* [Como são o token de push do Android e o HWID?](#what-does-android-push-token-and-hwid-look-like)
* [Como posso obter o token de push do meu dispositivo Android?](#how-can-i-obtain-my-android-device-push-token)
* [Quais permissões são necessárias e quais são opcionais?](#what-permissions-are-necessary-and-what-are-optional)
* [Como eu defino um UserID?](#how-do-i-set-a-userid)
* [Qual é a precisão do número total de assinantes do Android?](#how-accurate-is-the-total-number-of-android-subscribers)
* [Posso usar tags HTML em pushes enviados para o Android?](#can-i-use-html-tags-in-pushes-sent-to-android)
* [Como definir um ícone de notificação no Android Lollipop (e versões posteriores)?](#how-to-set-a-notification-icon-in-android-lollipop-and-later-versions)
* [Usando o SDK da Pushwoosh com outros serviços FCM](#using-pushwoosh-sdk-with-other-fcm-services)
* [Usando a Pushwoosh com as bibliotecas LeakCanary ou AppMetrica](#using-pushwoosh-with-leakcanary-or-appmetrica-libraries)
* [Excluindo uma notificação recebida de um dispositivo](#deleting-particular-received-notifications-from-a-device)

### Como são o token de push do Android e o HWID?

Os tokens de push de dispositivos Android diferem em comprimento (menos de 255 caracteres) e começam com **APA91b**, por exemplo:

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

Os tokens geralmente contêm um prefixo separado por dois pontos antes de **APA91b**, por exemplo: `eQnyCE6ULAQ:APA91bGrh4ya3b_owo9tshZNVAGhZdGMGb3sA5HbM...`

A Pushwoosh usa UUIDs como HWIDs, ou seja, strings geradas aleatoriamente de 32 caracteres alfanuméricos: `123e4567-e89b-12d3-a456-426655440000`

### Como posso obter o token de push do meu dispositivo Android?

Você pode obter o token de push do seu dispositivo Android no log do console. Use a ferramenta logcat no [Android Studio](https://developer.android.com/studio).

Abra o **monitor.bat** em `%USERPROFILE%\AppData\Local\Android\sdk\tools\monitor.bat`, conecte seu dispositivo ao PC e permita a depuração USB nas configurações do Android. Execute seu aplicativo no dispositivo. Localize `/registerDevice`, encontre o token de push para o seu dispositivo para usar em Dispositivos de Teste mais tarde.

<img src="/android-push-notifications-android-faq-1.webp" alt="Captura de tela mostrando a saída do logcat com informações de registro do token de push exibidas no Android Studio"/>

### Quais permissões são necessárias e quais são opcionais?

Quando instalado em um dispositivo Android, o aplicativo solicitará as seguintes permissões em conexão com o SDK da Pushwoosh:

```java
<!-- O FCM se conecta aos Serviços do Firebase. -->
 <uses-permission android:name="android.permission.INTERNET"/>

<!-- Impede que o processador entre em modo de suspensão quando uma mensagem é recebida. -->
 <uses-permission android:name="android.permission.WAKE_LOCK"/>

 <!-- Esta permissão é usada para determinar se o dispositivo pode acessar a rede. -->
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<!-- Este aplicativo tem permissão para registrar e receber mensagens de dados. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
```

Nosso SDK não solicita permissão para acessar imagens, contatos do dispositivo, etc.

### Como eu defino um UserID?

Você pode definir um [identificador de usuário (UserID)](/pt/developer/first-steps/collecting-user-ids/), que pode ser um ID do Facebook, nome de usuário, e-mail ou qualquer outro ID de usuário exclusivo. Isso permite que você combine dados e eventos em vários dispositivos associados ao mesmo usuário. Para definir o UserID, chame o método **setUserId**.

**Exemplo**

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

### Qual é a precisão do número total de assinantes do Android?

A Pushwoosh limpa os dispositivos Android não inscritos do banco de dados ao receber a resposta "NotRegistered" do FCM, que pode ser retornada após a segunda tentativa de alcançar um dispositivo específico. Isso significa que você precisa enviar 2 pushes para um dispositivo não inscrito para que ele seja removido do banco de dados.

O seguinte é o cenário mais comum descrito na [documentação do FCM](https://firebase.google.com/docs/cloud-messaging/):

1. Seu assinante desinstala o aplicativo.
2. A Pushwoosh envia uma mensagem para o servidor FCM.
3. O servidor FCM envia a mensagem para o dispositivo do seu usuário.
4. O cliente FCM no dispositivo recebe a mensagem e detecta que seu aplicativo foi desinstalado; os detalhes da detecção dependem da plataforma em que o aplicativo está sendo executado.
5. O cliente FCM no dispositivo informa ao servidor FCM que o aplicativo foi desinstalado.
6. O servidor FCM marca o ID de registro para exclusão.
7. A Pushwoosh envia outra mensagem para o FCM.
8. O FCM retorna uma mensagem NotRegistered.
9. A Pushwoosh remove o token de push da sua base de usuários.

Pode levar um tempo para que o ID de registro seja completamente removido do FCM. Assim, é possível que uma mensagem enviada na etapa 7 acima receba um ID de mensagem válido como resposta, mesmo que a mensagem não seja entregue ao aplicativo cliente.

### Posso usar tags HTML em pushes enviados para o Android?

Sim, no Android você pode usar as seguintes tags HTML para modificar a aparência de um push:

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

Coloque essas tags HTML no campo de entrada **Mensagem** e use-as na solicitação da API também. Alguns dispositivos Android podem não processar essas tags HTML corretamente, mas a maioria dos dispositivos exibe a formatação corretamente.

### Como definir um ícone de notificação no Android Lollipop (e versões posteriores)?

No Android Lollipop, os ícones foram alterados para serem apenas brancos. Portanto, se você selecionar **targetSdkVersion >= 21** em seu arquivo **AndroidManifest.xml**, o Android usará apenas o canal alfa do ícone.\
Veja mais sobre o comportamento na [documentação do Android](https://developer.android.com/docs).

O sistema ignora todos os canais não alfa nos ícones de ação e no ícone de notificação principal. Suponha que esses ícones serão apenas alfa. O sistema desenha os ícones de notificação em branco e os ícones de ação em cinza escuro. _Isso está além do controle do SDK da Pushwoosh_.

**1.** Crie o ícone de notificação de acordo com as [diretrizes do Android](https://material.io/design/platform-guidance/android-notifications.html#style). Conforme a [documentação](https://developer.android.com/about/versions/lollipop/android-5.0-changes), o sistema ignorará todas as cores.

**2.** Nomeie o ícone como `pw_notification.png` e coloque-o na pasta **res/drawable**. O SDK da Pushwoosh usará este ícone como padrão para notificações.

**3.** Alternativamente, você pode usar a API Remota e definir o valor do parâmetro `"android_icon"` para a imagem do ícone (sem a extensão do arquivo).

### Usando o SDK da Pushwoosh com outros serviços FCM

Você pode usar a Pushwoosh junto com outros SDKs que usam o FCM para mensagens push. Para fazer isso, crie um serviço de roteador para distribuir eventos entre os serviços. Primeiro, adicione a dependência **pushwoosh-firebase** junto com o módulo principal da Pushwoosh:

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

Crie a classe de roteamento:

<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)) {
           //este é um push da Pushwoosh, o SDK o manipulará automaticamente
            PushwooshFcmHelper.onMessageReceived(this, remoteMessage)
        } else {
            //este não é um push da Pushwoosh, você deve manipulá-lo por conta própria
            dispatchNonPushwooshMessage(remoteMessage);
        }
    }

    private fun dispatchNonPushwooshMessage(remoteMessage: RemoteMessage) {
       // Implemente sua lógica de manipulação de push aqui
   }
}
```
</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)) {
            //este é um push da Pushwoosh, o SDK o manipulará automaticamente
            PushwooshFcmHelper.onMessageReceived(this, remoteMessage);
        } else {
            //este não é um push da Pushwoosh, você deve manipulá-lo por conta própria
            dispatchNonPushwooshMessage(remoteMessage);
        }
    }

    private void dispatchNonPushwooshMessage(RemoteMessage remoteMessage) {
        // Implemente sua lógica de manipulação de push aqui
    }
}
```
</TabItem>
</Tabs>

Registre os roteadores em seu AndroidManifest.xml:

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

### Usando a Pushwoosh com as bibliotecas LeakCanary ou AppMetrica

Quando você integra ferramentas de análise como LeakCanary, AppMetrica ou outras, essas bibliotecas iniciam um novo processo, criando uma nova instância do aplicativo. Como você não pode ouvir as notificações push em outro processo, isso resulta no lançamento de `java.lang.NullPointerException`.

Se você chamar `registerForPushNotifications` dentro de `Application.onCreate()`, você deve verificar se está no processo principal do aplicativo. Use o seguinte código para realizar esta verificação:

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

### Excluindo notificações recebidas específicas de um dispositivo localmente

Se você deseja remover um push não relevante ao executar uma ação específica dentro do seu aplicativo, pode usar a seguinte abordagem:

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

				//cancelar pushes apenas com um sinalizador específico
				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());
		}
	}
}
```

## Compartilhe seu feedback conosco

Seu feedback nos ajuda a criar uma experiência melhor. Se você enfrentar alguma dificuldade durante o processo de integração do SDK, compartilhe suas ideias conosco [através deste formulário](https://docs.google.com/forms/d/e/1FAIpQLSd_0b8jwn-V_JmoPLIxIFYbHACCQhrzidOZV3ELywoQPXRSxw/viewform).