# Audience Management Integrate audience management features into your app. This guide covers how to identify contacts, access channel IDs, and set tags, attributes, and subscription lists on channels and contacts. For information about using these features for segmentation and targeting, see the [Audience User Guide]({{< ref "/guides/audience/segmentation/segmentation.md" >}}). # Channels > Access and manage channel IDs, listen for channel creation, and configure the channel capture tool. Each device or app install generates a unique identifier known as the Channel ID. Once a Channel ID is created, it persists in the application until the app is reinstalled or its internal data is cleared. For information about finding Channel IDs, using the Channel Capture tool, and other methods to access Channel IDs, see [Finding Channel IDs](https://www.airship.com/docs/guides/getting-started/developers/identifiers/). ## Accessing the Airship Channel ID Apps can access the Channel ID directly through the SDK. #### Kotlin ```kotlin val channelId = Airship.channel.id ``` #### Java ```java String channelId = Airship.getChannel().getId(); ``` The SDK creates the Channel ID asynchronously, so it may not be available immediately on the first run. The SDK automatically batches and applies changes to Channel data when the Channel is created, so you do not need to wait for the Channel to be available before modifying data. Applications that need to access the Channel ID can use a listener to receive notification when it becomes available. #### Kotlin Using `channelIdFlow` (StateFlow): ```kotlin // channelIdFlow is a StateFlow that emits the channel ID when it's created scope.launch { Airship.channel.channelIdFlow.collect { channelId -> channelId?.let { Log.d("Sample", "Channel created: $it") } } } ``` Using `addChannelListener`: ```kotlin Airship.channel.addChannelListener { channelId -> Log.d("Sample", "Channel created: $channelId") } ``` #### Java Using `addChannelListener`: ```java Airship.getChannel().addChannelListener(new AirshipChannelListener() { @Override public void onChannelCreated(@NonNull String channelId) { // created } }); ``` ## Channel Capture tool The Channel Capture tool is a feature built into the SDK that helps users find their Channel ID. For detailed information about how it works and how to use it, see [Finding Channel IDs](https://www.airship.com/docs/guides/getting-started/developers/identifiers/). The Channel Capture tool can be disabled through the Airship Config options passed to `takeOff` during SDK initialization. For information about setting up the Airship SDK and configuring `AirshipConfigOptions`, see [Android SDK Setup](https://www.airship.com/docs/developer/sdk-integration/android/installation/getting-started/). #### Kotlin ```kotlin val options = airshipConfigOptions { // ... setChannelCaptureEnabled(false) } ``` #### Java ```java AirshipConfigOptions options = AirshipConfigOptions.newBuilder() // ... .setChannelCaptureEnabled(false) .build(); ``` ## Delaying channel creation Airship creates the channel if at least one feature is enabled in the Privacy Manager. To delay channel creation, use the Privacy Manager to disable all features during initialization. For more information about Privacy Manager, see [Privacy Manager](https://www.airship.com/docs/developer/sdk-integration/android/data-collection/privacy-manager/). # Contacts > Identify contacts, reset contacts, and get named user IDs. A Contact is any user in your project. Contacts are identified as either an Anonymous Contact or a Named User. Airship can set targeting data on these identifiers, which are also used to map devices and channels to a specific user. For detailed information about contacts and named users, see [Named users](https://www.airship.com/docs/guides/audience/named-users/). ## Managing the Contact's identifier (Named User ID) You can call `identify` multiple times with the same Named User ID. The SDK automatically deduplicates `identify` calls made with the same Named User ID. If you change the ID from a previous value, the SDK automatically dissociates the Contact from the previous Named User ID. #### Kotlin ```kotlin Airship.contact.identify("some named user ID") ``` #### Java ```java Airship.getContact().identify("some named user ID"); ``` If the user logs out of the device, you may want to reset the contact. Resetting clears any anonymous data and dissociates the contact from the Named User ID, if set. Call this method only when the user manually logs out of the app. Otherwise, you cannot target the Channel by its Contact data. #### Kotlin ```kotlin Airship.contact.reset() ``` #### Java ```java Airship.getContact().reset(); ``` You can retrieve the Named User ID only if you set it through the SDK. #### Kotlin ```kotlin Airship.contact.namedUserId ``` #### Java ```java Airship.getContact().getNamedUserId(); ``` ### Email channel association When an email address is registered through the SDK, it will be registered for both transactional and commercial emails by default. To change this behavior, you can override the options to request [[Double Opt-In](https://www.airship.com/docs/reference/glossary/#double_opt_in)](https://www.airship.com/docs/developer/api-integrations/email/getting-started/#double-opt-in) for commercial messages. #### Kotlin ```kotlin val properties = JsonMap.newBuilder().put("place", "paris").build() val options = EmailRegistrationOptions.commercialOptions(commercialDate, transactionalDate, properties) Airship.contact.registerEmail("your@example.com", options) ``` #### Java ```java JsonMap properties = JsonMap.newBuilder().put("place", "paris").build(); EmailRegistrationOptions options = EmailRegistrationOptions.commercialOptions(commercialDate, transactionalDate, properties); Airship.getContact().registerEmail("your@example.com", options); ``` ### SMS channel association When an [MSISDN](https://www.airship.com/docs/reference/glossary/#msisdn) is registered through the SDK, Airship sends a message to that number, prompting them to opt in. For more information, see the SMS platform documentation: [Non-Mobile Double Opt-In](https://www.airship.com/docs/developer/api-integrations/sms/opt-in-out-handling/#non-mobile-double-opt-in). #### Kotlin ```kotlin val options = SmsRegistrationOptions.options("senderId") Airship.contact.registerSms("yourMsisdn", options) ``` #### Java ```java SmsRegistrationOptions options = SmsRegistrationOptions.options("senderId"); Airship.getContact().registerSms("yourMsisdn", options); ``` ### Open Channel association Open Channels support notifications to any medium that can accept a JSON payload, through either the Airship API or web dashboard. For more information about Open Channels, see the [Open Channels documentation](https://www.airship.com/docs/developer/api-integrations/open/getting-started/). #### Kotlin ```kotlin val options = OpenChannelRegistrationOptions.options("platformName") Airship.contact.registerOpenChannel("address", options) ``` #### Java ```java OpenChannelRegistrationOptions options = OpenChannelRegistrationOptions.options("platformName"); Airship.getContact().registerOpenChannel("address", options); ``` # Tags > Set device tags, contact tags, and tag groups for audience segmentation. For information about tags, including how to use them for segmentation and targeting, see the [Tags user guide](https://www.airship.com/docs/guides/audience/tags/). ## Channel Tags Channel tags are tags managed on the Channel by the SDK. Device tags (tags without a group) can be modified or fetched from the Channel. #### Kotlin ```kotlin Airship.channel.editTags { addTag("some_tag") removeTag("some_other_tag") } // Accessing channel tags val tags = Airship.channel.tags ``` #### Java ```java Airship.getChannel().editTags() .addTag("some_tag") .removeTag("some_other_tag") .apply(); // Accessing channel tags ArrayList tags = Airship.getChannel().getTags(); ``` ## Channel Tag Groups Tag groups are tags scoped within a group. Tag groups can be modified from the SDK but cannot be fetched. Device tags (tags without a group) can be fetched. If you need to be able to fetch tag groups, consider using subscription lists. #### Kotlin ```kotlin Airship.channel.editTagGroups { addTag("loyalty", "bronze-member") removeTag("loyalty", "bronze-member") setTag("games", "bingo") } ``` #### Java ```java Airship.getChannel().editTagGroups() .addTag("loyalty", "bronze-member") .removeTag("loyalty", "bronze-member") .setTag("games", "bingo") .apply(); ``` ## Contact Tag Groups Contact tag groups are tags scoped within a group at the Contact level. Tag groups can be modified from the SDK but cannot be fetched. If you need to be able to fetch tag groups, consider using subscription lists. #### Kotlin ```kotlin Airship.contact.editTagGroups { addTag("loyalty", "bronze-member") removeTag("loyalty", "bronze-member") setTag("games", "bingo") } ``` #### Java ```java Airship.getContact().editTagGroups() .addTag("loyalty", "bronze-member") .removeTag("loyalty", "bronze-member") .setTag("games", "bingo") .apply(); ``` ## Verifying Tags To verify that tags have been set correctly, look up the channel or contact in the [Contact Management](https://www.airship.com/docs/guides/audience/contact-management/) view. You can search by Channel ID or Named User ID to view the tags and tag groups associated with a channel or contact. # Attributes > Set channel and contact attributes as key-value pairs for personalization. For information about Attributes, including overview, use cases, and how to target Attributes, see [About Attributes](https://www.airship.com/docs/guides/audience/attributes/about/). ## Channel Attributes Channel attributes are attributes managed on the Channel by the SDK. #### Kotlin ```kotlin Airship.channel.editAttributes { setAttribute("device_name", "Bobby's Phone") setAttribute("average_rating", 4.99) removeAttribute("vip_status") } ``` #### Java ```java Airship.getChannel().editAttributes() .setAttribute("device_name", "Bobby's Phone") .setAttribute("average_rating", 4.99) .removeAttribute("vip_status") .apply(); ``` ## Contact Attributes Contact attributes are attributes managed on the Contact by the SDK. #### Kotlin ```kotlin Airship.contact.editAttributes { setAttribute("first_name", "Bobby") setAttribute("birthday", Date(524300400000)) } ``` #### Java ```java Airship.getContact().editAttributes() .setAttribute("first_name", "Bobby") .setAttribute("birthday", Date(524300400000)) .apply(); ``` ## JSON Attributes JSON Attributes are data objects containing one or more string, number, date, or boolean key-value pairs. You can set and remove JSON Attributes on a Channel or a Contact. #### Kotlin ```kotlin Airship.contact.editAttributes { setAttribute( attribute = "attribute_name", instanceId = "instance_id", expiration = Date(), json = jsonMapOf( "key" to "value", "another_key" to "another_value" ) ) } ``` ## Verifying Attributes To verify that attributes are set correctly, look up the channel or contact in the [Contact Management](https://www.airship.com/docs/guides/audience/contact-management/) view. Search by Channel ID or Named User ID to view the attributes associated with a channel or contact. # Subscription Lists > Manage channel and contact subscription lists for topic-based messaging. For information about Subscription Lists, including overview, use cases, and how to create subscription lists, see [Subscription Lists](https://www.airship.com/docs/guides/audience/segmentation/audience-lists/subscription/). ## Channel Subscription Lists Channel subscriptions apply only to the single channel. #### Kotlin ```kotlin // Modifying channel subscription lists Airship.channel.editSubscriptionLists { subscribe("food") unsubscribe("sports") } // Fetching channel subscription lists val channelSubscriptions = Airship.channel.fetchSubscriptionLists() ``` #### Java ```java // Modifying channel subscription lists Airship.getChannel().editSubscriptionLists() .subscribe("food") .unsubscribe("sports") .apply(); // Fetching channel subscription lists PendingResult> channelSubscriptions = Airship.getChannel().fetchSubscriptionListsPendingResult(); ``` ## Contact Subscription Lists Contact subscriptions are set at the user level and require a Channel scope that specifies the types to which the subscription list applies. #### Kotlin ```kotlin // Modifying contact subscription lists Airship.contact.editSubscriptionLists { subscribe("food", "app") unsubscribe("sports", "sms") } // Fetching contact subscription lists val contactSubscriptions = Airship.contact.fetchSubscriptionLists() ``` #### Java ```java // Modifying contact subscription lists Airship.getContact().editSubscriptionLists() .subscribe("food", "app") .unsubscribe("sports", "sms") .apply(); // Fetching contact subscription lists PendingResult>> contactSubscriptions = Airship.getContact().fetchSubscriptionListsPendingResult(); ``` ## Verifying Subscription Lists To verify that subscription lists are set correctly, look up the channel or contact in the [Contact Management](https://www.airship.com/docs/guides/audience/contact-management/) view. Search by Channel ID or Named User ID to view the subscription lists associated with a channel or contact.