> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/en/development-guide/flutter/push-message/flutter-android-push-message.md).

# Android Push Message Integration

{% stepper %}
{% step %}
**Connect Firebase Project**

To use push messages in an Android app, you need to configure the integration between the Hackle Workspace and a Firebase project.

For details, refer to [Android FCM Integration](/en/external-link/crm-channels/fcm-integration.md).
{% endstep %}

{% step %}
**Integrate Firebase Cloud Messaging SDK**

Complete the Android app setup by following the [Firebase SDK Integration Guide](https://firebase.google.com/docs/android/setup) and the [Firebase Cloud Messaging Installation Guide](https://firebase.google.com/docs/cloud-messaging/android/client).
{% endstep %}

{% step %}
**Integrate with Hackle SDK**

Add the Hackle SDK dependency and initialize the SDK by following the [SDK Integration](/en/development-guide/flutter.md) guide.

The push token is automatically registered when the app launches.

{% hint style="info" %}
Once the SDK integration is complete, push tokens are automatically collected and push message reception and click handling become available.
{% endhint %}
{% endstep %}

{% step %}
**Test Push Message**

**Check Token**

* You can check the token set on the Android device via the [Check User Identifier guide](https://docs.hackle.io/en/development-guide/flutter/push-message/pages/8kjmUWUYN7kpyIkpWPBy#사용자-식별자-확인하기).
* You can check the Android push token assigned to a specific user via the [User Profile guide](/en/user-view/user-profile.md).

**Send Test**

* Follow the [Push Message Test Send Guide](/en/crm-marketing/push-message-guide/create-campaign.md#id-3-1) to verify the push message on an Android device.
  {% endstep %}

{% step %}
**Receive Push Message**

When a push message is received, an icon is displayed in the status bar and notification center.

* On Samsung Galaxy Android smartphones, the app icon is displayed.
* On standard Android smartphones or simulators, a white circle icon is displayed.
* If you have configured a push message icon change, the changed icon is displayed.
  {% endstep %}
  {% endstepper %}

## Deep Link Navigation

Hackle push messages support deep link navigation when tapped.

When the corresponding activity is opened via a push message, you can retrieve the deep link information using the method below.

For more details about Flutter deep links, refer to the [Flutter Deep Linking Guide](https://docs.flutter.dev/ui/navigation/deep-linking).

## Change Push Message Icon

{% hint style="info" %}
This feature is supported in Flutter SDK 2.22.0 and above.
{% endhint %}

{% hint style="warning" %}
Due to Google's policy, icons with color cannot be set as push icons on standard Android smartphones.
{% endhint %}

Hackle push messages support changing the push icon. By assigning a resource to a reserved key in `AndroidManifest.xml`, you can change the push icon using local resources within the app.

Image and color resources to be used for the push icon must be added to Android Resources.

{% hint style="info" %}
For details about small\_icon, large\_icon, and color, refer to the [Android Push Design Guide](https://developer.android.com/design/ui/mobile/guides/home-screen/notifications?hl=ko#notification-header).
{% endhint %}

<table><thead><tr><th width="360">key</th><th>Description</th></tr></thead><tbody><tr><td><code>io_hackle_android_default_notification_small_icon</code></td><td>Sets the small icon.</td></tr><tr><td><code>io_hackle_android_default_notification_large_icon</code></td><td>Sets the large icon.</td></tr><tr><td><code>io_hackle_android_default_notification_color</code></td><td>Sets the small icon background color.</td></tr></tbody></table>

#### Example

```xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <application
        android:label="flutter_app"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">

       ...
       <meta-data
            android:name="io_hackle_android_default_notification_small_icon"
            android:resource="@drawable/ic_push_small"/>

       <meta-data
            android:name="io_hackle_android_default_notification_large_icon"
            android:resource="@drawable/ic_push_large"/>

       <meta-data
            android:name="io_hackle_android_default_notification_color"
            android:resource="@color/pie" />
       ...
    </application>
</manifest>
```

### Modify Push Message Icon from Dashboard

If a push icon is configured in the Dashboard, it modifies the large icon of the push.

If a push icon is set using local resources and a push icon is also sent from the Dashboard, the icon configured in the Dashboard is used.

## Push Channel Support

{% hint style="info" %}
This feature is supported in Flutter SDK 2.23.0 and above.
{% endhint %}

With Hackle push messages, you can receive pushes on channels pre-declared within the app. If a push is received with a channel ID that does not exist in the app, it is received on the default channel provided by Hackle.

{% hint style="info" %}
For detailed instructions on adding push channels to your app, refer to the [Android Developer Documentation](https://developer.android.com/develop/ui/views/notifications/channels?hl=ko).

If you want to show a notification popup when a push is received, as on iOS, set the channel importance to `IMPORTANCE_HIGH`.
{% endhint %}

#### Example

The following is an example of creating a channel in the `onCreate` function of the MainActivity class.

```kotlin
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import io.flutter.embedding.android.FlutterActivity


class MainActivity: FlutterActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel(applicationContext, "importance", "importance", NotificationManager.IMPORTANCE_HIGH)
        }
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel(context: Context, channelId: String, channelName: String, importance: Int) {
        val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (notificationManager.getNotificationChannel(channelId) != null) {
            return
        }

        val channel = NotificationChannel(
            channelId,
            channelName,
            importance
        )
        notificationManager.createNotificationChannel(channel)
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hackle.io/en/development-guide/flutter/push-message/flutter-android-push-message.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
