# Breaking Changes in Android (Kotlin) SDK 2.0.0

<p>This guide lists the breaking changes in the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/kotlin-sdk/" >Android (Kotlin)</a> SDK 2.0.0 and the device mode integrations released with it. Review them before you upgrade from an Android (Kotlin) SDK 1.x version.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="overview">Overview</h2><p>Android (Kotlin) SDK 2.0.0 has the following breaking changes:</p>
<ul>
<li>The SDK starts automatic sessions and sends <code>Application Installed</code> or <code>Application Updated</code> when the user first opens the app. Before 2.0.0, it did this when it initialized.</li>
<li>By default, background events no longer carry <code>sessionId</code> or <code>sessionStart</code>.</li>
<li>One session configuration parameter has a new name.</li>
<li>All device mode integrations have a new major version that requires SDK 2.0.0.</li>
<li>The CleverTap integration requires a newer CleverTap Android SDK and a higher <code>minSdk</code>.</li>
</ul>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="upgrade-the-sdk-and-integrations-together">Upgrade the SDK and integrations together</h2><p>The device mode integrations released with SDK 2.0.0 require SDK 2.0.0 or later. Upgrade the SDK and all integrations in the same app release:</p>
<table>
  <thead>
      <tr>
          <th>Package</th>
          <th>Version</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>com.rudderstack.sdk.kotlin:android</code></td>
          <td>2.0.0</td>
      </tr>
      <tr>
          <td><code>com.rudderstack.integration.kotlin:adjust</code></td>
          <td>2.0.0</td>
      </tr>
      <tr>
          <td><code>com.rudderstack.integration.kotlin:appsflyer</code></td>
          <td>3.0.0</td>
      </tr>
      <tr>
          <td><code>com.rudderstack.integration.kotlin:braze</code></td>
          <td>2.0.0</td>
      </tr>
      <tr>
          <td><code>com.rudderstack.integration.kotlin:clevertap</code></td>
          <td>2.0.0</td>
      </tr>
      <tr>
          <td><code>com.rudderstack.integration.kotlin:facebook</code></td>
          <td>2.0.0</td>
      </tr>
      <tr>
          <td><code>com.rudderstack.integration.kotlin:firebase</code></td>
          <td>2.0.0</td>
      </tr>
      <tr>
          <td><code>com.rudderstack.integration.kotlin:sprig</code></td>
          <td>2.0.0</td>
      </tr>
  </tbody>
</table>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="session-tracking">Session tracking</h2><p>A background event is an event that your app sends while it has no visible screen. Events sent from <code>Application.onCreate</code> before the first screen opens are also background events. A foreground service, for example in a music player, sends background events too.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="parameter-renamed">Parameter renamed</h3><p>The <code>updateSessionOnBackgroundEvents</code> parameter of <code>SessionConfiguration</code> is now <code>includeBackgroundEventsInSession</code>. The old name no longer exists. Code that uses it does not compile. The default value stays <code>false</code>. Its behavior also changes, as the next sections describe.</p>
<div class="rs-tabs">
	<div class="rs-tabs__list">
		<button type="button" class="rs-tabs__tab"
			id="tab-ecdbaf"
		
		>Kotlin</button>
		<button type="button" class="rs-tabs__tab"
			id="tab-cedfab"
		
		>Java</button>
	</div>
	
<div class="rs-tabs__panel" id="panel-ecdbaf">

<div class="rs-code">
  <div class="rs-code__head">kotlin<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-kotlin" data-lang="kotlin">// 1.7.0 to 1.8.0
SessionConfiguration(updateSessionOnBackgroundEvents = true)

// 2.0.0 and later
SessionConfiguration(includeBackgroundEventsInSession = true)</code></pre></div>
</div>

</div>

<div class="rs-tabs__panel" id="panel-cedfab" hidden>

<div class="rs-code">
  <div class="rs-code__head">java<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-java" data-lang="java">// 1.7.0 to 1.8.0
new SessionConfigurationBuilder().setUpdateSessionOnBackgroundEvents(true).build();

// 2.0.0 and later
new SessionConfigurationBuilder().setIncludeBackgroundEventsInSession(true).build();</code></pre></div>
</div>

</div>

</div>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="sessions-start-when-the-user-opens-the-app">Sessions start when the user opens the app</h3><table>
  <thead>
      <tr>
          <th>Before 2.0.0</th>
          <th>2.0.0 and later</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>The SDK starts or continues a session when it initializes. This also happens when Android starts the app in the background, for example to deliver a push notification.</td>
          <td>When the user first opens the app, the SDK continues the stored session. If no session exists or the stored one timed out, the SDK starts a new one.</td>
      </tr>
  </tbody>
</table>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><strong>Impact:</strong> When <code>includeBackgroundEventsInSession</code> is <code>false</code>, a background app start no longer creates a session. Your session count can decrease after the upgrade.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="background-events-when-includebackgroundeventsinsession-is-false-default">Background events when <code>includeBackgroundEventsInSession</code> is <code>false</code> (default)</h3><table>
  <thead>
      <tr>
          <th>Before 2.0.0</th>
          <th>2.0.0 and later</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Background events carry <code>sessionId</code>. They do not extend the session after the user leaves the app. In an app that Android starts in the background, they can extend it.</td>
          <td>Background events do not carry <code>sessionId</code> or <code>sessionStart</code>, and they do not extend the session.</td>
      </tr>
      <tr>
          <td><code>analytics.sessionId</code> returns the stored session ID in the background.</td>
          <td><code>analytics.sessionId</code> returns <code>null</code> in the background.</td>
      </tr>
  </tbody>
</table>
<p>These rules apply to automatic sessions. In a manual session, background events carry <code>sessionId</code> as before.</p>
<p>The SDK&rsquo;s lifecycle events (<code>Application Installed</code>, <code>Application Updated</code>, <code>Application Opened</code>, and <code>Application Backgrounded</code>) carry <code>sessionId</code> in the background. They do not extend the session. The SDK matches these events by name. A <code>track</code> event from your app with one of these names also carries <code>sessionId</code>.</p>

<!DOCTYPE html>
<html lang="en">
<blockquote class="tip">
  <div class="tip-quote">
    
    <div class="tip-text"><strong>Action:</strong> If your app tracks user activity from the background or from a foreground service, set <code>includeBackgroundEventsInSession</code> to <code>true</code>.</div>
  </div>
</blockquote>
</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="background-events-when-includebackgroundeventsinsession-is-true">Background events when <code>includeBackgroundEventsInSession</code> is <code>true</code></h3><table>
  <thead>
      <tr>
          <th>Before 2.0.0</th>
          <th>2.0.0 and later</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>A background event after the session timeout continues the old session.</td>
          <td>A background event after the session timeout starts a new session.</td>
      </tr>
  </tbody>
</table>
<p>From 2.0.0, a background event also starts a new session when no session exists. For example, your app can send an event when a push notification arrives. If the user has not opened the app yet, that event starts a session. When the user opens the app within the timeout, the same session continues.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="sessionstart-can-be-on-any-event"><code>sessionStart</code> can be on any event</h3><p>The SDK sets <code>context.sessionStart</code> on the first event that carries the ID of a new session. Before 2.0.0, this was usually <code>Application Installed</code> or <code>Application Opened</code>. From 2.0.0, this is more often an app event, for example a background event that starts a session.</p>

<!DOCTYPE html>
<html lang="en">
<blockquote class="tip">
  <div class="tip-quote">
    
    <div class="tip-text"><strong>Action:</strong> Some reports or transformations find new sessions by <code>sessionStart</code> on one event name. Change them to read <code>sessionStart</code> on any event.</div>
  </div>
</blockquote>
</html>
<p>See <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/client-side-features/session-tracking/" >Session Tracking in Mobile SDKs</a> for the full session rules.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="lifecycle-events">Lifecycle events</h2><table>
  <thead>
      <tr>
          <th>Before 2.0.0</th>
          <th>2.0.0 and later</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>The SDK sends <code>Application Installed</code> or <code>Application Updated</code> when it initializes. This also happens when Android starts the app in the background.</td>
          <td>The SDK sends <code>Application Installed</code> or <code>Application Updated</code> when the user first opens the app.</td>
      </tr>
  </tbody>
</table>
<p>If a user installs your app and never opens it, the SDK does not send <code>Application Installed</code>. If Android starts the app in the background first, the SDK sends the event later, when the user opens the app.</p>
<p>See <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/client-side-features/lifecycle-events-tracking/" >Application Lifecycle Tracking in Mobile SDKs</a> for more information.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="clevertap-integration">CleverTap integration</h2><p>The CleverTap integration 2.0.0 has the following breaking changes:</p>
<table>
  <thead>
      <tr>
          <th>Change</th>
          <th>Before 2.0.0</th>
          <th>2.0.0 and later</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>CleverTap Android SDK version</td>
          <td><code>[7.3.1, 7.7.0)</code></td>
          <td><code>[8.4.1, 9.0.0)</code></td>
      </tr>
      <tr>
          <td><code>minSdk</code></td>
          <td>21</td>
          <td>23</td>
      </tr>
      <tr>
          <td>Activity tracking</td>
          <td>The integration forwards the activity callbacks to CleverTap.</td>
          <td>The integration calls CleverTap&rsquo;s <code>ActivityLifecycleCallback.register</code>. CleverTap tracks app launches, notification clicks, deep links, and in-app messages itself.</td>
      </tr>
  </tbody>
</table>
<p>Note the following:</p>
<ul>
<li>If your app declares an older CleverTap Android SDK version, Gradle replaces it with the newest version in the range <code>[8.4.1, 9.0.0)</code>.</li>
<li>If your app pins an older version with <code>strictly</code>, the build fails. Do not force an older version with <code>force</code>.</li>
<li>If your app calls the CleverTap SDK directly, review the <a href="https://github.com/CleverTap/clevertap-android-sdk/blob/master/CHANGELOG.md" >CleverTap Android SDK changelog</a> for the changes up to your new version.</li>
<li>If your app creates the CleverTap instance itself before RudderStack initializes the destination, for example by calling <code>ActivityLifecycleCallback.register</code> or <code>CleverTapAPI.getDefaultInstance</code>, add your CleverTap credentials to the manifest. Without them, RudderStack cannot create the CleverTap destination.</li>
</ul>
<p>See <a href="https://www.rudderstack.com/docs/destinations/streaming-destinations/clevertap/" >CleverTap</a> for the setup steps.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="upgrade-checklist">Upgrade checklist</h2><ol>
<li>Upgrade the SDK and all device mode integrations to the versions in <a href="#upgrade-the-sdk-and-integrations-together" >Upgrade the SDK and integrations together</a>.</li>
<li>In Kotlin, rename <code>updateSessionOnBackgroundEvents</code> to <code>includeBackgroundEventsInSession</code>. In Java, rename <code>setUpdateSessionOnBackgroundEvents</code> to <code>setIncludeBackgroundEventsInSession</code>.</li>
<li>Set <code>includeBackgroundEventsInSession</code> to <code>true</code> if your app tracks user activity from the background or from a foreground service.</li>
<li>Review reports and transformations that count sessions, use <code>sessionStart</code>, or expect <code>sessionId</code> on background events.</li>
<li>If you use the CleverTap integration, set <code>minSdk</code> to 23 or higher. Then read the notes in <a href="#clevertap-integration" >CleverTap integration</a>.</li>
</ol>

